summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-24 07:43:32 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-24 07:43:32 (GMT)
commit08c45a8c7970403c3d658b1b0af9ac09f66b4a7e (patch)
tree25a8108e36b7328c266ba6e71647243dfd6b7cac
parent7135e7944c91d2e8b787c8782375423b9a90ed5b (diff)
Translated offsets and addresses with more accuracy.
-rw-r--r--plugins/dex/format.c2
-rw-r--r--plugins/elf/format.c68
-rw-r--r--plugins/elf/program.c84
-rw-r--r--plugins/elf/program.h6
-rw-r--r--plugins/elf/section.c84
-rw-r--r--plugins/elf/section.h6
-rw-r--r--plugins/mobicore/mclf.c2
-rw-r--r--src/format/executable-int.c74
-rw-r--r--src/format/executable-int.h13
-rw-r--r--src/format/executable.c52
-rw-r--r--src/format/executable.h4
-rw-r--r--src/glibext/gbinportion.c200
-rw-r--r--src/glibext/gbinportion.h6
13 files changed, 333 insertions, 268 deletions
diff --git a/plugins/dex/format.c b/plugins/dex/format.c
index b9b6ca9..f185cc3 100644
--- a/plugins/dex/format.c
+++ b/plugins/dex/format.c
@@ -407,6 +407,8 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS
preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status);
+ g_executable_format_setup_portions(exe, status);
+
if (!g_executable_format_complete_loading(exe, status))
goto gdfa_error;
diff --git a/plugins/elf/format.c b/plugins/elf/format.c
index 9e29a11..3394ba2 100644
--- a/plugins/elf/format.c
+++ b/plugins/elf/format.c
@@ -84,12 +84,6 @@ static bool g_elf_format_get_main_address(GElfFormat *, vmpa2t *);
/* Etend la définition des portions au sein d'un binaire. */
static void g_elf_format_refine_portions(GElfFormat *);
-/* Fournit l'emplacement correspondant à une position physique. */
-static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *);
-
-/* Fournit l'emplacement correspondant à une position physique. */
-static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *, virt_t, vmpa2t *);
-
/* Fournit l'emplacement d'une section donnée. */
static bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mrange_t *);
@@ -167,8 +161,8 @@ static void g_elf_format_class_init(GElfFormatClass *klass)
exe->get_main_addr = (get_main_addr_fc)g_elf_format_get_main_address;
exe->refine_portions = (refine_portions_fc)g_elf_format_refine_portions;
- exe->translate_phys = (translate_phys_fc)g_elf_format_translate_offset_into_vmpa;
- exe->translate_virt = (translate_virt_fc)g_elf_format_translate_address_into_vmpa;
+ exe->translate_phys = (translate_phys_fc)g_exe_format_translate_offset_into_vmpa_using_portions;
+ exe->translate_virt = (translate_virt_fc)g_exe_format_translate_address_into_vmpa_using_portions;
exe->get_range_by_name = (get_range_by_name_fc)g_elf_format_get_section_range_by_name;
@@ -382,6 +376,8 @@ static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusS
/* Chargements des informations utiles */
+ g_executable_format_setup_portions(exe, status);
+
/**
* On inscrit les éléments préchargés avant tout !
*
@@ -698,62 +694,6 @@ static void g_elf_format_refine_portions(GElfFormat *format)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
-* off = position physique à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une position physique. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *format, phys_t off, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
-
- result = translate_offset_into_vmpa_using_elf_sections(format, off, pos);
-
- if (!result)
- result = translate_offset_into_vmpa_using_elf_programs(format, off, pos);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* addr = adresse virtuelle à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une adresse virtuelle. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *format, virt_t addr, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
-
- result = translate_address_into_vmpa_using_elf_sections(format, addr, pos);
-
- if (!result)
- result = translate_address_into_vmpa_using_elf_programs(format, addr, pos);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
* name = nom de la section recherchée. *
* range = emplacement en mémoire à renseigner. [OUT] *
* *
diff --git a/plugins/elf/program.c b/plugins/elf/program.c
index 7fb63df..f4924f5 100644
--- a/plugins/elf/program.c
+++ b/plugins/elf/program.c
@@ -152,87 +152,3 @@ bool find_elf_program_by_type(const GElfFormat *format, uint32_t type, elf_phdr
return result;
}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* off = position physique à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une position physique. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *format, phys_t off, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
- uint16_t i; /* Boucle de parcours */
- elf_phdr program; /* Programme à analyser */
- virt_t addr; /* Adresse virtuelle calculée */
-
- result = false;
-
- for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++)
- {
- find_elf_program_by_index(format, i, &program);
-
- if (ELF_PHDR(format, program, p_offset) <= off
- && off < (ELF_PHDR(format, program, p_offset) + ELF_PHDR(format, program, p_filesz)))
- {
- addr = ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_offset) - off;
- init_vmpa(pos, off, addr);
- result = true;
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* addr = adresse virtuelle à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une adresse virtuelle. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *format, virt_t addr, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
- uint16_t i; /* Boucle de parcours */
- elf_phdr program; /* Programme à analyser */
- phys_t off; /* Position physique calculée */
-
- result = false;
-
- for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++)
- {
- find_elf_program_by_index(format, i, &program);
-
- if (ELF_PHDR(format, program, p_vaddr) <= addr
- && addr < (ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_filesz)))
- {
- off = ELF_PHDR(format, program, p_offset) + addr - ELF_PHDR(format, program, p_vaddr);
- init_vmpa(pos, off, addr);
- result = true;
- }
-
- }
-
- return result;
-
-}
diff --git a/plugins/elf/program.h b/plugins/elf/program.h
index 7c73340..34969cb 100644
--- a/plugins/elf/program.h
+++ b/plugins/elf/program.h
@@ -39,12 +39,6 @@ bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *);
/* Recherche un programme donné au sein de binaire par type. */
bool find_elf_program_by_type(const GElfFormat *, uint32_t, elf_phdr *);
-/* Fournit l'emplacement correspondant à une position physique. */
-bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *, phys_t, vmpa2t *);
-
-/* Fournit l'emplacement correspondant à une adresse virtuelle. */
-bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *, virt_t, vmpa2t *);
-
#endif /* _PLUGINS_ELF_PROGRAM_H */
diff --git a/plugins/elf/section.c b/plugins/elf/section.c
index cc47f9d..0e2fd3e 100644
--- a/plugins/elf/section.c
+++ b/plugins/elf/section.c
@@ -342,87 +342,3 @@ const char *extract_name_from_elf_string_section(const GElfFormat *format, const
return result;
}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* off = position physique à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une position physique. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *format, phys_t off, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
- uint16_t i; /* Boucle de parcours */
- elf_shdr section; /* Section à analyser */
- virt_t addr; /* Adresse virtuelle calculée */
-
- result = false;
-
- for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
- {
- find_elf_section_by_index(format, i, &section);
-
- if (ELF_SHDR(format, section, sh_offset) <= off
- && off < (ELF_SHDR(format, section, sh_offset) + ELF_SHDR(format, section, sh_size)))
- {
- addr = ELF_SHDR(format, section, sh_addr) + off - ELF_SHDR(format, section, sh_offset);
- init_vmpa(pos, off, addr);
- result = true;
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* addr = adresse virtuelle à retrouver. *
-* pos = position correspondante. [OUT] *
-* *
-* Description : Fournit l'emplacement correspondant à une adresse virtuelle. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *format, virt_t addr, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
- uint16_t i; /* Boucle de parcours */
- elf_shdr section; /* Section à analyser */
- phys_t off; /* Position physique calculée */
-
- result = false;
-
- for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
- {
- find_elf_section_by_index(format, i, &section);
-
- if (ELF_SHDR(format, section, sh_addr) <= addr
- && addr < (ELF_SHDR(format, section, sh_addr) + ELF_SHDR(format, section, sh_size)))
- {
- off = ELF_SHDR(format, section, sh_offset) + addr - ELF_SHDR(format, section, sh_addr);
- init_vmpa(pos, off, addr);
- result = true;
- }
-
- }
-
- return result;
-
-}
diff --git a/plugins/elf/section.h b/plugins/elf/section.h
index 021caf0..ac74ab1 100644
--- a/plugins/elf/section.h
+++ b/plugins/elf/section.h
@@ -57,12 +57,6 @@ bool find_elf_section_range_by_name(const GElfFormat *, const char *, mrange_t *
/* Identifie une chaîne de caractères dans une section adéquate. */
const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t);
-/* Fournit l'emplacement correspondant à une position physique. */
-bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *, phys_t, vmpa2t *);
-
-/* Fournit l'emplacement correspondant à une adresse virtuelle. */
-bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *, virt_t, vmpa2t *);
-
#endif /* _PLUGINS_ELF_SECTION_H */
diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c
index 0c4de64..37939f7 100644
--- a/plugins/mobicore/mclf.c
+++ b/plugins/mobicore/mclf.c
@@ -213,6 +213,8 @@ GBinFormat *g_mclf_format_new(GBinContent *content, GExeFormat *parent, GtkStatu
if (!read_mclf_header(result, &result->header, result->endian))
goto gmfn_error;
+ g_executable_format_setup_portions(G_EXE_FORMAT(result), status);
+
if (!load_mclf_symbols(result))
goto gmfn_error;
diff --git a/src/format/executable-int.c b/src/format/executable-int.c
index e13a7c9..d20a776 100644
--- a/src/format/executable-int.c
+++ b/src/format/executable-int.c
@@ -79,3 +79,77 @@ bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *for
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* off = position physique à retrouver. *
+* pos = position correspondante. [OUT] *
+* *
+* Description : Fournit l'emplacement correspondant à une position physique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_exe_format_translate_offset_into_vmpa_using_portions(GExeFormat *format, phys_t off, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ GBinPortion *portions; /* Liste de découpages */
+
+ portions = g_exe_format_get_portions(format);
+
+ if (portions == NULL)
+ result = false;
+
+ else
+ {
+ result = g_binary_portion_translate_offset_into_vmpa(portions, off, pos);
+
+ g_object_unref(G_OBJECT(portions));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* addr = adresse virtuelle à retrouver. *
+* pos = position correspondante. [OUT] *
+* *
+* Description : Fournit l'emplacement correspondant à une adresse virtuelle. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_exe_format_translate_address_into_vmpa_using_portions(GExeFormat *format, virt_t addr, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ GBinPortion *portions; /* Liste de découpages */
+
+ portions = g_exe_format_get_portions(format);
+
+ if (portions == NULL)
+ result = false;
+
+ else
+ {
+ result = g_binary_portion_translate_address_into_vmpa(portions, addr, pos);
+
+ g_object_unref(G_OBJECT(portions));
+
+ }
+
+ return result;
+
+}
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index ed2c7c1..58eba25 100644
--- a/src/format/executable-int.h
+++ b/src/format/executable-int.h
@@ -42,10 +42,10 @@ typedef bool (* get_main_addr_fc) (GExeFormat *, vmpa2t *);
typedef void (* refine_portions_fc) (GExeFormat *);
/* Fournit l'emplacement correspondant à une position physique. */
-typedef bool (* translate_phys_fc) (const GExeFormat *, phys_t, vmpa2t *);
+typedef bool (* translate_phys_fc) (GExeFormat *, phys_t, vmpa2t *);
/* Fournit l'emplacement correspondant à une adresse virtuelle. */
-typedef bool (* translate_virt_fc) (const GExeFormat *, virt_t, vmpa2t *);
+typedef bool (* translate_virt_fc) (GExeFormat *, virt_t, vmpa2t *);
/* Fournit l'emplacement d'une section donnée. */
typedef bool (* get_range_by_name_fc) (const GExeFormat *, const char *, mrange_t *);
@@ -82,6 +82,9 @@ struct _GExeFormatClass
};
+/* Crée les portions potentiellement utiles aux traductions. */
+void g_executable_format_setup_portions(GExeFormat *, GtkStatusStack *);
+
/* Effectue les ultimes opérations de chargement d'un binaire. */
bool g_executable_format_complete_loading(GExeFormat *, GtkStatusStack *);
@@ -91,6 +94,12 @@ bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *, ph
/* Fournit l'emplacement correspondant à une adresse virtuelle. */
bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *, virt_t, vmpa2t *);
+/* Fournit l'emplacement correspondant à une position physique. */
+bool g_exe_format_translate_offset_into_vmpa_using_portions(GExeFormat *, phys_t, vmpa2t *);
+
+/* Fournit l'emplacement correspondant à une adresse virtuelle. */
+bool g_exe_format_translate_address_into_vmpa_using_portions(GExeFormat *, virt_t, vmpa2t *);
+
#endif /* _FORMAT_EXECUTABLE_INT_H */
diff --git a/src/format/executable.c b/src/format/executable.c
index 0107074..a2ee569 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -289,39 +289,57 @@ bool g_exe_format_get_main_address(GExeFormat *format, vmpa2t *addr)
* Paramètres : format = instance à traiter. *
* status = barre de statut à tenir informée. *
* *
-* Description : Effectue les ultimes opérations de chargement d'un binaire. *
+* Description : Crée les portions potentiellement utiles aux traductions. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *status)
+void g_executable_format_setup_portions(GExeFormat *format, GtkStatusStack *status)
{
- bool result; /* Bilan à faire remonter */
GBinFormat *base; /* Version basique du format */
vmpa2t addr; /* Emplacement vide de sens */
phys_t length; /* Taille de portion globale */
base = G_BIN_FORMAT(format);
- result = g_binary_format_complete_loading(base, status);
+ /**
+ * Avant de lire l'entête du format, on ne sait pas où on se trouve !
+ */
+ init_vmpa(&addr, 0, VMPA_NO_VIRTUAL);
- if (result)
- {
- /**
- * Avant de lire l'entête du format, on ne sait pas où on se trouve !
- */
- init_vmpa(&addr, 0, VMPA_NO_VIRTUAL);
+ length = g_binary_content_compute_size(base->content);
+
+ format->portions = g_binary_portion_new(BPC_RAW, &addr, length);
- length = g_binary_content_compute_size(base->content);
+ G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format);
- format->portions = g_binary_portion_new(BPC_RAW, &addr, length);
+}
- G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format);
- }
+/******************************************************************************
+* *
+* Paramètres : format = instance à traiter. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Effectue les ultimes opérations de chargement d'un binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *status)
+{
+ bool result; /* Bilan à faire remonter */
+ GBinFormat *base; /* Version basique du format */
+
+ base = G_BIN_FORMAT(format);
+
+ result = g_binary_format_complete_loading(base, status);
return result;
@@ -447,7 +465,7 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format)
* *
******************************************************************************/
-bool g_exe_format_translate_offset_into_vmpa(const GExeFormat *format, phys_t off, vmpa2t *pos)
+bool g_exe_format_translate_offset_into_vmpa(GExeFormat *format, phys_t off, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
@@ -472,7 +490,7 @@ bool g_exe_format_translate_offset_into_vmpa(const GExeFormat *format, phys_t of
* *
******************************************************************************/
-bool g_exe_format_translate_address_into_vmpa(const GExeFormat *format, virt_t addr, vmpa2t *pos)
+bool g_exe_format_translate_address_into_vmpa(GExeFormat *format, virt_t addr, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
diff --git a/src/format/executable.h b/src/format/executable.h
index af69029..293a0c0 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -76,10 +76,10 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *);
mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count);
/* Fournit l'emplacement correspondant à une position physique. */
-bool g_exe_format_translate_offset_into_vmpa(const GExeFormat *, phys_t, vmpa2t *);
+bool g_exe_format_translate_offset_into_vmpa(GExeFormat *, phys_t, vmpa2t *);
/* Fournit l'emplacement correspondant à une position physique. */
-bool g_exe_format_translate_address_into_vmpa(const GExeFormat *, virt_t, vmpa2t *);
+bool g_exe_format_translate_address_into_vmpa(GExeFormat *, virt_t, vmpa2t *);
#define g_exe_format_translate_offset_into_address(fmt, off, addr) \
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 2275583..27413f6 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -119,7 +119,13 @@ static void g_binary_portion_print(GBinPortion *, GBufferLine *, size_t, size_t,
/* Détermine si une portion contient une adresse donnée. */
-static bool g_portion_layer_contains_addr(const GBinPortion *, const vmpa2t *);
+static bool g_binary_portion_contains_vmpa(const GBinPortion *, const vmpa2t *);
+
+/* Détermine si une portion contient une position donnée. */
+static bool g_binary_portion_contains_physical(const GBinPortion *, phys_t);
+
+/* Détermine si une portion contient une adresse donnée. */
+static bool g_binary_portion_contains_virtual(const GBinPortion *, virt_t);
@@ -1196,7 +1202,7 @@ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRecta
* *
******************************************************************************/
-static bool g_portion_layer_contains_addr(const GBinPortion *portion, const vmpa2t *addr)
+static bool g_binary_portion_contains_vmpa(const GBinPortion *portion, const vmpa2t *addr)
{
bool result; /* Bilan à retourner */
@@ -1245,7 +1251,7 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a
{
sub = portion->subs[i];
- if (!g_portion_layer_contains_addr(sub, addr))
+ if (!g_binary_portion_contains_vmpa(sub, addr))
continue;
if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area))
@@ -1372,3 +1378,191 @@ gboolean query_tooltip_for_binary_portion(GBinPortion *root, gint x, gint y, con
return TRUE;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = portion mère à consulter. *
+* off = position physique du point de recherche. *
+* *
+* Description : Détermine si une portion contient une position donnée. *
+* *
+* Retour : true ou false selon le résultat. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_binary_portion_contains_physical(const GBinPortion *portion, phys_t off)
+{
+ bool result; /* Bilan à retourner */
+ const mrange_t *range; /* Emplacement de portion */
+ const vmpa2t *addr; /* Départ de la portion */
+
+ range = g_binary_portion_get_range(portion);
+ addr = get_mrange_addr(range);
+
+ if (!has_phys_addr(addr))
+ result = false;
+
+ else
+ result = (addr->physical <= off && off < (addr->physical + range->length));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = couche de portions à parcourir pour les recherches.*
+* off = position physique à retrouver. *
+* pos = position correspondante. [OUT] *
+* *
+* Description : Fournit l'emplacement correspondant à une position physique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_portion_translate_offset_into_vmpa(const GBinPortion *portion, phys_t off, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ GBinPortion *sub; /* Portion incluse à traiter */
+ const mrange_t *range; /* Emplacement de portion */
+ const vmpa2t *addr; /* Départ de la portion */
+
+ result = false;
+
+ for (i = 0; i < portion->count; i++)
+ {
+ sub = portion->subs[i];
+
+ if (!g_binary_portion_contains_physical(sub, off))
+ continue;
+
+ result = g_binary_portion_translate_offset_into_vmpa(sub, off, pos);
+
+ break;
+
+ }
+
+ if (i == portion->count)
+ {
+ result = g_binary_portion_contains_physical(portion, off);
+
+ if (result)
+ {
+ range = g_binary_portion_get_range(portion);
+ addr = get_mrange_addr(range);
+
+ if (has_virt_addr(get_mrange_addr(range)))
+ init_vmpa(pos, off, addr->virtual + off - addr->physical);
+
+ else
+ init_vmpa(pos, off, VMPA_NO_VIRTUAL);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = portion mère à consulter. *
+* virt = adresse virtuelle du point de recherche. *
+* *
+* Description : Détermine si une portion contient une adresse donnée. *
+* *
+* Retour : true ou false selon le résultat. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_binary_portion_contains_virtual(const GBinPortion *portion, virt_t virt)
+{
+ bool result; /* Bilan à retourner */
+ const mrange_t *range; /* Emplacement de portion */
+ const vmpa2t *addr; /* Départ de la portion */
+
+ range = g_binary_portion_get_range(portion);
+ addr = get_mrange_addr(range);
+
+ if (!has_virt_addr(addr))
+ result = false;
+
+ else
+ result = (addr->virtual <= virt && virt < (addr->virtual + range->length));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = couche de portions à parcourir pour les recherches.*
+* virt = adresse virtuelle à retrouver. *
+* pos = position correspondante. [OUT] *
+* *
+* Description : Fournit l'emplacement correspondant à une adresse virtuelle. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_portion_translate_address_into_vmpa(const GBinPortion *portion, virt_t virt, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ GBinPortion *sub; /* Portion incluse à traiter */
+ const mrange_t *range; /* Emplacement de portion */
+ const vmpa2t *addr; /* Départ de la portion */
+
+ result = false;
+
+ for (i = 0; i < portion->count; i++)
+ {
+ sub = portion->subs[i];
+
+ if (!g_binary_portion_contains_virtual(sub, virt))
+ continue;
+
+ result = g_binary_portion_translate_address_into_vmpa(sub, virt, pos);
+
+ break;
+
+ }
+
+ if (i == portion->count)
+ {
+ result = g_binary_portion_contains_virtual(portion, virt);
+
+ if (result)
+ {
+ range = g_binary_portion_get_range(portion);
+ addr = get_mrange_addr(range);
+
+ if (has_phys_addr(addr) && has_virt_addr(addr))
+ init_vmpa(pos, addr->physical + virt - addr->virtual, virt);
+
+ else
+ init_vmpa(pos, VMPA_NO_PHYSICAL, virt);
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index b1184fb..581be68 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -159,6 +159,12 @@ bool get_binary_portion_pos_from_addr(GBinPortion *, const vmpa2t *, const GdkRe
/* Prépare une astuce concernant une portion pour son affichage. */
gboolean query_tooltip_for_binary_portion(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *);
+/* Fournit l'emplacement correspondant à une position physique. */
+bool g_binary_portion_translate_offset_into_vmpa(const GBinPortion *, phys_t, vmpa2t *);
+
+/* Fournit l'emplacement correspondant à une adresse virtuelle. */
+bool g_binary_portion_translate_address_into_vmpa(const GBinPortion *, virt_t, vmpa2t *);
+
#endif /* _GLIBEXT_BINPORTION_H */