summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--plugins/androhelpers/switch.c2
-rw-r--r--plugins/androhelpers/try_n_catch.c6
-rw-r--r--plugins/libcsem/exit.c15
-rw-r--r--src/analysis/db/items/comment.c8
-rw-r--r--src/analysis/decomp/il.c16
-rw-r--r--src/analysis/disass/dragon.c64
-rw-r--r--src/analysis/disass/links.c47
-rw-r--r--src/analysis/disass/loop.c19
-rw-r--r--src/analysis/disass/rank.c28
-rw-r--r--src/analysis/routine.c22
-rw-r--r--src/arch/instruction-int.h31
-rw-r--r--src/arch/instruction.c296
-rw-r--r--src/arch/instruction.h35
-rw-r--r--src/debug/debugger.c19
-rw-r--r--src/gtkext/graph/cluster.c42
-rw-r--r--src/gui/dialogs/gotox.c46
17 files changed, 349 insertions, 371 deletions
diff --git a/ChangeLog b/ChangeLog
index 5e243a0..fb22623 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+17-04-13 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/androhelpers/switch.c:
+ * plugins/androhelpers/try_n_catch.c:
+ * plugins/libcsem/exit.c:
+ * src/analysis/db/items/comment.c:
+ * src/analysis/decomp/il.c:
+ * src/analysis/disass/dragon.c:
+ * src/analysis/disass/links.c:
+ * src/analysis/disass/loop.c:
+ * src/analysis/disass/rank.c:
+ * src/analysis/routine.c:
+ Update code.
+
+ * src/arch/instruction-int.h:
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ Simplify the way links between instructions are handled.
+
+ * src/debug/debugger.c:
+ * src/gtkext/graph/cluster.c:
+ * src/gui/dialogs/gotox.c:
+ Update code.
+
17-04-09 Cyrille Bagard <nocbos@gmail.com>
* src/glibext/gbinportion.c:
diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c
index 275a6e7..20e6037 100644
--- a/plugins/androhelpers/switch.c
+++ b/plugins/androhelpers/switch.c
@@ -219,7 +219,7 @@ static void ensure_each_case_has_its_block(GArchInstruction *instr, GArchInstruc
prev = g_arch_instruction_get_prev_iter(instrs, instr);
if (prev != NULL
- && !g_arch_instruction_has_destinations(prev)
+ && g_arch_instruction_count_destinations(prev) == 0
&& !(g_arch_instruction_get_flags(prev) & AIF_RETURN_POINT))
{
g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW);
diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c
index 9052377..5dff71e 100644
--- a/plugins/androhelpers/try_n_catch.c
+++ b/plugins/androhelpers/try_n_catch.c
@@ -135,13 +135,13 @@ static void attach_caught_code(const GLoadedBinary *binary, const GBinRoutine *r
/* Si des détachements sont nécessaires... */
- if (!g_arch_instruction_has_sources(first) && try->start_addr > 0)
+ if (g_arch_instruction_count_sources(first) == 0 && try->start_addr > 0)
{
prev = g_arch_instruction_get_prev_iter(instrs, first);
g_arch_instruction_link_with(prev, first, ILT_EXEC_FLOW);
}
- if (!g_arch_instruction_has_sources(next) && (try->start_addr > 0 || try->insn_count > 0))
+ if (g_arch_instruction_count_sources(next) == 0 && (try->start_addr > 0 || try->insn_count > 0))
{
prev = g_arch_instruction_get_prev_iter(instrs, next);
g_arch_instruction_link_with(prev, next, ILT_EXEC_FLOW);
@@ -155,7 +155,7 @@ static void attach_caught_code(const GLoadedBinary *binary, const GBinRoutine *r
iter != NULL;
iter = g_arch_instruction_get_next_iter(instrs, iter, end))
{
- if (!g_arch_instruction_has_destinations(iter))
+ if (g_arch_instruction_count_destinations(iter) == 0)
continue;
for (i = 0; i < count; i++)
diff --git a/plugins/libcsem/exit.c b/plugins/libcsem/exit.c
index 6695787..6a21d5f 100644
--- a/plugins/libcsem/exit.c
+++ b/plugins/libcsem/exit.c
@@ -52,9 +52,9 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
const mrange_t *range; /* Emplacement du symbole */
GArchProcessor *proc; /* Architecture du binaire */
GArchInstruction *instr; /* Instruction de sortie */
- instr_link_t *sources; /* Instructions diverses liées */
size_t count; /* Nbre de sources affichées */
size_t i; /* Boucle de parcours */
+ instr_link_t *source; /* Instruction diverse liée */
format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
@@ -73,18 +73,21 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
if (instr == NULL)
goto mokoear_not_found;
- g_arch_instruction_rlock_src(instr);
- count = g_arch_instruction_get_sources(instr, &sources);
+ g_arch_instruction_lock_src(instr);
+
+ count = g_arch_instruction_count_sources(instr);
for (i = 0; i < count; i++)
{
- if (sources[i].type != ILT_CALL) continue;
+ source = g_arch_instruction_get_source(instr, i);
+
+ if (source->type != ILT_CALL) continue;
- g_arch_instruction_set_flag(sources[i].linked, AIF_RETURN_POINT);
+ g_arch_instruction_set_flag(source->linked, AIF_RETURN_POINT);
}
- g_arch_instruction_runlock_src(instr);
+ g_arch_instruction_unlock_src(instr);
g_object_unref(G_OBJECT(instr));
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 263f415..b43c1e6 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -581,9 +581,9 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
size_t index; /* Point d'insertion */
GArchProcessor *proc; /* Propriétaire d'instructions */
GArchInstruction *instr; /* Instruction à traiter */
- instr_link_t *sources; /* Instructions diverses liées */
size_t scount; /* Nbre de sources affichées */
size_t i; /* Boucle de parcours */
+ instr_link_t *source; /* Instruction diverse liée */
const mrange_t *range; /* Emplacement d'instruction */
size_t linked; /* Indice lié à traiter */
@@ -631,7 +631,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
instr = g_arch_processor_find_instr_by_address(proc, &comment->addr);
assert(instr != NULL);
- scount = g_arch_instruction_get_sources(instr, &sources);
+ scount = g_arch_instruction_count_sources(instr);
if (apply)
{
@@ -642,7 +642,9 @@ 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].linked);
+ source = g_arch_instruction_get_source(instr, i);
+
+ range = g_arch_instruction_get_range(source->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 e8ca49e..f409550 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -559,6 +559,8 @@ static void build_ite_branches(GITEInstruction *decomp, GFlowBlock *block, GDecC
g_object_unref(G_OBJECT(sub_ctx));
}
+ g_object_unref(G_OBJECT(next));
+
}
/* Branche 'false' */
@@ -576,6 +578,8 @@ static void build_ite_branches(GITEInstruction *decomp, GFlowBlock *block, GDecC
g_object_unref(G_OBJECT(sub_ctx));
}
+ g_object_unref(G_OBJECT(next));
+
}
g_ite_instruction_set_branches(decomp, true_dinstr, false_dinstr);
@@ -610,9 +614,9 @@ 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*/
- 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 */
+ instr_link_t *dest; /* Instr. visée par une autre */
vmpa_t addr; /* Adresse d'une instruction */
bool jump_to_case; /* Suite dans le cas suivant ? */
@@ -638,11 +642,15 @@ 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);
+
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (j = 0; j < dcount && is_common; j++)
{
- g_arch_instruction_get_location(dests[j].linked, NULL, NULL, &addr);
+ dest = g_arch_instruction_get_destination(last, j);
+
+ g_arch_instruction_get_location(dest->linked, NULL, NULL, &addr);
if (common_addr == VMPA_MAX)
common_addr = addr;
@@ -651,6 +659,8 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB
}
+ g_arch_instruction_unlock_dest(last);
+
}
/* La sortie du cas est unique ! */
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index b4c85c0..75ccc40 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -101,13 +101,13 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
GArchInstruction *last; /* Mémorisation du passé */
instr_iter_t *iter; /* Boucle de parcours */
GArchInstruction *instr; /* Instruction analysée */
- 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 */
+ instr_link_t *source; /* Instruction de source liée */
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. */
+ instr_link_t *dest; /* Instruction de destination */
result = NULL;
*count = 0;
@@ -163,13 +163,16 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
{
/* Analyse des sources */
- g_arch_instruction_rlock_src(instr);
- scount = g_arch_instruction_get_sources(instr, &sources);
+ g_arch_instruction_lock_src(instr);
+ scount = g_arch_instruction_count_sources(instr);
cut = false;
for (i = 0; i < scount && !cut; i++)
- switch (sources[i].type)
+ {
+ source = g_arch_instruction_get_source(instr, i);
+
+ switch (source->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -201,19 +204,24 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
}
- g_arch_instruction_runlock_src(instr);
+ }
+
+ g_arch_instruction_unlock_src(instr);
}
/* Analyse des destinations */
- g_arch_instruction_rlock_dest(instr);
- dcount = g_arch_instruction_get_destinations(instr, &dests);
+ g_arch_instruction_lock_dest(instr);
+ dcount = g_arch_instruction_count_destinations(instr);
cut = false;
for (i = 0; i < dcount && !cut; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(instr, i);
+
+ switch (dest->type)
{
case ILT_JUMP:
@@ -230,7 +238,9 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
}
- g_arch_instruction_runlock_dest(instr);
+ }
+
+ g_arch_instruction_unlock_dest(instr);
if (!need_alloc && g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
{
@@ -436,17 +446,20 @@ void compute_all_paths(dragon_node *nodes, size_t count)
{
void follow_flow_in_nodes(dragon_node *node)
{
- instr_link_t *dests; /* Liste des instructions liées*/
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
+ instr_link_t *dest; /* Instructions de destination */
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);
+ g_arch_instruction_lock_dest(node->last);
+ dcount = g_arch_instruction_count_destinations(node->last);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(node->last, i);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -454,7 +467,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].linked);
+ next = find_node_for_instruction(nodes, count, false, dest->linked);
if (next == NULL) break;
id = get_dragon_node_index(nodes, next);
@@ -470,7 +483,9 @@ void compute_all_paths(dragon_node *nodes, size_t count)
}
- g_arch_instruction_runlock_dest(node->last);
+ }
+
+ g_arch_instruction_unlock_dest(node->last);
}
@@ -518,9 +533,9 @@ 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 */
- instr_link_t *sources; /* Instructions d'origine */
size_t scount; /* Nombre de liens de source */
size_t i; /* Boucle de parcours #2 */
+ instr_link_t *source; /* Instruction d'origine */
inter = create_bit_field(count, false);
@@ -534,12 +549,15 @@ 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, &sources);
+ g_arch_instruction_lock_src(node->first);
+ scount = g_arch_instruction_count_sources(node->first);
//assert(scount > 0); // un 'ret' coupe, le suivant n'a pas de source
for (i = 0; i < scount; i++)
- switch (sources[i].type)
+ {
+ source = g_arch_instruction_get_source(node->first, i);
+
+ switch (source->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -547,7 +565,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, sources[i].linked);
+ predecessor = find_node_for_instruction(nodes, count, true, source->linked);
/*
printf(" -- finding pred @ 0x%08x -> 0x%08x :: %p\n",
@@ -567,7 +585,9 @@ void compute_all_dominators(dragon_node *nodes, size_t count)
}
- g_arch_instruction_runlock_src(node->first);
+ }
+
+ g_arch_instruction_unlock_src(node->first);
set_in_bit_field(inter, k, 1);
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index d67040b..e1bc58c 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -53,9 +53,9 @@ 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 ? */
- instr_link_t *others; /* Instructions diverses liées */
size_t count; /* Nbre de sources affichées */
+ bool has_src; /* Présence de sources ? */
+ instr_link_t *other; /* Instruction diverse liée */
size_t i; /* Boucle de parcours */
bool no_natural; /* Aucun lien naturel présent */
bool no_need; /* Pas de besoin pour ce lien */
@@ -65,17 +65,22 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
* on ne peut pas créer de lien plus naturel que l'existant.
*/
- g_arch_instruction_rlock_src(instr);
+ g_arch_instruction_lock_src(instr);
- count = g_arch_instruction_get_sources(instr, &others);
+ count = g_arch_instruction_count_sources(instr);
has_src = false;
for (i = 0; i < count && !has_src; i++)
- if (others[i].type != ILT_REF)
+ {
+ other = g_arch_instruction_get_source(instr, i);
+
+ if (other->type != ILT_REF)
has_src = true;
- g_arch_instruction_runlock_src(instr);
+ }
+
+ g_arch_instruction_unlock_src(instr);
if (!has_src)
return;
@@ -96,15 +101,18 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
* déjà en place.
*/
- g_arch_instruction_rlock_dest(prev);
+ g_arch_instruction_lock_dest(prev);
- count = g_arch_instruction_get_destinations(prev, &others);
+ count = g_arch_instruction_count_destinations(prev);
no_natural = true;
no_need = (count > 0);
for (i = 0; i < count && no_natural; i++)
- switch (others[i].type)
+ {
+ other = g_arch_instruction_get_destination(prev, i);
+
+ switch (other->type)
{
case ILT_EXEC_FLOW:
no_natural = false;
@@ -112,7 +120,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- if (others[i].linked != instr)
+ if (other->linked != instr)
no_need = false;
else
{
@@ -126,20 +134,25 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
}
+ }
+
check_done:
- g_arch_instruction_runlock_dest(prev);
+ g_arch_instruction_unlock_dest(prev);
if (no_natural && !no_need)
{
/* Vérification de la cohérence de l'ensemble */
#ifndef NDEBUG
- g_arch_instruction_rlock_src(instr);
- count = g_arch_instruction_get_sources(instr, &others);
+ g_arch_instruction_lock_src(instr);
+ count = g_arch_instruction_count_sources(instr);
for (i = 0; i < count; i++)
- switch (others[i].type)
+ {
+ other = g_arch_instruction_get_source(instr, i);
+
+ switch (other->type)
{
case ILT_EXEC_FLOW:
assert(false);
@@ -151,7 +164,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
case ILT_JUMP_IF_FALSE:
case ILT_LOOP:
case ILT_CATCH_EXCEPTION:
- assert(others[i].linked != prev);
+ assert(other->linked != prev);
break;
default:
@@ -159,7 +172,9 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
}
- g_arch_instruction_runlock_src(instr);
+ }
+
+ g_arch_instruction_unlock_src(instr);
#endif
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index d8ca355..b7e7ff9 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -49,9 +49,9 @@ 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 */
- 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 */
+ instr_link_t *dest; /* Instr. visée par une autre */
dragon_node *target; /* Noeud référence à tester */
size_t id; /* Indice du bit associé */
@@ -63,11 +63,14 @@ 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);
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(last, i);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -75,7 +78,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].linked);
+ target = find_node_for_instruction(nodes, count, false, dest->linked);
if (target == NULL) break;
id = get_dragon_node_index(nodes, target);
@@ -89,7 +92,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].linked, dests[i].type, ILT_LOOP);
+ /* status = */g_arch_instruction_change_link(last, dest->linked, dest->type, ILT_LOOP);
}
@@ -101,7 +104,9 @@ static void detect_back_edges(dragon_node *nodes, size_t count)
}
- g_arch_instruction_wunlock_dest(last);
+ }
+
+ g_arch_instruction_unlock_dest(last);
}
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c
index 3f4cd9f..6ff194b 100644
--- a/src/analysis/disass/rank.c
+++ b/src/analysis/disass/rank.c
@@ -61,9 +61,9 @@ 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*/
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
+ 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 */
@@ -77,14 +77,16 @@ 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);
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (i = 0; i < dcount; i++)
{
- range = g_arch_instruction_get_range(dests[i].linked);
+ dest = g_arch_instruction_get_destination(last, i);
- switch (dests[i].type)
+ range = g_arch_instruction_get_range(dest->linked);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_CATCH_EXCEPTION:
@@ -175,7 +177,7 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns
}
- g_arch_instruction_runlock_dest(last);
+ g_arch_instruction_unlock_dest(last);
return true;
@@ -304,9 +306,9 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
{
unsigned int next; /* Rang suivant obtenu */
GArchInstruction *last; /* Dernière instruction du bloc*/
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
+ instr_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 */
@@ -315,12 +317,14 @@ 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);
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (i = 0; i < dcount; i++)
{
- type = dests[i].type;
+ dest = g_arch_instruction_get_destination(last, i);
+
+ type = dest->type;
/* La boucle de remontée n'abaisse pas les rangs */
if (type == ILT_LOOP) continue;
@@ -337,7 +341,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
&& type != ILT_JUMP_IF_FALSE)
continue;
- target = g_block_list_find_by_starting_instr(list, dests[i].linked);
+ target = g_block_list_find_by_starting_instr(list, dest->linked);
/**
* Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
@@ -366,7 +370,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
}
- g_arch_instruction_runlock_dest(last);
+ g_arch_instruction_unlock_dest(last);
}
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index f84a5fd..583e151 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -1169,9 +1169,9 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
GBufferCache *cache; /* Tampon de désassemblage */
instr_iter_t *iter; /* Parcours local d'adresses */
GArchInstruction *instr; /* Instruction correspondante */
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
+ instr_link_t *dest; /* Instr. visée par une autre */
const mrange_t *irange; /* Emplacement d'instruction */
size_t index; /* Indice de ligne à traiter */
GBufferLine *line; /* Ligne présente à l'adresse */
@@ -1180,7 +1180,6 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
result = NULL;
-
config = get_main_configuration();
if (!g_generic_config_get_value(config, MPK_TOOLTIP_MAX_CALLS, &max_calls))
@@ -1219,11 +1218,14 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
/* Appels ? */
- g_arch_instruction_rlock_dest(instr);
- dcount = g_arch_instruction_get_destinations(instr, &dests);
+ g_arch_instruction_lock_dest(instr);
+ dcount = g_arch_instruction_count_destinations(instr);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(instr, i);
+
+ switch (dest->type)
{
case ILT_CALL:
@@ -1272,10 +1274,10 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
case ILT_REF:
- if (!G_IS_RAW_INSTRUCTION(dests[i].linked))
+ if (!G_IS_RAW_INSTRUCTION(dest->linked))
continue;
- if (!g_raw_instruction_is_string(G_RAW_INSTRUCTION(dests[i].linked)))
+ if (!g_raw_instruction_is_string(G_RAW_INSTRUCTION(dest->linked)))
continue;
string_count++;
@@ -1289,7 +1291,7 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
continue;
}
- irange = g_arch_instruction_get_range(dests[i].linked);
+ irange = g_arch_instruction_get_range(dest->linked);
index = g_buffer_cache_find_index_by_addr(cache, get_mrange_addr(irange), true);
@@ -1326,7 +1328,9 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
}
- g_arch_instruction_runlock_dest(instr);
+ }
+
+ g_arch_instruction_unlock_dest(instr);
g_object_unref(G_OBJECT(instr));
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index beb6b50..b7bd5f3 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -60,22 +60,13 @@ struct _GArchInstruction
/**
* Il existe le besoin indéniable d'un verrou pour les accès aux instructions
* liées. Il faut par ailleurs un verrou distinct pour les sources et les
- * destination car une même instruction peut boucler sur elle même et la
+ * destinations car une même instruction peut boucler sur elle même et la
* fonction g_arch_instruction_change_link() pose des verrous sur les
* deux extrémités.
*
- * Par ailleurs, la consommation mémoire augmente vite : GRWLock pèse 16
- * octets et size_t mesure la taille d'un long sur 64 bits.
- *
- * Que ce soit avec les pointeurs (un allocateur aligne généralement les
- * adresses retournées) ou avec les tailles (il est peu probable d'avoir
- * 0x80000000 instructions d'origine), on dispose d'espace mémoire inutilisé
- * adapté pour compresser la structure GArchInstruction.
- *
- * La GLib propose incidemment des fonctions g_bit_lock() / g_bit_unlock()...
- *
- * On perd au passage la distinction entre les accès en lecture et ceux en
- * écriture, mais tant pis : la réduction de l'empreinte mémoire prime !
+ * La GLib propose les fonctions g_bit_lock() / g_bit_unlock(), légères mais
+ * sans distinction entre lectures et écritures. Tant pis : la réduction de
+ * l'empreinte mémoire prime !
*
* Par contre la documentation indique :
*
@@ -83,23 +74,19 @@ struct _GArchInstruction
* Attempting to lock on two different bits within the same integer is not supported.
* """
*
- * Donc on conserve un compteur distinct pour chaque extrémité.
+ * Donc on doit bien conserver un compteur distinct pour chaque extrémité.
+ * Cela correspond de toute façon à la définition optimisée des tableaux
+ * suivante.
*/
- instr_link_t *from; /* Origines des références */
- instr_link_t *to; /* Instructions visées */
- gint from_count; /* Nombre de ces origines */
- gint to_count; /* Nombre de ces destinations */
+ flat_array_t *from; /* Origines des références */
+ flat_array_t *to; /* Instructions visées */
ArchInstrFlag flags; /* Informations complémentaires*/
};
-/* Bit de verrou pour les champs (from|to)_count */
-#define INSTR_LINK_LOCK_BIT 31
-
-
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
{
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 4bb2e2d..14e78dc 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -51,29 +51,6 @@ static void g_arch_instruction_finalize(GArchInstruction *);
-/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
-
-
-/* Dénombre les liens présents à une extrémité donnée. */
-static size_t g_arch_instruction_get_link_counter(GArchInstruction *, bool);
-
-#define g_arch_instruction_get_source_counter(ins) \
- g_arch_instruction_get_link_counter(ins, true)
-
-#define g_arch_instruction_get_destination_counter(ins) \
- g_arch_instruction_get_link_counter(ins, false)
-
-/* Incrémente le nombre de liens définis à une extrémité donnée. */
-static size_t g_arch_instruction_inc_link_counter(GArchInstruction *, bool);
-
-#define g_arch_instruction_inc_source_counter(ins) \
- g_arch_instruction_inc_link_counter(ins, true)
-
-#define g_arch_instruction_inc_destination_counter(ins) \
- g_arch_instruction_inc_link_counter(ins, false)
-
-
-
/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
@@ -147,8 +124,8 @@ static void g_arch_instruction_init(GArchInstruction *instr)
{
instr->operands = NULL;
- instr->from_count = 0;
- instr->to_count = 0;
+ instr->from = NULL;
+ instr->to = NULL;
}
@@ -657,7 +634,6 @@ void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
* *
* Paramètres : instr = instruction à mettre à jour. *
* src = sélection de l'extrémité à traiter. *
-* write = précise le type d'accès prévu (lecture/écriture). *
* lock = indique le sens du verrouillage à mener. *
* *
* Description : Met à disposition un encadrement des accès aux liens. *
@@ -668,80 +644,16 @@ void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
* *
******************************************************************************/
-void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool src, bool write, bool lock)
+void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool src, bool lock)
{
- volatile gint *address; /* Choix de l'entier à traiter */
+ flat_array_t **array; /* Choix du tableau ciblé */
- address = (src ? &instr->from_count : &instr->to_count);
+ array = (src ? &instr->from : &instr->to);
if (lock)
- g_bit_lock(address, INSTR_LINK_LOCK_BIT);
+ lock_flat_array(array);
else
- g_bit_unlock(address, INSTR_LINK_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* src = sélection de l'extrémité à traiter. *
-* *
-* Description : Dénombre les liens présents à une extrémité donnée. *
-* *
-* Retour : Quantité positive. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static size_t g_arch_instruction_get_link_counter(GArchInstruction *instr, bool src)
-{
- size_t result; /* Nombre de liens à renvoyer */
- volatile gint *address; /* Choix de l'entier à traiter */
-
- address = (src ? &instr->from_count : &instr->to_count);
-
- assert(!g_bit_trylock(address, INSTR_LINK_LOCK_BIT));
-
- result = g_atomic_int_get(address) & ~(1 << INSTR_LINK_LOCK_BIT);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* src = sélection de l'extrémité à traiter. *
-* *
-* Description : Incrémente le nombre de liens définis à une extrémité donnée.*
-* *
-* Retour : Nouvelle quantité mise à jour. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static size_t g_arch_instruction_inc_link_counter(GArchInstruction *instr, bool src)
-{
- size_t result; /* Nombre de liens à renvoyer */
- volatile gint *address; /* Choix de l'entier à traiter */
-
- address = (src ? &instr->from_count : &instr->to_count);
-
- assert(!g_bit_trylock(address, INSTR_LINK_LOCK_BIT));
-
- result = g_atomic_int_get(address) & ~(1 << INSTR_LINK_LOCK_BIT);
-
- result++;
-
- assert((result & (1 << INSTR_LINK_LOCK_BIT)) == 0);
-
- g_atomic_int_set(address, (1 << INSTR_LINK_LOCK_BIT) | result);
-
- return result;
+ unlock_flat_array(array);
}
@@ -764,18 +676,23 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct
bool result; /* Bilan à retourner */
size_t count; /* Nombre de liens à parcourir */
size_t i; /* Boucle de parcours */
+ instr_link_t *dlink; /* Définition de destination */
result = false;
- g_arch_instruction_rlock_dest(instr);
+ g_arch_instruction_lock_dest(instr);
- count = g_arch_instruction_get_destination_counter(instr);
+ count = g_arch_instruction_count_destinations(instr);
for (i = 0; i < count && !result; i++)
- if (instr->to[i].linked == dest)
- result = true;
+ {
+ dlink = g_arch_instruction_get_destination(instr, i);
- g_arch_instruction_runlock_dest(instr);
+ result = (dlink->linked == dest);
+
+ }
+
+ g_arch_instruction_unlock_dest(instr);
return result;
@@ -798,38 +715,30 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct
void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type)
{
- size_t count; /* Raccourci pour la lecture */
- instr_link_t *new; /* Nouveau lien à définir */
+ instr_link_t new_src; /* Nouveau lien à définir #1 */
+ instr_link_t new_dst; /* Nouveau lien à définir #2 */
/* Côté destination */
- g_arch_instruction_wlock_src(dest);
-
- count = g_arch_instruction_inc_source_counter(dest);
-
- dest->from = (instr_link_t *)realloc(dest->from, count * sizeof(instr_link_t));
-
- new = &dest->from[count - 1];
-
- new->linked = instr;
- new->type = type;
-
- g_arch_instruction_wunlock_src(dest);
+ new_src.linked = instr;
+ new_src.type = type;
/* Côté point de départ */
- g_arch_instruction_wlock_dest(instr);
+ new_dst.linked = dest;
+ new_dst.type = type;
- count = g_arch_instruction_inc_destination_counter(instr);
+ /* Ajout dans le respect d'une cohérence globale */
- instr->to = (instr_link_t *)realloc(instr->to, count * sizeof(instr_link_t));
+ g_arch_instruction_lock_src(dest);
+ g_arch_instruction_lock_dest(instr);
- new = &instr->to[count - 1];
+ add_item_to_flat_array(&dest->from, &new_src, sizeof(instr_link_t));
- new->linked = dest;
- new->type = type;
+ add_item_to_flat_array(&instr->to, &new_dst, sizeof(instr_link_t));
- g_arch_instruction_wunlock_dest(instr);
+ g_arch_instruction_unlock_dest(instr);
+ g_arch_instruction_unlock_src(dest);
}
@@ -845,7 +754,7 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des
* *
* Retour : true pour une mise à jour réussie, false sinon. *
* *
-* Remarques : Le verrou doit être posé sur les destination de 'instr'. *
+* Remarques : Le verrou doit être posé sur les destinations de 'instr'. *
* *
******************************************************************************/
@@ -854,52 +763,56 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
bool result; /* Bilan à retourner */
size_t count; /* Raccourci pour la lecture */
size_t i; /* Boucle de parcours */
- size_t from_idx; /* Indice côté destination */
- size_t to_idx; /* Indice côté source */
+ instr_link_t *slink; /* Définition de source */
+ instr_link_t *dlink; /* Définition de destination */
result = false;
- assert(!g_bit_trylock(&instr->to_count, INSTR_LINK_LOCK_BIT));
-
- g_arch_instruction_wlock_src(dest);
+ g_arch_instruction_lock_src(dest);
/* Côté destination */
- count = g_arch_instruction_get_source_counter(dest);
+ count = g_arch_instruction_count_sources(dest);
for (i = 0; i < count; i++)
- if (dest->from[i].linked == instr && dest->from[i].type == old)
+ {
+ slink = g_arch_instruction_get_source(dest, i);
+
+ if (slink->linked == instr && slink->type == old)
break;
+ }
+
if (i == count)
goto gaicl_exit;
- else
- from_idx = i;
/* Côté point de départ */
- count = g_arch_instruction_get_destination_counter(instr);
+ count = g_arch_instruction_count_destinations(instr);
for (i = 0; i < count; i++)
- if (instr->to[i].linked == dest && instr->to[i].type == old)
+ {
+ dlink = g_arch_instruction_get_destination(instr, i);
+
+ if (dlink->linked == dest && dlink->type == old)
break;
+ }
+
if (i == count)
goto gaicl_exit;
- else
- to_idx = i;
/* Si les deux extrémités sont raccord... */
- dest->from[from_idx].type = new;
+ slink->type = new;
- instr->to[to_idx].type = new;
+ dlink->type = new;
result = true;
gaicl_exit:
- g_arch_instruction_wunlock_src(dest);
+ g_arch_instruction_unlock_src(dest);
return result;
@@ -910,48 +823,45 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
* *
-* Description : Indique si l'instruction a une ou plusieurs origines. *
+* Description : Fournit la quantité d'instructions pointant vers une autre. *
* *
-* Retour : Bilan de la consultation. *
+* Retour : Nombre de ces origines. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_has_sources(GArchInstruction *instr)
+size_t g_arch_instruction_count_sources(const GArchInstruction *instr)
{
- size_t count; /* Nombre de liens présents */
-
- assert(!g_bit_trylock(&instr->from_count, INSTR_LINK_LOCK_BIT));
+ size_t result; /* Nombre de liens à renvoyer */
- count = g_arch_instruction_get_source_counter(instr);
+ result = count_flat_array_items(instr->from);
- return (count > 0);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter.*
-* sources = liste des liens aux instructions d'origine. [OUT] *
+* Paramètres : instr = instruction dont les informations sont à consulter. *
+* index = indice de l'élément à retrouver. *
* *
-* Description : Fournit les origines d'une instruction donnée. *
+* Description : Fournit les détails d'une origine d'une instruction donnée. *
* *
-* Retour : Nombre de ces origines. *
+* Retour : Lien déterminé vers une instruction d'origine. *
* *
* Remarques : - *
* *
******************************************************************************/
-size_t g_arch_instruction_get_sources(GArchInstruction *instr, instr_link_t **sources)
+instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index)
{
- assert(!g_bit_trylock(&instr->from_count, INSTR_LINK_LOCK_BIT));
+ instr_link_t *result; /* Détails présents à renvoyer */
- if (sources != NULL)
- *sources = instr->from;
+ result = get_flat_array_item(instr->from, index, sizeof(instr_link_t));
- return g_arch_instruction_get_source_counter(instr);
+ return result;
}
@@ -960,23 +870,21 @@ size_t g_arch_instruction_get_sources(GArchInstruction *instr, instr_link_t **so
* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
* *
-* Description : Indique si l'instruction a une suite autre que la suivante. *
+* Description : Donne le nombre d'instructions non naturellement suivantes. *
* *
-* Retour : Bilan de la consultation. *
+* Retour : Nombre de ces destinations. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_has_destinations(GArchInstruction *instr)
+size_t g_arch_instruction_count_destinations(const GArchInstruction *instr)
{
- size_t count; /* Nombre de liens présents */
-
- assert(!g_bit_trylock(&instr->to_count, INSTR_LINK_LOCK_BIT));
+ size_t result; /* Nombre de liens à renvoyer */
- count = g_arch_instruction_get_destination_counter(instr);
+ result = count_flat_array_items(instr->to);
- return (count > 0);
+ return result;
}
@@ -984,24 +892,23 @@ bool g_arch_instruction_has_destinations(GArchInstruction *instr)
/******************************************************************************
* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
-* dests = liste de liens aux instructions de destination. [OUT]*
+* index = indice de l'élément à retrouver. *
* *
-* Description : Fournit les destinations d'une instruction donnée. *
+* Description : Fournit les détails d'une destination d'une instruction. *
* *
-* Retour : Nombre de ces destinations. *
+* Retour : Lien déterminé vers une instruction de destination. *
* *
* Remarques : - *
* *
******************************************************************************/
-size_t g_arch_instruction_get_destinations(GArchInstruction *instr, instr_link_t **dests)
+instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index)
{
- assert(!g_bit_trylock(&instr->to_count, INSTR_LINK_LOCK_BIT));
+ instr_link_t *result; /* Détails présents à renvoyer */
- if (dests != NULL)
- *dests = instr->to;
+ result = get_flat_array_item(instr->to, index, sizeof(instr_link_t));
- return g_arch_instruction_get_destination_counter(instr);
+ return result;
}
@@ -1024,53 +931,28 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins
GArchInstruction *result; /* Résultat à remonter */
size_t count; /* Nombre de liens à parcourir */
size_t i; /* Boucle de parcours */
+ instr_link_t *dest; /* Destination à étudier */
result = NULL;
- assert(!g_bit_trylock(&instr->to_count, INSTR_LINK_LOCK_BIT));
+ g_arch_instruction_lock_dest(instr);
- count = g_arch_instruction_get_destination_counter(instr);
+ count = g_arch_instruction_count_destinations(instr);
for (i = 0; i < count && result == NULL; i++)
- if (instr->to[i].type == type)
- result = instr->to[i].linked;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : iter = membre du groupe donné en référence. *
-* list = liste des instructions à analyser. *
-* count = taille de cette liste. *
-* *
-* Description : Indique la position dans les instructions identiques. *
-* *
-* Retour : Indice dans les instructions identiques du groupe. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_arch_instruction_compute_group_index(GArchInstruction **iter, GArchInstruction **list, size_t count)
-{
- size_t result; /* Valeur à retourner */
- size_t i; /* Boucle de parcours */
-
- result = 0;
-
- for (i = 0; i < count; i++)
{
- if ((list + i) == iter)
- break;
+ dest = g_arch_instruction_get_destination(instr, i);
- if (list[i] == *iter)
- result++;
+ if (dest->type == type)
+ {
+ result = dest->linked;
+ g_object_ref(G_OBJECT(result));
+ }
}
+ g_arch_instruction_unlock_dest(instr);
+
return result;
}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index d38bb62..bb2dc94 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -215,7 +215,7 @@ typedef struct _instr_link_t
/* Met à disposition un encadrement des accès aux liens. */
-void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool, bool);
+void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool);
/* Détermine si un lien est déjà établi entre deux instructions. */
bool g_arch_instruction_has_link_to(GArchInstruction *, const GArchInstruction *);
@@ -226,36 +226,27 @@ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, Instru
/* Change la nature d'un lien entre deux instructions. */
bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType);
-#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true, true)
-#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true, false)
+#define g_arch_instruction_lock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true)
+#define g_arch_instruction_unlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false)
-#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false, true)
-#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false, false)
+/* Fournit la quantité d'instructions pointant vers une autre. */
+size_t g_arch_instruction_count_sources(const GArchInstruction *);
-/* Indique si l'instruction a une ou plusieurs origines. */
-bool g_arch_instruction_has_sources(GArchInstruction *);
+/* Fournit les détails d'une origine d'une instruction donnée. */
+instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t);
-/* Fournit les origines d'une instruction donnée. */
-size_t g_arch_instruction_get_sources(GArchInstruction *, instr_link_t **);
+#define g_arch_instruction_lock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true)
+#define g_arch_instruction_unlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false)
-#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true, true)
-#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true, false)
+/* Donne le nombre d'instructions non naturellement suivantes. */
+size_t g_arch_instruction_count_destinations(const GArchInstruction *);
-#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false, true)
-#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false, false)
-
-/* Indique si l'instruction a une suite autre que la suivante. */
-bool g_arch_instruction_has_destinations(GArchInstruction *);
-
-/* Fournit les destinations d'une instruction donnée. */
-size_t g_arch_instruction_get_destinations(GArchInstruction *, instr_link_t **);
+/* Fournit les détails d'une destination d'une instruction. */
+instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t);
/* Fournit la destination d'une instruction et d'un type donné. */
GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *, InstructionLinkType);
-/* Indique la position dans les instructions identiques. */
-size_t g_arch_instruction_compute_group_index(GArchInstruction **, GArchInstruction **, size_t);
-
/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */
diff --git a/src/debug/debugger.c b/src/debug/debugger.c
index 0dfe315..85ca241 100644
--- a/src/debug/debugger.c
+++ b/src/debug/debugger.c
@@ -1037,9 +1037,9 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
instr_iter_t *iter; /* Parcours local d'adresses */
GArchInstruction *instr; /* Instruction correspondante */
virt_t ret; /* Adresse de retour d'appel */
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
+ instr_link_t *dest; /* Instr. visée par une autre */
const mrange_t *range; /* Emplacement d'instruction */
result = NULL;
@@ -1071,12 +1071,15 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
/* Sinon on se penche sur ses destinations */
else
{
- g_arch_instruction_rlock_dest(instr);
+ g_arch_instruction_lock_dest(instr);
- dcount = g_arch_instruction_get_destinations(instr, &dests);
+ dcount = g_arch_instruction_count_destinations(instr);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(instr, i);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -1088,7 +1091,7 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
(*count)++;
result = (virt_t *)realloc(result, *count * sizeof(virt_t));
- range = g_arch_instruction_get_range(dests[i].linked);
+ range = g_arch_instruction_get_range(dest->linked);
result[*count - 1] = get_virt_addr(get_mrange_addr(range));
break;
@@ -1100,7 +1103,7 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
(*count)++;
result = (virt_t *)realloc(result, *count * sizeof(virt_t));
- range = g_arch_instruction_get_range(dests[i].linked);
+ range = g_arch_instruction_get_range(dest->linked);
result[*count - 1] = get_virt_addr(get_mrange_addr(range));
@@ -1113,7 +1116,9 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
}
- g_arch_instruction_runlock_dest(instr);
+ }
+
+ g_arch_instruction_unlock_dest(instr);
/* Si tout ça ne donne rien, on se rabat sur l'instruction suivante par défaut */
if (*count == 0)
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 9aee82c..413af86 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -904,9 +904,9 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
{
unsigned int level; /* Niveau du nouvel ensemble */
GArchInstruction *last; /* Dernière instruction du bloc*/
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #1 */
+ instr_link_t *dest; /* Instr. visée par une autre */
GGraphCluster *target; /* Bloc ciblé par un lien */
leaving_edge *leaving; /* Point de départ d'un lien */
unsigned int target_level; /* Rang du bloc ciblé */
@@ -920,11 +920,14 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
g_basic_block_get_boundary(cluster->block, NULL, &last);
- g_arch_instruction_rlock_dest(last);
- dcount = g_arch_instruction_get_destinations(last, &dests);
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(last, i);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -932,7 +935,7 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- target = G_GRAPH_CLUSTER(g_hash_table_lookup(all, dests[i].linked));
+ target = G_GRAPH_CLUSTER(g_hash_table_lookup(all, dest->linked));
assert(target != NULL);
/* Point de départ */
@@ -982,7 +985,7 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
leaving->index = cluster->ba_count - 1;
- incoming->type = dests[i].type;
+ incoming->type = dest->type;
if (incoming->type == ILT_JUMP_IF_TRUE)
incoming->edge = g_graph_edge_new_true(&leaving->start, &incoming->y, &incoming->end);
@@ -1027,7 +1030,9 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
}
- g_arch_instruction_runlock_dest(last);
+ }
+
+ g_arch_instruction_unlock_dest(last);
@@ -1508,9 +1513,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
#ifndef NDEBUG
gboolean new; /* Bloc déjà traité ? */
#endif
- instr_link_t *dests; /* Instr. visées par une autre */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #1 */
+ instr_link_t *dest; /* Instr. visée par une autre */
GBasicBlock *target; /* Bloc ciblé par un lien */
size_t j; /* Boucle de parcours #2 */
bool changed; /* Un ajout a été effectué ? */
@@ -1533,11 +1538,14 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
/* Détermination des blocs suivants */
- g_arch_instruction_rlock_dest(last);
- dcount = g_arch_instruction_get_destinations(last, &dests);
+ g_arch_instruction_lock_dest(last);
+ dcount = g_arch_instruction_count_destinations(last);
for (i = 0; i < dcount; i++)
- switch (dests[i].type)
+ {
+ dest = g_arch_instruction_get_destination(last, i);
+
+ switch (dest->type)
{
case ILT_EXEC_FLOW:
case ILT_JUMP:
@@ -1545,7 +1553,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- target = g_block_list_find_by_starting_instr(list, dests[i].linked);
+ target = g_block_list_find_by_starting_instr(list, dest->linked);
/**
* Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
@@ -1558,7 +1566,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
*
*/
- printf(" NEW BLK :: %d -> %p\n", dests[i].type, target);
+ printf(" NEW BLK :: %d -> %p\n", dest->type, target);
if (target != NULL)
{
@@ -1588,11 +1596,11 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
* la table globale.
*/
- if (!g_hash_table_contains(all, dests[i].linked))
+ if (!g_hash_table_contains(all, dest->linked))
{
assert((pending->count + 1) < g_block_list_count_blocks(list));
pending->list[pending->count++] = target;
- printf(" --push-- %d -> %p\n", dests[i].type, target);
+ printf(" --push-- %d -> %p\n", dest->type, target);
}
}
@@ -1618,7 +1626,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
}
- g_arch_instruction_runlock_dest(last);
+ }
+
+ g_arch_instruction_unlock_dest(last);
/* Intégration de tous les blocs en attente */
diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c
index e467f8e..00ad356 100644
--- a/src/gui/dialogs/gotox.c
+++ b/src/gui/dialogs/gotox.c
@@ -276,9 +276,9 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
{
GtkWidget *result; /* Fenêtre à renvoyer */
GtkTreeStore *store; /* Modèle de gestion */
- instr_link_t *list; /* Liste d'instructions */
size_t count; /* Nombre d'éléments présents */
size_t i; /* Boucle de parcours */
+ instr_link_t *item; /* Instruction diverse liée */
const vmpa2t *addr; /* Adresse à considérer */
/* Mise en place de la boîte de dialogue */
@@ -294,27 +294,43 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
if (back)
{
- g_arch_instruction_rlock_src(instr);
- count = g_arch_instruction_get_sources(instr, &list);
+ g_arch_instruction_lock_src(instr);
+
+ count = g_arch_instruction_count_sources(instr);
+
+ for (i = 0; i < count; i++)
+ {
+ item = g_arch_instruction_get_source(instr, i);
+
+ addr = get_mrange_addr(g_arch_instruction_get_range(item->linked));
+
+ add_new_location_to_list(store, binary, addr, NULL);
+
+ }
+
+ g_arch_instruction_unlock_src(instr);
+
}
+
else
{
- g_arch_instruction_rlock_dest(instr);
- count = g_arch_instruction_get_destinations(instr, &list);
- }
+ g_arch_instruction_lock_dest(instr);
- for (i = 0; i < count; i++)
- {
- addr = get_mrange_addr(g_arch_instruction_get_range(list[i].linked));
+ count = g_arch_instruction_count_destinations(instr);
- add_new_location_to_list(store, binary, addr, NULL);
+ for (i = 0; i < count; i++)
+ {
+ item = g_arch_instruction_get_destination(instr, i);
- }
+ addr = get_mrange_addr(g_arch_instruction_get_range(item->linked));
- if (back)
- g_arch_instruction_runlock_src(instr);
- else
- g_arch_instruction_runlock_dest(instr);
+ add_new_location_to_list(store, binary, addr, NULL);
+
+ }
+
+ g_arch_instruction_unlock_dest(instr);
+
+ }
g_object_unref(G_OBJECT(store));