From e5e7408e52f33039db6315f82b294e604503ad78 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 28 Jan 2017 00:07:27 +0100 Subject: Established natural links between instructions only when relevant. --- ChangeLog | 5 +++ src/analysis/disass/links.c | 85 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd3d98f..bfaf59a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +17-01-28 Cyrille Bagard + + * src/analysis/disass/links.c: + Establish natural links between instructions only when relevant. + 17-01-27 Cyrille Bagard * src/gtkext/easygtk.c: diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index d3434cb..0884dce 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -24,6 +24,8 @@ #include "links.h" +#include + #include "../../arch/instruction.h" #include "../../arch/raw.h" @@ -52,6 +54,8 @@ 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 ? */ + bool no_natural; /* Aucun lien naturel présent */ + bool no_need; /* Pas de besoin pour ce lien */ instr_link_t *others; /* Instructions diverses liées */ size_t count; /* Nbre de sources affichées */ size_t i; /* Boucle de parcours */ @@ -80,42 +84,81 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) return; /** - * On s'assure que le lien naturel est valide. + * On s'assure que le lien naturel est nécessaire et qu'il n'est pas + * déjà en place. */ + no_natural = true; + no_need = true; + g_arch_instruction_rlock_dest(prev); count = g_arch_instruction_get_destinations(prev, &others); - for (i = 0; i < count; i++) - { - 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; - } + for (i = 0; i < count && no_natural; i++) + switch (others[i].type) + { + case ILT_EXEC_FLOW: + no_natural = false; + break; + + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + if (others[i].linked != instr) + no_need = false; + else + { + no_need = true; + goto check_done; + } + break; + + default: + break; + + } + + check_done: g_arch_instruction_runlock_dest(prev); - if (count > 0 && i < count) return; + if (no_natural && !no_need) + { + /* Vérification de la cohérence de l'ensemble */ +#ifndef NDEBUG - /** - * On vérifie que le lien n'existe pas déjà avant d'en créer un... - */ + g_arch_instruction_rlock_src(instr); + count = g_arch_instruction_get_sources(instr, &others); - g_arch_instruction_rlock_src(instr); - count = g_arch_instruction_get_sources(instr, &others); + for (i = 0; i < count; i++) + switch (others[i].type) + { + case ILT_NONE: + case ILT_EXEC_FLOW: + assert(false); + break; - for (i = 0; i < count; i++) - { - 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; - } + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + case ILT_LOOP: + case ILT_CATCH_EXCEPTION: + assert(others[i].linked != prev); + break; - g_arch_instruction_runlock_src(instr); + default: + break; + + } + + g_arch_instruction_runlock_src(instr); + +#endif - if (i == count) g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW); + } + } -- cgit v0.11.2-87-g4458