diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-03-14 22:18:27 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-03-14 22:18:27 (GMT) | 
| commit | fab9d7cd46922abea7d94f36dcd4630cdf3f4719 (patch) | |
| tree | ad41bb921db17631104a069e4df64fb4fc5ccfc1 /src/format/dwarf/abbrev.c | |
| parent | 8d8e5c02096f59a7227308a591fc5050ea5d92ff (diff) | |
Improved the basic support of Dwarf information.
Diffstat (limited to 'src/format/dwarf/abbrev.c')
| -rw-r--r-- | src/format/dwarf/abbrev.c | 607 | 
1 files changed, 607 insertions, 0 deletions
diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 0428806..039c3a0 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -25,6 +25,611 @@  #include <malloc.h> + + +#include "dwarf-int.h" + + + + + +/* Description d'un attribut d'une abréviation */ +typedef struct _dw_abbrev_attr +{ +    DwarfAttrib name;                       /* Sujet de l'élément          */ +    DwarfForm form;                         /* Représentation              */ + +} 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     */ + +    struct _dw_abbrev **children;           /* Liste des sous-éléments     */ +    size_t children_count;                  /* Nombre de ces enfants       */ + +}; + + + + + +/* Procède à la conversion de base d'une abréviation DWARF. */ +static bool check_abbreviation_decl(const GDwarfFormat *, const dw_abbrev_decl *, dw_abbrev *); + +/* 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 *); + + + + + +/****************************************************************************** +*                                                                             * +*  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) +{ +    bool result;                            /* Bilan à faire remonter      */ +    mrange_t range;                         /* Couverture d'une section    */ +    vmpa2t *pos;                            /* Position de tête de lecture */ + +    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; + +} + + +/****************************************************************************** +*                                                                             * +*  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]  * +*                                                                             * +*  Description : Charge une abréviation valide pour un DWARF en mémoire.      * +*                                                                             * +*  Retour      : Bilan de l'opération, potentiellement un succès sans sortie. * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev **abbrev) +{ +    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          */ + +    *abbrev = NULL; + +    /** +     * Cette routine est la transcription du paragraphe 7.5.3 ("Abbreviations Tables"), +     * de la quatrième version de la définition du format DWARF. +     * +     * La spécification précise : +     * +     *    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' : +     * +     *    Read the abbrev code. A zero here indicates the end of the abbrev table. +     * +     */ + +    if (!read_dwarf_abbrev_decl(format, pos, &decl)) +        goto lda_bad_exit; + +    if (decl.code == 0) +        goto lda_exit; + +    *abbrev = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); + +    if (!check_abbreviation_decl(format, &decl, *abbrev)) +        goto lda_bad_exit; + +    /* Chargement des attributs */ + +    for (;;) +    { +        status = read_dwarf_abbrev_attr(format, pos, &attr); +        if (!status) goto lda_bad_exit; + +        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); + +        if (attr.name == DW_ATTR_invalid && attr.form == DW_FORM_invalid) +            break; + +        (*abbrev)->attribs_count++; +        (*abbrev)->attribs = (dw_abbrev_attr *)realloc((*abbrev)->attribs, +                                                       (*abbrev)->attribs_count * sizeof(dw_abbrev_attr)); + +        status = check_abbreviation_attrib(format, &attr, +                                           &(*abbrev)->attribs[(*abbrev)->attribs_count - 1]); +        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: + +    return true; + + lda_bad_exit: + +    free_dwarf_abbreviation(*abbrev); + +    return false; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : abbrev = abréviation chargée en mémoire à traiter.           * +*                                                                             * +*  Description : Supprime de la mémoire toute trace d'une abréviation DWARF.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void free_dwarf_abbreviation(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); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                decl   = structure brute dont le contenu est à valider.      * +*                abbrev = abréviation à constituer à partir du brut. [OUT]    * +*                                                                             * +*  Description : Procède à la conversion de base d'une abréviation DWARF.     * +*                                                                             * +*  Retour      : Validité confirmée ou non.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_decl *decl, dw_abbrev *abbrev) +{ +    bool result;                            /* Validité à retourner        */ + +    result = (decl->has_children == DW_CHILDREN_no +              || decl->has_children == DW_CHILDREN_yes); + + +    /* TODO : vérifier les bornes de 'tag' */ + + +    if (result) +    { +        abbrev->code = decl->code; +        abbrev->tag = decl->tag; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                decl   = structure brute dont le contenu est à valider.      * +*                abbrev = abréviation à constituer à partir du brut. [OUT]    * +*                                                                             * +*  Description : Procède à la conversion d'un attribut d'abréviation DWARF.   * +*                                                                             * +*  Retour      : Validité confirmée ou non.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib) +{ +    bool result;                            /* Validité à retourner        */ + +    result = true; + + +    /* TODO : vérifier les bornes de 'name' et 'form' */ + + +    if (result) +    { +        attrib->name = attr->name; +        attrib->form = attr->form; + + + +    } + +    return result; + +} + + + + + + + + +/****************************************************************************** +*                                                                             * +*  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.         * +*                                                                             * +*  Description : Compte le nombre d'attributs présents dans une abréviation.  * +*                                                                             * +*  Retour      : Quantité d'attributs pris en compte dans l'abréviation.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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; + +} + + + + + + +/****************************************************************************** +*                                                                             * +*  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]                   * +*                                                                             * +*  Description : Lit la valeur correspondant à un type donné.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw_abbrev *abbrev, const dw_compil_unit_header *cu, vmpa2t *pos) +{ +    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)); + +    for (i = 0; i < abbrev->attribs_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)); +        if (!status) break; + +    } + +    if (i != abbrev->attribs_count) +    { +        free(result); +        result = NULL; +    } + +    return result; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 + +#include <malloc.h>  #include <stdarg.h>  #include <string.h> @@ -781,3 +1386,5 @@ bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev      return result;  } + +#endif  | 
