diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/binary.c | 2 | ||||
| -rw-r--r-- | src/format/dwarf/abbrev.c | 95 | ||||
| -rw-r--r-- | src/format/dwarf/abbrev.h | 9 | ||||
| -rw-r--r-- | src/format/dwarf/dwarf-int.h | 14 | ||||
| -rw-r--r-- | src/format/dwarf/info.c | 413 | ||||
| -rw-r--r-- | src/format/dwarf/utils.c | 36 | ||||
| -rw-r--r-- | src/format/dwarf/utils.h | 4 | 
7 files changed, 521 insertions, 52 deletions
| diff --git a/src/binary.c b/src/binary.c index 9c0fefb..4938b0f 100644 --- a/src/binary.c +++ b/src/binary.c @@ -160,9 +160,11 @@ void fill_snippet(GtkSnippet *snippet)      /*find_line_info(bin_data, &len);*/ +      printf("Exiting...\n");      exit(0); +      offset = base; diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 2eec460..a9fee2c 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -41,13 +41,13 @@  void free_dwarf_abbrev(dw_abbrev *);  /* Charge une abréviations DWARF. */ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_t *); +dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, uint64_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, ...); +bool _read_dwarf_abbrev_attribute(dwarf_format *, off_t *, DwarfForm, ...); @@ -80,7 +80,7 @@ bool load_dwarf_abbreviations(dwarf_format *format)      dw_abbrev *abbrev; -    int64_t index; +    uint64_t index;      printf("Searching...\n"); @@ -202,13 +202,13 @@ void free_dwarf_abbrev(dw_abbrev *abbrev)  *                                                                             *  ******************************************************************************/ -dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *index) +dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, uint64_t *index)  {      dw_abbrev *result;                      /* Abréviation à retourner     */      bool has_children;                      /* Indique la présence de fils */ -    int64_t value1;                         /* Valeur quelconque lue #1    */ -    int64_t value2;                         /* Valeur quelconque lue #2    */ -    int64_t sub_index;                      /* Indice d'un sous-élément    */ +    uint64_t value1;                        /* Valeur quelconque lue #1    */ +    uint64_t value2;                        /* Valeur quelconque lue #2    */ +    uint64_t sub_index;                     /* Indice d'un sous-élément    */      dw_abbrev *child;                       /* Sous-élément à intégrer     */      result = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); @@ -216,9 +216,9 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i      result->offset = *pos;      /* Code de l'élément */ -    if (!read_leb128(format, pos, index)) goto rda_error; +    if (!read_uleb128(format, pos, index, true)) goto rda_error; -    if (!read_leb128(format, pos, &value1)) goto rda_error; +    if (!read_uleb128(format, pos, &value1, true)) goto rda_error;      result->tag = value1;      printf(" --ta :: 0x%02llx\n", value1); @@ -232,8 +232,8 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i      while (DBG_FORMAT(format)->content[*pos] != 0x00)      { -        if (!read_leb128(format, pos, &value1)) goto rda_error; -        if (!read_leb128(format, pos, &value2)) goto rda_error; +        if (!read_uleb128(format, pos, &value1, true)) goto rda_error; +        if (!read_uleb128(format, pos, &value2, true)) goto rda_error;          result->attribs = (dw_abbrev_attr *)realloc(result->attribs, ++result->attribs_count * sizeof(dw_abbrev_attr)); @@ -305,11 +305,34 @@ const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *ind  } +const dw_abbrev *find_dwarf_abbreviations_old(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 à consulter.               *  *                offset = position dans les abréviations.                     * -*                index  = code de l'abréviation.                              * +*                pos    = position dans le flux binaire courant. [OUT]        *  *                                                                             *  *  Description : Recherche une abréviation DWARF donnée.                      *  *                                                                             * @@ -319,15 +342,24 @@ const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *ind  *                                                                             *  ******************************************************************************/ -const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, uint8_t index) +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, off_t *pos)  {      const dw_abbrev *result;                /* Structure à retourner       */ +    uint64_t index;                         /* Code de l'abréviation       */      size_t i;                               /* Boucle de parcours          */ -    if (index == 0) return NULL; -      result = NULL; +    do +    { +        if (!read_uleb128(format, pos, &index, true)) +        { +            printf("error skipping padding...\n"); +            return NULL; +        } +    } +    while (index == 0); +      for (i = 0; i < format->abbrevs_count; i++)          if (format->abbrevs[i]->offset == *offset) break; @@ -347,7 +379,6 @@ const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *off  *  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.                           * @@ -358,7 +389,7 @@ const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *off  *                                                                             *  ******************************************************************************/ -bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, DwarfAttrib attrib, ...) +bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, ...)  {      bool result;                            /* Bilan à revoyer             */      va_list ap;                             /* Adresse fournie en dernier  */ @@ -376,7 +407,7 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo      char **strval;                          /* Chaîne de caractères        */      size_t length;                          /* Taille d'une chaîne         */ -    va_start(ap, attrib); +    va_start(ap, form);      switch (form)      { @@ -486,11 +517,12 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo                      if (strval != NULL)                          (*strval)[length] = 0; +                  } -                else +                else if (strval != NULL)                  { -                    if (strval != NULL) -                        free(*strval); +                    free(*strval); +                    *strval = NULL;                  }              } @@ -498,7 +530,7 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo              break;          case DWF_BLOCK: -            result = read_uleb128(format, pos, &size_to_read); +            result = read_uleb128(format, pos, &size_to_read, true);              result &= ((*pos + size_to_read) <= DBG_FORMAT(format)->length);              if (result)              { @@ -550,6 +582,11 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo              result = read_abbrev_offset(format, pos, &offset);              if (result)              { +                if (va_arg(ap, bool *) != NULL) +                { +                    printf("TODO\n"); +                    exit(0); +                }                  /*                  boolval = va_arg(ap, bool *);                  if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00); @@ -649,6 +686,7 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo  *                                                                             *  *  Paramètres  : format = informations de débogage à compléter.               *  *                pos    = tête de lecture à mettre à jour. [OUT]              * +*                update = indique si la position est à mettre à jour.         *  *                abbrev = informations à parcourir.                           *  *                attrib = attribut visé par la lecture.                       *  *                ...    = lieu d'enregistrement ou NULL. [OUT]                * @@ -661,24 +699,27 @@ bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm fo  *                                                                             *  ******************************************************************************/ -bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev, DwarfAttrib attrib, ...) +bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, bool update, const dw_abbrev *abbrev, DwarfAttrib attrib, ...)  {      bool result;                            /* Bilan à retourner           */ +    off_t curpos;                           /* Tête de lecture effective   */      size_t i;                               /* Boucle de parcours          */      va_list ap;                             /* Adresse fournie en dernier  */      result = true; +    curpos = *pos; +      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); +        else result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, 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 *)); +            result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, va_arg(ap, void *));          else              result = false; @@ -686,6 +727,8 @@ bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbr      } +    if (result && update) *pos = curpos; +      return result;  } @@ -713,7 +756,7 @@ bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev      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); +        result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, NULL);      return result; diff --git a/src/format/dwarf/abbrev.h b/src/format/dwarf/abbrev.h index 0839287..cbc394e 100644 --- a/src/format/dwarf/abbrev.h +++ b/src/format/dwarf/abbrev.h @@ -39,11 +39,14 @@ bool load_dwarf_abbreviations(dwarf_format *);  /* 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); +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *find_dwarf_abbreviations_old(dwarf_format *, const off_t *, uint8_t); + +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *find_dwarf_abbreviations(dwarf_format *, const off_t *, off_t *);  /* Lit la valeur d'un attribut DWARF. */ -bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, const dw_abbrev *, DwarfAttrib, ...); +bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, bool, 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 *); diff --git a/src/format/dwarf/dwarf-int.h b/src/format/dwarf/dwarf-int.h index 52130f8..4863bfe 100644 --- a/src/format/dwarf/dwarf-int.h +++ b/src/format/dwarf/dwarf-int.h @@ -69,6 +69,17 @@ typedef struct _dw_abbrev  } dw_abbrev; +/* Eléments récupérés sur une fonction */ +typedef struct _dw_dbg_function +{ +    char *name;                             /* Nom de la fonction          */ +    char *prototype;                        /* Chaîne descriptive          */ + +    uint64_t low_pc;                        /* Début de la fonction        */ +    uint64_t high_pc;                       /* Fin de la fonction          */ + +} dw_dbg_function; +  /* Description du format DWARF */ @@ -81,6 +92,9 @@ struct _dwarf_format      dw_abbrev **abbrevs;                    /* Liste des abréviations      */      size_t abbrevs_count;                   /* Nombre de ces abréviations  */ +    dw_dbg_function dbg_functions;          /* Liste de fonctions trouvées */ +    size_t dbg_fc_count;                    /* Nombre de ces fonctions     */ +  }; diff --git a/src/format/dwarf/info.c b/src/format/dwarf/info.c index 0dc5048..30d2391 100644 --- a/src/format/dwarf/info.c +++ b/src/format/dwarf/info.c @@ -25,6 +25,7 @@  #include <malloc.h> +#include <string.h>  #include "abbrev.h" @@ -35,6 +36,7 @@  /* Informations utiles d'une unité de compilation */  typedef struct _compil_unit  { +    off_t startpos;                         /* Position de début d'unité   */      off_t endpos;                           /* Position d'unité suivante   */      off_t offset;                           /* Position dans les abréviat° */ @@ -51,6 +53,8 @@ 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 *); +/* Obtient la description humaine d'un type. */ +char *resolve_dwarf_function_type(dwarf_format *, const dw_abbrev *, const off_t *, const compil_unit *); @@ -177,6 +181,8 @@ bool read_dwarf_compilation_unit(dwarf_format *format, off_t *pos, compil_unit *      result = true; +    cu->startpos = *pos; +      if (read_unit_length(format, pos, &ulength))          printf("Unit Length :: %d  (0x%x)\n", ulength, ulength); @@ -250,17 +256,45 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u      off_t oldpos; +    off_t oldpos2;      const dw_abbrev *abbrev; +    const dw_abbrev *subabbrev; +    const dw_abbrev *subabbrev2; +    char *name;      uint64_t low_pc;      uint64_t high_pc; +    uint32_t type_pos; +    char *retstr; + +    uint64_t tempo; + +    size_t i;                               /* Boucle de parcours          */ + +    char *prototype = NULL; +    size_t proto_len = 0; + + + +    bool first_arg;                         /* Marque le 1er argument      */ +    bool is_pointer;                        /* Mémorise le type 'pointeur' */ +      while (*pos < cu->endpos)      { + +        printf(" =+> Cur :: 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]); + +          if (read_address_size/*leb128*/(format, pos, &index))              printf("abbrev index :: %hhd\n", index);          else printf("abbrev index error\n"); @@ -269,7 +303,13 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u          if (index == 0) continue; -        abbrev = find_dwarf_abbreviations(format, &cu->offset, index); +        abbrev = find_dwarf_abbreviations_old(format, &cu->offset, index); + + + + + +        //abbrev = find_dwarf_abbreviations(format, &cu->offset, pos);          printf(" --> %p\n", abbrev); @@ -283,16 +323,257 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u          { -        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"); +            if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_NAME, &name)) +                printf(" ## Name :: %s\n", name); +            else printf(" error: no name\n"); + + +            if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_LOW_PC, &low_pc)) +                printf(" ## LOW PC :: 0x%08x\n", low_pc); +            else printf(" error: no low pc\n"); + + +            if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_HIGH_PC, &high_pc)) +                printf(" ## HIGH PC :: 0x%08x\n", high_pc); +            else printf(" error: no high pc\n"); + + + +            /* Type de la fonction */ + +            if (read_dwarf_abbrev_attribute(format, &oldpos, false, abbrev, DWA_TYPE, &type_pos)) +                printf(" ## type :: 0x%08x\n", type_pos); +            else printf(" error: no type\n"); + + +            oldpos = cu->startpos + type_pos; + + + + +            subabbrev2 = find_dwarf_abbreviations(format, &cu->offset, &oldpos); + +            retstr = resolve_dwarf_function_type(format, subabbrev2, &oldpos, cu); + +            if (retstr == NULL) +            { +                proto_len += 3; +                prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                strcat(prototype, "???"); + +                is_pointer = false; + +            } +            else +            { +                proto_len += strlen(retstr); +                prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                strcat(prototype, retstr); + +                is_pointer = (retstr[strlen(retstr) - 1] == '*'); + +                free(retstr); + +            } + + + + +            /* On saute l'abréviation de la déclaration de fonction... */ + +            oldpos = *pos; + +            if (!read_uleb128(format, &oldpos, &tempo, true)) +                printf("error skipping index\n"); + +            if (!skip_dwarf_abbrev(format, &oldpos, abbrev)) +                printf("error skipping\n"); + +            do +            { +                if (!read_uleb128(format, &oldpos, &tempo, false)) +                    printf("error skipping padding...\n"); + +                if (tempo == 0) +                    read_uleb128(format, &oldpos, &tempo, true); + +            } +            while (tempo == 0); + +            /* Lecture des différents arguments */ + +            proto_len += (!is_pointer ? 1 : 0) + strlen(name) + 1; +            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +            if (!is_pointer) strcat(prototype, " "); +            strcat(prototype, name); +            strcat(prototype, "("); + +            first_arg = true; + +            while (1) +            { +                subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); +                printf("subabbrev == %p\n", subabbrev); + +                switch (subabbrev->tag) +                { +                    case DWT_UNSPECIFIED_PARAMETERS: + +                        /* Virgule de séparation */ + +                        if (first_arg) first_arg = false; +                        else +                        { +                            proto_len += 2; +                            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                            strcat(prototype, ", "); +                        } + +                        /* Marque de l'absence de type */ + +                        proto_len += 3; +                        prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                        strcat(prototype, "..."); + +                        break; + +                    case DWT_FORMAL_PARAMETER: + + + +                        oldpos2 = oldpos; + + + +                        if (read_dwarf_abbrev_attribute(format, &oldpos2, true, subabbrev, DWA_TYPE, &type_pos)) +                            printf(" ## type :: 0x%08x\n", type_pos); +                        else printf(" error: no type\n"); + +                        oldpos2 = cu->startpos + type_pos; + + + + +            printf(" =+> Next arg :: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n", +                   DBG_FORMAT(format)->content[oldpos2], +                   DBG_FORMAT(format)->content[oldpos2 + 1], +                   DBG_FORMAT(format)->content[oldpos2 + 2], +                   DBG_FORMAT(format)->content[oldpos2 + 3], +                   DBG_FORMAT(format)->content[oldpos2 + 4]); + + + + +                        subabbrev2 = find_dwarf_abbreviations(format, &cu->offset, &oldpos2); +                        printf("subabbrev2 == %p\n", subabbrev2); + + + + +                        retstr = resolve_dwarf_function_type(format, subabbrev2, &oldpos2, cu); +                        printf("  ----) '%s'\n", retstr); + +                        /* Virgule de séparation */ + +                        if (first_arg) first_arg = false; +                        else +                        { +                            proto_len += 2; +                            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                            strcat(prototype, ", "); +                        } + +                        /* Type de l'argument */ + +                        if (retstr == NULL) +                        { +                            proto_len += 3; +                            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                            strcat(prototype, "???"); + +                            is_pointer = false; + +                        } +                        else +                        { +                            proto_len += strlen(retstr); +                            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                            strcat(prototype, retstr); + +                            is_pointer = (retstr[strlen(retstr) - 1] == '*'); + +                            free(retstr); + +                        } + + + +                        oldpos2 = oldpos; + +                        if (read_dwarf_abbrev_attribute(format, &oldpos2, true, subabbrev, DWA_NAME, &retstr)) +                            printf(" ## Name :: %s\n", retstr); +                        else printf(" error: no name\n"); + + +                        if (retstr != NULL) +                        { +                            proto_len += strlen(retstr) + (!is_pointer ? 1 : 0) + 1; +                            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +                            if (!is_pointer) strcat(prototype, " "); +                            strcat(prototype, retstr); + +                            free(retstr); + +                        } + + + + + + + +                        break; + +                    default: +                        goto exit_loop; +                        break; + +                } + +                if (!skip_dwarf_abbrev(format, &oldpos, subabbrev)) +                    printf("error skipping\n"); + +                /* +                do +                { +                    if (!read_uleb128(format, &oldpos, &tempo, false)) +                        printf("error skipping padding...\n"); + +                    if (tempo == 0) +                        read_uleb128(format, &oldpos, &tempo, true); + +                } +                while (tempo == 0); +                */ + +            } + +            exit_loop: + +            proto_len += 1; +            prototype = (char *)realloc(prototype, (proto_len + 1) * sizeof(char)); +            strcat(prototype, ")"); + +            printf(" |\n"); +            printf(" | %s\n", prototype); +            printf(" |\n"); + +            prototype = NULL; +            proto_len = 0; + -        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");          } @@ -322,3 +603,119 @@ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_u      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations de débogage à compléter.               * +*                abbrev = abréviation associée au type.                       * +*                pos    = tête de lecture à avoir sous le coude.              * +*                cu     = unité de compilation courante.                      * +*                                                                             * +*  Description : Obtient la description humaine d'un type.                    * +*                                                                             * +*  Retour      : Chaîne de caractères en cas de succès, NULL sinon.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *resolve_dwarf_function_type(dwarf_format *format, const dw_abbrev *abbrev, const off_t *pos, const compil_unit *cu) +{ +    char *result;                           /* Description à retourner     */ +    off_t oldpos;                           /* Conservation de l'indice    */ +    uint32_t type_pos;                      /* Sous-type détecté           */ +    uint64_t index;                         /* Indice de l'abréviation...  */ +    const dw_abbrev *subabbrev;             /* ... et abréviation associée */ +    size_t len;                             /* Longeur d'un résultat       */ + +    result = NULL; +    oldpos = *pos; + +    switch (abbrev->tag) +    { +        case DWT_BASE_TYPE: +            oldpos = *pos; +            read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_NAME, &result); +            break; + +        case DWT_POINTER_TYPE: + +            if (read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_TYPE, &type_pos)) +                printf(" ## sub type :: 0x%08x\n", type_pos); +            else printf(" error: no type\n"); + +            oldpos = cu->startpos + type_pos; + + +            subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); +            printf("subabbrev == %p\n", subabbrev); + + + + +            result = resolve_dwarf_function_type(format, subabbrev, &oldpos, cu); + +            if (result != NULL) +            { +                len = strlen(result); + +                if (result[len - 1] == '*') +                { +                    result = (char *)realloc(result, (len + 2) * sizeof(char)); +                    result[len] = '*'; +                } +                else +                { +                    result = (char *)realloc(result, (len + 3) * sizeof(char)); +                    strcat(result, " *"); +                } + +            } + +            break; + +        case DWT_CONST_TYPE: + + + +            if (read_dwarf_abbrev_attribute(format, &oldpos, true, abbrev, DWA_TYPE, &type_pos)) +                printf(" ## sub type :: 0x%08x\n", type_pos); +            else printf(" error: no type\n"); + +            oldpos = cu->startpos + type_pos; + + + + + + +            subabbrev = find_dwarf_abbreviations(format, &cu->offset, &oldpos); +            printf("subabbrev == %p\n", subabbrev); + + + + +            result = resolve_dwarf_function_type(format, subabbrev, &oldpos, cu); + +            if (result != NULL) +            { +                len = strlen(result); + +                result = (char *)realloc(result, (len + strlen("const ") + 1) * sizeof(char)); +                memmove(&result[strlen("const ")], result, len); +                memcpy(result, "const ", strlen("const ")); + +            } + +            break; + +        default: +            printf("### NOT HANDLED ### Tag :: 0x%02x\n", abbrev->tag); +            break; + +    } + +    return result; + +} diff --git a/src/format/dwarf/utils.c b/src/format/dwarf/utils.c index fa8ef20..359cc52 100644 --- a/src/format/dwarf/utils.c +++ b/src/format/dwarf/utils.c @@ -36,40 +36,45 @@  *  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 signée.                *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * -*  Remarques   : -                                                            * +*  Remarques   : En cas d'échec, la tête de lecture est indéterminée.         *  *                                                                             *  ******************************************************************************/ -bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value) +bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value, bool update)  { +    off_t curpos;                           /* Tête de lecture effective   */      int shift;                              /* Décallage à 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 ((*pos + i) >= DBG_FORMAT(format)->length) return false; +        if (curpos >= DBG_FORMAT(format)->length) return false; -        *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift; +        *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift;          shift += 7; -        (*pos)++; +        curpos++; -        if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break; +        if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break;      } -    if ((shift < 64) && (DBG_FORMAT(format)->content[*pos - 1] & 0x40) == 0x40) +    if ((shift < 64) && (DBG_FORMAT(format)->content[curpos - 1] & 0x40) == 0x40)          *value |= - (1 << shift); +    if (update) *pos = curpos; +      return (i < 8);  } @@ -80,37 +85,42 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value)  *  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   : -                                                            * +*  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 read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value, bool update)  { +    off_t curpos;                           /* Tête de lecture effective   */      int shift;                              /* Décallage à 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 ((*pos + i) >= DBG_FORMAT(format)->length) return false; +        if (curpos >= DBG_FORMAT(format)->length) return false; -        *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift; +        *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift;          shift += 7; -        (*pos)++; +        curpos++; -        if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break; +        if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break;      } +    if (update) *pos = curpos; +      return (i < 8);  } diff --git a/src/format/dwarf/utils.h b/src/format/dwarf/utils.h index fc5b3fc..e5102e2 100644 --- a/src/format/dwarf/utils.h +++ b/src/format/dwarf/utils.h @@ -34,10 +34,10 @@  /* Lit une valeur Little Endian Base 128 signée. */ -bool read_leb128(dwarf_format *, off_t *, int64_t *); +bool read_leb128(dwarf_format *, off_t *, int64_t *, bool);  /* Lit une valeur Little Endian Base 128 non signée. */ -bool read_uleb128(dwarf_format *, off_t *, uint64_t *); +bool read_uleb128(dwarf_format *, off_t *, uint64_t *, bool);  /* Lit une valeur représentant une longueur d'unité. */  bool read_unit_length(dwarf_format *, off_t *, off_t *); | 
