/* OpenIDA - Outil d'analyse de fichiers binaires * abbrev.c - manipulation des abréviation DWARF * * Copyright (C) 2008 Cyrille Bagard * * This file is part of OpenIDA. * * 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 . */ #include "abbrev.h" #include #include "dwarf-int.h" #include "utils.h" #include /* Libère de la mémoire une abréviation DWARF. */ void free_dwarf_abbrev(dw_abbrev *); /* Charge une abréviations DWARF. */ dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_t *); /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * * * Description : Charge les abréviations trouvés pour un DWARF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool load_dwarf_abbreviations(dwarf_format *format) { bool result; /* Bilan à renvoyer */ off_t offset; off_t start; off_t size; bool test; int i; int j; dw_abbrev *abbrev; int64_t index; printf("Searching...\n"); result = true; test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_abbrev", &start, &size, NULL); offset = start; printf(" -> offset=%d size=%d\n", offset, size); for (i = 0; i < size; i++) { 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"); while (offset < (start + size)) { abbrev = read_dwarf_abbreviations(format, &offset, &index); offset++; /* 0x00 */ printf("abbrev :: %p\n", abbrev); if (abbrev != NULL) { format->abbrevs = (dw_abbrev **)realloc(format->abbrevs, ++format->abbrevs_count * sizeof(dw_abbrev *)); format->abbrevs[format->abbrevs_count - 1] = abbrev; printf(" %d attribs, %d children\n", abbrev->attribs_count, abbrev->children_count); } else { unload_dwarf_abbreviations(format); result = false; break; } } return result; } /****************************************************************************** * * * Paramètres : format = informations de débogage à effacer. * * * * Description : Décharge les abréviations trouvés pour un DWARF. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void unload_dwarf_abbreviations(dwarf_format *format) { size_t i; /* Boucle de parcours */ for (i = 0; i < format->abbrevs_count; i++) free_dwarf_abbrev(format->abbrevs[i]); } /****************************************************************************** * * * Paramètres : abbrev = élément à supprimer de la mémoire. * * * * Description : Libère de la mémoire une abréviation DWARF. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void free_dwarf_abbrev(dw_abbrev *abbrev) { size_t i; /* Boucle de parcours */ for (i = 0; i < abbrev->children_count; i++) free_dwarf_abbrev(abbrev->children[i]); free(abbrev->attribs); free(abbrev->children); free(abbrev); } /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * pos = tête de lecture à mettre à jour. [OUT] * * index = code de l'abréviation. [OUT] * * * * Description : Charge une abréviations DWARF. * * * * Retour : Adresse d'une abréviation ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_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 */ 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)); if (!read_leb128(format, pos, &value1)) goto rda_error; result->tag = value1; if (*pos >= DBG_FORMAT(format)->length) goto rda_error; has_children = (DBG_FORMAT(format)->content[(*pos)++] == DW_CHILDREN_YES); /* Liste des attributs */ 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; result->attribs = (dw_abbrev_attr *)realloc(result->attribs, ++result->attribs_count * sizeof(dw_abbrev_attr)); result->attribs[result->attribs_count - 1].attrib = value1; result->attribs[result->attribs_count - 1].form = value2; } (*pos) += 2; /* 0x00 0x00 */ /* Chargement des sous-éléments */ if (has_children) while (DBG_FORMAT(format)->content[*pos] != 0x00) { child = read_dwarf_abbreviations(format, pos, &sub_index); if (child == NULL) 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 *)); result->children[result->children_count - 1] = child; } return result; rda_error: free_dwarf_abbrev(result); return NULL; }