summaryrefslogtreecommitdiff
path: root/src/format/dwarf/info.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/dwarf/info.c')
-rw-r--r--src/format/dwarf/info.c413
1 files changed, 405 insertions, 8 deletions
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;
+
+}