From 1b2ad075c4929cfc2b1efe9ff633a12c31dc7594 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 22 Aug 2008 21:57:08 +0000 Subject: Made a first try to get all registered prototypes of functions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@18 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 21 +++ src/binary.c | 2 + src/format/dwarf/abbrev.c | 95 +++++++--- src/format/dwarf/abbrev.h | 9 +- src/format/dwarf/dwarf-int.h | 14 ++ src/format/dwarf/info.c | 413 ++++++++++++++++++++++++++++++++++++++++++- src/format/dwarf/utils.c | 36 ++-- src/format/dwarf/utils.h | 4 +- 8 files changed, 542 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index f34d4fa..4969bee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-08-22 Cyrille Bagard + + * src/binary.c: + Skip the GUI display. + + * src/format/dwarf/abbrev.c: + * src/format/dwarf/abbrev.h: + Make abbreviation codes unsigned. Clean the code. Add the ability to not + update the reading position when reading abbreviation attributes. + + * src/format/dwarf/dwarf-int.h: + Add some definitions for registered prototypes of functions. + + * src/format/dwarf/info.c: + Make a first try to get all registered prototypes of functions. + + * src/format/dwarf/utils.c: + * src/format/dwarf/utils.h: + Add the ability to not update the reading position when decoding + [U]LEB128. Fix a bug when decoding [U]LEB128 numbers. + 2008-08-17 Cyrille Bagard * src/format/dwarf/abbrev.c: diff --git a/src/binary.c b/src/binary.c index 9c0fefb..4938b0f 100644 --- a/src/binary.c +++ b/src/binary.c @@ -160,9 +160,11 @@ void fill_snippet(GtkSnippet *snippet) /*find_line_info(bin_data, &len);*/ + printf("Exiting...\n"); exit(0); + offset = base; diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 2eec460..a9fee2c 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -41,13 +41,13 @@ void free_dwarf_abbrev(dw_abbrev *); /* Charge une abréviations DWARF. */ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_t *); +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, DwarfAttrib, ...); +bool _read_dwarf_abbrev_attribute(dwarf_format *, off_t *, DwarfForm, ...); @@ -80,7 +80,7 @@ bool load_dwarf_abbreviations(dwarf_format *format) dw_abbrev *abbrev; - int64_t index; + uint64_t index; printf("Searching...\n"); @@ -202,13 +202,13 @@ void free_dwarf_abbrev(dw_abbrev *abbrev) * * ******************************************************************************/ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *index) +dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, uint64_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 */ + 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)); @@ -216,9 +216,9 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i result->offset = *pos; /* Code de l'élément */ - if (!read_leb128(format, pos, index)) goto rda_error; + if (!read_uleb128(format, pos, index, true)) goto rda_error; - if (!read_leb128(format, pos, &value1)) goto rda_error; + if (!read_uleb128(format, pos, &value1, true)) goto rda_error; result->tag = value1; printf(" --ta :: 0x%02llx\n", value1); @@ -232,8 +232,8 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i 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; + 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)); @@ -305,11 +305,34 @@ const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *ind } +const dw_abbrev *find_dwarf_abbreviations_old(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 à consulter. * * offset = position dans les abréviations. * -* index = code de l'abréviation. * +* pos = position dans le flux binaire courant. [OUT] * * * * Description : Recherche une abréviation DWARF donnée. * * * @@ -319,15 +342,24 @@ const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *ind * * ******************************************************************************/ -const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, uint8_t index) +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, off_t *pos) { const dw_abbrev *result; /* Structure à retourner */ + uint64_t index; /* Code de l'abréviation */ size_t i; /* Boucle de parcours */ - if (index == 0) return NULL; - 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; @@ -347,7 +379,6 @@ const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *off * 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. * @@ -358,7 +389,7 @@ const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *off * * ******************************************************************************/ -bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, DwarfAttrib attrib, ...) +bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, ...) { bool result; /* Bilan à revoyer */ va_list ap; /* Adresse fournie en dernier */ @@ -376,7 +407,7 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo char **strval; /* Chaîne de caractères */ size_t length; /* Taille d'une chaîne */ - va_start(ap, attrib); + va_start(ap, form); switch (form) { @@ -486,11 +517,12 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo if (strval != NULL) (*strval)[length] = 0; + } - else + else if (strval != NULL) { - if (strval != NULL) - free(*strval); + free(*strval); + *strval = NULL; } } @@ -498,7 +530,7 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo break; case DWF_BLOCK: - result = read_uleb128(format, pos, &size_to_read); + result = read_uleb128(format, pos, &size_to_read, true); result &= ((*pos + size_to_read) <= DBG_FORMAT(format)->length); if (result) { @@ -550,6 +582,11 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo 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); @@ -649,6 +686,7 @@ 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] * @@ -661,24 +699,27 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo * * ******************************************************************************/ -bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) +bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, bool update, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) { 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, pos, abbrev->attribs[i].form, abbrev->attribs[i].attrib, NULL); + 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, pos, abbrev->attribs[i].form, attrib, va_arg(ap, void *)); + result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, va_arg(ap, void *)); else result = false; @@ -686,6 +727,8 @@ bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbr } + if (result && update) *pos = curpos; + return result; } @@ -713,7 +756,7 @@ bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev 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); + result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, NULL); return result; diff --git a/src/format/dwarf/abbrev.h b/src/format/dwarf/abbrev.h index 0839287..cbc394e 100644 --- a/src/format/dwarf/abbrev.h +++ b/src/format/dwarf/abbrev.h @@ -39,11 +39,14 @@ bool load_dwarf_abbreviations(dwarf_format *); /* Décharge les abréviations trouvées pour un DWARF. */ void unload_dwarf_abbreviations(dwarf_format *); -/* Recherche une abréviation DWARF. */ -const dw_abbrev *find_dwarf_abbreviations(dwarf_format *, const off_t *, uint8_t); +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *find_dwarf_abbreviations_old(dwarf_format *, const off_t *, uint8_t); + +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *, const off_t *, off_t *); /* Lit la valeur d'un attribut DWARF. */ -bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, const dw_abbrev *, DwarfAttrib, ...); +bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, bool, const dw_abbrev *, DwarfAttrib, ...); /* Fait avancer la tête de lecture d'une seule abréviation. */ bool skip_dwarf_abbrev(dwarf_format *, off_t *, const dw_abbrev *); diff --git a/src/format/dwarf/dwarf-int.h b/src/format/dwarf/dwarf-int.h index 52130f8..4863bfe 100644 --- a/src/format/dwarf/dwarf-int.h +++ b/src/format/dwarf/dwarf-int.h @@ -69,6 +69,17 @@ typedef struct _dw_abbrev } dw_abbrev; +/* Eléments récupérés sur une fonction */ +typedef struct _dw_dbg_function +{ + char *name; /* Nom de la fonction */ + char *prototype; /* Chaîne descriptive */ + + uint64_t low_pc; /* Début de la fonction */ + uint64_t high_pc; /* Fin de la fonction */ + +} dw_dbg_function; + /* Description du format DWARF */ @@ -81,6 +92,9 @@ struct _dwarf_format dw_abbrev **abbrevs; /* Liste des abréviations */ size_t abbrevs_count; /* Nombre de ces abréviations */ + dw_dbg_function dbg_functions; /* Liste de fonctions trouvées */ + size_t dbg_fc_count; /* Nombre de ces fonctions */ + }; diff --git a/src/format/dwarf/info.c b/src/format/dwarf/info.c index 0dc5048..30d2391 100644 --- a/src/format/dwarf/info.c +++ b/src/format/dwarf/info.c @@ -25,6 +25,7 @@ #include +#include #include "abbrev.h" @@ -35,6 +36,7 @@ /* Informations utiles d'une unité de compilation */ typedef struct _compil_unit { + off_t startpos; /* Position de début d'unité */ off_t endpos; /* Position d'unité suivante */ off_t offset; /* Position dans les abréviat° */ @@ -51,6 +53,8 @@ bool read_dwarf_compilation_unit(dwarf_format *, off_t *, compil_unit *); /* Enregistre toutes les déclarations de fonction trouvées. */ bool look_for_dwarf_subprograms(dwarf_format *, off_t *, const compil_unit *); +/* Obtient la description humaine d'un type. */ +char *resolve_dwarf_function_type(dwarf_format *, const dw_abbrev *, const off_t *, const compil_unit *); @@ -177,6 +181,8 @@ bool read_dwarf_compilation_unit(dwarf_format *format, off_t *pos, compil_unit * result = true; + cu->startpos = *pos; + if (read_unit_length(format, pos, &ulength)) printf("Unit Length :: %d (0x%x)\n", ulength, ulength); @@ -250,17 +256,45 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u off_t oldpos; + off_t oldpos2; const dw_abbrev *abbrev; + const dw_abbrev *subabbrev; + const dw_abbrev *subabbrev2; + char *name; uint64_t low_pc; uint64_t high_pc; + uint32_t type_pos; + char *retstr; + + uint64_t tempo; + + size_t i; /* Boucle de parcours */ + + char *prototype = NULL; + size_t proto_len = 0; + + + + bool first_arg; /* Marque le 1er argument */ + bool is_pointer; /* Mémorise le type 'pointeur' */ + while (*pos < cu->endpos) { + + printf(" =+> Cur :: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n", + DBG_FORMAT(format)->content[*pos], + DBG_FORMAT(format)->content[*pos + 1], + DBG_FORMAT(format)->content[*pos + 2], + DBG_FORMAT(format)->content[*pos + 3], + DBG_FORMAT(format)->content[*pos + 4]); + + if (read_address_size/*leb128*/(format, pos, &index)) printf("abbrev index :: %hhd\n", index); else printf("abbrev index error\n"); @@ -269,7 +303,13 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u if (index == 0) continue; - abbrev = find_dwarf_abbreviations(format, &cu->offset, index); + abbrev = find_dwarf_abbreviations_old(format, &cu->offset, index); + + + + + + //abbrev = find_dwarf_abbreviations(format, &cu->offset, pos); printf(" --> %p\n", abbrev); @@ -283,16 +323,257 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u { - if (read_dwarf_abbrev_attribute(format, &oldpos, abbrev, DWA_LOW_PC, &low_pc)) - printf(" ## LOW PC :: 0x%08x\n", low_pc); - else printf(" error: no low pc\n"); + if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_NAME, &name)) + printf(" ## Name :: %s\n", name); + else printf(" error: no name\n"); + + + if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_LOW_PC, &low_pc)) + printf(" ## LOW PC :: 0x%08x\n", low_pc); + else printf(" error: no low pc\n"); + + + if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_HIGH_PC, &high_pc)) + printf(" ## HIGH PC :: 0x%08x\n", high_pc); + else printf(" error: no high pc\n"); + + + + /* Type de la fonction */ + + if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_TYPE, &type_pos)) + printf(" ## type :: 0x%08x\n", type_pos); + else printf(" error: no type\n"); + + + oldpos = cu->startpos + type_pos; + + + + + subabbrev2 = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + + retstr = resolve_dwarf_function_type(format, subabbrev2, &oldpos, cu); + + if (retstr == NULL) + { + proto_len += 3; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, "???"); + + is_pointer = false; + + } + else + { + proto_len += strlen(retstr); + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, retstr); + + is_pointer = (retstr[strlen(retstr) - 1] == '*'); + + free(retstr); + + } + + + + + /* On saute l'abréviation de la déclaration de fonction... */ + + oldpos = *pos; + + if (!read_uleb128(format, &oldpos, &tempo, true)) + printf("error skipping index\n"); + + if (!skip_dwarf_abbrev(format, &oldpos, abbrev)) + printf("error skipping\n"); + + do + { + if (!read_uleb128(format, &oldpos, &tempo, false)) + printf("error skipping padding...\n"); + + if (tempo == 0) + read_uleb128(format, &oldpos, &tempo, true); + + } + while (tempo == 0); + + /* Lecture des différents arguments */ + + proto_len += (!is_pointer ? 1 : 0) + strlen(name) + 1; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + if (!is_pointer) strcat(prototype, " "); + strcat(prototype, name); + strcat(prototype, "("); + + first_arg = true; + + while (1) + { + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + printf("subabbrev == %p\n", subabbrev); + + switch (subabbrev->tag) + { + case DWT_UNSPECIFIED_PARAMETERS: + + /* Virgule de séparation */ + + if (first_arg) first_arg = false; + else + { + proto_len += 2; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, ", "); + } + + /* Marque de l'absence de type */ + + proto_len += 3; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, "..."); + + break; + + case DWT_FORMAL_PARAMETER: + + + + oldpos2 = oldpos; + + + + if (read_dwarf_abbrev_attribute(format, &oldpos2, true, subabbrev, DWA_TYPE, &type_pos)) + printf(" ## type :: 0x%08x\n", type_pos); + else printf(" error: no type\n"); + + oldpos2 = cu->startpos + type_pos; + + + + + printf(" =+> Next arg :: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n", + DBG_FORMAT(format)->content[oldpos2], + DBG_FORMAT(format)->content[oldpos2 + 1], + DBG_FORMAT(format)->content[oldpos2 + 2], + DBG_FORMAT(format)->content[oldpos2 + 3], + DBG_FORMAT(format)->content[oldpos2 + 4]); + + + + + subabbrev2 = find_dwarf_abbreviations(format, &cu->offset, &oldpos2); + printf("subabbrev2 == %p\n", subabbrev2); + + + + + retstr = resolve_dwarf_function_type(format, subabbrev2, &oldpos2, cu); + printf(" ----) '%s'\n", retstr); + + /* Virgule de séparation */ + + if (first_arg) first_arg = false; + else + { + proto_len += 2; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, ", "); + } + + /* Type de l'argument */ + + if (retstr == NULL) + { + proto_len += 3; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, "???"); + + is_pointer = false; + + } + else + { + proto_len += strlen(retstr); + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, retstr); + + is_pointer = (retstr[strlen(retstr) - 1] == '*'); + + free(retstr); + + } + + + + oldpos2 = oldpos; + + if (read_dwarf_abbrev_attribute(format, &oldpos2, true, subabbrev, DWA_NAME, &retstr)) + printf(" ## Name :: %s\n", retstr); + else printf(" error: no name\n"); + + + if (retstr != NULL) + { + proto_len += strlen(retstr) + (!is_pointer ? 1 : 0) + 1; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + if (!is_pointer) strcat(prototype, " "); + strcat(prototype, retstr); + + free(retstr); + + } + + + + + + + + break; + + default: + goto exit_loop; + break; + + } + + if (!skip_dwarf_abbrev(format, &oldpos, subabbrev)) + printf("error skipping\n"); + + /* + do + { + if (!read_uleb128(format, &oldpos, &tempo, false)) + printf("error skipping padding...\n"); + + if (tempo == 0) + read_uleb128(format, &oldpos, &tempo, true); + + } + while (tempo == 0); + */ + + } + + exit_loop: + + proto_len += 1; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, ")"); + + printf(" |\n"); + printf(" | %s\n", prototype); + printf(" |\n"); + + prototype = NULL; + proto_len = 0; + - oldpos = *pos; - if (read_dwarf_abbrev_attribute(format, &oldpos, abbrev, DWA_HIGH_PC, &high_pc)) - printf(" ## HIGH PC :: 0x%08x\n", high_pc); - else printf(" error: no high pc\n"); } @@ -322,3 +603,119 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u return result; } + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* abbrev = abréviation associée au type. * +* pos = tête de lecture à avoir sous le coude. * +* cu = unité de compilation courante. * +* * +* Description : Obtient la description humaine d'un type. * +* * +* Retour : Chaîne de caractères en cas de succès, NULL sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *resolve_dwarf_function_type(dwarf_format *format, const dw_abbrev *abbrev, const off_t *pos, const compil_unit *cu) +{ + char *result; /* Description à retourner */ + off_t oldpos; /* Conservation de l'indice */ + uint32_t type_pos; /* Sous-type détecté */ + uint64_t index; /* Indice de l'abréviation... */ + const dw_abbrev *subabbrev; /* ... et abréviation associée */ + size_t len; /* Longeur d'un résultat */ + + result = NULL; + oldpos = *pos; + + switch (abbrev->tag) + { + case DWT_BASE_TYPE: + oldpos = *pos; + read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_NAME, &result); + break; + + case DWT_POINTER_TYPE: + + if (read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_TYPE, &type_pos)) + printf(" ## sub type :: 0x%08x\n", type_pos); + else printf(" error: no type\n"); + + oldpos = cu->startpos + type_pos; + + + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + printf("subabbrev == %p\n", subabbrev); + + + + + result = resolve_dwarf_function_type(format, subabbrev, &oldpos, cu); + + if (result != NULL) + { + len = strlen(result); + + if (result[len - 1] == '*') + { + result = (char *)realloc(result, (len + 2) * sizeof(char)); + result[len] = '*'; + } + else + { + result = (char *)realloc(result, (len + 3) * sizeof(char)); + strcat(result, " *"); + } + + } + + break; + + case DWT_CONST_TYPE: + + + + if (read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_TYPE, &type_pos)) + printf(" ## sub type :: 0x%08x\n", type_pos); + else printf(" error: no type\n"); + + oldpos = cu->startpos + type_pos; + + + + + + + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + printf("subabbrev == %p\n", subabbrev); + + + + + result = resolve_dwarf_function_type(format, subabbrev, &oldpos, cu); + + if (result != NULL) + { + len = strlen(result); + + result = (char *)realloc(result, (len + strlen("const ") + 1) * sizeof(char)); + memmove(&result[strlen("const ")], result, len); + memcpy(result, "const ", strlen("const ")); + + } + + break; + + default: + printf("### NOT HANDLED ### Tag :: 0x%02x\n", abbrev->tag); + break; + + } + + return result; + +} diff --git a/src/format/dwarf/utils.c b/src/format/dwarf/utils.c index fa8ef20..359cc52 100644 --- a/src/format/dwarf/utils.c +++ b/src/format/dwarf/utils.c @@ -36,40 +36,45 @@ * Paramètres : format = informations de débogage à consulter. * * pos = tête de lecture à mettre à jour. [OUT] * * value = valeur au format LEB128 lue. [OUT] * +* update = indique si la position est à mettre à jour. * * * * Description : Lit une valeur Little Endian Base 128 signée. * * * * Retour : Bilan de l'opération. * * * -* Remarques : - * +* Remarques : En cas d'échec, la tête de lecture est indéterminée. * * * ******************************************************************************/ -bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value) +bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value, bool update) { + off_t curpos; /* Tête de lecture effective */ int shift; /* Décallage à appliquer */ off_t i; /* Boucle de parcours */ + curpos = *pos; shift = 0; *value = 0; for (i = 0; i < 8; i++) { /* On évite les débordements... */ - if ((*pos + i) >= DBG_FORMAT(format)->length) return false; + if (curpos >= DBG_FORMAT(format)->length) return false; - *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift; + *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift; shift += 7; - (*pos)++; + curpos++; - if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break; + if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break; } - if ((shift < 64) && (DBG_FORMAT(format)->content[*pos - 1] & 0x40) == 0x40) + if ((shift < 64) && (DBG_FORMAT(format)->content[curpos - 1] & 0x40) == 0x40) *value |= - (1 << shift); + if (update) *pos = curpos; + return (i < 8); } @@ -80,37 +85,42 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value) * Paramètres : format = informations de débogage à consulter. * * pos = tête de lecture à mettre à jour. [OUT] * * value = valeur au format LEB128 lue. [OUT] * +* update = indique si la position est à mettre à jour. * * * * Description : Lit une valeur Little Endian Base 128 non signée. * * * * Retour : Bilan de l'opération. * * * -* Remarques : - * +* Remarques : En cas d'échec, la tête de lecture est indéterminée. * * * ******************************************************************************/ -bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value) +bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value, bool update) { + off_t curpos; /* Tête de lecture effective */ int shift; /* Décallage à appliquer */ off_t i; /* Boucle de parcours */ + curpos = *pos; shift = 0; *value = 0; for (i = 0; i < 8; i++) { /* On évite les débordements... */ - if ((*pos + i) >= DBG_FORMAT(format)->length) return false; + if (curpos >= DBG_FORMAT(format)->length) return false; - *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift; + *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift; shift += 7; - (*pos)++; + curpos++; - if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break; + if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break; } + if (update) *pos = curpos; + return (i < 8); } diff --git a/src/format/dwarf/utils.h b/src/format/dwarf/utils.h index fc5b3fc..e5102e2 100644 --- a/src/format/dwarf/utils.h +++ b/src/format/dwarf/utils.h @@ -34,10 +34,10 @@ /* Lit une valeur Little Endian Base 128 signée. */ -bool read_leb128(dwarf_format *, off_t *, int64_t *); +bool read_leb128(dwarf_format *, off_t *, int64_t *, bool); /* Lit une valeur Little Endian Base 128 non signée. */ -bool read_uleb128(dwarf_format *, off_t *, uint64_t *); +bool read_uleb128(dwarf_format *, off_t *, uint64_t *, bool); /* Lit une valeur représentant une longueur d'unité. */ bool read_unit_length(dwarf_format *, off_t *, off_t *); -- cgit v0.11.2-87-g4458