summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-10-14 00:10:11 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-10-14 00:10:11 (GMT)
commit48726043e2f07874e7a09a866c4cc537a65a683c (patch)
tree557e4f6cd700d131e8964d02890a6381f87e52cd
parent18beadb4192144b00c06769645befb17ae1ce98e (diff)
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
-rw-r--r--ChangeLog24
-rw-r--r--src/analysis/disass/links.c150
-rw-r--r--src/arch/arm/v7/fetch.c13
-rw-r--r--src/arch/arm/v7/opdefs/bl_A8825.d2
-rw-r--r--src/arch/arm/v7/post.c30
-rw-r--r--src/arch/instruction.c10
-rw-r--r--src/format/format.c24
-rw-r--r--src/format/symbol.c15
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;