diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-10-28 22:26:53 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-10-28 22:26:53 (GMT) |
commit | 8c71b36d401b2473342daddcb9b7eb4b83ba3295 (patch) | |
tree | 13515f99f3e01fc2d1701189e500fa69763da7f9 /src/analysis/disass | |
parent | 2c70e3332b43bdcbe215081b697395d254418e48 (diff) |
Optimized access to instruction sources and destinations.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/dragon.c | 29 | ||||
-rw-r--r-- | src/analysis/disass/links.c | 19 | ||||
-rw-r--r-- | src/analysis/disass/loop.c | 11 | ||||
-rw-r--r-- | src/analysis/disass/rank.c | 31 |
4 files changed, 44 insertions, 46 deletions
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c index c817727..6220014 100644 --- a/src/analysis/disass/dragon.c +++ b/src/analysis/disass/dragon.c @@ -101,11 +101,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ GArchInstruction *last; /* Mémorisation du passé */ GArchInstruction *iter; /* Boucle de parcours */ const mrange_t *irange; /* Emplacement d'instruction */ - InstructionLinkType *types; /* Type de lien entre instr. */ + instr_link_t *sources; /* Liste des instructions liées*/ size_t scount; /* Nombre de liens de source */ bool cut; /* Un découpage a été réalisé ?*/ size_t i; /* Boucle de parcours */ dragon_node *new; /* Nouvel élément à créer */ + instr_link_t *dests; /* Liste des instructions liées*/ size_t dcount; /* Nombre de liens de dest. */ result = NULL; @@ -165,12 +166,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ /* Analyse des sources */ g_arch_instruction_rlock_src(iter); - scount = g_arch_instruction_get_sources(iter, NULL, &types); + scount = g_arch_instruction_get_sources(iter, &sources); cut = false; for (i = 0; i < scount && !cut; i++) - switch (types[i]) + switch (sources[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -209,12 +210,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ /* Analyse des destinations */ g_arch_instruction_rlock_dest(iter); - dcount = g_arch_instruction_get_destinations(iter, NULL, &types); + dcount = g_arch_instruction_get_destinations(iter, &dests); cut = false; for (i = 0; i < dcount && !cut; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_JUMP: @@ -431,18 +432,17 @@ void compute_all_paths(dragon_node *nodes, size_t count) { void follow_flow_in_nodes(dragon_node *node) { - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Liste des instructions liées*/ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ dragon_node *next; /* Noeud suivant dans le code */ size_t id; /* Indice du bit associé */ g_arch_instruction_rlock_dest(node->last); - dcount = g_arch_instruction_get_destinations(node->last, &dests, &types); + dcount = g_arch_instruction_get_destinations(node->last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -450,7 +450,7 @@ void compute_all_paths(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - next = find_node_for_instruction(nodes, count, false, dests[i]); + next = find_node_for_instruction(nodes, count, false, dests[i].linked); if (next == NULL) break; id = get_dragon_node_index(nodes, next); @@ -514,8 +514,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count) size_t k; /* Boucle de parcours #1 */ dragon_node *node; /* Noeud à traiter */ dragon_node *predecessor; /* Noeud prédécesseur direct */ - GArchInstruction **srcs; /* Instructions d'origine */ - InstructionLinkType *types; /* Type de lien entre instr. */ + instr_link_t *sources; /* Instructions d'origine */ size_t scount; /* Nombre de liens de source */ size_t i; /* Boucle de parcours #2 */ @@ -532,11 +531,11 @@ void compute_all_dominators(dragon_node *nodes, size_t count) set_all_in_bit_field(inter); g_arch_instruction_rlock_src(node->first); - scount = g_arch_instruction_get_sources(node->first, &srcs, &types); + scount = g_arch_instruction_get_sources(node->first, &sources); //assert(scount > 0); // un 'ret' coupe, le suivant n'a pas de source for (i = 0; i < scount; i++) - switch (types[i]) + switch (sources[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -544,7 +543,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - predecessor = find_node_for_instruction(nodes, count, true, srcs[i]); + predecessor = find_node_for_instruction(nodes, count, true, sources[i].linked); /* printf(" -- finding pred @ 0x%08x -> 0x%08x :: %p\n", diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 294274f..9a6749e 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -52,8 +52,7 @@ static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) { bool has_src; /* Présence de sources ? */ - GArchInstruction **others; /* Instructions diverses liées */ - InstructionLinkType *types; /* Types de lien existants */ + instr_link_t *others; /* Instructions diverses liées */ size_t count; /* Nbre de sources affichées */ size_t i; /* Boucle de parcours */ @@ -85,14 +84,14 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) */ g_arch_instruction_rlock_dest(prev); - count = g_arch_instruction_get_destinations(prev, &others, &types); + count = g_arch_instruction_get_destinations(prev, &others); for (i = 0; i < count; i++) { - if (types[i] == ILT_EXEC_FLOW) break; - if (types[i] == ILT_JUMP) break; - if (types[i] == ILT_CASE_JUMP) break; - if (types[i] == ILT_LOOP) break; + if (others[i].type == ILT_EXEC_FLOW) break; + if (others[i].type == ILT_JUMP) break; + if (others[i].type == ILT_CASE_JUMP) break; + if (others[i].type == ILT_LOOP) break; } g_arch_instruction_runlock_dest(prev); @@ -104,12 +103,12 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) */ g_arch_instruction_rlock_src(instr); - count = g_arch_instruction_get_sources(instr, &others, &types); + count = g_arch_instruction_get_sources(instr, &others); for (i = 0; i < count; i++) { - if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; - if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break; + if (others[i].linked == prev && others[i].type == ILT_JUMP_IF_TRUE) break; + if (others[i].linked == prev && others[i].type == ILT_JUMP_IF_FALSE) break; } g_arch_instruction_runlock_src(instr); diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 99121a8..204a7d6 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -49,8 +49,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) dragon_node *node; /* Noeud à traiter */ const bitfield_t *dominators; /* Liste de dominateurs */ GArchInstruction *last; /* Instruction finale de noeud */ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #2 */ dragon_node *target; /* Noeud référence à tester */ @@ -65,10 +64,10 @@ static void detect_back_edges(dragon_node *nodes, size_t count) get_dragon_node_bounding_instructions(node, NULL, &last); g_arch_instruction_wlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -76,7 +75,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - target = find_node_for_instruction(nodes, count, false, dests[i]); + target = find_node_for_instruction(nodes, count, false, dests[i].linked); if (target == NULL) break; id = get_dragon_node_index(nodes, target); @@ -90,7 +89,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) (unsigned int)g_arch_instruction_get_range(dests[i])->addr.virtual); */ - /* status = */g_arch_instruction_change_link(last, dests[i], types[i], ILT_LOOP); + /* status = */g_arch_instruction_change_link(last, dests[i].linked, dests[i].type, ILT_LOOP); } diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 3721ca0..cd5915c 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -61,8 +61,7 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns unsigned int next; /* Rang suivant obtenu */ GInstrBlock *links; /* Blocs liés au bloc courant */ GArchInstruction *last; /* Dernière instruction du bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ const mrange_t *range; /* Emplacement d'une cible */ @@ -79,13 +78,13 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns g_flow_block_get_boundary(block, NULL, &last); g_arch_instruction_rlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) { - range = g_arch_instruction_get_range(dests[i]); + range = g_arch_instruction_get_range(dests[i].linked); - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_CATCH_EXCEPTION: @@ -305,10 +304,10 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) { unsigned int next; /* Rang suivant obtenu */ GArchInstruction *last; /* Dernière instruction du bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ + InstructionLinkType type; /* Raccourci pour confort */ GBasicBlock *target; /* Bloc ciblé par un lien */ unsigned int rank; /* Rang à constituer */ @@ -317,26 +316,28 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) g_basic_block_get_boundary(block, NULL, &last); g_arch_instruction_rlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) { + type = dests[i].type; + /* La boucle de remontée n'abaisse pas les rangs */ - if (types[i] == ILT_LOOP) continue; + if (type == ILT_LOOP) continue; /** * On se doit de suivre le même cheminement que celui emprunté lors * du parcours de create_dragon_nodes(). * Sinon, les chemins divergent et une récursion infinie peut survenir. */ - if (types[i] != ILT_EXEC_FLOW - && types[i] != ILT_JUMP - && types[i] != ILT_CASE_JUMP - && types[i] != ILT_JUMP_IF_TRUE - && types[i] != ILT_JUMP_IF_FALSE) + if (type != ILT_EXEC_FLOW + && type != ILT_JUMP + && type != ILT_CASE_JUMP + && type != ILT_JUMP_IF_TRUE + && type != ILT_JUMP_IF_FALSE) continue; - target = g_block_list_find_by_starting_instr(list, dests[i]); + target = g_block_list_find_by_starting_instr(list, dests[i].linked); /** * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. |