/* 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;
}