diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-01-13 23:44:21 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-01-13 23:44:21 (GMT) |
commit | 2a6d92e2d55c0a7826137b2cc2e3148bb298abb9 (patch) | |
tree | 55714d85528a4cbe15e802b8a7bc2cdbf861c744 /src/analysis/disass | |
parent | 2ed3c9274c8dafb660bc25743a1aac7c72c12965 (diff) |
Provided uncached code block links.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/block.c | 114 | ||||
-rw-r--r-- | src/analysis/disass/rank.c | 13 |
2 files changed, 113 insertions, 14 deletions
diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c index 6cf7c17..23393f6 100644 --- a/src/analysis/disass/block.c +++ b/src/analysis/disass/block.c @@ -25,6 +25,7 @@ #include <assert.h> +#include <malloc.h> #include "../block-int.h" @@ -70,8 +71,11 @@ static void g_basic_block_finalize(GBasicBlock *); /* Détermine si un bloc de code débute à une adresse donnée. */ static bool g_basic_block_is_starting_with(const GBasicBlock *, const vmpa2t *); -/* Etablit les liens entre un bloc de code et ses voisins. */ -static void g_basic_block_resolve_links(GBasicBlock *, const GBlockList *); +/* Fournit les détails des origines d'un bloc de code donné. */ +static block_link_t *g_basic_block_get_sources(const GBasicBlock *, const GBlockList *, size_t *); + +/* Fournit les détails des destinations de bloc de code. */ +static block_link_t *g_basic_block_get_destinations(const GBasicBlock *, const GBlockList *, size_t *); /* Fournit la représentation graphique d'un bloc de code. */ static GBufferView *g_basic_block_build_view(const GBasicBlock *, segcnt_list *); @@ -112,7 +116,8 @@ static void g_basic_block_class_init(GBasicBlockClass *class) block = G_CODE_BLOCK_CLASS(class); block->is_starting = (block_is_starting_fc)g_basic_block_is_starting_with; - block->link = (block_resolve_links_fc)g_basic_block_resolve_links; + block->get_src = (block_get_links_fc)g_basic_block_get_sources; + block->get_dest = (block_get_links_fc)g_basic_block_get_destinations; block->build = (block_build_view_fc)g_basic_block_build_view; } @@ -248,24 +253,102 @@ static bool g_basic_block_is_starting_with(const GBasicBlock *block, const vmpa2 /****************************************************************************** * * -* Paramètres : block = bloc de code à mettre à jour. * +* Paramètres : block = bloc dont les informations sont à consulter. * * list = ensemble des blocs de code à disposition. * +* count = nombre de ces origines. [OUT] * * * -* Description : Etablit les liens entre un bloc de code et ses voisins. * +* Description : Fournit les détails des origines d'un bloc de code donné. * * * -* Retour : - * +* Retour : Liens déterminés vers des blocs de code d'origine. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static block_link_t *g_basic_block_get_sources(const GBasicBlock *block, const GBlockList *list, size_t *count) +{ + block_link_t *result; /* Détails présents à renvoyer */ + size_t scount; /* Nombre de liens d'origine */ + size_t i; /* Boucle de parcours */ + const instr_link_t *src; /* Instr. visée par une autre */ + const mrange_t *range; /* Couverture d'instruction */ + GCodeBlock *target; /* Bloc ciblé par un lien */ + block_link_t *new; /* Nouvelle entrée à définir */ + + result = NULL; + *count = 0; + + g_arch_instruction_lock_src(block->first); + scount = g_arch_instruction_count_sources(block->first); + + for (i = 0; i < scount; i++) + { + src = g_arch_instruction_get_source(block->first, i); + + range = g_arch_instruction_get_range(src->linked); + + target = g_block_list_find_by_starting_addr(list, get_mrange_addr(range)); + + /** + * Les liens ne sont pas toujours internes ! + */ + + if (target != NULL) + { + result = realloc(result, ++(*count) * sizeof(block_link_t)); + + new = &result[*count - 1]; + + new->linked = target; + new->type = src->type; + + /** + * On pourrait par optimisation retirer les deux lignes suivantes... + */ + + ref_block_link(new); + + g_object_unref(G_OBJECT(target)); + + } + + unref_instr_link(src); + + } + + g_arch_instruction_unlock_src(block->first); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc dont les informations sont à consulter. * +* list = ensemble des blocs de code à disposition. * +* count = nombre de ces destinations. [OUT] * +* * +* Description : Fournit les détails des destinations de bloc de code. * +* * +* Retour : Liens déterminés vers des blocs de code de destination. * * * * Remarques : - * * * ******************************************************************************/ -static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *list) +static block_link_t *g_basic_block_get_destinations(const GBasicBlock *block, const GBlockList *list, size_t *count) { + block_link_t *result; /* Détails présents à renvoyer */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ const instr_link_t *dest; /* Instr. visée par une autre */ const mrange_t *range; /* Couverture d'instruction */ GCodeBlock *target; /* Bloc ciblé par un lien */ + block_link_t *new; /* Nouvelle entrée à définir */ + + result = NULL; + *count = 0; g_arch_instruction_lock_dest(block->last); dcount = g_arch_instruction_count_destinations(block->last); @@ -291,8 +374,21 @@ static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *li if (target != NULL) { - g_code_block_link_with(G_CODE_BLOCK(block), target, dest->type); + result = realloc(result, ++(*count) * sizeof(block_link_t)); + + new = &result[*count - 1]; + + new->linked = target; + new->type = dest->type; + + /** + * On pourrait par optimisation retirer les deux lignes suivantes... + */ + + ref_block_link(new); + g_object_unref(G_OBJECT(target)); + } unref_instr_link(dest); @@ -301,6 +397,8 @@ static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *li g_arch_instruction_unlock_dest(block->last); + return result; + } diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index b6eb4c5..d703aee 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -50,19 +50,19 @@ void rank_routine_block(const GBlockList *list, GCodeBlock *block) { size_t next; /* Rang suivant obtenu */ size_t dcount; /* Nombre de liens de dest. */ + block_link_t *links; /* Liens associés au bloc */ size_t i; /* Boucle de parcours */ - const block_link_t *dest; /* Instr. visée par une autre */ + block_link_t *dest; /* Bloc visé par un autre */ InstructionLinkType type; /* Raccourci pour confort */ unsigned int rank; /* Rang à constituer */ next = g_code_block_get_rank(block) + 1; - g_code_block_lock_dest(block); - dcount = g_code_block_count_destinations(block); + links = g_code_block_get_destinations(block, &dcount); for (i = 0; i < dcount; i++) { - dest = g_code_block_get_destination(block, i); + dest = &links[i]; type = dest->type; @@ -93,11 +93,12 @@ void rank_routine_block(const GBlockList *list, GCodeBlock *block) next_dest: - unref_instr_link(dest); + unref_block_link(dest); } - g_code_block_unlock_dest(block); + if (links != NULL) + free(links); } |