From f6f110acb8bf3243dffc527271c17619a078fcc4 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 17 Aug 2008 21:13:03 +0000 Subject: Looked for prototyped functions using the registered abbreviations. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@17 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 24 +++ src/format/dwarf/Makefile.am | 1 + src/format/dwarf/abbrev.c | 488 +++++++++++++++++++++++++++++++++++++++++-- src/format/dwarf/abbrev.h | 14 +- src/format/dwarf/d_dwarf.c | 5 +- src/format/dwarf/dwarf-int.h | 14 ++ src/format/dwarf/info.c | 324 ++++++++++++++++++++++++++++ src/format/dwarf/info.h | 43 ++++ src/format/dwarf/utils.c | 223 ++++++++++++++++++++ src/format/dwarf/utils.h | 16 ++ 10 files changed, 1132 insertions(+), 20 deletions(-) create mode 100644 src/format/dwarf/info.c create mode 100644 src/format/dwarf/info.h diff --git a/ChangeLog b/ChangeLog index 6971ba6..f34d4fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2008-08-17 Cyrille Bagard + + * src/format/dwarf/abbrev.c: + * src/format/dwarf/abbrev.h: + Add several functions to process the parsed abbreviations. + + * src/format/dwarf/d_dwarf.c: + Improve the loading thanks to the new features. + + * src/format/dwarf/dwarf-int.h: + Specify a format (32 or 64 bits) and refine the abbreviation definition. + + * src/format/dwarf/info.c: + * src/format/dwarf/info.h: + New entries: look for prototyped functions using the registered + abbreviations. + + * src/format/dwarf/Makefile.am: + Add info.[ch] to libformatdwarf_a_SOURCES. + + * src/format/dwarf/utils.c: + * src/format/dwarf/utils.h: + Read more values: uleb128, unit length, uhalf, offset and address size. + 2008-08-10 Cyrille Bagard * src/format/dwarf/abbrev.c: diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am index 6103ac2..507a50e 100644 --- a/src/format/dwarf/Makefile.am +++ b/src/format/dwarf/Makefile.am @@ -5,6 +5,7 @@ libformatdwarf_a_SOURCES = \ abbrev.h abbrev.c \ d_dwarf.h d_dwarf.c \ dwarf_def.h \ + info.h info.c \ utils.h utils.c libformatdwarf_a_CFLAGS = $(AM_CFLAGS) diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 6eada92..2eec460 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -25,9 +25,10 @@ #include +#include +#include -#include "dwarf-int.h" #include "utils.h" @@ -42,13 +43,19 @@ void free_dwarf_abbrev(dw_abbrev *); /* Charge une abréviations DWARF. */ dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_t *); +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *, uint8_t *); + +/* Lit la valeur d'un attribut DWARF. */ +bool _read_dwarf_abbrev_attribute(dwarf_format *, off_t *, DwarfForm, DwarfAttrib, ...); + /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * * -* Description : Charge les abréviations trouvés pour un DWARF. * +* Description : Charge les abréviations trouvées pour un DWARF. * * * * Retour : Bilan de l'opération. * * * @@ -70,7 +77,6 @@ bool load_dwarf_abbreviations(dwarf_format *format) bool test; int i; - int j; dw_abbrev *abbrev; @@ -94,14 +100,6 @@ bool load_dwarf_abbreviations(dwarf_format *format) { 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"); @@ -119,6 +117,8 @@ bool load_dwarf_abbreviations(dwarf_format *format) if (abbrev != NULL) { + abbrev->offset -= start; + format->abbrevs = (dw_abbrev **)realloc(format->abbrevs, ++format->abbrevs_count * sizeof(dw_abbrev *)); format->abbrevs[format->abbrevs_count - 1] = abbrev; @@ -143,7 +143,7 @@ bool load_dwarf_abbreviations(dwarf_format *format) * * * Paramètres : format = informations de débogage à effacer. * * * -* Description : Décharge les abréviations trouvés pour un DWARF. * +* Description : Décharge les abréviations trouvées pour un DWARF. * * * * Retour : - * * * @@ -194,7 +194,7 @@ void free_dwarf_abbrev(dw_abbrev *abbrev) * pos = tête de lecture à mettre à jour. [OUT] * * index = code de l'abréviation. [OUT] * * * -* Description : Charge une abréviations DWARF. * +* Description : Charge une abréviation DWARF. * * * * Retour : Adresse d'une abréviation ou NULL en cas d'échec. * * * @@ -211,17 +211,23 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i 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)); + result->offset = *pos; + + /* Code de l'élément */ + if (!read_leb128(format, pos, index)) goto rda_error; + if (!read_leb128(format, pos, &value1)) goto rda_error; result->tag = value1; + printf(" --ta :: 0x%02llx\n", value1); + if (*pos >= DBG_FORMAT(format)->length) goto rda_error; has_children = (DBG_FORMAT(format)->content[(*pos)++] == DW_CHILDREN_YES); + printf(" --ch ? %d\n", has_children); + /* Liste des attributs */ while (DBG_FORMAT(format)->content[*pos] != 0x00) @@ -247,7 +253,7 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i if (child == NULL) goto rda_error; - //if ((sub_index - *index - 1) != result->children_count) 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 *)); @@ -264,3 +270,451 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i return NULL; } + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation racine à parcourir. * +* index = code de l'abréviation. [OUT] * +* * +* Description : Recherche une abréviation DWARF donnée. * +* * +* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *index) +{ + const dw_abbrev *result; /* Structure à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + if (*index == 0) result = abbrev; + else + for (i = 0; i < abbrev->children_count && result == NULL; i++) + { + (*index)--; + result = _find_dwarf_abbreviations(abbrev->children[i], index); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* offset = position dans les abréviations. * +* index = code de l'abréviation. * +* * +* Description : Recherche une abréviation DWARF donnée. * +* * +* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, uint8_t index) +{ + const dw_abbrev *result; /* Structure à retourner */ + size_t i; /* Boucle de parcours */ + + if (index == 0) return NULL; + + result = NULL; + + for (i = 0; i < format->abbrevs_count; i++) + if (format->abbrevs[i]->offset == *offset) break; + + if (i < format->abbrevs_count) + { + index--; + result = _find_dwarf_abbreviations(format->abbrevs[i], &index); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* form = format des données à lire. * +* attrib = attribut visé par la lecture. * +* ... = lieu d'enregistrement ou NULL. [OUT] * +* * +* Description : Lit la valeur d'un attribut DWARF. * +* * +* Retour : true si la lecture est un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, DwarfAttrib attrib, ...) +{ + bool result; /* Bilan à revoyer */ + va_list ap; /* Adresse fournie en dernier */ + uint8_t *val8; /* Données sur 8 bits */ + uint16_t *val16; /* Données sur 16 bits */ + uint32_t *val32; /* Données sur 32 bits */ + uint64_t *val64; /* Données sur 64 bits */ + bool *boolval; /* Valeur booléenne */ + uint8_t tmp8; /* Données sur 8 bits */ + uint16_t tmp16; /* Données sur 16 bits */ + uint32_t tmp32; /* Données sur 32 bits */ + uint64_t tmp64; /* Données sur 64 bits */ + uint64_t size_to_read; /* Nombre d'octets à lire */ + off_t offset; /* Décallage dans une zone */ + char **strval; /* Chaîne de caractères */ + size_t length; /* Taille d'une chaîne */ + + va_start(ap, attrib); + + switch (form) + { + case DWF_ADDR: + result = ((*pos + (format->format == DWF_32_BITS ? 4 : 8)) <= DBG_FORMAT(format)->length); + if (result) + { + val64 = va_arg(ap, uint64_t *); + if (val64 != NULL) + { + if (format->format == DWF_32_BITS) + { + tmp32 = *((uint32_t *)&DBG_FORMAT(format)->content[*pos]); + //memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4); + *val64 = tmp32; + } + else memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); + } + *pos += (format->format == DWF_32_BITS ? 4 : 8); + } + break; + + case DWF_BLOCK2: + result = ((*pos + 2) <= DBG_FORMAT(format)->length); + if (result) + { + memcpy(&tmp16, &DBG_FORMAT(format)->content[*pos], 2); + size_to_read = tmp16; + /* ... */ + *pos += 2 + size_to_read; + } + break; + + case DWF_BLOCK4: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + if (result) + { + memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4); + size_to_read = tmp32; + /* ... */ + *pos += 4 + size_to_read; + } + break; + + case DWF_DATA2: + result = ((*pos + 2) <= DBG_FORMAT(format)->length); + if (result) + { + val16 = va_arg(ap, uint16_t *); + if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2); + *pos += 2; + } + break; + + case DWF_DATA4: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + if (result) + { + val32 = va_arg(ap, uint32_t *); + if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4); + *pos += 4; + } + break; + + case DWF_DATA8: + result = ((*pos + 8) <= DBG_FORMAT(format)->length); + if (result) + { + val64 = va_arg(ap, uint64_t *); + if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); + *pos += 8; + } + break; + + case DWF_STRING: + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (result) + { + strval = va_arg(ap, char **); + if (strval != NULL) *strval = (char *)calloc(1, sizeof(char)); + length = 0; + + while (result) + { + if (DBG_FORMAT(format)->content[*pos] == '\0') break; + + length++; + + if (strval != NULL) + { + *strval = (char *)realloc(*strval, (length + 1) * sizeof(char)); + (*strval)[length - 1] = DBG_FORMAT(format)->content[*pos]; + } + + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (!result) break; + + (*pos)++; + + } + + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + + if (result) + { + (*pos)++; + + if (strval != NULL) + (*strval)[length] = 0; + } + else + { + if (strval != NULL) + free(*strval); + } + + } + + break; + + case DWF_BLOCK: + result = read_uleb128(format, pos, &size_to_read); + result &= ((*pos + size_to_read) <= DBG_FORMAT(format)->length); + if (result) + { + /* ... */ + *pos += size_to_read; + } + break; + + case DWF_BLOCK1: + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (result) + { + memcpy(&tmp8, &DBG_FORMAT(format)->content[*pos], 1); + size_to_read = tmp8; + /* ... */ + *pos += 1 + size_to_read; + } + break; + + case DWF_DATA1: + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (result) + { + val8 = va_arg(ap, uint8_t *); + if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1); + *pos += 1; + } + break; + + case DWF_FLAG: + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (result) + { + boolval = va_arg(ap, bool *); + if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); + *pos += 1; + } + break; + + case DWF_SDATA: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_STRP: + result = read_abbrev_offset(format, pos, &offset); + if (result) + { + /* + boolval = va_arg(ap, bool *); + if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); + */ + } + break; + + + case DWF_UDATA: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_REF_ADDR: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_REF1: + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + if (result) + { + val8 = va_arg(ap, uint8_t *); + if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1); + *pos += 1; + } + break; + + case DWF_REF2: + result = ((*pos + 2) <= DBG_FORMAT(format)->length); + if (result) + { + val16 = va_arg(ap, uint16_t *); + if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2); + *pos += 2; + } + break; + + case DWF_REF4: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + if (result) + { + val32 = va_arg(ap, uint32_t *); + if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4); + *pos += 4; + } + break; + + case DWF_REF8: + result = ((*pos + 8) <= DBG_FORMAT(format)->length); + if (result) + { + val64 = va_arg(ap, uint64_t *); + if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8); + *pos += 8; + } + break; + + case DWF_REF_UDATA: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + case DWF_INDIRECT: + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + printf("bad\n"); exit(0); + + break; + + + + + default: + result = false; + break; + + } + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* abbrev = informations à parcourir. * +* attrib = attribut visé par la lecture. * +* ... = lieu d'enregistrement ou NULL. [OUT] * +* * +* Description : Lit la valeur d'un attribut DWARF. * +* * +* Retour : true si la lecture est un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + va_list ap; /* Adresse fournie en dernier */ + + result = true; + + for (i = 0; i < abbrev->attribs_count && result; i++) + if (abbrev->attribs[i].attrib == attrib) break; + else result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, abbrev->attribs[i].attrib, NULL); + + if (result) + { + va_start(ap, attrib); + + if (i < abbrev->attribs_count) + result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, attrib, va_arg(ap, void *)); + else + result = false; + + va_end(ap); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à compléter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* abbrev = informations à survoler. * +* * +* Description : Fait avancer la tête de lecture d'une seule abréviation. * +* * +* Retour : true si l'opération est un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev) +{ + bool result; /* Bilan à revoyer */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < abbrev->attribs_count && result; i++) + result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, abbrev->attribs[i].attrib, NULL); + + return result; + +} diff --git a/src/format/dwarf/abbrev.h b/src/format/dwarf/abbrev.h index f375abc..0839287 100644 --- a/src/format/dwarf/abbrev.h +++ b/src/format/dwarf/abbrev.h @@ -29,15 +29,25 @@ #include "d_dwarf.h" +#include "dwarf-int.h" -/* Charge les abréviations trouvés pour un DWARF. */ +/* Charge les abréviations trouvées pour un DWARF. */ bool load_dwarf_abbreviations(dwarf_format *); -/* Décharge les abréviations trouvés pour un DWARF. */ +/* Décharge les abréviations trouvées pour un DWARF. */ void unload_dwarf_abbreviations(dwarf_format *); +/* Recherche une abréviation DWARF. */ +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *, const off_t *, uint8_t); + +/* Lit la valeur d'un attribut DWARF. */ +bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, const dw_abbrev *, DwarfAttrib, ...); + +/* Fait avancer la tête de lecture d'une seule abréviation. */ +bool skip_dwarf_abbrev(dwarf_format *, off_t *, const dw_abbrev *); + #endif /* _FORMAT_DWARF_ABBREV_H */ diff --git a/src/format/dwarf/d_dwarf.c b/src/format/dwarf/d_dwarf.c index 7537e34..17dc711 100644 --- a/src/format/dwarf/d_dwarf.c +++ b/src/format/dwarf/d_dwarf.c @@ -29,7 +29,7 @@ #include "abbrev.h" #include "dwarf-int.h" - +#include "info.h" @@ -63,9 +63,12 @@ dwarf_format *load_dwarf(const uint8_t *content, off_t length, exe_format *e_for DBG_FORMAT(result)->e_format = e_format; + result->format = DWF_32_BITS; test = load_dwarf_abbreviations(result); + test = load_dwarf_information(result); + return result; diff --git a/src/format/dwarf/dwarf-int.h b/src/format/dwarf/dwarf-int.h index 371d193..52130f8 100644 --- a/src/format/dwarf/dwarf-int.h +++ b/src/format/dwarf/dwarf-int.h @@ -34,6 +34,17 @@ +/* Format du DWARF */ +typedef enum _DwarfFormat +{ + DWF_32_BITS, /* Mode 32 bits */ + DWF_64_BITS /* Mode 64 bits */ + +} DwarfFormat; + + + + /* Description d'un attribut d'une abréviation */ typedef struct _dw_abbrev_attr { @@ -46,6 +57,7 @@ typedef struct _dw_abbrev_attr /* Description d'une abréviation */ typedef struct _dw_abbrev { + off_t offset; /* Position dans le corps */ DwarfTag tag; /* Sujet de l'élément */ dw_abbrev_attr *attribs; /* Liste des attributs */ @@ -64,6 +76,8 @@ struct _dwarf_format { dbg_format dummy; /* A laisser en premier */ + DwarfFormat format; /* Format de l'instance */ + dw_abbrev **abbrevs; /* Liste des abréviations */ size_t abbrevs_count; /* Nombre de ces abréviations */ diff --git a/src/format/dwarf/info.c b/src/format/dwarf/info.c new file mode 100644 index 0000000..0dc5048 --- /dev/null +++ b/src/format/dwarf/info.c @@ -0,0 +1,324 @@ + +/* 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; + +} diff --git a/src/format/dwarf/info.h b/src/format/dwarf/info.h new file mode 100644 index 0000000..cf87019 --- /dev/null +++ b/src/format/dwarf/info.h @@ -0,0 +1,43 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * info.h - prototypes pour la 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 . + */ + + +#ifndef _FORMAT_DWARF_INFO_H +#define _FORMAT_DWARF_INFO_H + + +#include + + +#include "d_dwarf.h" + + + +/* Charge les informations trouvées dans un DWARF. */ +bool load_dwarf_information(dwarf_format *); + +/* Décharge les informations trouvées dans un DWARF. */ +void unload_dwarf_information(dwarf_format *); + + + +#endif /* _FORMAT_DWARF_INFO_H */ diff --git a/src/format/dwarf/utils.c b/src/format/dwarf/utils.c index b5dbf6b..fa8ef20 100644 --- a/src/format/dwarf/utils.c +++ b/src/format/dwarf/utils.c @@ -24,6 +24,9 @@ #include "utils.h" +#include + + #include "dwarf-int.h" @@ -47,6 +50,7 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value) int shift; /* Décallage à appliquer */ off_t i; /* Boucle de parcours */ + shift = 0; *value = 0; for (i = 0; i < 8; i++) @@ -69,3 +73,222 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value) return (i < 8); } + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* value = valeur au format LEB128 lue. [OUT] * +* * +* Description : Lit une valeur Little Endian Base 128 non signée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value) +{ + int shift; /* Décallage à appliquer */ + off_t i; /* Boucle de parcours */ + + shift = 0; + *value = 0; + + for (i = 0; i < 8; i++) + { + /* On évite les débordements... */ + if ((*pos + i) >= DBG_FORMAT(format)->length) return false; + + *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift; + + shift += 7; + (*pos)++; + + if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break; + + } + + return (i < 8); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* value = valeur entière lue. [OUT] * +* * +* Description : Lit une valeur représentant une longueur d'unité. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Un peu sale : la sortie est signée et dépend du système, * +* alors que la valeur est non signée et dépend de la cible. * +* * +******************************************************************************/ + +bool read_unit_length(dwarf_format *format, off_t *pos, off_t *value) +{ + bool result; /* Bilan à retourner */ + uint32_t val32; /* Entier sur 4 octets */ + uint64_t val64; /* Entier sur 8 octets */ + + /* FIXME : Endian... */ + + if (format->format == DWF_32_BITS) + { + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + if (result) + { + memcpy(&val32, &DBG_FORMAT(format)->content[*pos], 4); + (*pos) += 4; + + *value = val32; + + } + + } + else + { + result = ((*pos + 4 + 8) <= DBG_FORMAT(format)->length); + + if (result) + { + memcpy(&val64, &DBG_FORMAT(format)->content[*pos + 4], 8); + (*pos) += 4 + 8; + + *value = val64; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* value = valeur entière non signée lue. [OUT] * +* * +* Description : Lit une valeur non signée sur deux octets. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_uhalf(dwarf_format *format, off_t *pos, uint16_t *value) +{ + bool result; /* Bilan à retourner */ + + /* FIXME : Endian... */ + + result = ((*pos + 2) <= DBG_FORMAT(format)->length); + + if (result) + { + memcpy(value, &DBG_FORMAT(format)->content[*pos], 2); + (*pos) += 2; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* value = valeur entière lue. [OUT] * +* * +* Description : Lit une valeur indiquant une position dans les abréviations. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Un peu sale : la sortie est signée et dépend du système, * +* alors que la valeur est non signée et dépend de la cible. * +* * +******************************************************************************/ + +bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value) +{ + bool result; /* Bilan à retourner */ + uint32_t val32; /* Entier sur 4 octets */ + uint64_t val64; /* Entier sur 8 octets */ + + /* FIXME : Endian... */ + + if (format->format == DWF_32_BITS) + { + result = ((*pos + 4) <= DBG_FORMAT(format)->length); + + if (result) + { + memcpy(&val32, &DBG_FORMAT(format)->content[*pos], 4); + (*pos) += 4; + + *value = val32; + + } + + } + else + { + result = ((*pos + 8) <= DBG_FORMAT(format)->length); + + if (result) + { + memcpy(&val64, &DBG_FORMAT(format)->content[*pos], 8); + (*pos) += 8; + + *value = val64; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à mettre à jour. [OUT] * +* value = valeur entière non signée lue. [OUT] * +* * +* Description : Lit une valeur indiquant la taille des adresses mémoire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_address_size(dwarf_format *format, off_t *pos, uint8_t *value) +{ + bool result; /* Bilan à retourner */ + + result = ((*pos + 1) <= DBG_FORMAT(format)->length); + + if (result) + { + *value = DBG_FORMAT(format)->content[*pos]; + (*pos)++; + } + + return result; + +} diff --git a/src/format/dwarf/utils.h b/src/format/dwarf/utils.h index 556e4d9..fc5b3fc 100644 --- a/src/format/dwarf/utils.h +++ b/src/format/dwarf/utils.h @@ -26,6 +26,7 @@ #include +#include #include "d_dwarf.h" @@ -35,6 +36,21 @@ /* Lit une valeur Little Endian Base 128 signée. */ bool read_leb128(dwarf_format *, off_t *, int64_t *); +/* Lit une valeur Little Endian Base 128 non signée. */ +bool read_uleb128(dwarf_format *, off_t *, uint64_t *); + +/* Lit une valeur représentant une longueur d'unité. */ +bool read_unit_length(dwarf_format *, off_t *, off_t *); + +/* Lit une valeur non signée sur deux octets. */ +bool read_uhalf(dwarf_format *, off_t *, uint16_t *); + +/* Lit une valeur indiquant une position dans les abréviations. */ +bool read_abbrev_offset(dwarf_format *, off_t *, off_t *); + +/* Lit une valeur indiquant la taille des adresses mémoire. */ +bool read_address_size(dwarf_format *, off_t *, uint8_t *); + #endif /* _FORMAT_DWARF_UTILS_H */ -- cgit v0.11.2-87-g4458