From 6906aa19b7ac4c14615c30d15bfb26b0b86557d5 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 13 Apr 2017 18:34:34 +0200 Subject: Simplified the way links between instructions are handled. --- ChangeLog | 24 +++ plugins/androhelpers/switch.c | 2 +- plugins/androhelpers/try_n_catch.c | 6 +- plugins/libcsem/exit.c | 15 +- src/analysis/db/items/comment.c | 8 +- src/analysis/decomp/il.c | 16 +- src/analysis/disass/dragon.c | 64 +++++--- src/analysis/disass/links.c | 47 ++++-- src/analysis/disass/loop.c | 19 ++- src/analysis/disass/rank.c | 28 ++-- src/analysis/routine.c | 22 +-- src/arch/instruction-int.h | 31 ++-- src/arch/instruction.c | 296 +++++++++++-------------------------- src/arch/instruction.h | 35 ++--- src/debug/debugger.c | 19 ++- src/gtkext/graph/cluster.c | 42 ++++-- src/gui/dialogs/gotox.c | 46 ++++-- 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 + + * 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 * 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)); -- cgit v0.11.2-87-g4458