diff options
Diffstat (limited to 'src/format/dwarf/info.c')
-rw-r--r-- | src/format/dwarf/info.c | 413 |
1 files changed, 405 insertions, 8 deletions
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 <malloc.h> +#include <string.h> #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; + +} |