From 1b2ad075c4929cfc2b1efe9ff633a12c31dc7594 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 22 Aug 2008 21:57:08 +0000
Subject: Made a first try to get all registered prototypes of functions.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@18 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  21 +++
 src/binary.c                 |   2 +
 src/format/dwarf/abbrev.c    |  95 +++++++---
 src/format/dwarf/abbrev.h    |   9 +-
 src/format/dwarf/dwarf-int.h |  14 ++
 src/format/dwarf/info.c      | 413 ++++++++++++++++++++++++++++++++++++++++++-
 src/format/dwarf/utils.c     |  36 ++--
 src/format/dwarf/utils.h     |   4 +-
 8 files changed, 542 insertions(+), 52 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f34d4fa..4969bee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2008-08-22  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/binary.c:
+	Skip the GUI display.
+
+	* src/format/dwarf/abbrev.c:
+	* src/format/dwarf/abbrev.h:
+	Make abbreviation codes unsigned. Clean the code. Add the ability to not
+	update the reading position when reading abbreviation attributes.
+
+	* src/format/dwarf/dwarf-int.h:
+	Add some definitions for registered prototypes of functions.
+
+	* src/format/dwarf/info.c:
+	Make a first try to get all registered prototypes of functions.
+
+	* src/format/dwarf/utils.c:
+	* src/format/dwarf/utils.h:
+	Add the ability to not update the reading position when decoding
+	[U]LEB128. Fix a bug when decoding [U]LEB128 numbers.
+
 2008-08-17  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/format/dwarf/abbrev.c:
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 *);
-- 
cgit v0.11.2-87-g4458