diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/format/executable-int.c | 74 | ||||
-rw-r--r-- | src/format/executable-int.h | 13 | ||||
-rw-r--r-- | src/format/executable.c | 52 | ||||
-rw-r--r-- | src/format/executable.h | 4 | ||||
-rw-r--r-- | src/glibext/gbinportion.c | 200 | ||||
-rw-r--r-- | src/glibext/gbinportion.h | 6 |
6 files changed, 325 insertions, 24 deletions
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 */ |