diff options
Diffstat (limited to 'plugins/dwarf/abbrev.c')
-rw-r--r-- | plugins/dwarf/abbrev.c | 1181 |
1 files changed, 159 insertions, 1022 deletions
diff --git a/plugins/dwarf/abbrev.c b/plugins/dwarf/abbrev.c index f214430..e755acf 100644 --- a/plugins/dwarf/abbrev.c +++ b/plugins/dwarf/abbrev.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * abbrev.c - manipulation des abréviation DWARF * - * Copyright (C) 2008-2017 Cyrille Bagard + * Copyright (C) 2008-2018 Cyrille Bagard * * This file is part of Chrysalide. * @@ -24,13 +24,16 @@ #include "abbrev.h" -#include <malloc.h> +#include <analysis/contents/restricted.h> -#include "dwarf-int.h" +#include "checks.h" +#include "format-int.h" +#include "utils.h" +/* ----------------------- TRAITEMENT D'ABREVIATION A L'UNITE ----------------------- */ /* Description d'un attribut d'une abréviation */ @@ -41,78 +44,59 @@ typedef struct _dw_abbrev_attr } dw_abbrev_attr; - /* Description d'une abréviation */ struct _dw_abbrev { uleb128_t code; /* Identifiant attribué */ DwarfTag tag; /* Sujet de l'élément */ - dw_abbrev_attr *attribs; /* Liste des attributs */ - size_t attribs_count; /* Nombre de ces attributs */ + bool has_children; /* Présence de sous-éléments ? */ - struct _dw_abbrev **children; /* Liste des sous-éléments */ - size_t children_count; /* Nombre de ces enfants */ + dw_abbrev_attr *attribs; /* Liste des attributs */ + size_t count; /* Nombre de ces attributs */ }; +/* Charge une abréviation valide pour un DWARF en mémoire. */ +static bool load_dwarf_abbreviation(GDwarfFormat *, const dw_compil_unit_header *, GBinContent *, vmpa2t *, dw_abbrev **); - +/* Supprime de la mémoire toute trace d'une abréviation DWARF. */ +static void free_dwarf_abbrev(dw_abbrev *); /* Procède à la conversion de base d'une abréviation DWARF. */ -static bool check_abbreviation_decl(const GDwarfFormat *, const dw_abbrev_decl *, dw_abbrev *); +static bool conv_abbrev_decl(GDwarfFormat *, const dw_compil_unit_header *, const dw_abbrev_decl *, dw_abbrev *, const vmpa2t *); /* Procède à la conversion d'un attribut d'abréviation DWARF. */ -static bool check_abbreviation_attrib(const GDwarfFormat *, const dw_abbrev_raw_attr *, dw_abbrev_attr *); +static bool conv_abbrev_attrib(GDwarfFormat *, const dw_compil_unit_header *, const dw_abbrev_raw_attr *, dw_abbrev_attr *, const vmpa2t *); +/* ----------------------- TRAITEMENT D'ABREVIATIONS PAR LOTS ----------------------- */ -/****************************************************************************** -* * -* Paramètres : format = informations de débogage à constituer. * -* * -* Description : Charge toutes les abbréviations présentes dans un DWARF. * -* * -* Retour : Bilan de l'opération, potentiellement un succès sans sortie. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_all_dwarf_abbreviations(GDwarfFormat *format) +/* Brochette d'abréviations */ +struct _dw_abbrev_brotherhood { - bool result; /* Bilan à faire remonter */ - mrange_t range; /* Couverture d'une section */ - vmpa2t *pos; /* Position de tête de lecture */ + dw_abbrev **abbrevs; /* Liste des sous-éléments */ + size_t count; /* Nombre de ces éléments */ - result = g_exe_format_get_section_range_by_name(G_DBG_FORMAT(format)->executable, ".debug_abbrev", &range); - - pos = get_mrange_addr(&range); - - printf("start :: 0x%08x\n", (unsigned int)pos->physical); - - result &= load_dwarf_abbreviation(format, pos, &format->abbreviations); - - printf("abbrevs :: %p\n", format->abbreviations); +}; - if (format->abbreviations != NULL) - printf(" -> children : %zu\n", format->abbreviations->children_count); - else - printf(" -> (nothing)\n"); - return result; -} +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT D'ABREVIATION A L'UNITE */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : format = informations de débogage à consulter. * -* pos = tête de lecture à faire évoluer. * -* abbrev = abréviation lue et complète, NULL si aucune. [OUT] * +* Paramètres : format = informations de débogage à consulter. * +* cu = unité de compilation parente. * +* content = contenu binaire borné à parcourir. * +* pos = tête de lecture à faire évoluer. [OUT] * +* abbrev = abréviation lue et complète, NULL si aucune. [OUT] * * * * Description : Charge une abréviation valide pour un DWARF en mémoire. * * * @@ -122,14 +106,15 @@ bool load_all_dwarf_abbreviations(GDwarfFormat *format) * * ******************************************************************************/ -bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev **abbrev) +static bool load_dwarf_abbreviation(GDwarfFormat *format, const dw_compil_unit_header *cu, GBinContent *content, vmpa2t *pos, dw_abbrev **abbrev) { + vmpa2t old; /* Mémorisation d'une position */ + dw_abbrev *new; /* Nouvelle abréviation */ dw_abbrev_decl decl; /* En-tête d'abréviation */ - bool status; /* Bilan d'une lecture */ dw_abbrev_raw_attr attr; /* Attribut de l'abréviation */ - dw_abbrev *child; /* Rejeton à intégrer */ + bool status; /* Bilan d'une lecture */ - *abbrev = NULL; + new = NULL; /** * Cette routine est la transcription du paragraphe 7.5.3 ("Abbreviations Tables"), @@ -139,77 +124,58 @@ bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev * * As mentioned in Section 2.3, each chain of sibling entries is terminated by a null entry. * - * Cependant, ce formalisme n'est pas constaté dans la pratique. D'ailleurs, readelf - * comporte le commentaire suivant dans le fichier 'dwarf_reader.cc' : + * Par ailleurs, readelf comporte le commentaire suivant dans le fichier 'dwarf_reader.cc' : * * Read the abbrev code. A zero here indicates the end of the abbrev table. * */ - if (!read_dwarf_abbrev_decl(format, pos, &decl)) + copy_vmpa(&old, pos); + + if (!read_dwarf_abbrev_decl(content, pos, &decl)) goto lda_bad_exit; if (decl.code == 0) goto lda_exit; - *abbrev = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); + new = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); - if (!check_abbreviation_decl(format, &decl, *abbrev)) + if (!conv_abbrev_decl(format, cu, &decl, new, &old)) goto lda_bad_exit; /* Chargement des attributs */ for (;;) { - status = read_dwarf_abbrev_attr(format, pos, &attr); - if (!status) goto lda_bad_exit; + copy_vmpa(&old, pos); - printf(" -- [0x%llx] [0x%llx] name = %u\tform = %u\n", - (unsigned long long)pos->physical, - (unsigned long long)decl.code, - (unsigned int)attr.name, (unsigned int)attr.form); + status = read_dwarf_abbrev_attr(content, pos, &attr); + if (!status) goto lda_bad_exit; - if (attr.name == DW_ATTR_invalid && attr.form == DW_FORM_invalid) + if (attr.name == 0 && attr.form == 0) break; - (*abbrev)->attribs_count++; - (*abbrev)->attribs = (dw_abbrev_attr *)realloc((*abbrev)->attribs, - (*abbrev)->attribs_count * sizeof(dw_abbrev_attr)); + new->count++; + new->attribs = (dw_abbrev_attr *)realloc(new->attribs, + new->count * sizeof(dw_abbrev_attr)); - status = check_abbreviation_attrib(format, &attr, - &(*abbrev)->attribs[(*abbrev)->attribs_count - 1]); + status = conv_abbrev_attrib(format, cu, &attr, &new->attribs[new->count - 1], &old); if (!status) goto lda_bad_exit; } - /* Chargement des enfants */ - - printf(" || children ? %d vs %d\n", (int)decl.has_children, (int)DW_CHILDREN_yes); - - if (decl.has_children == DW_CHILDREN_yes) - for (;;) - { - status = load_dwarf_abbreviation(format, pos, &child); - if (!status) goto lda_bad_exit; - - if (child == NULL) - break; - - (*abbrev)->children_count++; - (*abbrev)->children = (dw_abbrev **)realloc((*abbrev)->children, - (*abbrev)->children_count * sizeof(dw_abbrev)); - - (*abbrev)->children[(*abbrev)->children_count - 1] = child; - - } - lda_exit: + *abbrev = new; + return true; lda_bad_exit: - free_dwarf_abbreviation(*abbrev); + if (new != NULL) + free_dwarf_abbrev(new); + + *abbrev = NULL; return false; @@ -228,22 +194,11 @@ bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev * * ******************************************************************************/ -void free_dwarf_abbreviation(dw_abbrev *abbrev) +static void free_dwarf_abbrev(dw_abbrev *abbrev) { - size_t i; /* Boucle de parcours */ - if (abbrev->attribs != NULL) free(abbrev->attribs); - if (abbrev->children != NULL) - { - for (i = 0; i < abbrev->children_count; i++) - free_dwarf_abbreviation(abbrev->children[i]); - - free(abbrev->attribs); - - } - free(abbrev); } @@ -251,9 +206,11 @@ void free_dwarf_abbreviation(dw_abbrev *abbrev) /****************************************************************************** * * -* Paramètres : format = informations chargées à consulter. * +* Paramètres : format = informations de débogage à consulter. * +* cu = unité de compilation parente. * * decl = structure brute dont le contenu est à valider. * * abbrev = abréviation à constituer à partir du brut. [OUT] * +* pos = emplacement de l'élément à vérifier dans le binaire.* * * * Description : Procède à la conversion de base d'une abréviation DWARF. * * * @@ -263,21 +220,19 @@ void free_dwarf_abbreviation(dw_abbrev *abbrev) * * ******************************************************************************/ -static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_decl *decl, dw_abbrev *abbrev) +static bool conv_abbrev_decl(GDwarfFormat *format, const dw_compil_unit_header *cu, const dw_abbrev_decl *decl, dw_abbrev *abbrev, const vmpa2t *pos) { bool result; /* Validité à retourner */ - result = (decl->has_children == DW_CHILDREN_no - || decl->has_children == DW_CHILDREN_yes); - - - /* TODO : vérifier les bornes de 'tag' */ - + result = check_dwarf_abbrev_decl(format, decl, cu->version, pos); if (result) { abbrev->code = decl->code; abbrev->tag = decl->tag; + + abbrev->has_children = (decl->has_children == DW_CHILDREN_yes); + } return result; @@ -287,9 +242,11 @@ static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_ /****************************************************************************** * * -* Paramètres : format = informations chargées à consulter. * +* Paramètres : format = informations de débogage à consulter. * +* cu = unité de compilation parente. * * decl = structure brute dont le contenu est à valider. * * abbrev = abréviation à constituer à partir du brut. [OUT] * +* pos = emplacement de l'élément à vérifier dans le binaire.* * * * Description : Procède à la conversion d'un attribut d'abréviation DWARF. * * * @@ -299,23 +256,16 @@ static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_ * * ******************************************************************************/ -static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib) +static bool conv_abbrev_attrib(GDwarfFormat *format, const dw_compil_unit_header *cu, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib, const vmpa2t *pos) { bool result; /* Validité à retourner */ - result = true; - - - /* TODO : vérifier les bornes de 'name' et 'form' */ - + result = check_dwarf_abbrev_attrib(format, attr, cu->version, pos); if (result) { attrib->name = attr->name; attrib->form = attr->form; - - - } return result; @@ -323,31 +273,6 @@ static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbre } - - - - - - -/****************************************************************************** -* * -* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * -* * -* Description : Fournit l'étiquette associée à l'ensemble des attributs. * -* * -* Retour : Etiquette officielle de l'ensemble représenté. * -* * -* Remarques : - * -* * -******************************************************************************/ - -DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *abbrev) -{ - return abbrev->tag; - -} - - /****************************************************************************** * * * Paramètres : abbrev = abréviation chargée en mémoire à consulter. * @@ -362,178 +287,18 @@ DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *abbrev) size_t dwarf_abbreviation_count_attribs(const dw_abbrev *abbrev) { - return abbrev->attribs_count; - -} - - -/****************************************************************************** -* * -* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * -* attrib = désignation de l'attribut à retrouver. * -* index = indice de cet attribut dans l'ensemble. [OUT] * -* * -* Description : Recherche un attribut dans une abréviation. * -* * -* Retour : Indication sur le bilan des recherches. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool dwarf_abbreviation_get_attrib_index(const dw_abbrev *abbrev, DwarfAttrib attrib, size_t *index) -{ - bool result; /* Etat de validité à renvoyer */ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < abbrev->attribs_count; i++) - if (abbrev->attribs[i].name == attrib) - break; - - if (i < abbrev->attribs_count) - { - result = true; - *index = i; - } - else - result = false; - - return result; + return abbrev->count; } - - - - /****************************************************************************** * * -* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * -* attrib = désignation de l'attribut à retrouver. * -* index = indice de cet attribut dans l'ensemble. * -* form = type de valeur attendu pour un attribut donné. [OUT]* -* * -* Description : Détermine le type d'un attribut dans une abréviation. * -* * -* Retour : Indication sur le bilan des accès. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool dwarf_abbreviation_get_form_for_index(const dw_abbrev *abbrev, size_t index, DwarfForm *form) -{ - if (index >= abbrev->attribs_count) - return false; - - *form = abbrev->attribs[index].form; - - return true; - -} - - - - - - -/****************************************************************************** -* * -* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * -* * -* Description : Indique si une abbréviation comporte des sous-définitions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool dwarf_abbreviation_has_children(const dw_abbrev *abbrev) -{ - return (abbrev->children_count > 0); - -} - - - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : format = informations de débogage à consulter. * -* code = identifiant de l'abbréviation recherchée. * -* * -* Description : Recherche une abréviation DWARF donnée. * -* * -* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const dw_abbrev *find_dwarf_abbreviations(const GDwarfFormat *format, uleb128_t code) -{ - const dw_abbrev *result; /* Trouvaille à retourner */ - - if (format->abbreviations->code == code) - result = format->abbreviations; - - else - { - const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uleb128_t c) - { - const dw_abbrev *found; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - - if (abbrev->code == c) - found = abbrev; - else - { - found = NULL; - - for (i = 0; i < abbrev->children_count && found == NULL; i++) - found = _find_dwarf_abbreviations(abbrev->children[i], c); - - } - - return found; - - } - - result = _find_dwarf_abbreviations(format->abbreviations, code); - - } - - return result; - -} - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : format = contenu binaire de débogage à parcourir. * -* cu = unité de compilation parente. * -* form = nature de la valeur à lire. * -* pos = tête de lecture au sein des données. [OUT] * -* value = valeur au format donné lue. [OUT] * +* Paramètres : abbrev = abréviation à consulter. * +* format = contenu binaire de débogage à parcourir. * +* content = contenu encadré à parcourir. * +* pos = tête de lecture au sein des données. [OUT] * +* cu = unité de compilation parente. * * * * Description : Lit la valeur correspondant à un type donné. * * * @@ -543,37 +308,28 @@ const dw_abbrev *find_dwarf_abbreviations(const GDwarfFormat *format, uleb128_t * * ******************************************************************************/ -dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw_abbrev *abbrev, const dw_compil_unit_header *cu, vmpa2t *pos) +dw_value *translate_abbrev_attribs(const dw_abbrev *abbrev, const GDwarfFormat *format, GBinContent *content, vmpa2t *pos, const dw_compil_unit_header *cu) { dw_value *result; /* Valeurs lues retournées */ size_t i; /* Boucle de parcours */ bool status; /* Bilan d'une lecture */ - result = (dw_value *)calloc(abbrev->attribs_count, sizeof(dw_value)); + result = (dw_value *)calloc(abbrev->count, sizeof(dw_value)); - for (i = 0; i < abbrev->attribs_count; i++) + for (i = 0; i < abbrev->count; i++) { result[i].attrib = abbrev->attribs[i].name; - printf("-- loading attrib %x (%u) -- form = %x (%u) -- pos = %llx --\n", - (unsigned int)abbrev->attribs[i].name, - (unsigned int)abbrev->attribs[i].name, - (unsigned int)abbrev->attribs[i].form, - (unsigned int)abbrev->attribs[i].form, - (unsigned long long)(pos->physical - 0x1039)); - - status = G_DWARF_FORMAT_GET_CLASS(format)->read_form(format, cu, - abbrev->attribs[i].form, pos, &result[i].value); - if (!status) printf("[%zu] failed for %x\n", i, abbrev->attribs[i].form); - if (status) printf("[%zu] success for %x\n", i, abbrev->attribs[i].form); - printf(" current pos :: %llx\n", (unsigned long long)(pos->physical - 0x1039)); + status = read_dwarf_form_value(format, content, pos, cu, + abbrev->attribs[i].form, &result[i].value); + if (!status) break; } - if (i != abbrev->attribs_count) + if (i != abbrev->count) { - free(result); + free_abbrev_attribs(result, abbrev->count); result = NULL; } @@ -582,195 +338,12 @@ dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if 0 - -#include <malloc.h> -#include <stdarg.h> -#include <string.h> - - -#include "utils.h" - - - -#include <ctype.h> - - - -/* Libère de la mémoire une abréviation DWARF. */ -void free_dwarf_abbrev(dw_abbrev *); - -/* Charge une abréviations DWARF. */ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, uint64_t *); - -/* Recherche une abréviation DWARF donnée. */ -const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *, uint8_t *); - -/* Lit la valeur d'un attribut DWARF. */ -bool _read_dwarf_abbrev_attribute(dwarf_format *, off_t *, DwarfForm, ...); - - - -/****************************************************************************** -* * -* Paramètres : format = informations de débogage à compléter. * -* * -* Description : Charge les abréviations trouvées pour un DWARF. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_dwarf_abbreviations(dwarf_format *format) -{ - bool result; /* Bilan à renvoyer */ - - - - - off_t offset; - off_t start; - off_t size; - - bool test; - - int i; - - - dw_abbrev *abbrev; - uint64_t index; - - printf("Searching...\n"); - - - result = true; - - test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_abbrev", &start, &size, NULL); - - offset = start; - - - printf(" -> offset=%d size=%d\n", offset, size); - - - - for (i = 0; i < size; i++) - { - if (i % 10 == 0) printf("\n"); - printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]); - } - - printf("\n"); - - - - - while (offset < (start + size)) - { - abbrev = read_dwarf_abbreviations(format, &offset, &index); - - offset++; /* 0x00 */ - - printf("abbrev :: %p\n", abbrev); - - if (abbrev != NULL) - { - abbrev->offset -= start; - - format->abbrevs = (dw_abbrev **)realloc(format->abbrevs, ++format->abbrevs_count * sizeof(dw_abbrev *)); - format->abbrevs[format->abbrevs_count - 1] = abbrev; - - printf(" %d attribs, %d children\n", abbrev->attribs_count, abbrev->children_count); - - } - else - { - unload_dwarf_abbreviations(format); - result = false; - break; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations de débogage à effacer. * -* * -* Description : Décharge les abréviations trouvées pour un DWARF. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_dwarf_abbreviations(dwarf_format *format) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < format->abbrevs_count; i++) - free_dwarf_abbrev(format->abbrevs[i]); - -} - - /****************************************************************************** * * -* Paramètres : abbrev = élément à supprimer de la mémoire. * +* Paramètres : values = liste de valeurs typées à traiter. * +* count = nombre d'éléments de la liste. * * * -* Description : Libère de la mémoire une abréviation DWARF. * +* Description : Supprime de la mémoire une liste de valeurs typées. * * * * Retour : - * * * @@ -778,511 +351,118 @@ void unload_dwarf_abbreviations(dwarf_format *format) * * ******************************************************************************/ -void free_dwarf_abbrev(dw_abbrev *abbrev) +void free_abbrev_attribs(dw_value *values, size_t count) { size_t i; /* Boucle de parcours */ - for (i = 0; i < abbrev->children_count; i++) - free_dwarf_abbrev(abbrev->children[i]); - - free(abbrev->attribs); - free(abbrev->children); + for (i = 0; i < count; i++) + if (values[i].value != NULL) + free_dwarf_form_value(values[i].value); - free(abbrev); + free(values); } /****************************************************************************** * * -* Paramètres : format = informations de débogage à compléter. * -* pos = tête de lecture à mettre à jour. [OUT] * -* index = code de l'abréviation. [OUT] * +* Paramètres : abbrev = abréviation à consulter. * * * -* Description : Charge une abréviation DWARF. * +* Description : Détermine si l'abréviation possède des enfants. * * * -* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* Retour : true si des sous-éléments sont présents. * * * * Remarques : - * * * ******************************************************************************/ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, uint64_t *index) +bool has_abbrev_children(const dw_abbrev *abbrev) { - dw_abbrev *result; /* Abréviation à retourner */ - bool has_children; /* Indique la présence de fils */ - uint64_t value1; /* Valeur quelconque lue #1 */ - uint64_t value2; /* Valeur quelconque lue #2 */ - uint64_t sub_index; /* Indice d'un sous-élément */ - dw_abbrev *child; /* Sous-élément à intégrer */ - - result = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); - - result->offset = *pos; - - /* Code de l'élément */ - if (!read_uleb128(format, pos, index, true)) goto rda_error; - - if (!read_uleb128(format, pos, &value1, true)) goto rda_error; - result->tag = value1; - - printf(" --ta :: 0x%02llx\n", value1); - - if (*pos >= DBG_FORMAT(format)->length) goto rda_error; - has_children = (DBG_FORMAT(format)->content[(*pos)++] == DW_CHILDREN_YES); - - printf(" --ch ? %d\n", has_children); - - /* Liste des attributs */ - - while (DBG_FORMAT(format)->content[*pos] != 0x00) - { - if (!read_uleb128(format, pos, &value1, true)) goto rda_error; - if (!read_uleb128(format, pos, &value2, true)) goto rda_error; - - result->attribs = (dw_abbrev_attr *)realloc(result->attribs, ++result->attribs_count * sizeof(dw_abbrev_attr)); - - result->attribs[result->attribs_count - 1].attrib = value1; - result->attribs[result->attribs_count - 1].form = value2; - - } - - (*pos) += 2; /* 0x00 0x00 */ - - /* Chargement des sous-éléments */ - - if (has_children) - while (DBG_FORMAT(format)->content[*pos] != 0x00) - { - child = read_dwarf_abbreviations(format, pos, &sub_index); - - if (child == NULL) goto rda_error; - - if ((sub_index - *index - 1) != result->children_count) goto rda_error; - - result->children = (dw_abbrev **)realloc(result->children, ++result->children_count * sizeof(dw_abbrev *)); + bool result; /* Bilan à retourner */ - result->children[result->children_count - 1] = child; - - } + result = abbrev->has_children; return result; - rda_error: - - free_dwarf_abbrev(result); - - return NULL; - } -/****************************************************************************** -* * -* Paramètres : abbrev = abréviation racine à parcourir. * -* index = code de l'abréviation. [OUT] * -* * -* Description : Recherche une abréviation DWARF donnée. * -* * -* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *index) -{ - const dw_abbrev *result; /* Structure à retourner */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - if (*index == 0) result = abbrev; - else - for (i = 0; i < abbrev->children_count && result == NULL; i++) - { - (*index)--; - result = _find_dwarf_abbreviations(abbrev->children[i], index); - } - - return result; -} +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT D'ABREVIATIONS PAR LOTS */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : format = informations de débogage à consulter. * -* offset = position dans les abréviations. * -* pos = position dans le flux binaire courant. [OUT] * +* Paramètres : format = informations de débogage à constituer. * +* cu = en-tête de description de l'unité à traiter. * * * -* Description : Recherche une abréviation DWARF donnée. * +* Description : Charge une série d'abréviations présentes dans un DWARF. * * * -* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* Retour : Structure mise en place, ou NULL en cas d'erreur. * * * -* Remarques : - * +* Remarques : Le décalage est positionné à VMPA_NO_PHYSICAL en cas de fin. * * * ******************************************************************************/ -const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, off_t *pos) +dw_abbrev_brotherhood *load_all_dwarf_abbreviations(GDwarfFormat *format, const dw_compil_unit_header *cu) { - const dw_abbrev *result; /* Structure à retourner */ - uint64_t index; /* Code de l'abréviation */ - size_t i; /* Boucle de parcours */ + dw_abbrev_brotherhood *result; /* Abréviations à retourner */ + GExeFormat *exe; /* Exécutable associé */ + mrange_t range; /* Couverture d'une section */ + bool status; /* Bilan d'un appel */ + GBinContent *content; /* Contenu binaire à lire */ + GBinContent *restricted; /* Limitation des traitements */ + vmpa2t pos; /* Position de tête de lecture */ + dw_abbrev *abbrev; /* Nouvelle abréviation */ result = NULL; - do - { - if (!read_uleb128(format, pos, &index, true)) - { - printf("error skipping padding...\n"); - return NULL; - } - } - while (index == 0); - - for (i = 0; i < format->abbrevs_count; i++) - if (format->abbrevs[i]->offset == *offset) break; - - if (i < format->abbrevs_count) - { - index--; - result = _find_dwarf_abbreviations(format->abbrevs[i], &index); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : abbrev = informations à parcourir. * -* attrib = attribut visé par la lecture. * -* * -* Description : Indique la présence ou l'absence d'un attribut donné. * -* * -* Retour : true si l'attribut est présent, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool test_dwarf_abbrev_attribute(const dw_abbrev *abbrev, DwarfAttrib attrib) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - result = false; - - for (i = 0; i < abbrev->attribs_count && !result; i++) - result = (abbrev->attribs[i].attrib == attrib); - - return result; - -} + exe = G_DBG_FORMAT(format)->executable; + status = g_exe_format_get_section_range_by_name(exe, ".debug_abbrev", &range); -/****************************************************************************** -* * -* Paramètres : format = informations de débogage à compléter. * -* pos = tête de lecture à mettre à jour. [OUT] * -* form = format des données à lire. * -* ... = lieu d'enregistrement ou NULL. [OUT] * -* * -* Description : Lit la valeur d'un attribut DWARF. * -* * -* Retour : true si la lecture est un succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, ...) -{ - bool result; /* Bilan à revoyer */ - va_list ap; /* Adresse fournie en dernier */ - uint8_t *val8; /* Données sur 8 bits */ - uint16_t *val16; /* Données sur 16 bits */ - uint32_t *val32; /* Données sur 32 bits */ - uint64_t *val64; /* Données sur 64 bits */ - uint64_t *sval64; /* Données sur 64 bits (signée)*/ - bool *boolval; /* Valeur booléenne */ - uint8_t tmp8; /* Données sur 8 bits */ - uint16_t tmp16; /* Données sur 16 bits */ - uint32_t tmp32; /* Données sur 32 bits */ - uint64_t tmp64; /* Données sur 64 bits */ - uint64_t stmp64; /* Données sur 64 bits (signée)*/ - uint64_t size_to_read; /* Nombre d'octets à lire */ - off_t offset; /* Décalage dans une zone */ - char **strval; /* Chaîne de caractères */ - size_t length; /* Taille d'une chaîne */ - - va_start(ap, form); - - switch (form) + if (status) { - case DWF_ADDR: - result = ((*pos + (format->format == DWF_32_BITS ? 4 : 8)) <= DBG_FORMAT(format)->length); - if (result) - { - val64 = va_arg(ap, uint64_t *); - if (val64 != NULL) - { - if (format->format == DWF_32_BITS) - { - memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4); - *val64 = tmp32; - } - else memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); - } - *pos += (format->format == DWF_32_BITS ? 4 : 8); - } - break; + /* Définition d'un zone de travail */ - case DWF_BLOCK2: - result = ((*pos + 2) <= DBG_FORMAT(format)->length); - if (result) - { - memcpy(&tmp16, &DBG_FORMAT(format)->content[*pos], 2); - size_to_read = tmp16; - /* ... */ - *pos += 2 + size_to_read; - } - break; + content = G_BIN_FORMAT(format)->content; + restricted = g_restricted_content_new(content, &range); - case DWF_BLOCK4: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); - if (result) - { - memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4); - size_to_read = tmp32; - /* ... */ - *pos += 4 + size_to_read; - } - break; + copy_vmpa(&pos, get_mrange_addr(&range)); + advance_vmpa(&pos, cu->debug_abbrev_offset); - case DWF_DATA2: - result = ((*pos + 2) <= DBG_FORMAT(format)->length); - if (result) - { - val16 = va_arg(ap, uint16_t *); - if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2); - *pos += 2; - } - break; + /* Lecture de toutes les abréviations */ - case DWF_DATA4: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); - if (result) - { - val32 = va_arg(ap, uint32_t *); - if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4); - *pos += 4; - } - break; - - case DWF_DATA8: - result = ((*pos + 8) <= DBG_FORMAT(format)->length); - if (result) - { - val64 = va_arg(ap, uint64_t *); - if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); - *pos += 8; - } - break; - - case DWF_STRING: - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (result) - { - strval = va_arg(ap, char **); - if (strval != NULL) *strval = (char *)calloc(1, sizeof(char)); - length = 0; - - while (result) - { - if (DBG_FORMAT(format)->content[*pos] == '\0') break; - - length++; - - if (strval != NULL) - { - *strval = (char *)realloc(*strval, (length + 1) * sizeof(char)); - (*strval)[length - 1] = DBG_FORMAT(format)->content[*pos]; - } - - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (!result) break; - - (*pos)++; - - } - - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - - if (result) - { - (*pos)++; - - if (strval != NULL) - (*strval)[length] = 0; - - } - else if (strval != NULL) - { - free(*strval); - *strval = NULL; - } - - } - - break; - - case DWF_BLOCK: - result = read_uleb128(format, pos, &size_to_read, true); - result &= ((*pos + size_to_read) <= DBG_FORMAT(format)->length); - if (result) - { - /* ... */ - *pos += size_to_read; - } - break; - - case DWF_BLOCK1: - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (result) - { - memcpy(&tmp8, &DBG_FORMAT(format)->content[*pos], 1); - size_to_read = tmp8; - /* ... */ - *pos += 1 + size_to_read; - } - break; - - case DWF_DATA1: - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (result) - { - val8 = va_arg(ap, uint8_t *); - if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1); - *pos += 1; - } - break; - - case DWF_FLAG: - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (result) - { - boolval = va_arg(ap, bool *); - if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); - *pos += 1; - } - break; - - case DWF_SDATA: - sval64 = va_arg(ap, int64_t *); - if (sval64 == NULL) sval64 = &stmp64; - result = read_uleb128(format, pos, sval64, true); - break; - - case DWF_STRP: - result = read_abbrev_offset(format, pos, &offset); - if (result) - { - if (va_arg(ap, bool *) != NULL) - { - printf("TODO\n"); - exit(0); - } - /* - boolval = va_arg(ap, bool *); - if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); - */ - } - break; - - case DWF_UDATA: - val64 = va_arg(ap, uint64_t *); - if (val64 == NULL) val64 = &tmp64; - result = read_uleb128(format, pos, val64, true); - break; - - case DWF_REF_ADDR: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); - - printf("bad at %d\n", __LINE__); exit(0); - - break; - - - case DWF_REF1: - result = ((*pos + 1) <= DBG_FORMAT(format)->length); - if (result) - { - val8 = va_arg(ap, uint8_t *); - if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1); - *pos += 1; - } - break; - - case DWF_REF2: - result = ((*pos + 2) <= DBG_FORMAT(format)->length); - if (result) - { - val16 = va_arg(ap, uint16_t *); - if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2); - *pos += 2; - } - break; - - case DWF_REF4: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); - if (result) - { - val32 = va_arg(ap, uint32_t *); - if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4); - *pos += 4; - } - break; - - case DWF_REF8: - result = ((*pos + 8) <= DBG_FORMAT(format)->length); - if (result) - { - val64 = va_arg(ap, uint64_t *); - if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); - *pos += 8; - } - break; - - case DWF_REF_UDATA: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); - - printf("bad at %d\n", __LINE__); exit(0); - - break; + result = calloc(1, sizeof(dw_abbrev_brotherhood)); + while (true) + { + status = load_dwarf_abbreviation(format, cu, restricted, &pos, &abbrev); + if (!status) break; - case DWF_INDIRECT: - result = ((*pos + 4) <= DBG_FORMAT(format)->length); + if (abbrev == NULL) + break; - printf("bad at %d\n", __LINE__); exit(0); + result->abbrevs = realloc(result->abbrevs, ++result->count * sizeof(dw_abbrev *)); - break; + result->abbrevs[result->count - 1] = abbrev; + } + /* Nettoyage */ + if (!status) + { + free_all_dwarf_abbreviations(result); + result = NULL; + } - default: - result = false; - break; + g_object_unref(G_OBJECT(restricted)); } - va_end(ap); - return result; } @@ -1290,101 +470,58 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo /****************************************************************************** * * -* Paramètres : format = informations de débogage à compléter. * -* pos = tête de lecture à mettre à jour. [OUT] * -* update = indique si la position est à mettre à jour. * -* abbrev = informations à parcourir. * -* attrib = attribut visé par la lecture. * -* ... = lieu d'enregistrement ou NULL. [OUT] * +* Paramètres : list = série d'abréviations chargées en mémoire à traiter. * * * -* Description : Lit la valeur d'un attribut DWARF. * +* Description : Supprime de la mémoire toute trace d'abréviations DWARF. * * * -* Retour : true si la lecture est un succès, false sinon. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, bool update, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) +void free_all_dwarf_abbreviations(dw_abbrev_brotherhood *list) { - bool result; /* Bilan à retourner */ - off_t curpos; /* Tête de lecture effective */ size_t i; /* Boucle de parcours */ - va_list ap; /* Adresse fournie en dernier */ - - result = true; - - curpos = *pos; - - for (i = 0; i < abbrev->attribs_count && result; i++) - if (abbrev->attribs[i].attrib == attrib) break; - else result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, NULL); - - if (result) - { - va_start(ap, attrib); - - if (i < abbrev->attribs_count) - result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, va_arg(ap, void *)); - else - result = false; - va_end(ap); + for (i = 0; i < list->count; i++) + free_dwarf_abbrev(list->abbrevs[i]); - } - - if (result && update) *pos = curpos; + if (list->abbrevs != NULL) + free(list->abbrevs); - return result; + free(list); } /****************************************************************************** * * -* Paramètres : format = informations de débogage à compléter. * -* pos = tête de lecture à mettre à jour. [OUT] * -* abbrev = informations à survoler. * +* Paramètres : list = série d'abréviations à consulter. * +* code = identifiant de l'abbréviation recherchée. * * * -* Description : Fait avancer la tête de lecture d'une seule abréviation. * +* Description : Recherche une abréviation DWARF donnée. * * * -* Retour : true si l'opération est un succès, false sinon. * +* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ -bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev) +const dw_abbrev *find_dwarf_abbreviation(const dw_abbrev_brotherhood *list, uleb128_t code) { - bool result; /* Bilan à revoyer */ + const dw_abbrev *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ - uint64_t index; /* Code de padding */ - - result = true; - - /* Ecartement du corps */ - for (i = 0; i < abbrev->attribs_count && result; i++) - result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, NULL); - - /* Ecartement du padding */ + result = NULL; - do - { - if (!read_uleb128(format, pos, &index, false)) + for (i = 0; i < list->count; i++) + if (list->abbrevs[i]->code == code) { - printf("error skipping padding...\n"); - return false; + result = list->abbrevs[i]; + break; } - if (index == 0) - read_uleb128(format, pos, &index, true); - - } - while (index == 0); - return result; } - -#endif |