summaryrefslogtreecommitdiff
path: root/src/analysis/disass/rank.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass/rank.c')
-rw-r--r--src/analysis/disass/rank.c318
1 files changed, 17 insertions, 301 deletions
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c
index 6e737a5..b4a8f92 100644
--- a/src/analysis/disass/rank.c
+++ b/src/analysis/disass/rank.c
@@ -24,270 +24,12 @@
#include "rank.h"
-
-
-#if 0
-
-#include <assert.h>
-#include <sys/param.h>
-
-
-#include "../blocks/flow.h"
-#include "../blocks/virtual.h"
-
-
-
-/* Classe le contenu d'un bloc d'instructions exécutées. */
-static bool rank_flow_block(GFlowBlock *, BlockVisitOrder, const GInstrBlock *);
-
-
-
-/******************************************************************************
-* *
-* Paramètres : block = bloc d'instructions concerné par la visite. *
-* order = indication quant au sens de visite. *
-* list = ensemble des blocs basiques à parcourir. *
-* *
-* Description : Classe le contenu d'un bloc d'instructions exécutées. *
-* *
-* Retour : true pour continuer la visite. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GInstrBlock *list)
-{
- unsigned int next; /* Rang suivant obtenu */
- GInstrBlock *links; /* Blocs liés au bloc courant */
- GArchInstruction *last; /* Dernière instruction du bloc*/
- 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; /* Emplacement d'une cible */
- GFlowBlock *target; /* Bloc ciblé par un lien */
- unsigned int rank; /* Rang à constituer */
-
- /* Si le bloc visité n'est pas basique... */
- if (order != BVO_PENDING) return true;
-
- next = g_flow_block_get_rank(block) + 1;
-
- links = g_instr_block_get_links_block(G_INSTR_BLOCK(block));
-
- g_flow_block_get_boundary(block, NULL, &last);
-
- g_arch_instruction_lock_dest(last);
- dcount = g_arch_instruction_count_destinations(last);
-
- for (i = 0; i < dcount; i++)
- {
- dest = g_arch_instruction_get_destination(last, i);
-
- range = g_arch_instruction_get_range(dest->linked);
-
- switch (dest->type)
- {
- case ILT_EXEC_FLOW:
- case ILT_CATCH_EXCEPTION:
- target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true));
- //assert(target != NULL);
- break;
-
- case ILT_JUMP:
- target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true));
-
- /**
- * Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
- * Par exemple sous ARM :
- *
- * 00008358 <call_gmon_start>:
- * ....
- * 8362: f7ff bfcf b.w 8304 <_init+0x38>
- * ....
- *
- */
- /* assert(target != NULL);*/
-
- break;
-
- case ILT_CASE_JUMP:
- target = G_FLOW_BLOCK(g_instr_block_find_by_addr(links, get_mrange_addr(range), true));
- //assert(target != NULL);
- break;
-
- case ILT_JUMP_IF_TRUE:
- case ILT_JUMP_IF_FALSE:
-
- /**
- * Même dans les branches if/then/else, il n'y a pas forcément de groupe de blocs
- * associé. C'est par exemple le cas dans des constructions telles que celle de
- * la fonction __libc_csu_init() :
- *
- * if (...)
- * do
- * {
- * ...
- * }
- * while (...)
- *
- * ...
- *
- * Le code final est étiquetté comme étant le 'else' de la première condition,
- * donc au niveau de la condition de bouclage, il appartient déjà à un autre
- * et n'est donc pas réattribué une seconde fois.
- *
- */
-
- if (links != NULL)
- target = G_FLOW_BLOCK(g_instr_block_find_by_addr(links, get_mrange_addr(range), true));
- else
- target = NULL;
-
- /**
- * Le bloc visé ne se trouve pas toujours dans les blocs attachés :
- *
- * { bloc IF }
- * { bloc THEN }
- * { block NEXT }
- *
- * Le bloc NEXT est ici à rechercher dans la liste globale.
- */
-
- if (target == NULL)
- target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true));
-
- //assert(target != NULL);
-
- break;
-
- default:
- target = NULL;
- break;
-
- }
-
- unref_instr_link(dest);
-
- if (target != NULL)
- {
- rank = MAX(next, g_flow_block_get_rank(target));
-
- g_flow_block_set_rank(target, rank);
-
- }
-
- }
-
- g_arch_instruction_unlock_dest(last);
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : routine = routine regroupant les blocs à traiter. *
-* *
-* Description : Classe les blocs des routines. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void rank_routine_blocks(GBinRoutine *routine)
-{
- GInstrBlock *main_block; /* Ensemble des blocs d'instr. */
-
- main_block = g_binary_routine_get_basic_blocks(routine);
-
-
- if (main_block == NULL) return;
-
-
- g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block);
-
-
-#if 0
-
- printf("===== BLOCK(S) xXXx ======\n");
-
-
- bool visit_ranked_block(GInstrBlock *blk, BlockVisitOrder order, int *indent)
- {
- int i;
-
- switch (order)
- {
- case BVO_IN:
- case BVO_PENDING:
-
- for (i = 0; i < *indent; i++)
- printf(" ");
-
- printf("%p '%s'", blk, G_OBJECT_TYPE_NAME(blk));
-
- if (G_IS_FLOW_BLOCK(blk))
- {
- vmpa2t start;
- vmpa2t end;
-
- g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blk), &start, &end);
-
- printf(" 0x%08x -> 0x%08x (rank = %u)",
- (unsigned int)start.virtual,
- (unsigned int)end.virtual,
- g_flow_block_get_rank(G_FLOW_BLOCK(blk)));
-
- }
-
- printf("\n");
-
- if (order == BVO_IN) (*indent)++;
- break;
-
- case BVO_OUT:
- (*indent)--;
- break;
-
- }
-
- return true;
-
- }
-
- g_instr_block_visit(main_block, (instr_block_visitor_cb)visit_ranked_block, (int []){ 0 });
-
- printf("\n");
-
-
-#endif
-
-
-
-
-}
-
-
-
-#endif
-
-
-
-
-
-
-
#include <assert.h>
/* Classe les blocs basiques d'une routine. */
-void rank_routine_block(const GBlockList *, GBasicBlock *);
-
+void rank_routine_block(const GBlockList *, GCodeBlock *);
@@ -304,27 +46,23 @@ void rank_routine_block(const GBlockList *, GBasicBlock *);
* *
******************************************************************************/
-void rank_routine_block(const GBlockList *list, GBasicBlock *block)
+void rank_routine_block(const GBlockList *list, GCodeBlock *block)
{
- unsigned int next; /* Rang suivant obtenu */
- GArchInstruction *last; /* Dernière instruction du bloc*/
+ size_t next; /* Rang suivant obtenu */
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 block_link_t *dest; /* Instr. visée par une autre */
InstructionLinkType type; /* Raccourci pour confort */
- GBasicBlock *target; /* Bloc ciblé par un lien */
unsigned int rank; /* Rang à constituer */
- next = g_basic_block_get_rank(block) + 1;
-
- g_basic_block_get_boundary(block, NULL, &last);
+ next = g_code_block_get_rank(block) + 1;
- g_arch_instruction_lock_dest(last);
- dcount = g_arch_instruction_count_destinations(last);
+ g_code_block_lock_dest(block);
+ dcount = g_code_block_count_destinations(block);
for (i = 0; i < dcount; i++)
{
- dest = g_arch_instruction_get_destination(last, i);
+ dest = g_code_block_get_destination(block, i);
type = dest->type;
@@ -343,30 +81,13 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
&& type != ILT_JUMP_IF_FALSE)
goto next_dest;
- target = g_block_list_find_by_starting_instr(list, dest->linked);
+ rank = g_code_block_get_rank(dest->linked);
- /**
- * Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
- * Par exemple sous ARM :
- *
- * 00008358 <call_gmon_start>:
- * ....
- * 8362: f7ff bfcf b.w 8304 <_init+0x38>
- * ....
- *
- */
-
- if (target != NULL)
+ if (next > rank || rank == -1)
{
- rank = g_basic_block_get_rank(target);
-
- if (next > rank || rank == -1)
- {
- g_basic_block_set_rank(target, next);
+ g_code_block_set_rank(dest->linked, next);
- rank_routine_block(list, target);
-
- }
+ rank_routine_block(list, dest->linked);
}
@@ -376,7 +97,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
}
- g_arch_instruction_unlock_dest(last);
+ g_code_block_unlock_dest(block);
}
@@ -396,22 +117,17 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
void rank_routine_blocks(GBinRoutine *routine)
{
GBlockList *blocks; /* Ensemble des blocs d'instr. */
- GBasicBlock *start; /* Bloc basique de départ */
+ GCodeBlock *start; /* Bloc basique de départ */
blocks = g_binary_routine_get_basic_blocks(routine);
- start = g_block_list_get_block(blocks, 0 /* FIXME */);
+ start = g_block_list_get_block(blocks, 0);
assert(start != NULL);
-
- g_basic_block_set_rank(start, 0);
-
+ g_code_block_set_rank(start, 0);
rank_routine_block(blocks, start);
-
-
-
-
+ g_object_unref(G_OBJECT(start));
}