summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-10-28 22:26:53 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-10-28 22:26:53 (GMT)
commit8c71b36d401b2473342daddcb9b7eb4b83ba3295 (patch)
tree13515f99f3e01fc2d1701189e500fa69763da7f9 /src/analysis
parent2c70e3332b43bdcbe215081b697395d254418e48 (diff)
Optimized access to instruction sources and destinations.
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/blocks/flow.c20
-rw-r--r--src/analysis/db/items/comment.c6
-rw-r--r--src/analysis/decomp/il.c6
-rw-r--r--src/analysis/disass/dragon.c29
-rw-r--r--src/analysis/disass/links.c19
-rw-r--r--src/analysis/disass/loop.c11
-rw-r--r--src/analysis/disass/rank.c31
7 files changed, 59 insertions, 63 deletions
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c
index 970fc21..0f278bd 100644
--- a/src/analysis/blocks/flow.c
+++ b/src/analysis/blocks/flow.c
@@ -565,8 +565,7 @@ void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa2t *start,
bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlowBlock *target)
{
bool result; /* Bilan à retourner */
- 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 */
vmpa_t addr; /* Adresse de la destination */
@@ -575,23 +574,23 @@ bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlo
result = (block == target);
g_arch_instruction_rlock_dest(block->last);
- dcount = g_arch_instruction_get_destinations(block->last, &dests, &types);
+ dcount = g_arch_instruction_get_destinations(block->last, &dests);
for (i = 0; i < dcount && !result; i++)
- switch (types[i])
+ switch (dests[i].type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
case ILT_CASE_JUMP:
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
+ g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr);
next = g_instr_block_find_by_addr(list, addr, true);
result = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, target);
break;
case ILT_LOOP:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
+ g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr);
next = g_instr_block_find_by_addr(list, addr, true);
result = (G_FLOW_BLOCK(next) == target);
default:
@@ -625,8 +624,7 @@ bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlo
bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollowPosition mask, flow_block_follow_cb callback, void *data)
{
bool result; /* Bilan à retourner */
- 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 */
vmpa_t addr; /* Adresse de la destination */
@@ -638,10 +636,10 @@ bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollow
result = callback(block, BFP_ENTER, data);
g_arch_instruction_rlock_dest(block->last);
- dcount = g_arch_instruction_get_destinations(block->last, &dests, &types);
+ dcount = g_arch_instruction_get_destinations(block->last, &dests);
for (i = 0; i < dcount && result; i++)
- switch (types[i])
+ switch (dests[i].type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -649,7 +647,7 @@ bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollow
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
+ g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr);
next = g_instr_block_find_by_addr(list, addr, true);
if (next)
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 6ce3d05..453d649 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -520,7 +520,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
GBufferLine *line; /* Ligne de tampon à marquer */
GArchProcessor *proc; /* Propriétaire d'instructions */
GArchInstruction *instr; /* Instruction à traiter */
- GArchInstruction **sources; /* Instructions diverses liées */
+ instr_link_t *sources; /* Instructions diverses liées */
size_t scount; /* Nbre de sources affichées */
size_t i; /* Boucle de parcours */
const mrange_t *range; /* Emplacement d'instruction */
@@ -613,7 +613,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
assert(instr != NULL);
- scount = g_arch_instruction_get_sources(instr, &sources, NULL);
+ scount = g_arch_instruction_get_sources(instr, &sources);
if (apply)
{
@@ -624,7 +624,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
for (i = 0; i < scount && result; i++)
{
- range = g_arch_instruction_get_range(sources[i]);
+ range = g_arch_instruction_get_range(sources[i].linked);
/**
* On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL.
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c
index 36b5dfe..f19dd1a 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -610,7 +610,7 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB
vmpa_t common_addr; /* Adresse commune de suite */
bool is_common; /* Suite commune ? */
GArchInstruction *last; /* Dernière instruction de bloc*/
- GArchInstruction **dests; /* Instr. visée par une autre */
+ instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t j; /* Boucle de parcours #2 */
vmpa_t addr; /* Adresse d'une instruction */
@@ -638,11 +638,11 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB
for (i = 0; i < lcount && is_common; i++)
{
g_flow_block_get_boundary(G_FLOW_BLOCK(leafs[i]), NULL, &last);
- dcount = g_arch_instruction_get_destinations(last, &dests, NULL);
+ dcount = g_arch_instruction_get_destinations(last, &dests);
for (j = 0; j < dcount && is_common; j++)
{
- g_arch_instruction_get_location(dests[j], NULL, NULL, &addr);
+ g_arch_instruction_get_location(dests[j].linked, NULL, NULL, &addr);
if (common_addr == VMPA_MAX)
common_addr = addr;
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.