diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2018-11-24 14:28:22 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2018-11-24 14:28:22 (GMT) | 
| commit | dd851e1fb743d77b421519ee5915534aed2d2c4f (patch) | |
| tree | 9a9f91c09438467ade7a67c5e2188b4051d23569 /plugins/dwarf/utils.c | |
| parent | 59b1bdfdc9b64dac8fd1450c51aa5014c8c469f0 (diff) | |
Updated the DWARF support.
Diffstat (limited to 'plugins/dwarf/utils.c')
| -rw-r--r-- | plugins/dwarf/utils.c | 255 | 
1 files changed, 73 insertions, 182 deletions
| diff --git a/plugins/dwarf/utils.c b/plugins/dwarf/utils.c index b767970..444d3a6 100644 --- a/plugins/dwarf/utils.c +++ b/plugins/dwarf/utils.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * utils.h - prototypes pour les fonctions d'aisance vis à vis du format DWARF   * - * Copyright (C) 2008-2017 Cyrille Bagard + * Copyright (C) 2008-2018 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -24,192 +24,109 @@  #include "utils.h" -#include <string.h> - - -#include "dwarf-int.h" - -  /******************************************************************************  *                                                                             * -*  Paramètres  : format = informations de débogage à consulter.               * -*                pos    = tête de lecture à mettre à jour. [OUT]              * -*                value  = valeur au format LEB128 lue. [OUT]                  * -*                update = indique si la position est à mettre à jour.         * +*  Paramètres  : content = contenu binaire à consulter.                       * +*                pos     = position de début de lecture. [OUT]                * +*                endian  = boutisme reconnu dans le format.                   * +*                header  = en-tête à déterminer. [OUT]                        * +*                next    = position du prochain en-tête. [OUT]                *  *                                                                             * -*  Description : Lit une valeur Little Endian Base 128 signée.                * +*  Description : Procède à la lecture de l'en-tête d'un contenu binaire DWARF.*  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * -*  Remarques   : En cas d'échec, la tête de lecture est indéterminée.         * +*  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value, bool update) +bool read_dwarf_section_header(const GBinContent *content, vmpa2t *pos, SourceEndian endian, dw_section_header *header, vmpa2t *next)  { -    off_t curpos;                           /* Tête de lecture effective   */ -    int shift;                              /* Décalage à appliquer        */ -    off_t i;                                /* Boucle de parcours          */ - -    curpos = *pos; -    shift = 0; -    *value = 0; - -    for (i = 0; i < 8; i++) -    { -        /* On évite les débordements... */ -        if (curpos >= DBG_FORMAT(format)->length) return false; +    bool result;                            /* Bilan à retourner           */ +    uint32_t first;                         /* Premier paquet d'octets     */ +    bool status;                            /* Bilan d'opération           */ -        *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift; +    result = false; -        shift += 7; -        curpos++; +    status = g_binary_content_read_u32(content, pos, endian, &first); +    if (!status) goto rdsh_exit; -        if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break; +    if (first >= 0xfffffff0 && first != 0xffffffff) +        goto rdsh_exit; +    if (first == 0xffffffff) +    { +        result = g_binary_content_read_u64(content, pos, endian, &header->unit_length); +        header->is_32b = false;      } - -    if ((shift < 64) && (DBG_FORMAT(format)->content[curpos - 1] & 0x40) == 0x40) -        *value |= - (1 << shift); - -    if (update) *pos = curpos; - -    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]                  * -*                update = indique si la position est à mettre à jour.         * -*                                                                             * -*  Description : Lit une valeur Little Endian Base 128 non signée.            * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : En cas d'échec, la tête de lecture est indéterminée.         * -*                                                                             * -******************************************************************************/ - -bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value, bool update) -{ -    off_t curpos;                           /* Tête de lecture effective   */ -    int shift;                              /* Décalage à appliquer        */ -    off_t i;                                /* Boucle de parcours          */ - -    curpos = *pos; -    shift = 0; -    *value = 0; - -    for (i = 0; i < 8; i++) +    else      { -        /* On évite les débordements... */ -        if (curpos >= DBG_FORMAT(format)->length) return false; - -        *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift; - -        shift += 7; -        curpos++; - -        if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break; +        result = true; +        header->unit_length = first; +        header->is_32b = true; +    } +    if (next != NULL) +    { +        copy_vmpa(next, pos); +        advance_vmpa(next, header->unit_length);      } -    if (update) *pos = curpos; +    result &= g_binary_content_read_u16(content, pos, endian, &header->version); + + rdsh_exit: -    return (i < 8); +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : format = informations de débogage à consulter.               * -*                pos    = tête de lecture à mettre à jour. [OUT]              * -*                value  = valeur entière lue. [OUT]                           * +*  Paramètres  : content = contenu binaire à consulter.                       * +*                pos     = position de début de lecture. [OUT]                * +*                endian  = boutisme reconnu dans le format.                   * +*                header  = en-tête à déterminer. [OUT]                        * +*                next    = position du prochain en-tête. [OUT]                *  *                                                                             * -*  Description : Lit une valeur représentant une longueur d'unité.            * +*  Description : Procède à la lecture de l'en-tête d'une unité de compilation.*  *                                                                             *  *  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.    * +*  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool read_unit_length(dwarf_format *format, off_t *pos, off_t *value) +bool read_dwarf_compil_unit_header(GBinContent *content, vmpa2t *pos, SourceEndian endian, dw_compil_unit_header *header, vmpa2t *next)  {      bool result;                            /* Bilan à retourner           */ -    uint32_t val32;                         /* Entier sur 4 octets         */ -    uint64_t val64;                         /* Entier sur 8 octets         */ +    uint32_t val32;                         /* Premier paquet d'octets     */ +    bool status;                            /* Bilan d'opération           */ -    /* FIXME : Endian... */ +    result = false; -    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; +    status = read_dwarf_section_header(content, pos, endian, (dw_section_header *)header, next); +    if (!status) goto rdcuh_exit; -            *value = val32; +    if (header->is_32b) +    { +        status = g_binary_content_read_u32(content, pos, endian, &val32); +        if (!status) goto rdcuh_exit; -        } +        header->debug_abbrev_offset = 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; - -        } +        status = g_binary_content_read_u64(content, pos, endian, &header->debug_abbrev_offset); +        if (!status) goto rdcuh_exit;      } -    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 = g_binary_content_read_u8(content, pos, &header->address_size); -    result = ((*pos + 2) <= DBG_FORMAT(format)->length); - -    if (result) -    { -        memcpy(value, &DBG_FORMAT(format)->content[*pos], 2); -        (*pos) += 2; -    } + rdcuh_exit:      return result; @@ -218,53 +135,30 @@ bool read_uhalf(dwarf_format *format, off_t *pos, uint16_t *value)  /******************************************************************************  *                                                                             * -*  Paramètres  : format = informations de débogage à consulter.               * -*                pos    = tête de lecture à mettre à jour. [OUT]              * -*                value  = valeur entière lue. [OUT]                           * +*  Paramètres  : content = contenu binaire à consulter.                       * +*                pos     = position de début de lecture. [OUT]                * +*                decl    = structure lue à retourner. [OUT]                   *  *                                                                             * -*  Description : Lit une valeur indiquant une position dans les abréviations. * +*  Description : Procède à la lecture d'une déclaration d'abréviation DWARF.  *  *                                                                             *  *  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.    * +*  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value) +bool read_dwarf_abbrev_decl(const GBinContent *content, vmpa2t *pos, dw_abbrev_decl *decl)  {      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; +    result = g_binary_content_read_uleb128(content, pos, &decl->code); -        } - -    } -    else +    if (result && decl->code > 0)      { -        result = ((*pos + 8) <= DBG_FORMAT(format)->length); +        result = g_binary_content_read_uleb128(content, pos, &decl->tag);          if (result) -        { -            memcpy(&val64, &DBG_FORMAT(format)->content[*pos], 8); -            (*pos) += 8; - -            *value = val64; - -        } +            result = g_binary_content_read_u8(content, pos, &decl->has_children);      } @@ -275,11 +169,11 @@ bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)  /******************************************************************************  *                                                                             * -*  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]                * +*  Paramètres  : content = contenu binaire à consulter.                       * +*                pos     = position de début de lecture. [OUT]                * +*                attr    = structure lue à retourner. [OUT]                   *  *                                                                             * -*  Description : Lit une valeur indiquant la taille des adresses mémoire.     * +*  Description : Procède à la lecture d'un attribut d'abréviation DWARF.      *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -287,17 +181,14 @@ bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)  *                                                                             *  ******************************************************************************/ -bool read_address_size(dwarf_format *format, off_t *pos, uint8_t *value) +bool read_dwarf_abbrev_attr(const GBinContent *content, vmpa2t *pos, dw_abbrev_raw_attr *attr)  {      bool result;                            /* Bilan à retourner           */ -    result = ((*pos + 1) <= DBG_FORMAT(format)->length); +    result = g_binary_content_read_uleb128(content, pos, &attr->name);      if (result) -    { -        *value = DBG_FORMAT(format)->content[*pos]; -        (*pos)++; -    } +        result = g_binary_content_read_uleb128(content, pos, &attr->form);      return result; | 
