diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2008-08-10 12:25:22 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2008-08-10 12:25:22 (GMT) |
commit | a13b6baeeea114919d0e9eb25e35657b144437dc (patch) | |
tree | 8b22b991f2424b83db81ecc1ac063c5949adfb0b /src/format/dwarf/abbrev.c | |
parent | 904476ddf621d9513bf90a3fa396d2e6c1ea2952 (diff) |
Read all the DWARF abbreviations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@16 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dwarf/abbrev.c')
-rw-r--r-- | src/format/dwarf/abbrev.c | 177 |
1 files changed, 175 insertions, 2 deletions
diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 8cf5dcd..6eada92 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -28,12 +28,20 @@ #include "dwarf-int.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 *, int64_t *); + /****************************************************************************** @@ -50,34 +58,50 @@ bool load_dwarf_abbreviations(dwarf_format *format) { - + bool result; /* Bilan à renvoyer */ off_t offset; + off_t start; off_t size; bool test; int i; + int j; + dw_abbrev *abbrev; + int64_t index; + printf("Searching...\n"); - test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_abbrev", &offset, &size, NULL); + 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]); + + if ((i + 1) % 10 == 0) + { + printf("\t\t"); + for (j = 0; j < 10; j++) + printf("%c", (isprint(DBG_FORMAT(format)->content[offset + i]) ? DBG_FORMAT(format)->content[offset + i] : '.')); + } + } printf("\n"); @@ -85,9 +109,158 @@ bool load_dwarf_abbreviations(dwarf_format *format) + while (offset < (start + size)) + { + abbrev = read_dwarf_abbreviations(format, &offset, &index); + + offset++; /* 0x00 */ + + printf("abbrev :: %p\n", abbrev); + + if (abbrev != NULL) + { + 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és 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. * +* * +* Description : Libère de la mémoire une abréviation DWARF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void free_dwarf_abbrev(dw_abbrev *abbrev) +{ + 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); + free(abbrev); } + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* index = code de l'abréviation. [OUT] * +* * +* Description : Charge une abréviations DWARF. * +* * +* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *index) +{ + dw_abbrev *result; /* Abréviation à retourner */ + bool has_children; /* Indique la présence de fils */ + int64_t value1; /* Valeur quelconque lue #1 */ + int64_t value2; /* Valeur quelconque lue #2 */ + int64_t sub_index; /* Indice d'un sous-élément */ + dw_abbrev *child; /* Sous-élément à intégrer */ + + /* Code de l'élément */ + if (!read_leb128(format, pos, index)) return NULL; + + result = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); + + if (!read_leb128(format, pos, &value1)) goto rda_error; + result->tag = value1; + + if (*pos >= DBG_FORMAT(format)->length) goto rda_error; + has_children = (DBG_FORMAT(format)->content[(*pos)++] == DW_CHILDREN_YES); + + /* Liste des attributs */ + + while (DBG_FORMAT(format)->content[*pos] != 0x00) + { + if (!read_leb128(format, pos, &value1)) goto rda_error; + if (!read_leb128(format, pos, &value2)) 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 *)); + + result->children[result->children_count - 1] = child; + + } + + return result; + + rda_error: + + free_dwarf_abbrev(result); + + return NULL; + +} |