diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2008-08-17 21:13:03 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2008-08-17 21:13:03 (GMT) |
commit | f6f110acb8bf3243dffc527271c17619a078fcc4 (patch) | |
tree | 1e543cdf23b7bb646f36a51d21d18b91b92706c8 /src/format/dwarf/abbrev.c | |
parent | a13b6baeeea114919d0e9eb25e35657b144437dc (diff) |
Looked for prototyped functions using the registered abbreviations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@17 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dwarf/abbrev.c')
-rw-r--r-- | src/format/dwarf/abbrev.c | 488 |
1 files changed, 471 insertions, 17 deletions
diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 6eada92..2eec460 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -25,9 +25,10 @@ #include <malloc.h> +#include <stdarg.h> +#include <string.h> -#include "dwarf-int.h" #include "utils.h" @@ -42,13 +43,19 @@ void free_dwarf_abbrev(dw_abbrev *); /* Charge une abréviations DWARF. */ dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_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, DwarfAttrib, ...); + /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * * -* Description : Charge les abréviations trouvés pour un DWARF. * +* Description : Charge les abréviations trouvées pour un DWARF. * * * * Retour : Bilan de l'opération. * * * @@ -70,7 +77,6 @@ bool load_dwarf_abbreviations(dwarf_format *format) bool test; int i; - int j; dw_abbrev *abbrev; @@ -94,14 +100,6 @@ bool load_dwarf_abbreviations(dwarf_format *format) { 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"); @@ -119,6 +117,8 @@ bool load_dwarf_abbreviations(dwarf_format *format) 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; @@ -143,7 +143,7 @@ bool load_dwarf_abbreviations(dwarf_format *format) * * * Paramètres : format = informations de débogage à effacer. * * * -* Description : Décharge les abréviations trouvés pour un DWARF. * +* Description : Décharge les abréviations trouvées pour un DWARF. * * * * Retour : - * * * @@ -194,7 +194,7 @@ void free_dwarf_abbrev(dw_abbrev *abbrev) * pos = tête de lecture à mettre à jour. [OUT] * * index = code de l'abréviation. [OUT] * * * -* Description : Charge une abréviations DWARF. * +* Description : Charge une abréviation DWARF. * * * * Retour : Adresse d'une abréviation ou NULL en cas d'échec. * * * @@ -211,17 +211,23 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i 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)); + result->offset = *pos; + + /* Code de l'élément */ + if (!read_leb128(format, pos, index)) goto rda_error; + if (!read_leb128(format, pos, &value1)) 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) @@ -247,7 +253,7 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i if (child == NULL) goto rda_error; - //if ((sub_index - *index - 1) != result->children_count) 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 *)); @@ -264,3 +270,451 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i 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; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* offset = position dans les abréviations. * +* index = code de l'abréviation. * +* * +* 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(dwarf_format *format, const off_t *offset, uint8_t index) +{ + const dw_abbrev *result; /* Structure à retourner */ + size_t i; /* Boucle de parcours */ + + if (index == 0) return NULL; + + result = NULL; + + 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 : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* form = format des données à lire. * +* attrib = attribut visé par la lecture. * +* ... = 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, DwarfAttrib attrib, ...) +{ + 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 */ + 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 size_to_read; /* Nombre d'octets à lire */ + off_t offset; /* Décallage dans une zone */ + char **strval; /* Chaîne de caractères */ + size_t length; /* Taille d'une chaîne */ + + va_start(ap, attrib); + + switch (form) + { + 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) + { + tmp32 = *((uint32_t *)&DBG_FORMAT(format)->content[*pos]); + //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; + + 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; + + 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; + + 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; + + 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); + } + + } + + break; + + case DWF_BLOCK: + result = read_uleb128(format, pos, &size_to_read); + 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: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_STRP: + result = read_abbrev_offset(format, pos, &offset); + if (result) + { + /* + boolval = va_arg(ap, bool *); + if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); + */ + } + break; + + + case DWF_UDATA: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_REF_ADDR: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); 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\n"); exit(0); + + break; + + + case DWF_INDIRECT: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + + + default: + result = false; + break; + + } + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* abbrev = informations à parcourir. * +* attrib = attribut visé par la lecture. * +* ... = 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, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + va_list ap; /* Adresse fournie en dernier */ + + result = true; + + for (i = 0; i < abbrev->attribs_count && result; i++) + if (abbrev->attribs[i].attrib == attrib) break; + else result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, abbrev->attribs[i].attrib, NULL); + + if (result) + { + va_start(ap, attrib); + + if (i < abbrev->attribs_count) + result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, attrib, va_arg(ap, void *)); + else + result = false; + + va_end(ap); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* abbrev = informations à survoler. * +* * +* Description : Fait avancer la tête de lecture d'une seule abréviation. * +* * +* Retour : true si l'opération est un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev) +{ + bool result; /* Bilan à revoyer */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < abbrev->attribs_count && result; i++) + result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, abbrev->attribs[i].attrib, NULL); + + return result; + +} |