diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/format/dwarf/Makefile.am | 1 | ||||
| -rw-r--r-- | src/format/dwarf/abbrev.c | 488 | ||||
| -rw-r--r-- | src/format/dwarf/abbrev.h | 14 | ||||
| -rw-r--r-- | src/format/dwarf/d_dwarf.c | 5 | ||||
| -rw-r--r-- | src/format/dwarf/dwarf-int.h | 14 | ||||
| -rw-r--r-- | src/format/dwarf/info.c | 324 | ||||
| -rw-r--r-- | src/format/dwarf/info.h | 43 | ||||
| -rw-r--r-- | src/format/dwarf/utils.c | 223 | ||||
| -rw-r--r-- | src/format/dwarf/utils.h | 16 | 
9 files changed, 1108 insertions, 20 deletions
| 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 <malloc.h> +#include <stdarg.h> +#include <string.h> -#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 <http://www.gnu.org/licenses/>. + */ + + +#include "info.h" + + +#include <malloc.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_DWARF_INFO_H +#define _FORMAT_DWARF_INFO_H + + +#include <stdbool.h> + + +#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 <string.h> + +  #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 <stdbool.h> +#include <stdint.h>  #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 */ | 
