diff options
Diffstat (limited to 'src/format/dwarf/die.c')
-rw-r--r-- | src/format/dwarf/die.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/format/dwarf/die.c b/src/format/dwarf/die.c new file mode 100644 index 0000000..8c25a1d --- /dev/null +++ b/src/format/dwarf/die.c @@ -0,0 +1,303 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * die.c - gestion des entrées renvoyant à des informations de débogage + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "die.h" + + +#include <assert.h> +#include <malloc.h> + + +#include "dwarf-int.h" + + + +/** + * § 2.1 The Debugging Information Entry (DIE). + */ + +typedef struct _dw_die +{ + unsigned int level; /* Niveau hiérarchique */ + phys_t offset; /* Position dans le flux */ + + const dw_abbrev *abbrev; /* Lien vers la représentation */ + + dw_value *values; /* Liste des valeurs associées */ + + bool has_children; /* Feuille ou noeud de l'arbre */ + struct _dw_die **children; /* Liste d'éventuels enfants */ + size_t children_count; /* Taille de cette liste */ + +} dw_die; + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* endian = boutisme reconnu dans le format. * +* header = en-tête de description de l'unité à traiter. * +* die = emplacement de stockage de l'entrée ou NULL. [OUT] * +* * +* Description : Procède à la lecture de l'en-tête d'une unité de compilation.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Le format autorise à ne rien produire ici légitimement. * +* * +******************************************************************************/ + +bool build_dwarf_die(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die **die) +{ + uleb128_t code; /* Code de la description liée */ + bool status; /* Bilan de la lecture */ + const dw_abbrev *abbrev; /* Lien vers la représentation */ + dw_value *values; /* Liste des valeurs associées */ + + *die = NULL; + + /** + * § 7.5.2 Debugging Information Entry. + */ + + status = g_binary_content_read_uleb128(G_BIN_FORMAT(format)->content, pos, &code); + if (!status) return false; + + printf("[ok] code = 0x%llx\n", (unsigned long long)code); + + if (code == 0) return true; + + abbrev = find_dwarf_abbreviations(format, code); + + printf("[ok] abbrev = %p\n", abbrev); + + printf("----------------------\n"); + + + values = translate_abbreviation_attributes(format, abbrev, header, pos); + if (values == NULL) return false; + + printf("[ok] values = %p\n", values); + + + + *die = (dw_die *)calloc(1, sizeof(dw_die)); + + (*die)->abbrev = abbrev; + + (*die)->values = values; + + (*die)->has_children = dwarf_abbreviation_has_children(abbrev); + + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à libérer de la mémoire. * +* * +* Description : Supprime les éléments mis en place pour une entrée d'info. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_dwarf_die(dw_die *die) +{ + size_t i; /* Boucle de parcours */ + + if (die->values != NULL) + free(die->values); + + for (i = 0; i < die->children_count; i++) + delete_dwarf_die(die->children[i]); + + if (die->children != NULL) + free(die->children); + + free(die); + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Structure de représentation en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_abbrev *dw_die_get_abbrev(const dw_die *die) +{ + return die->abbrev; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* index = indice de cet attribut dans l'ensemble. * +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Valeur recherchée ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_form_value *dw_die_peek_value(const dw_die *die, size_t index) +{ + dw_form_value *result; /* Valeur ciblée à retourner */ + + if (index >= dwarf_abbreviation_count_attribs(die->abbrev)) + return NULL; + + result = &die->values[index].value; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée d'information à consulter. * +* attrib = désignation de l'attribut à retrouver. * +* form = type de valeur attendu pour un attribut donné. [OUT]* +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Valeur recherchée ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_form_value *dw_die_peek_extended_value(const dw_die *die, DwarfAttrib attrib, DwarfForm *form) +{ + const dw_form_value *result; /* Valeur ciblée à retourner */ + size_t index; /* Indice d'élément à relire */ + bool status; /* Bilan d'une récupération */ + + status = dwarf_abbreviation_get_attrib_index(die->abbrev, attrib, &index); + if (!status) return NULL; + + status = dwarf_abbreviation_get_form_for_index(die->abbrev, index, form); + if (!status) return NULL; + + result = dw_die_peek_value(die, index); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Indique si une entrée de débogage possède des enfants. * +* * +* Retour : true ou false selon la situation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dw_die_has_children(const dw_die *die) +{ + return die->has_children; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Indique si une entrée de débogage possède des enfants. * +* * +* Retour : true ou false selon la situation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void dw_die_append_child(dw_die *die, dw_die *child) +{ + assert(die->has_children); + + die->children = (dw_die **)realloc(die->children, ++die->children_count * sizeof(dw_die *)); + + die->children[die->children_count - 1] = child; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT PAR ENSEMBLES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : root = entrée première à consulter. * +* visitor = intervention régulière à respecter. * +* data = données quelconques à associer aux visites. * +* * +* Description : Entame une grande tournée de toutes les entrées présentes. * +* * +* Retour : true si l'opération s'est déroulée complètement, false sinon.* +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dw_die_visit(dw_die *root, visit_dies_fc visitor, void *data) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = visitor(root, data); + + for (i = 0; i < root->children_count && result; i++) + result = dw_die_visit(root->children[i], visitor, data); + + return result; + +} |