/* OpenIDA - Outil d'analyse de fichiers binaires
* info.c - lecture des informations principales du format 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 "info.h"
#include
#include "abbrev.h"
#include "dwarf-int.h"
#include "utils.h"
/* Informations utiles d'une unité de compilation */
typedef struct _compil_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;
/* Procède à la lecture d'une unité de compilation. */
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 *);
/******************************************************************************
* *
* 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)
look_for_dwarf_subprograms(format, &offset, &cu);
//break;
}
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)
{
bool result; /* Bilan à retourner */
off_t ulength; /* Taille de l'unité */
uint16_t version; /* Version du format DWARF */
off_t abbrev_pos; /* Position dans les abréviat° */
uint8_t memsize; /* Taille des adresses mémoire */
off_t oldpos;
uint8_t index;
result = true;
if (read_unit_length(format, pos, &ulength))
printf("Unit Length :: %d (0x%x)\n", ulength, ulength);
else printf("error ul\n");
cu->endpos = *pos + ulength;
oldpos = *pos;
if (read_uhalf(format, pos, &version))
printf("version :: %hd\n", version);
else printf("error version\n");
if (version > 3) return false;
if (read_abbrev_offset(format, pos, &abbrev_pos))
printf("abbrev offset :: %d\n", abbrev_pos);
else printf("error abbrev offset\n");
if (read_address_size(format, pos, &memsize))
printf("mem size :: %hhd\n", memsize);
else printf("error memsize\n");
cu->offset = abbrev_pos;
cu->ptrsize = memsize;
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]);
/*
*pos = oldpos + ulength;
*/
return result;
}
/******************************************************************************
* *
* Paramètres : format = informations de débogage à compléter. *
* pos = tête de lecture à mettre à jour. [OUT] *
* cu = unité de compilation courante. *
* *
* Description : Enregistre toutes les déclarations de fonction trouvées. *
* *
* Retour : true en cas de succès de la lecture, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_unit *cu)
{
bool result; /* Bilan à retourner */
uint8_t index; /* Indice de l'abbréviation */
result = true;
off_t oldpos;
const dw_abbrev *abbrev;
uint64_t low_pc;
uint64_t high_pc;
while (*pos < cu->endpos)
{
if (read_address_size/*leb128*/(format, pos, &index))
printf("abbrev index :: %hhd\n", index);
else printf("abbrev index error\n");
/* Contraintes d'alignement... */
if (index == 0) continue;
abbrev = find_dwarf_abbreviations(format, &cu->offset, index);
printf(" --> %p\n", abbrev);
printf(" == 0x%02x (matched ? %d)\n", abbrev->tag, abbrev->tag == DWT_SUBPROGRAM);
oldpos = *pos;
if (abbrev->tag == DWT_SUBPROGRAM)
{
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");
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");
}
if (!skip_dwarf_abbrev(format, pos, abbrev))
printf("error skipping :(\n");
printf(" == progress %d\n", *pos - oldpos);
printf(" == %d < %d\n", *pos, cu->endpos);
}
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;
}