diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-11-24 11:41:13 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-11-24 11:41:13 (GMT) |
commit | dad453ff553f0ab07206f26345dc0adeffb775fd (patch) | |
tree | 322f3b26da0d0d25011b7e64afc7c7ee37aa5608 /plugins/dwarf/info.c | |
parent | 615171f171f53791a25aeab7970e29b024177d48 (diff) |
Moved the DWARF support as plugin and disabled it.
Diffstat (limited to 'plugins/dwarf/info.c')
-rw-r--r-- | plugins/dwarf/info.c | 853 |
1 files changed, 853 insertions, 0 deletions
diff --git a/plugins/dwarf/info.c b/plugins/dwarf/info.c new file mode 100644 index 0000000..432280e --- /dev/null +++ b/plugins/dwarf/info.c @@ -0,0 +1,853 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * info.c - lecture des informations principales du format DWARF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "info.h" + + +#include "die.h" +#include "dwarf-int.h" +#include "../debuggable-int.h" + + + + + +static bool extract_dies_from_debug_information(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die *parent, dw_die **die); + + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage DWARF à compléter. * +* * +* Description : Charge les informations depuis une section ".debug_info". * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_dwarf_debug_information(GDwarfFormat *format) +{ + bool result; /* Bilan à renvoyer */ + + + + mrange_t range; /* Couverture d'une section */ + vmpa2t end; + vmpa2t iter; /* Tête de lecture mouvante */ + + dw_compil_unit_header header; + dw_die *die; + + + + result = g_exe_format_get_section_range_by_name(G_DBG_FORMAT(format)->executable, ".debug_info", &range); + if (!result) goto lddi_exit; + + copy_vmpa(&iter, get_mrange_addr(&range)); + + + printf("[%d] Passage :: 0x%08llx 0x%08llx\n", + result, + (unsigned long long)range.addr.physical, + (unsigned long long)range.addr.virtual); + + compute_mrange_end_addr(&range, &end); + + while (result) + { + /* Si il n'y a plus rien à lire dans la section... */ + if (cmp_vmpa(&iter, &end) >= 0) break; + + + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("\n"); + printf("HEADER START :: 0x%x\n", (unsigned int)iter.physical); + + + result = read_dwarf_compil_unit_header(G_BIN_FORMAT(format)->content, &iter, + SRE_LITTLE /* FIXME */, &header); + if (!result) break; + + printf("[%d] header :: addr size=%hhu\n", result, header.address_size); + + + result = extract_dies_from_debug_information(format, &iter, + SRE_LITTLE /* FIXME */, &header, + NULL, &die); + + + + } + + + format->info_die = die; + + + lddi_exit: + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage DWARF à compléter. * +* pos = position de début de lecture. [OUT] * +* endian = boutisme reconnu dans le format. * +* header = en-tête de description de l'unité à traiter. * +* parent = entrée parent de rattachement ou NULL si racine. * +* die = emplacement de stockage de l'entrée. [OUT] * +* * +* Description : Procède à la lecture de l'en-tête d'un contenu binaire DWARF.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool extract_dies_from_debug_information(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die *parent, dw_die **die) +{ + bool result; /* Bilan à faire remonter */ + dw_die *child; /* Entrée subordonnée à charger*/ + + printf("==================================\n"); + printf("=== version : 0x%hx\n", header->version); + printf("=== offset abbrev : 0x%llx\n", (unsigned long long)header->debug_abbrev_offset); + printf("==================================\n"); + + + phys_t start = 0x1039; + + printf("start :: 0x%x\n", (unsigned int)(pos->physical - start)); + printf("start :: 0x%x\n", (unsigned int)(0x0 + pos->physical)); + + result = build_dwarf_die(format, pos, SRE_LITTLE /* FIXME */, header, die); + if (*die == NULL) return result; + + if (parent != NULL) + dw_die_append_child(parent, *die); + + if (dw_die_has_children(*die)) + { + printf("<<<< children >>>>\n"); + + printf("next :: 0x%x\n", (unsigned int)(pos->physical - start)); + + while (result) + { + result = extract_dies_from_debug_information(format, pos, endian, header, *die, &child); + + if (!result) + delete_dwarf_die(*die); + + /* Entrée avec un code nul -> fin */ + if (child == NULL) break; + + } + + } + + return result; + +} + + + + + + + +#if 0 +#include <malloc.h> +#include <string.h> + + +#include "abbrev.h" +#include "dwarf-int.h" +#include "utils.h" + + +/* 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° */ + uint8_t ptrsize; /* Taille des adresses mémoire */ + +} compil_unit; + + + +#define _(str) str + + +/* Procède à la lecture d'une unité de compilation. */ +bool read_dwarf_compilation_unit(dwarf_format *, off_t *, compil_unit *); + +/* Récupère toutes les déclarations DWARF utiles trouvées. */ +bool parse_dwarf_compilation_unit(dwarf_format *, off_t *, const compil_unit *); + +/* Enregistre toutes les déclarations de fonction trouvées. */ +dw_dbg_function *look_for_dwarf_subprograms(dwarf_format *, const dw_abbrev *, 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 *); + + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* * +* Description : Charge les informations trouvées dans un DWARF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_dwarf_information(dwarf_format *format) +{ + bool result; /* Bilan à renvoyer */ + + + + + off_t offset; + off_t start; + off_t size; + + bool test; + + int i; + + + compil_unit cu; + + + + result = true; + + test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_info", &start, &size, NULL); + + offset = start; + + + printf(" -> offset=%d size=%d\n", offset, size); + + + + for (i = 0; i < size; i++) + { + if (i % 25 == 0) printf("\n"); + printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]); + } + + printf("\n"); + + + + while (offset < (start + size) && result) + { + printf("-------------\n"); + + result = read_dwarf_compilation_unit(format, &offset, &cu); + + if (result) + parse_dwarf_compilation_unit(format, &offset, &cu); + + } + + + printf("##############\nRegistered functions:\n"); + + for (i = 0; i < format->dbg_fc_count; i++) + printf(" > [0x%08llx] %s\n", format->dbg_functions[i]->low_pc, format->dbg_functions[i]->prototype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à effacer. * +* * +* Description : Décharge les informations trouvées dans un DWARF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_dwarf_information(dwarf_format *format) +{ + + + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* cu = unité de compilation lue. [OUT] * +* * +* Description : Procède à la lecture d'une unité de compilation. * +* * +* Retour : true en cas de succès de la lecture, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_compilation_unit(dwarf_format *format, off_t *pos, compil_unit *cu) +{ + off_t ulength; /* Taille de l'unité */ + uint16_t version; /* Version du format DWARF */ + + cu->startpos = *pos; + + if (!read_unit_length(format, pos, &ulength)) + return false; + + cu->endpos = *pos + ulength; + + if (!read_uhalf(format, pos, &version)) + return false; + + if (version > 3) return false; + + if (!read_abbrev_offset(format, pos, &cu->offset)) + return false; + + if (!read_address_size(format, pos, &cu->ptrsize)) + return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* cu = unité de compilation courante. * +* * +* Description : Récupère toutes les déclarations DWARF utiles trouvées. * +* * +* Retour : true en cas de succès de la lecture, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool parse_dwarf_compilation_unit(dwarf_format *format, off_t *pos, const compil_unit *cu) +{ + bool result; /* Bilan à retourner */ + const dw_abbrev *abbrev; /* Abréviation rencontrée */ + dw_dbg_function *function; /* Nouvelle fonction lue */ + + + + result = true; + + while (*pos < cu->endpos && result) + { + + + 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]); + + + + abbrev = find_dwarf_abbreviations(format, &cu->offset, pos); + + if (abbrev == NULL) + break; + + + + printf(" --> %p\n", abbrev); + + printf(" == 0x%02x (matched ? %d)\n", abbrev->tag, abbrev->tag == DWT_SUBPROGRAM); + + + + switch (abbrev->tag) + { + case DWT_SUBPROGRAM: + function = look_for_dwarf_subprograms(format, abbrev, pos, cu); + + if (function != NULL) + { + format->dbg_functions = (dw_dbg_function **)realloc(format->dbg_functions, ++format->dbg_fc_count * sizeof(dw_dbg_function *)); + format->dbg_functions[format->dbg_fc_count - 1] = function; + } + else result = false; + + break; + + default: + break; + + } + + + + + + + + + + + + + if (!skip_dwarf_abbrev(format, pos, abbrev)) + printf("error skipping :(\n"); + + + } + + + printf(" =+> Next :: 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]); + + + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* abbrev = abréviation trouvée à traiter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* cu = unité de compilation courante. * +* * +* Description : Enregistre toutes les déclarations de fonction trouvées. * +* * +* Retour : Fonction chargée en mémoire ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +dw_dbg_function *look_for_dwarf_subprograms(dwarf_format *format, const dw_abbrev *abbrev, off_t *pos, const compil_unit *cu) +{ + dw_dbg_function *result; /* Structure à retourner */ + uint32_t type_pos; /* Décalage p/r au pt courant */ + off_t subpos; /* Sous-position de lecture #1 */ + const dw_abbrev *subabbrev; /* Abréviation fille à lire */ + char *retstr; /* Elément du prototype */ + char *prototype; /* Stockage temporaire */ + size_t proto_len; /* Taille du prototype */ + bool is_pointer; /* Mémorise le type 'pointeur' */ + uint64_t index; /* Index de la fonction */ + bool first_arg; /* Marque le 1er argument */ + off_t subpos2; /* Sous-position de lecture #2 */ + const dw_abbrev *subabbrev2; /* Abréviation fille à lire #2 */ + + result = (dw_dbg_function *)calloc(1, sizeof(dw_dbg_function)); + + /* Récupération des informations de base */ + + if (!read_dwarf_abbrev_attribute(format, pos, false, abbrev, DWA_NAME, &result->name)) + goto lfds_error; + + if (!read_dwarf_abbrev_attribute(format, pos, false, abbrev, DWA_LOW_PC, &result->low_pc)) + goto lfds_error; + + if (!read_dwarf_abbrev_attribute(format, pos, false, abbrev, DWA_HIGH_PC, &result->high_pc)) + goto lfds_error; + + /* Type de la fonction */ + + if (test_dwarf_abbrev_attribute(abbrev, DWA_TYPE)) + { + if (!read_dwarf_abbrev_attribute(format, pos, false, abbrev, DWA_TYPE, &type_pos)) + goto lfds_error; + + subpos = cu->startpos + type_pos; + + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &subpos); + + retstr = resolve_dwarf_function_type(format, subabbrev, &subpos, cu); + + } + else retstr = strdup("void"); + + if (retstr == NULL) + { + proto_len = 3; + prototype = (char *)calloc(proto_len + 1, sizeof(char)); + strcat(prototype, "???"); + + is_pointer = false; + + } + else + { + proto_len = strlen(retstr); + prototype = (char *)calloc(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... */ + + subpos = *pos; + + if (!read_uleb128(format, &subpos, &index, true)) + goto lfds_error; + + if (!skip_dwarf_abbrev(format, &subpos, abbrev)) + goto lfds_error; + + /* Lecture des différents arguments */ + + proto_len += (!is_pointer ? 1 : 0) + strlen(result->name) + 1; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + if (!is_pointer) strcat(prototype, " "); + strcat(prototype, result->name); + strcat(prototype, "("); + + first_arg = true; + + while (1) + { + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &subpos); + if (subabbrev == NULL) goto exit_loop; + + 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: + + if (!read_dwarf_abbrev_attribute(format, &subpos, false, subabbrev, DWA_TYPE, &type_pos)) + goto lfds_error; + + subpos2 = cu->startpos + type_pos; + + subabbrev2 = find_dwarf_abbreviations(format, &cu->offset, &subpos2); + + retstr = resolve_dwarf_function_type(format, subabbrev2, &subpos2, cu); + + /* 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); + + } + + /* Nom de l'argument */ + + if (test_dwarf_abbrev_attribute(abbrev, DWA_NAME)) + { + if (!read_dwarf_abbrev_attribute(format, &subpos, false, subabbrev, DWA_NAME, &retstr)) + goto lfds_error; + } + else retstr = strdup(_("[no name]")); + + 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, &subpos, subabbrev)) + goto lfds_error; + + } + + exit_loop: + + proto_len += 1; + prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); + strcat(prototype, ")"); + + result->prototype = prototype; + + return result; + + lfds_error: + + if (result->name != NULL) free(result->name); + if (result->prototype != NULL) free(result->prototype); + + free(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* 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) + { + /* 0x04 */ + case DWT_ENUMERATION_TYPE: + + oldpos = *pos; + read_dwarf_abbrev_attribute(format, &oldpos, true /* ??? */, abbrev, DWA_NAME, &result); + + if (result != NULL) + { + len = strlen(result); + + result = (char *)realloc(result, (strlen("enum ") + len + 1) * sizeof(char)); + memmove(&result[strlen("enum ")], result, len); + memcpy(result, "enum ", strlen("enum ")); + + } + + break; + + /* 0x0f */ + case DWT_POINTER_TYPE: + + if (test_dwarf_abbrev_attribute(abbrev, DWA_TYPE)) + { + if (!read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_TYPE, &type_pos)) + return NULL; + + oldpos = cu->startpos + type_pos; + + subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + + result = resolve_dwarf_function_type(format, subabbrev, &oldpos, cu); + + } + else result = strdup("void"); + + 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; + + /* 0x13 */ + case DWT_STRUCTURE_TYPE: + + oldpos = *pos; + read_dwarf_abbrev_attribute(format, &oldpos, true /* ??? */, abbrev, DWA_NAME, &result); + + if (result != NULL) + { + len = strlen(result); + + result = (char *)realloc(result, (strlen("struct ") + len + 1) * sizeof(char)); + memmove(&result[strlen("struct ")], result, len); + memcpy(result, "struct ", strlen("struct ")); + + } + + break; + + /* 0x16 */ + case DWT_TYPEDEF: + oldpos = *pos; + read_dwarf_abbrev_attribute(format, &oldpos, true /* ??? */, abbrev, DWA_NAME, &result); + break; + + /* 0x24 */ + case DWT_BASE_TYPE: + oldpos = *pos; + read_dwarf_abbrev_attribute(format, &oldpos, true /* ??? */, abbrev, DWA_NAME, &result); + break; + + /* 0x26 */ + 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, (strlen("const ") + len + 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; + +} +#endif |