summaryrefslogtreecommitdiff
path: root/src/analysis/disass/links.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-03-31 23:20:33 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-03-31 23:20:33 (GMT)
commit5cc7bd39ae41af40a0c939acf98f90bf1375effd (patch)
tree4f7140e2c5a8d939c672fb941e66903300229e82 /src/analysis/disass/links.c
parent52e036040b5e0ad8acde3d467ac8d9ca43ed414c (diff)
Saved some progress in the definition of basic blocks.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@497 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass/links.c')
-rw-r--r--src/analysis/disass/links.c87
1 files changed, 82 insertions, 5 deletions
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 022ace3..06b6b03 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -33,10 +33,8 @@
/* Complète un désassemblage accompli pour une instruction. */
static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *);
-
-
-
-
+/* Rétablit un lien naturel coupé par un autre lien. */
+static void establish_natural_link(GArchInstruction *, GArchInstruction *);
@@ -118,10 +116,83 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
target = g_arch_instruction_find_by_address(list, &addr, true);
if (target != NULL)
- g_arch_instruction_link_with(instr, target, ILT_JUMP /* FIXME */);
+ g_arch_instruction_link_with(instr, target, ILT_REF);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction désassemblée à traiter. *
+* prev = instruction précédente. *
+* *
+* Description : Rétablit un lien naturel coupé par un autre lien. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
+{
+ GArchInstruction **others; /* Instructions diverses liées */
+ InstructionLinkType *types; /* Types de lien existants */
+ size_t count; /* Nbre de sources affichées */
+ size_t i; /* Boucle de parcours */
+
+ /**
+ * Si rien ne vient séparer les deux instructions,
+ * on ne peut pas créer de lien plus naturel que l'existant.
+ */
+
+ if (!g_arch_instruction_has_sources(instr))
+ return;
+
+ /**
+ * Si on se trouve à une extrémité, on ne se lie pas
+ * avec le voisin.
+ */
+
+ if (g_arch_instruction_is_return(prev))
+ return;
+
+ if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
+ return;
+
+ /**
+ * On s'assure que le lien naturel est valide.
+ */
+
+ count = g_arch_instruction_get_destinations(prev, &others, &types, NULL);
+
+ 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 (i < count) return;
+
+ /**
+ * On vérifie que le lien n'existe pas déjà avant d'en créer un...
+ */
+ count = g_arch_instruction_get_sources(instr, &others, &types);
+
+ 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 (i == count)
+ g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW);
+
}
@@ -142,13 +213,19 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
void establish_links_between_instructions(GArchInstruction *list, GBinFormat *format, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
+ GArchInstruction *prev; /* Itération précédente */
GArchInstruction *iter; /* Boucle de parcours */
+ prev = NULL;
+
for (iter = list;
iter != NULL;
iter = g_arch_instruction_get_next_iter(list, iter, ~0/* FIXME */))
{
+ if (prev != NULL)
+ establish_natural_link(iter, prev);
+ prev = iter;
establish_links_for_instruction(iter, list, format);