diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2013-01-05 13:30:19 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2013-01-05 13:30:19 (GMT) |
commit | d626276398a3cdd3cd6432e073a8866aa91418ce (patch) | |
tree | 15e4b325ebb0636b26058cd39fda3e1e87b534cc /src/analysis/blocks | |
parent | bfd81d1f289913f4d6e09cd8d99f4aaeed98436b (diff) |
Refined the definition of basic blocks and used them to build extra clusters for dot.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@317 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/blocks')
-rw-r--r-- | src/analysis/blocks/flow.c | 62 | ||||
-rw-r--r-- | src/analysis/blocks/flow.h | 3 | ||||
-rw-r--r-- | src/analysis/blocks/virtual.c | 54 | ||||
-rw-r--r-- | src/analysis/blocks/virtual.h | 3 |
4 files changed, 116 insertions, 6 deletions
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c index f80b7c8..85d98ee 100644 --- a/src/analysis/blocks/flow.c +++ b/src/analysis/blocks/flow.c @@ -65,15 +65,18 @@ static void g_flow_block_dispose(GFlowBlock *); /* Procède à la libération totale de la mémoire. */ static void g_flow_block_finalize(GFlowBlock *); +/* Parcours le bloc d'instructions dans un ordre donné. */ +static bool g_flow_block_visit(GFlowBlock *, instr_block_visitor_cb, void *); + +/* Etablit la liste de tous les blocs présents. */ +static void g_flow_block_list_all_blocks(const GFlowBlock *, GInstrBlock ***, size_t *); + /* Prend note de l'usage d'un registre, au besoin. */ static void g_flow_block_memorize_access(GFlowBlock *, GArchRegister *, RegAccessType, vmpa_t); /* Note les différents accès aux registres. */ static void g_flow_block_compute_regs_access(GFlowBlock *); -/* Etablit la liste de tous les blocs présents. */ -static void g_flow_block_list_all_blocks(const GFlowBlock *, GInstrBlock ***, size_t *); - /* Fournit les différents accès aux registres. */ static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *, size_t *); @@ -125,6 +128,7 @@ static void g_flow_block_init(GFlowBlock *block) parent = G_INSTR_BLOCK(block); + parent->visit_blocks = (visit_all_blocks_fc)g_flow_block_visit; parent->list_blocks = (list_all_blocks_fc)g_flow_block_list_all_blocks; parent->list_regs = (list_regs_accesses_fc)g_flow_block_list_regs_accesses; @@ -199,7 +203,7 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first, { GFlowBlock *result; /* Structure à retourner */ - vmpa_t addr; /* Adresse de la destination */ + //vmpa_t addr; /* Adresse de la destination */ result = g_object_new(G_TYPE_FLOW_BLOCK, NULL); @@ -232,6 +236,27 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first, /****************************************************************************** * * +* Paramètres : block = bloc d'instructions concerné par la visite. * +* callback = ensemble de blocs à parcourir. * +* data = donnée utilisateur à associer au parcours. * +* * +* Description : Parcours le bloc d'instructions dans un ordre donné. * +* * +* Retour : true si le parcours a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_flow_block_visit(GFlowBlock *block, instr_block_visitor_cb callback, void *data) +{ + return callback(G_INSTR_BLOCK(block), BVO_PENDING, data); + +} + + +/****************************************************************************** +* * * Paramètres : block = bloc d'instructions à consulter. * * list = ensemble de blocs à compléter. [OUT] * * count = nombre de blocs au total. [OUT] * @@ -394,6 +419,28 @@ static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *block /****************************************************************************** * * * Paramètres : block = bloc d'instructions à consulter. * +* first = instruction de départ du bloc. [OUT] * +* last = dernière instruction du bloc. [OUT] * +* * +* Description : Fournit les instructions limites d'un bloc d'exécution. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_flow_block_get_boundary(const GFlowBlock *block, GArchInstruction **first, GArchInstruction **last) +{ + *first = block->first; + *last = block->last; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * * start = adresse de départ du bloc. [OUT] * * end = dernière adresse du bloc. [OUT] * * * @@ -407,7 +454,10 @@ static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *block void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa_t *start, vmpa_t *end) { - g_arch_instruction_get_location(block->first, NULL, NULL, start); - g_arch_instruction_get_location(block->last, NULL, NULL, end); + if (start != NULL) + g_arch_instruction_get_location(block->first, NULL, NULL, start); + + if (end != NULL) + g_arch_instruction_get_location(block->last, NULL, NULL, end); } diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h index 14f49ec..8bd7257 100644 --- a/src/analysis/blocks/flow.h +++ b/src/analysis/blocks/flow.h @@ -55,6 +55,9 @@ GType g_flow_block_get_type(void); /* Crée un bloc d'exécution d'instructions. */ GInstrBlock *g_flow_block_new(GArchInstruction *, GArchInstruction *, GArchInstruction *); +/* Fournit les instructions limites d'un bloc d'exécution. */ +void g_flow_block_get_boundary(const GFlowBlock *, GArchInstruction **, GArchInstruction **); + /* Fournit les adresses limites d'un bloc d'exécution. */ void g_flow_block_get_boundary_addresses(const GFlowBlock *, vmpa_t *, vmpa_t *); diff --git a/src/analysis/blocks/virtual.c b/src/analysis/blocks/virtual.c index c981ece..90bccca 100644 --- a/src/analysis/blocks/virtual.c +++ b/src/analysis/blocks/virtual.c @@ -69,6 +69,9 @@ static void g_virtual_block_dispose(GVirtualBlock *); /* Procède à la libération totale de la mémoire. */ static void g_virtual_block_finalize(GVirtualBlock *); +/* Parcours le bloc d'instructions dans un ordre donné. */ +static bool g_virtual_block_visit(GVirtualBlock *, instr_block_visitor_cb, void *); + /* Etablit la liste de tous les blocs présents. */ static void g_virtual_block_list_all_blocks(const GVirtualBlock *, GInstrBlock ***, size_t *); @@ -123,6 +126,7 @@ static void g_virtual_block_init(GVirtualBlock *block) parent = G_INSTR_BLOCK(block); + parent->visit_blocks = (visit_all_blocks_fc)g_virtual_block_visit; parent->list_blocks = (list_all_blocks_fc)g_virtual_block_list_all_blocks; parent->list_regs = (list_regs_accesses_fc)g_virtual_block_list_regs_accesses; @@ -203,6 +207,37 @@ GInstrBlock *g_virtual_block_new(void) /****************************************************************************** * * +* Paramètres : block = bloc d'instructions concerné par la visite. * +* callback = ensemble de blocs à parcourir. * +* data = donnée utilisateur à associer au parcours. * +* * +* Description : Parcours le bloc d'instructions dans un ordre donné. * +* * +* Retour : true si le parcours a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_virtual_block_visit(GVirtualBlock *block, instr_block_visitor_cb callback, void *data) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = callback(G_INSTR_BLOCK(block), BVO_IN, data); + + for (i = 0; i < block->children_count && result; i++) + result = g_instr_block_visit(block->children[i], callback, data); + + result &= callback(G_INSTR_BLOCK(block), BVO_OUT, data); + + return true; + +} + + +/****************************************************************************** +* * * Paramètres : block = bloc d'instructions à consulter. * * list = ensemble de blocs à compléter. [OUT] * * count = nombre de blocs au total. [OUT] * @@ -270,3 +305,22 @@ void g_virtual_block_add_child(GVirtualBlock *block, GInstrBlock *child) g_object_ref(G_OBJECT(child)); } + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * +* * +* Description : Compte le nombre de blocs contenus dans le groupe courant. * +* * +* Retour : Quantité normalement non nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_virtual_block_count_children(GVirtualBlock *block) +{ + return block->children_count; + +} diff --git a/src/analysis/blocks/virtual.h b/src/analysis/blocks/virtual.h index f1f559f..5e8ddcd 100644 --- a/src/analysis/blocks/virtual.h +++ b/src/analysis/blocks/virtual.h @@ -58,6 +58,9 @@ GInstrBlock *g_virtual_block_new(void); /* Ajoute un bloc au groupe courant. */ void g_virtual_block_add_child(GVirtualBlock *, GInstrBlock *); +/* Compte le nombre de blocs contenus dans le groupe courant. */ +size_t g_virtual_block_count_children(GVirtualBlock *); + #endif /* _ANALYSIS_BLOCKS_VIRTUAL_H */ |