From 48726043e2f07874e7a09a866c4cc537a65a683c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 14 Oct 2015 00:10:11 +0000
Subject: Forced the full definition of locations to fix the search of symbols.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@594 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                         |  24 ++++++
 src/analysis/disass/links.c       | 150 +++++++++++++++++++-------------------
 src/arch/arm/v7/fetch.c           |  13 +++-
 src/arch/arm/v7/opdefs/bl_A8825.d |   2 +-
 src/arch/arm/v7/post.c            |  30 +++++---
 src/arch/instruction.c            |  10 ++-
 src/format/format.c               |  24 +++++-
 src/format/symbol.c               |  15 +---
 8 files changed, 157 insertions(+), 111 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f594cba..7eabc65 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 15-10-14  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/analysis/disass/links.c:
+	Reorganize the code.
+
+	* src/arch/arm/v7/fetch.c:
+	Fix a bug about switching between ARM and Thumb modes. Force the full
+	definition of locations.
+
+	* src/arch/arm/v7/opdefs/bl_A8825.d:
+	Typo.
+
+	* src/arch/arm/v7/post.c:
+	Force the full definition of locations.
+
+	* src/arch/instruction.c:
+	Typo.
+
+	* src/format/format.c:
+	Force the full definition of locations to fix the search of symbols.
+
+	* src/format/symbol.c:
+	Fix the comparison of symbols.
+
+15-10-14  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/analysis/disass/fetch.c:
 	Update code.
 
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 43b7e6f..8d826c5 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -30,13 +30,86 @@
 
 
 
