From 8c71b36d401b2473342daddcb9b7eb4b83ba3295 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 29 Oct 2016 00:26:53 +0200 Subject: Optimized access to instruction sources and destinations. --- ChangeLog | 22 ++++ plugins/libcsem/exit.c | 9 +- plugins/pychrysa/arch/instruction.c | 18 ++-- src/analysis/blocks/flow.c | 20 ++-- src/analysis/db/items/comment.c | 6 +- src/analysis/decomp/il.c | 6 +- src/analysis/disass/dragon.c | 29 +++-- src/analysis/disass/links.c | 19 ++-- src/analysis/disass/loop.c | 11 +- src/analysis/disass/rank.c | 31 +++--- src/arch/instruction-int.h | 15 +-- src/arch/instruction.c | 204 +++++++++++++----------------------- src/arch/instruction.h | 37 ++++--- src/gtkext/graph/cluster.c | 30 +++--- src/gui/dialogs/gotox.c | 8 +- 15 files changed, 211 insertions(+), 254 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0a760a..49e0b88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +16-10-29 Cyrille Bagard + + * plugins/libcsem/exit.c: + * plugins/pychrysa/arch/instruction.c: + * src/analysis/blocks/flow.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: + Update code. + + * src/arch/instruction-int.h: + * src/arch/instruction.c: + * src/arch/instruction.h: + Optimize access to instruction sources and destinations. + + * src/gtkext/graph/cluster.c: + * src/gui/dialogs/gotox.c: + Update code. + 16-10-28 Cyrille Bagard * plugins/androhelpers/switch.c: diff --git a/plugins/libcsem/exit.c b/plugins/libcsem/exit.c index aa3ca18..d26d4bf 100644 --- a/plugins/libcsem/exit.c +++ b/plugins/libcsem/exit.c @@ -49,8 +49,7 @@ 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 */ - GArchInstruction **sources; /* Instructions diverses liées */ - InstructionLinkType *types; /* Types de lien existants */ + instr_link_t *sources; /* Instructions diverses liées */ size_t count; /* Nbre de sources affichées */ size_t i; /* Boucle de parcours */ @@ -69,13 +68,13 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range)); g_arch_instruction_rlock_src(instr); - count = g_arch_instruction_get_sources(instr, &sources, &types); + count = g_arch_instruction_get_sources(instr, &sources); for (i = 0; i < count; i++) { - if (types[i] != ILT_CALL) continue; + if (sources[i].type != ILT_CALL) continue; - g_arch_instruction_set_flag(sources[i], AIF_RETURN_POINT); + g_arch_instruction_set_flag(sources[i].linked, AIF_RETURN_POINT); } diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c index ff3d2ad..f52b1ad 100644 --- a/plugins/pychrysa/arch/instruction.c +++ b/plugins/pychrysa/arch/instruction.c @@ -103,8 +103,7 @@ static PyObject *py_arch_instruction_get_sources(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ GArchInstruction *instr; /* Version native */ - GArchInstruction **dests; /* Destination des liens */ - InstructionLinkType *types; /* Nature de ces liens */ + instr_link_t *sources; /* Origine des liens */ size_t count; /* Nombre de liens présents */ size_t i; /* Boucle de parcours */ PyObject *dest; /* Destination de lien Python */ @@ -113,14 +112,14 @@ static PyObject *py_arch_instruction_get_sources(PyObject *self, PyObject *args) instr = G_ARCH_INSTRUCTION(pygobject_get(self)); - count = g_arch_instruction_get_sources(instr, &dests, &types); + count = g_arch_instruction_get_sources(instr, &sources); result = PyTuple_New(count); for (i = 0; i < count; i++) { - dest = pygobject_new(G_OBJECT(dests[i])); - type = PyLong_FromLong(types[i]); + dest = pygobject_new(G_OBJECT(sources[i].linked)); + type = PyLong_FromLong(sources[i].type); ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", dest, type)); assert(ret == 0); @@ -149,8 +148,7 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, PyObject * { PyObject *result; /* Instance à retourner */ GArchInstruction *instr; /* Version native */ - GArchInstruction **dests; /* Destination des liens */ - InstructionLinkType *types; /* Nature de ces liens */ + instr_link_t *dests; /* Destination des liens */ size_t count; /* Nombre de liens présents */ size_t i; /* Boucle de parcours */ PyObject *dest; /* Destination de lien Python */ @@ -159,14 +157,14 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, PyObject * instr = G_ARCH_INSTRUCTION(pygobject_get(self)); - count = g_arch_instruction_get_destinations(instr, &dests, &types); + count = g_arch_instruction_get_destinations(instr, &dests); result = PyTuple_New(count); for (i = 0; i < count; i++) { - dest = pygobject_new(G_OBJECT(dests[i])); - type = PyLong_FromLong(types[i]); + dest = pygobject_new(G_OBJECT(dests[i].linked)); + type = PyLong_FromLong(dests[i].type); ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", dest, type)); assert(ret == 0); diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c index 970fc21..0f278bd 100644 --- a/src/analysis/blocks/flow.c +++ b/src/analysis/blocks/flow.c @@ -565,8 +565,7 @@ void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa2t *start, bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlowBlock *target) { bool result; /* Bilan à retourner */ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ vmpa_t addr; /* Adresse de la destination */ @@ -575,23 +574,23 @@ bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlo result = (block == target); g_arch_instruction_rlock_dest(block->last); - dcount = g_arch_instruction_get_destinations(block->last, &dests, &types); + dcount = g_arch_instruction_get_destinations(block->last, &dests); for (i = 0; i < dcount && !result; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: case ILT_CASE_JUMP: case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); + g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); next = g_instr_block_find_by_addr(list, addr, true); result = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, target); break; case ILT_LOOP: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); + g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); next = g_instr_block_find_by_addr(list, addr, true); result = (G_FLOW_BLOCK(next) == target); default: @@ -625,8 +624,7 @@ bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlo bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollowPosition mask, flow_block_follow_cb callback, void *data) { bool result; /* Bilan à retourner */ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ vmpa_t addr; /* Adresse de la destination */ @@ -638,10 +636,10 @@ bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollow result = callback(block, BFP_ENTER, data); g_arch_instruction_rlock_dest(block->last); - dcount = g_arch_instruction_get_destinations(block->last, &dests, &types); + dcount = g_arch_instruction_get_destinations(block->last, &dests); for (i = 0; i < dcount && result; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -649,7 +647,7 @@ bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollow case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); + g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); next = g_instr_block_find_by_addr(list, addr, true); if (next) diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index 6ce3d05..453d649 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -520,7 +520,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap GBufferLine *line; /* Ligne de tampon à marquer */ GArchProcessor *proc; /* Propriétaire d'instructions */ GArchInstruction *instr; /* Instruction à traiter */ - GArchInstruction **sources; /* Instructions diverses liées */ + instr_link_t *sources; /* Instructions diverses liées */ size_t scount; /* Nbre de sources affichées */ size_t i; /* Boucle de parcours */ const mrange_t *range; /* Emplacement d'instruction */ @@ -613,7 +613,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range)); assert(instr != NULL); - scount = g_arch_instruction_get_sources(instr, &sources, NULL); + scount = g_arch_instruction_get_sources(instr, &sources); if (apply) { @@ -624,7 +624,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap for (i = 0; i < scount && result; i++) { - range = g_arch_instruction_get_range(sources[i]); + range = g_arch_instruction_get_range(sources[i].linked); /** * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL. diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c index 36b5dfe..f19dd1a 100644 --- a/src/analysis/decomp/il.c +++ b/src/analysis/decomp/il.c @@ -610,7 +610,7 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB vmpa_t common_addr; /* Adresse commune de suite */ bool is_common; /* Suite commune ? */ GArchInstruction *last; /* Dernière instruction de bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t j; /* Boucle de parcours #2 */ vmpa_t addr; /* Adresse d'une instruction */ @@ -638,11 +638,11 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB for (i = 0; i < lcount && is_common; i++) { g_flow_block_get_boundary(G_FLOW_BLOCK(leafs[i]), NULL, &last); - dcount = g_arch_instruction_get_destinations(last, &dests, NULL); + dcount = g_arch_instruction_get_destinations(last, &dests); for (j = 0; j < dcount && is_common; j++) { - g_arch_instruction_get_location(dests[j], NULL, NULL, &addr); + g_arch_instruction_get_location(dests[j].linked, NULL, NULL, &addr); if (common_addr == VMPA_MAX) common_addr = addr; diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c index c817727..6220014 100644 --- a/src/analysis/disass/dragon.c +++ b/src/analysis/disass/dragon.c @@ -101,11 +101,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ GArchInstruction *last; /* Mémorisation du passé */ GArchInstruction *iter; /* Boucle de parcours */ const mrange_t *irange; /* Emplacement d'instruction */ - InstructionLinkType *types; /* Type de lien entre instr. */ + instr_link_t *sources; /* Liste des instructions liées*/ size_t scount; /* Nombre de liens de source */ bool cut; /* Un découpage a été réalisé ?*/ size_t i; /* Boucle de parcours */ dragon_node *new; /* Nouvel élément à créer */ + instr_link_t *dests; /* Liste des instructions liées*/ size_t dcount; /* Nombre de liens de dest. */ result = NULL; @@ -165,12 +166,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ /* Analyse des sources */ g_arch_instruction_rlock_src(iter); - scount = g_arch_instruction_get_sources(iter, NULL, &types); + scount = g_arch_instruction_get_sources(iter, &sources); cut = false; for (i = 0; i < scount && !cut; i++) - switch (types[i]) + switch (sources[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -209,12 +210,12 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_ /* Analyse des destinations */ g_arch_instruction_rlock_dest(iter); - dcount = g_arch_instruction_get_destinations(iter, NULL, &types); + dcount = g_arch_instruction_get_destinations(iter, &dests); cut = false; for (i = 0; i < dcount && !cut; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_JUMP: @@ -431,18 +432,17 @@ void compute_all_paths(dragon_node *nodes, size_t count) { void follow_flow_in_nodes(dragon_node *node) { - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Liste des instructions liées*/ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ dragon_node *next; /* Noeud suivant dans le code */ size_t id; /* Indice du bit associé */ g_arch_instruction_rlock_dest(node->last); - dcount = g_arch_instruction_get_destinations(node->last, &dests, &types); + dcount = g_arch_instruction_get_destinations(node->last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -450,7 +450,7 @@ void compute_all_paths(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - next = find_node_for_instruction(nodes, count, false, dests[i]); + next = find_node_for_instruction(nodes, count, false, dests[i].linked); if (next == NULL) break; id = get_dragon_node_index(nodes, next); @@ -514,8 +514,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count) size_t k; /* Boucle de parcours #1 */ dragon_node *node; /* Noeud à traiter */ dragon_node *predecessor; /* Noeud prédécesseur direct */ - GArchInstruction **srcs; /* Instructions d'origine */ - InstructionLinkType *types; /* Type de lien entre instr. */ + instr_link_t *sources; /* Instructions d'origine */ size_t scount; /* Nombre de liens de source */ size_t i; /* Boucle de parcours #2 */ @@ -532,11 +531,11 @@ void compute_all_dominators(dragon_node *nodes, size_t count) set_all_in_bit_field(inter); g_arch_instruction_rlock_src(node->first); - scount = g_arch_instruction_get_sources(node->first, &srcs, &types); + scount = g_arch_instruction_get_sources(node->first, &sources); //assert(scount > 0); // un 'ret' coupe, le suivant n'a pas de source for (i = 0; i < scount; i++) - switch (types[i]) + switch (sources[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -544,7 +543,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - predecessor = find_node_for_instruction(nodes, count, true, srcs[i]); + predecessor = find_node_for_instruction(nodes, count, true, sources[i].linked); /* printf(" -- finding pred @ 0x%08x -> 0x%08x :: %p\n", diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 294274f..9a6749e 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -52,8 +52,7 @@ static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) { bool has_src; /* Présence de sources ? */ - GArchInstruction **others; /* Instructions diverses liées */ - InstructionLinkType *types; /* Types de lien existants */ + instr_link_t *others; /* Instructions diverses liées */ size_t count; /* Nbre de sources affichées */ size_t i; /* Boucle de parcours */ @@ -85,14 +84,14 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) */ g_arch_instruction_rlock_dest(prev); - count = g_arch_instruction_get_destinations(prev, &others, &types); + count = g_arch_instruction_get_destinations(prev, &others); for (i = 0; i < count; i++) { - if (types[i] == ILT_EXEC_FLOW) break; - if (types[i] == ILT_JUMP) break; - if (types[i] == ILT_CASE_JUMP) break; - if (types[i] == ILT_LOOP) break; + if (others[i].type == ILT_EXEC_FLOW) break; + if (others[i].type == ILT_JUMP) break; + if (others[i].type == ILT_CASE_JUMP) break; + if (others[i].type == ILT_LOOP) break; } g_arch_instruction_runlock_dest(prev); @@ -104,12 +103,12 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) */ g_arch_instruction_rlock_src(instr); - count = g_arch_instruction_get_sources(instr, &others, &types); + count = g_arch_instruction_get_sources(instr, &others); for (i = 0; i < count; i++) { - if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; - if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break; + if (others[i].linked == prev && others[i].type == ILT_JUMP_IF_TRUE) break; + if (others[i].linked == prev && others[i].type == ILT_JUMP_IF_FALSE) break; } g_arch_instruction_runlock_src(instr); diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 99121a8..204a7d6 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -49,8 +49,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) dragon_node *node; /* Noeud à traiter */ const bitfield_t *dominators; /* Liste de dominateurs */ GArchInstruction *last; /* Instruction finale de noeud */ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #2 */ dragon_node *target; /* Noeud référence à tester */ @@ -65,10 +64,10 @@ static void detect_back_edges(dragon_node *nodes, size_t count) get_dragon_node_bounding_instructions(node, NULL, &last); g_arch_instruction_wlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -76,7 +75,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - target = find_node_for_instruction(nodes, count, false, dests[i]); + target = find_node_for_instruction(nodes, count, false, dests[i].linked); if (target == NULL) break; id = get_dragon_node_index(nodes, target); @@ -90,7 +89,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count) (unsigned int)g_arch_instruction_get_range(dests[i])->addr.virtual); */ - /* status = */g_arch_instruction_change_link(last, dests[i], types[i], ILT_LOOP); + /* status = */g_arch_instruction_change_link(last, dests[i].linked, dests[i].type, ILT_LOOP); } diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 3721ca0..cd5915c 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -61,8 +61,7 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns unsigned int next; /* Rang suivant obtenu */ GInstrBlock *links; /* Blocs liés au bloc courant */ GArchInstruction *last; /* Dernière instruction du bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ const mrange_t *range; /* Emplacement d'une cible */ @@ -79,13 +78,13 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns g_flow_block_get_boundary(block, NULL, &last); g_arch_instruction_rlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) { - range = g_arch_instruction_get_range(dests[i]); + range = g_arch_instruction_get_range(dests[i].linked); - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_CATCH_EXCEPTION: @@ -305,10 +304,10 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) { unsigned int next; /* Rang suivant obtenu */ GArchInstruction *last; /* Dernière instruction du bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ + InstructionLinkType type; /* Raccourci pour confort */ GBasicBlock *target; /* Bloc ciblé par un lien */ unsigned int rank; /* Rang à constituer */ @@ -317,26 +316,28 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) g_basic_block_get_boundary(block, NULL, &last); g_arch_instruction_rlock_dest(last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) { + type = dests[i].type; + /* La boucle de remontée n'abaisse pas les rangs */ - if (types[i] == ILT_LOOP) continue; + if (type == ILT_LOOP) continue; /** * On se doit de suivre le même cheminement que celui emprunté lors * du parcours de create_dragon_nodes(). * Sinon, les chemins divergent et une récursion infinie peut survenir. */ - if (types[i] != ILT_EXEC_FLOW - && types[i] != ILT_JUMP - && types[i] != ILT_CASE_JUMP - && types[i] != ILT_JUMP_IF_TRUE - && types[i] != ILT_JUMP_IF_FALSE) + if (type != ILT_EXEC_FLOW + && type != ILT_JUMP + && type != ILT_CASE_JUMP + && type != ILT_JUMP_IF_TRUE + && type != ILT_JUMP_IF_FALSE) continue; - target = g_block_list_find_by_starting_instr(list, dests[i]); + target = g_block_list_find_by_starting_instr(list, dests[i].linked); /** * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index c393b5f..6c9da03 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -70,20 +70,13 @@ struct _GArchInstruction GArchOperand **operands; /* Liste des opérandes */ size_t operands_count; /* Nbre. d'opérandes utilisées */ - GArchInstruction **from; /* Origines des références */ - InstructionLinkType *from_types; /* Type des liens de dest. */ + instr_link_t *from; /* Origines des références */ size_t from_count; /* Nombre de ces origines */ - GRWLock from_access; /* Verrou de protection */ -#ifndef NDEBUG - gint hold_from_access; /* Suivi des verrouillages */ -#endif - - GArchInstruction **to; /* Eventuelles lignes visées */ - InstructionLinkType *to_types; /* Type des liens de dest. */ + instr_link_t *to; /* Instructions visées */ size_t to_count; /* Nombre de ces destinations */ - GRWLock to_access; /* Verrou de protection */ + GRWLock link_access; /* Verrou de protection */ #ifndef NDEBUG - gint hold_to_access; /* Suivi des verrouillages */ + gint hold_link_access; /* Suivi des verrouillages */ #endif //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index fa631ac..b57b49d 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -107,11 +107,10 @@ static void g_arch_instruction_init(GArchInstruction *instr) instr->max_displayed_len = VMPA_NO_PHYSICAL; - g_rw_lock_init(&instr->from_access); - g_atomic_int_set(&instr->hold_from_access, 0); - - g_rw_lock_init(&instr->to_access); - g_atomic_int_set(&instr->hold_to_access, 0); + g_rw_lock_init(&instr->link_access); +#ifndef NDEBUG + g_atomic_int_set(&instr->hold_link_access, 0); +#endif } @@ -149,8 +148,7 @@ static void g_arch_instruction_dispose(GArchInstruction *instr) static void g_arch_instruction_finalize(GArchInstruction *instr) { - g_rw_lock_clear(&instr->from_access); - g_rw_lock_clear(&instr->to_access); + g_rw_lock_clear(&instr->link_access); G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr)); @@ -559,6 +557,46 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg /****************************************************************************** * * +* Paramètres : instr = instruction à mettre à jour. * +* 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. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool write, bool lock) +{ +#ifndef NDEBUG + if (!lock) + g_atomic_int_dec_and_test(&instr->hold_link_access); +#endif + + if (write) + { + if (lock) g_rw_lock_writer_lock(&instr->link_access); + else g_rw_lock_writer_unlock(&instr->link_access); + } + else + { + if (lock) g_rw_lock_reader_lock(&instr->link_access); + else g_rw_lock_reader_unlock(&instr->link_access); + } + +#ifndef NDEBUG + if (lock) + g_atomic_int_inc(&instr->hold_link_access); +#endif + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction dont les informations sont à consulter. * * dest = ligne visée par la liaison (côté destination). * * type = type de lien à construire. * @@ -575,6 +613,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg 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 */ /* Côté destination */ @@ -582,13 +621,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des count = ++dest->from_count; - dest->from = (GArchInstruction **)realloc(dest->from, - count * sizeof(GArchInstruction *)); - dest->from_types = (InstructionLinkType *)realloc(dest->from_types, - count * sizeof(InstructionLinkType)); + dest->from = (instr_link_t *)realloc(dest->from, count * sizeof(instr_link_t)); + + new = &dest->from[count - 1]; - dest->from[count - 1] = instr; - dest->from_types[count - 1] = type; + new->linked = instr; + new->type = type; g_arch_instruction_wunlock_src(dest); @@ -598,13 +636,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des count = ++instr->to_count; - instr->to = (GArchInstruction **)realloc(instr->to, - count * sizeof(GArchInstruction *)); - instr->to_types = (InstructionLinkType *)realloc(instr->to_types, - count * sizeof(InstructionLinkType)); + instr->to = (instr_link_t *)realloc(instr->to, count * sizeof(instr_link_t)); + + new = &instr->to[count - 1]; - instr->to[count - 1] = dest; - instr->to_types[count - 1] = type; + new->linked = dest; + new->type = type; g_arch_instruction_wunlock_dest(instr); @@ -636,7 +673,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d result = false; - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); g_arch_instruction_wlock_src(dest); @@ -645,7 +682,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d count = dest->from_count; for (i = 0; i < count; i++) - if (dest->from[i] == instr && dest->from_types[i] == old) + if (dest->from[i].linked == instr && dest->from[i].type == old) break; if (i == count) @@ -658,7 +695,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d count = instr->to_count; for (i = 0; i < count; i++) - if (instr->to[i] == dest && instr->to_types[i] == old) + if (instr->to[i].linked == dest && instr->to[i].type == old) break; if (i == count) @@ -668,9 +705,9 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d /* Si les deux extrémités sont raccord... */ - dest->from_types[from_idx] = new; + dest->from[from_idx].type = new; - instr->to_types[to_idx] = new; + instr->to[to_idx].type = new; result = true; @@ -680,49 +717,6 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d return result; - - /* TODO : si les informations complémentaires restent en place, compléter ! */ - -} - - -/****************************************************************************** -* * -* Paramètres : collec = collection à mettre à jour. * -* 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 sources. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write, bool lock) -{ -#ifndef NDEBUG - if (!lock) - g_atomic_int_dec_and_test(&instr->hold_from_access); -#endif - - if (write) - { - if (lock) g_rw_lock_writer_lock(&instr->from_access); - else g_rw_lock_writer_unlock(&instr->from_access); - } - else - { - if (lock) g_rw_lock_reader_lock(&instr->from_access); - else g_rw_lock_reader_unlock(&instr->from_access); - } - -#ifndef NDEBUG - if (lock) - g_atomic_int_inc(&instr->hold_from_access); -#endif - } @@ -740,7 +734,7 @@ void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write, bool g_arch_instruction_has_sources(const GArchInstruction *instr) { - assert(g_atomic_int_get(&instr->hold_from_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->from_count > 0); @@ -749,9 +743,8 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) /****************************************************************************** * * -* Paramètres : instr = instruction dont les informations sont à consulter. * -* srcs = liste des instructions d'origine. [OUT] * -* types = liste des types de liens présents. [OUT] * +* Paramètres : instr = instruction dont les informations sont à consulter.* +* sources = liste des liens aux instructions d'origine. [OUT] * * * * Description : Fournit les origines d'une instruction donnée. * * * @@ -761,15 +754,12 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) * * ******************************************************************************/ -size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***srcs, InstructionLinkType **types) +size_t g_arch_instruction_get_sources(const GArchInstruction *instr, instr_link_t **sources) { - assert(g_atomic_int_get(&instr->hold_from_access) > 0); - - if (srcs != NULL) - *srcs = instr->from; + assert(g_atomic_int_get(&instr->hold_link_access) > 0); - if (types != NULL) - *types = instr->from_types; + if (sources != NULL) + *sources = instr->from; return instr->from_count; @@ -778,46 +768,6 @@ size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstru /****************************************************************************** * * -* Paramètres : collec = collection à mettre à jour. * -* 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 destinations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool write, bool lock) -{ -#ifndef NDEBUG - if (!lock) - g_atomic_int_dec_and_test(&instr->hold_to_access); -#endif - - if (write) - { - if (lock) g_rw_lock_writer_lock(&instr->to_access); - else g_rw_lock_writer_unlock(&instr->to_access); - } - else - { - if (lock) g_rw_lock_reader_lock(&instr->to_access); - else g_rw_lock_reader_unlock(&instr->to_access); - } - -#ifndef NDEBUG - if (lock) - g_atomic_int_inc(&instr->hold_to_access); -#endif - -} - - -/****************************************************************************** -* * * Paramètres : instr = instruction dont les informations sont à consulter. * * * * Description : Indique si l'instruction a une suite autre que la suivante. * @@ -830,7 +780,7 @@ void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool w bool g_arch_instruction_has_destinations(const GArchInstruction *instr) { - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->to_count > 0); @@ -840,8 +790,7 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * -* dests = liste des instructions de destination. [OUT] * -* types = liste des types de liens présents. [OUT] * +* dests = liste de liens aux instructions de destination. [OUT]* * * * Description : Fournit les destinations d'une instruction donnée. * * * @@ -851,16 +800,13 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) * * ******************************************************************************/ -size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types) +size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, instr_link_t **dests) { - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); if (dests != NULL) *dests = instr->to; - if (types != NULL) - *types = instr->to_types; - return instr->to_count; } @@ -886,11 +832,11 @@ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstructio result = NULL; - assert(g_atomic_int_get(&instr->hold_to_access) > 0); + assert(g_atomic_int_get(&instr->hold_link_access) > 0); for (i = 0; i < instr->to_count && result == NULL; i++) - if (instr->to_types[i] == type) - result = instr->to[i]; + if (instr->to[i].type == type) + result = instr->to[i].linked; return result; diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 00e64ab..fed88a3 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -174,6 +174,17 @@ typedef enum _InstructionLinkType } InstructionLinkType; +/* Déscription d'une liaison entre deux instructions */ +typedef struct _instr_link_t +{ + GArchInstruction *linked; /* Autre instruction liée */ + InstructionLinkType type; /* Type de liaison */ + +} instr_link_t; + + +/* Met à disposition un encadrement des accès aux liens. */ +void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool); /* Etablit un lien entre deux instructions. */ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType); @@ -181,35 +192,29 @@ 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); -/* Met à disposition un encadrement des accès aux sources. */ -void g_arch_instruction_lock_unlock_sources(GArchInstruction *, bool, bool); - -#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, true) -#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, false) +#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true) +#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false) -#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, true) -#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, false) +#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, true) +#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, false) /* Indique si l'instruction a une ou plusieurs origines. */ bool g_arch_instruction_has_sources(const GArchInstruction *); /* Fournit les origines d'une instruction donnée. */ -size_t g_arch_instruction_get_sources(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **); - -/* Met à disposition un encadrement des accès aux destinations. */ -void g_arch_instruction_lock_unlock_destinations(GArchInstruction *, bool, bool); +size_t g_arch_instruction_get_sources(const GArchInstruction *, instr_link_t **); -#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, true) -#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, false) +#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, true) +#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, false) -#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, true) -#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, false) +#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true) +#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false) /* Indique si l'instruction a une suite autre que la suivante. */ bool g_arch_instruction_has_destinations(const GArchInstruction *); /* Fournit les destinations d'une instruction donnée. */ -size_t g_arch_instruction_get_destinations(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **); +size_t g_arch_instruction_get_destinations(const GArchInstruction *, instr_link_t **); /* Fournit la destination d'une instruction et d'un type donné. */ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *, InstructionLinkType); diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c index 2f6feda..a619b2d 100644 --- a/src/gtkext/graph/cluster.c +++ b/src/gtkext/graph/cluster.c @@ -904,8 +904,7 @@ 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*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #1 */ GGraphCluster *target; /* Bloc ciblé par un lien */ @@ -922,10 +921,10 @@ 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, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -933,7 +932,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])); + target = G_GRAPH_CLUSTER(g_hash_table_lookup(all, dests[i].linked)); assert(target != NULL); /* Point de départ */ @@ -983,12 +982,12 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all leaving->index = cluster->ba_count - 1; - incoming->type = types[i]; + incoming->type = dests[i].type; - if (types[i] == ILT_JUMP_IF_TRUE) + if (incoming->type == ILT_JUMP_IF_TRUE) incoming->edge = g_graph_edge_new_true(&leaving->start, &incoming->y, &incoming->end); - else if (types[i] == ILT_JUMP_IF_FALSE) + else if (incoming->type == ILT_JUMP_IF_FALSE) incoming->edge = g_graph_edge_new_false(&leaving->start, &incoming->y, &incoming->end); else @@ -1509,8 +1508,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi #ifndef NDEBUG gboolean new; /* Bloc déjà traité ? */ #endif - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ + instr_link_t *dests; /* Instr. visées par une autre */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #1 */ GBasicBlock *target; /* Bloc ciblé par un lien */ @@ -1536,10 +1534,10 @@ 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, &types); + dcount = g_arch_instruction_get_destinations(last, &dests); for (i = 0; i < dcount; i++) - switch (types[i]) + switch (dests[i].type) { case ILT_EXEC_FLOW: case ILT_JUMP: @@ -1547,7 +1545,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]); + target = g_block_list_find_by_starting_instr(list, dests[i].linked); /** * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. @@ -1560,7 +1558,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi * */ - printf(" NEW BLK :: %d -> %p\n", types[i], target); + printf(" NEW BLK :: %d -> %p\n", dests[i].type, target); if (target != NULL) { @@ -1590,11 +1588,11 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi * la table globale. */ - if (!g_hash_table_contains(all, dests[i])) + if (!g_hash_table_contains(all, dests[i].linked)) { assert((pending->count + 1) < g_block_list_count_blocks(list)); pending->list[pending->count++] = target; - printf(" --push-- %d -> %p\n", types[i], target); + printf(" --push-- %d -> %p\n", dests[i].type, target); } } diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c index fe18e4e..96f974a 100644 --- a/src/gui/dialogs/gotox.c +++ b/src/gui/dialogs/gotox.c @@ -273,7 +273,7 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi { GtkWidget *result; /* Fenêtre à renvoyer */ GtkTreeStore *store; /* Modèle de gestion */ - GArchInstruction **list; /* Liste d'instructions */ + instr_link_t *list; /* Liste d'instructions */ size_t count; /* Nombre d'éléments présents */ size_t i; /* Boucle de parcours */ const vmpa2t *addr; /* Adresse à considérer */ @@ -292,17 +292,17 @@ 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, NULL); + count = g_arch_instruction_get_sources(instr, &list); } else { g_arch_instruction_rlock_dest(instr); - count = g_arch_instruction_get_destinations(instr, &list, NULL); + count = g_arch_instruction_get_destinations(instr, &list); } for (i = 0; i < count; i++) { - addr = get_mrange_addr(g_arch_instruction_get_range(list[i])); + addr = get_mrange_addr(g_arch_instruction_get_range(list[i].linked)); add_new_location_to_list(store, binary, addr, NULL); -- cgit v0.11.2-87-g4458