summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-08-22 21:57:08 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-08-22 21:57:08 (GMT)
commit1b2ad075c4929cfc2b1efe9ff633a12c31dc7594 (patch)
tree9c535020b1519b0f94513cab561adeb8f4b212cc
parentf6f110acb8bf3243dffc527271c17619a078fcc4 (diff)
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
-rw-r--r--ChangeLog21
-rw-r--r--src/binary.c2
-rw-r--r--src/format/dwarf/abbrev.c95
-rw-r--r--src/format/dwarf/abbrev.h9
-rw-r--r--src/format/dwarf/dwarf-int.h14
-rw-r--r--src/format/dwarf/info.c413
-rw-r--r--src/format/dwarf/utils.c36
-rw-r--r--src/format/dwarf/utils.h4
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 *);