+/* Rétablit un lien naturel coupé par un autre lien. */
+static void establish_natural_link(GArchInstruction *, GArchInstruction *);
+
 /* 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 *);
 
 
+/******************************************************************************
+*                                                                             *
+*  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_get_flags(prev) & AIF_RETURN_POINT)
+        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 (count > 0 && 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);
+
+}
+
 
 /******************************************************************************
 *                                                                             *
@@ -125,79 +198,6 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
 
 /******************************************************************************
 *                                                                             *
-*  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_get_flags(prev) & AIF_RETURN_POINT)
-        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 (count > 0 && 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);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : list      = ensemble d'instructions à relier.                *
 *                format    = accès aux données du binaire d'origine.          *
 *                statusbar = barre de statut avec progression à mettre à jour.*
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 73cec6d..da83d15 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -353,7 +353,7 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
 *                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à inverser.     *
+*                iset    = type de jeu d'instructions courant.                *
 *                                                                             *
 *  Description : Complète un désassemblage accompli pour une instruction.     *
 *                                                                             *
@@ -429,7 +429,13 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     else
         val_offset = phys_pc - offset;
 
-    init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL);
+    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), val_offset, &sym_addr))
+    {
+        assert(0);
+        return;
+    }
+
+    //init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL);
     init_mrange(&sym_range, &sym_addr, 4);
 
 
@@ -502,6 +508,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     /// FIXME ?!
     if (target < 0x8000) return;
 
+    if (target > 0x6966c) return;
 
 
     new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
@@ -517,7 +524,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     //target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+    g_armv7_context_push_drop_point_ext(context, target, iset);
 
 
     //exit(0);
diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d
index a9b395a..c2eb7bd 100644
--- a/src/arch/arm/v7/opdefs/bl_A8825.d
+++ b/src/arch/arm/v7/opdefs/bl_A8825.d
@@ -113,7 +113,7 @@
 
 @encoding(A2) {
 
-    @word cond(4) 1 0 1 H(1) imm24(24)
+    @word 1 1 1 1 1 0 1 H(1) imm24(24)
 
     @syntax "blx" <imm32>
 
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index e95bd66..e066bb0 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -24,9 +24,6 @@
 #include "post.h"
 
 
-#include <assert.h>
-
-
 #include "../../target.h"
 
 
@@ -60,13 +57,13 @@ void post_process_branch_instructions(GArchInstruction *instr, GArchProcessor *p
 
     op = g_arch_instruction_get_operand(instr, 0);
 
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)
+        && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target))
     {
         new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
 
         if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
         {
-            init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
             init_mrange(&trange, &target, 0);
 
             vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL);
@@ -124,13 +121,23 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GArchPro
 
     op = g_arch_instruction_get_operand(instr, 0);
 
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)
+        && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target))
     {
+
+
+        /// FIXME (DUR) ?!
+        if (addr < 0x8000) return;
+
+        if (addr > 0x6966c) return;
+
+
+
+
         new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
 
         if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
         {
-            init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
             init_mrange(&trange, &target, 0);
 
             vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL);
@@ -188,13 +195,13 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GArchPro
 
     op = g_arch_instruction_get_operand(instr, 1);
 
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)
+        && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target))
     {
         new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
 
         if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
         {
-            init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
             init_mrange(&trange, &target, 0);
 
             vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL);
@@ -256,7 +263,8 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
     if (!G_IS_IMM_OPERAND(op)) return;
 
 
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)
+        && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target))
     {
         new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
 
@@ -277,7 +285,6 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
 
             } while (0);
 
-            init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
             init_mrange(&trange, &target, 0);
 
             vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL);
@@ -317,6 +324,5 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
         g_arch_instruction_replace_operand(instr, new, op);
 
     }
-    else assert(0);
 
 }
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index d9d7693..c3c32dc 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -663,7 +663,7 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr = instruction dont les informations sont à consulter.  *
-*                dests = liste des instructions de destination. [OUT]         *
+*                srcs  = liste des instructions d'origine. [OUT]              *
 *                types = liste des types de liens présents. [OUT]             *
 *                                                                             *
 *  Description : Fournit les origines d'une instruction donnée.               *
@@ -674,9 +674,10 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types)
+size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***srcs, InstructionLinkType **types)
 {
-    *dests = instr->from;
+    if (srcs != NULL)
+        *srcs = instr->from;
 
     if (types != NULL)
         *types = instr->from_types;
@@ -724,7 +725,8 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr)
 
 size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types, link_extra_info **info)
 {
-    *dests = instr->to;
+    if (dests != NULL)
+        *dests = instr->to;
 
     if (types != NULL)
         *types = instr->to_types;
diff --git a/src/format/format.c b/src/format/format.c
index 9f03924..9c42508 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -221,7 +221,7 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
 *                                                                             *
 *  Description : Ajoute un symbole à la collection du format binaire.         *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : true si le symbole était bien localisé et a été inséré.      *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -229,6 +229,26 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
 
 void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool sort)
 {
+    const mrange_t *range;                  /* Couverture du symbole       */
+    const vmpa2t *addr;                     /* Emplacement du symbole      */
+
+    /**
+     * Lorsque les fonctions de recherche type g_binary_format_find_symbol_at()
+     * sont appelées avec une localisation, cette dernière peut reposer soit sur
+     * une position physique soit une adresse virtuelle uniquement.
+     *
+     * Pour que les comparaisons de positions puissent se réaliser, il faut donc
+     * pouvoir satisfaire les deux aspects : physiques et virtuels.
+     *
+     * On corrige donc le tir si besoin est ici.
+     */
+
+#ifndef NDEBUG
+    range = g_binary_symbol_get_range(symbol);
+    addr = get_mrange_addr(range);
+
+    assert(get_phy_addr(addr) != VMPA_NO_PHYSICAL && get_virt_addr(addr) != VMPA_NO_VIRTUAL);
+#endif
 
     g_rw_lock_writer_lock(&format->syms_lock);
 
@@ -628,7 +648,7 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr
 
         range = g_binary_symbol_get_range(*sym);
 
-        return cmp_vmpa_by_virt(addr, get_mrange_addr(range));
+        return cmp_vmpa(addr, get_mrange_addr(range));
 
     }
 
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 70a1d24..2346c63 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -202,8 +202,6 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b)
     int result;                             /* Bilan à retourner           */
 	const mrange_t *ra;						/* Emplacement du symbole A	   */
 	const mrange_t *rb;						/* Emplacement du symbole B	   */
-    const vmpa2t *aa;                       /* Adresse du symbole A        */
-    const vmpa2t *ab;                       /* Adresse du symbole B        */
 
 	ra = g_binary_symbol_get_range(*a);
 	rb = g_binary_symbol_get_range(*b);
@@ -218,18 +216,7 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b)
 		result = -1;
 
 	else
-	{
-		aa = get_mrange_addr(ra);
-		ab = get_mrange_addr(rb);
-
-        result = cmp_vmpa_by_virt(aa, ab);
-
-		//result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0);
-		///result = cmp_mrange(ra, rb);
-
-		//printf(" ?? 0x%08lx vs 0x%08lx -> %d\n", aa->virtual, ab->virtual, result);
-
-	}
+        result = cmp_mrange(ra, rb);
 
     return result;
 
-- 
cgit v0.11.2-87-g4458