summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-08-17 21:13:03 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-08-17 21:13:03 (GMT)
commitf6f110acb8bf3243dffc527271c17619a078fcc4 (patch)
tree1e543cdf23b7bb646f36a51d21d18b91b92706c8
parenta13b6baeeea114919d0e9eb25e35657b144437dc (diff)
Looked for prototyped functions using the registered abbreviations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@17 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog24
-rw-r--r--src/format/dwarf/Makefile.am1
-rw-r--r--src/format/dwarf/abbrev.c488
-rw-r--r--src/format/dwarf/abbrev.h14
-rw-r--r--src/format/dwarf/d_dwarf.c5
-rw-r--r--src/format/dwarf/dwarf-int.h14
-rw-r--r--src/format/dwarf/info.c324
-rw-r--r--src/format/dwarf/info.h43
-rw-r--r--src/format/dwarf/utils.c223
-rw-r--r--src/format/dwarf/utils.h16
10 files changed, 1132 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 6971ba6..f34d4fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2008-08-17 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/format/dwarf/abbrev.c:
+ * src/format/dwarf/abbrev.h:
+ Add several functions to process the parsed abbreviations.
+
+ * src/format/dwarf/d_dwarf.c:
+ Improve the loading thanks to the new features.
+
+ * src/format/dwarf/dwarf-int.h:
+ Specify a format (32 or 64 bits) and refine the abbreviation definition.
+
+ * src/format/dwarf/info.c:
+ * src/format/dwarf/info.h:
+ New entries: look for prototyped functions using the registered
+ abbreviations.
+
+ * src/format/dwarf/Makefile.am:
+ Add info.[ch] to libformatdwarf_a_SOURCES.
+
+ * src/format/dwarf/utils.c:
+ * src/format/dwarf/utils.h:
+ Read more values: uleb128, unit length, uhalf, offset and address size.
+
2008-08-10 Cyrille Bagard <nocbos@gmail.com>
* src/format/dwarf/abbrev.c:
diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am
index 6103ac2..507a50e 100644
--- a/src/format/dwarf/Makefile.am
+++ b/src/format/dwarf/Makefile.am
@@ -5,6 +5,7 @@ libformatdwarf_a_SOURCES = \
abbrev.h abbrev.c \
d_dwarf.h d_dwarf.c \
dwarf_def.h \
+ info.h info.c \
utils.h utils.c
libformatdwarf_a_CFLAGS = $(AM_CFLAGS)
diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c
index 6eada92..2eec460 100644
--- a/src/format/dwarf/abbrev.c
+++ b/src/format/dwarf/abbrev.c
@@ -25,9 +25,10 @@
#include <malloc.h>
+#include <stdarg.h>
+#include <string.h>
-#include "dwarf-int.h"
#include "utils.h"
@@ -42,13 +43,19 @@ void free_dwarf_abbrev(dw_abbrev *);
/* Charge une abréviations DWARF. */
dw_abbrev *read_dwarf_abbreviations(dwarf_format *, off_t *, int64_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, ...);
+
/******************************************************************************
* *
* Paramètres : format = informations de débogage à compléter. *
* *
-* Description : Charge les abréviations trouvés pour un DWARF. *
+* Description : Charge les abréviations trouvées pour un DWARF. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -70,7 +77,6 @@ bool load_dwarf_abbreviations(dwarf_format *format)
bool test;
int i;
- int j;
dw_abbrev *abbrev;
@@ -94,14 +100,6 @@ bool load_dwarf_abbreviations(dwarf_format *format)
{
if (i % 10 == 0) printf("\n");
printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]);
-
- if ((i + 1) % 10 == 0)
- {
- printf("\t\t");
- for (j = 0; j < 10; j++)
- printf("%c", (isprint(DBG_FORMAT(format)->content[offset + i]) ? DBG_FORMAT(format)->content[offset + i] : '.'));
- }
-
}
printf("\n");
@@ -119,6 +117,8 @@ bool load_dwarf_abbreviations(dwarf_format *format)
if (abbrev != NULL)
{
+ abbrev->offset -= start;
+
format->abbrevs = (dw_abbrev **)realloc(format->abbrevs, ++format->abbrevs_count * sizeof(dw_abbrev *));
format->abbrevs[format->abbrevs_count - 1] = abbrev;
@@ -143,7 +143,7 @@ bool load_dwarf_abbreviations(dwarf_format *format)
* *
* Paramètres : format = informations de débogage à effacer. *
* *
-* Description : Décharge les abréviations trouvés pour un DWARF. *
+* Description : Décharge les abréviations trouvées pour un DWARF. *
* *
* Retour : - *
* *
@@ -194,7 +194,7 @@ void free_dwarf_abbrev(dw_abbrev *abbrev)
* pos = tête de lecture à mettre à jour. [OUT] *
* index = code de l'abréviation. [OUT] *
* *
-* Description : Charge une abréviations DWARF. *
+* Description : Charge une abréviation DWARF. *
* *
* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
* *
@@ -211,17 +211,23 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i
int64_t sub_index; /* Indice d'un sous-élément */
dw_abbrev *child; /* Sous-élément à intégrer */
- /* Code de l'élément */
- if (!read_leb128(format, pos, index)) return NULL;
-
result = (dw_abbrev *)calloc(1, sizeof(dw_abbrev));
+ result->offset = *pos;
+
+ /* Code de l'élément */
+ if (!read_leb128(format, pos, index)) goto rda_error;
+
if (!read_leb128(format, pos, &value1)) goto rda_error;
result->tag = value1;
+ printf(" --ta :: 0x%02llx\n", value1);
+
if (*pos >= DBG_FORMAT(format)->length) goto rda_error;
has_children = (DBG_FORMAT(format)->content[(*pos)++] == DW_CHILDREN_YES);
+ printf(" --ch ? %d\n", has_children);
+
/* Liste des attributs */
while (DBG_FORMAT(format)->content[*pos] != 0x00)
@@ -247,7 +253,7 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i
if (child == NULL) goto rda_error;
- //if ((sub_index - *index - 1) != result->children_count) goto rda_error;
+ if ((sub_index - *index - 1) != result->children_count) goto rda_error;
result->children = (dw_abbrev **)realloc(result->children, ++result->children_count * sizeof(dw_abbrev *));
@@ -264,3 +270,451 @@ dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, int64_t *i
return NULL;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : abbrev = abréviation racine à parcourir. *
+* index = code de l'abréviation. [OUT] *
+* *
+* Description : Recherche une abréviation DWARF donnée. *
+* *
+* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uint8_t *index)
+{
+ const dw_abbrev *result; /* Structure à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = NULL;
+
+ if (*index == 0) result = abbrev;
+ else
+ for (i = 0; i < abbrev->children_count && result == NULL; i++)
+ {
+ (*index)--;
+ result = _find_dwarf_abbreviations(abbrev->children[i], index);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* offset = position dans les abréviations. *
+* index = code de l'abréviation. *
+* *
+* Description : Recherche une abréviation DWARF donnée. *
+* *
+* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const dw_abbrev *find_dwarf_abbreviations(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 à 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. *
+* *
+* Retour : true si la lecture est un succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, DwarfForm form, DwarfAttrib attrib, ...)
+{
+ bool result; /* Bilan à revoyer */
+ va_list ap; /* Adresse fournie en dernier */
+ uint8_t *val8; /* Données sur 8 bits */
+ uint16_t *val16; /* Données sur 16 bits */
+ uint32_t *val32; /* Données sur 32 bits */
+ uint64_t *val64; /* Données sur 64 bits */
+ bool *boolval; /* Valeur booléenne */
+ uint8_t tmp8; /* Données sur 8 bits */
+ uint16_t tmp16; /* Données sur 16 bits */
+ uint32_t tmp32; /* Données sur 32 bits */
+ uint64_t tmp64; /* Données sur 64 bits */
+ uint64_t size_to_read; /* Nombre d'octets à lire */
+ off_t offset; /* Décallage dans une zone */
+ char **strval; /* Chaîne de caractères */
+ size_t length; /* Taille d'une chaîne */
+
+ va_start(ap, attrib);
+
+ switch (form)
+ {
+ case DWF_ADDR:
+ result = ((*pos + (format->format == DWF_32_BITS ? 4 : 8)) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val64 = va_arg(ap, uint64_t *);
+ if (val64 != NULL)
+ {
+ if (format->format == DWF_32_BITS)
+ {
+ tmp32 = *((uint32_t *)&DBG_FORMAT(format)->content[*pos]);
+ //memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4);
+ *val64 = tmp32;
+ }
+ else memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8);
+ }
+ *pos += (format->format == DWF_32_BITS ? 4 : 8);
+ }
+ break;
+
+ case DWF_BLOCK2:
+ result = ((*pos + 2) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ memcpy(&tmp16, &DBG_FORMAT(format)->content[*pos], 2);
+ size_to_read = tmp16;
+ /* ... */
+ *pos += 2 + size_to_read;
+ }
+ break;
+
+ case DWF_BLOCK4:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ memcpy(&tmp32, &DBG_FORMAT(format)->content[*pos], 4);
+ size_to_read = tmp32;
+ /* ... */
+ *pos += 4 + size_to_read;
+ }
+ break;
+
+ case DWF_DATA2:
+ result = ((*pos + 2) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val16 = va_arg(ap, uint16_t *);
+ if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2);
+ *pos += 2;
+ }
+ break;
+
+ case DWF_DATA4:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val32 = va_arg(ap, uint32_t *);
+ if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4);
+ *pos += 4;
+ }
+ break;
+
+ case DWF_DATA8:
+ result = ((*pos + 8) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val64 = va_arg(ap, uint64_t *);
+ if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8);
+ *pos += 8;
+ }
+ break;
+
+ case DWF_STRING:
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ strval = va_arg(ap, char **);
+ if (strval != NULL) *strval = (char *)calloc(1, sizeof(char));
+ length = 0;
+
+ while (result)
+ {
+ if (DBG_FORMAT(format)->content[*pos] == '\0') break;
+
+ length++;
+
+ if (strval != NULL)
+ {
+ *strval = (char *)realloc(*strval, (length + 1) * sizeof(char));
+ (*strval)[length - 1] = DBG_FORMAT(format)->content[*pos];
+ }
+
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (!result) break;
+
+ (*pos)++;
+
+ }
+
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ (*pos)++;
+
+ if (strval != NULL)
+ (*strval)[length] = 0;
+ }
+ else
+ {
+ if (strval != NULL)
+ free(*strval);
+ }
+
+ }
+
+ break;
+
+ case DWF_BLOCK:
+ result = read_uleb128(format, pos, &size_to_read);
+ result &= ((*pos + size_to_read) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ /* ... */
+ *pos += size_to_read;
+ }
+ break;
+
+ case DWF_BLOCK1:
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ memcpy(&tmp8, &DBG_FORMAT(format)->content[*pos], 1);
+ size_to_read = tmp8;
+ /* ... */
+ *pos += 1 + size_to_read;
+ }
+ break;
+
+ case DWF_DATA1:
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val8 = va_arg(ap, uint8_t *);
+ if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1);
+ *pos += 1;
+ }
+ break;
+
+ case DWF_FLAG:
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ boolval = va_arg(ap, bool *);
+ if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00);
+ *pos += 1;
+ }
+ break;
+
+ case DWF_SDATA:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ printf("bad\n"); exit(0);
+
+ break;
+
+
+ case DWF_STRP:
+ result = read_abbrev_offset(format, pos, &offset);
+ if (result)
+ {
+ /*
+ boolval = va_arg(ap, bool *);
+ if (boolval != NULL) *boolval = (DBG_FORMAT(format)->content[*pos] != 0x00);
+ */
+ }
+ break;
+
+
+ case DWF_UDATA:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ printf("bad\n"); exit(0);
+
+ break;
+
+
+ case DWF_REF_ADDR:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ printf("bad\n"); exit(0);
+
+ break;
+
+
+ case DWF_REF1:
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val8 = va_arg(ap, uint8_t *);
+ if (val8 != NULL) memcpy(val8, &DBG_FORMAT(format)->content[*pos], 1);
+ *pos += 1;
+ }
+ break;
+
+ case DWF_REF2:
+ result = ((*pos + 2) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val16 = va_arg(ap, uint16_t *);
+ if (val16 != NULL) memcpy(val16, &DBG_FORMAT(format)->content[*pos], 2);
+ *pos += 2;
+ }
+ break;
+
+ case DWF_REF4:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val32 = va_arg(ap, uint32_t *);
+ if (val32 != NULL) memcpy(val32, &DBG_FORMAT(format)->content[*pos], 4);
+ *pos += 4;
+ }
+ break;
+
+ case DWF_REF8:
+ result = ((*pos + 8) <= DBG_FORMAT(format)->length);
+ if (result)
+ {
+ val64 = va_arg(ap, uint64_t *);
+ if (val64 != NULL) memcpy(val64, &DBG_FORMAT(format)->content[*pos], 8);
+ *pos += 8;
+ }
+ break;
+
+ case DWF_REF_UDATA:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ printf("bad\n"); exit(0);
+
+ break;
+
+
+ case DWF_INDIRECT:
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ printf("bad\n"); exit(0);
+
+ break;
+
+
+
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ va_end(ap);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à compléter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* abbrev = informations à parcourir. *
+* attrib = attribut visé par la lecture. *
+* ... = lieu d'enregistrement ou NULL. [OUT] *
+* *
+* Description : Lit la valeur d'un attribut DWARF. *
+* *
+* Retour : true si la lecture est un succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev, DwarfAttrib attrib, ...)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+ va_list ap; /* Adresse fournie en dernier */
+
+ result = true;
+
+ 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);
+
+ 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 *));
+ else
+ result = false;
+
+ va_end(ap);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à compléter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* abbrev = informations à survoler. *
+* *
+* Description : Fait avancer la tête de lecture d'une seule abréviation. *
+* *
+* Retour : true si l'opération est un succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev)
+{
+ bool result; /* Bilan à revoyer */
+ size_t i; /* Boucle de parcours */
+
+ 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);
+
+ return result;
+
+}
diff --git a/src/format/dwarf/abbrev.h b/src/format/dwarf/abbrev.h
index f375abc..0839287 100644
--- a/src/format/dwarf/abbrev.h
+++ b/src/format/dwarf/abbrev.h
@@ -29,15 +29,25 @@
#include "d_dwarf.h"
+#include "dwarf-int.h"
-/* Charge les abréviations trouvés pour un DWARF. */
+/* Charge les abréviations trouvées pour un DWARF. */
bool load_dwarf_abbreviations(dwarf_format *);
-/* Décharge les abréviations trouvés pour un DWARF. */
+/* 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);
+
+/* Lit la valeur d'un attribut DWARF. */
+bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, 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 *);
+
#endif /* _FORMAT_DWARF_ABBREV_H */
diff --git a/src/format/dwarf/d_dwarf.c b/src/format/dwarf/d_dwarf.c
index 7537e34..17dc711 100644
--- a/src/format/dwarf/d_dwarf.c
+++ b/src/format/dwarf/d_dwarf.c
@@ -29,7 +29,7 @@
#include "abbrev.h"
#include "dwarf-int.h"
-
+#include "info.h"
@@ -63,9 +63,12 @@ dwarf_format *load_dwarf(const uint8_t *content, off_t length, exe_format *e_for
DBG_FORMAT(result)->e_format = e_format;
+ result->format = DWF_32_BITS;
test = load_dwarf_abbreviations(result);
+ test = load_dwarf_information(result);
+
return result;
diff --git a/src/format/dwarf/dwarf-int.h b/src/format/dwarf/dwarf-int.h
index 371d193..52130f8 100644
--- a/src/format/dwarf/dwarf-int.h
+++ b/src/format/dwarf/dwarf-int.h
@@ -34,6 +34,17 @@
+/* Format du DWARF */
+typedef enum _DwarfFormat
+{
+ DWF_32_BITS, /* Mode 32 bits */
+ DWF_64_BITS /* Mode 64 bits */
+
+} DwarfFormat;
+
+
+
+
/* Description d'un attribut d'une abréviation */
typedef struct _dw_abbrev_attr
{
@@ -46,6 +57,7 @@ typedef struct _dw_abbrev_attr
/* Description d'une abréviation */
typedef struct _dw_abbrev
{
+ off_t offset; /* Position dans le corps */
DwarfTag tag; /* Sujet de l'élément */
dw_abbrev_attr *attribs; /* Liste des attributs */
@@ -64,6 +76,8 @@ struct _dwarf_format
{
dbg_format dummy; /* A laisser en premier */
+ DwarfFormat format; /* Format de l'instance */
+
dw_abbrev **abbrevs; /* Liste des abréviations */
size_t abbrevs_count; /* Nombre de ces abréviations */
diff --git a/src/format/dwarf/info.c b/src/format/dwarf/info.c
new file mode 100644
index 0000000..0dc5048
--- /dev/null
+++ b/src/format/dwarf/info.c
@@ -0,0 +1,324 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * info.c - lecture des informations principales du format DWARF
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "info.h"
+
+
+#include <malloc.h>
+
+
+#include "abbrev.h"
+#include "dwarf-int.h"
+#include "utils.h"
+
+
+/* Informations utiles d'une unité de compilation */
+typedef struct _compil_unit
+{
+ off_t endpos; /* Position d'unité suivante */
+
+ off_t offset; /* Position dans les abréviat° */
+ uint8_t ptrsize; /* Taille des adresses mémoire */
+
+} compil_unit;
+
+
+
+
+/* Procède à la lecture d'une unité de compilation. */
+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 *);
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à compléter. *
+* *
+* Description : Charge les informations trouvées dans un DWARF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_dwarf_information(dwarf_format *format)
+{
+ bool result; /* Bilan à renvoyer */
+
+
+
+
+ off_t offset;
+ off_t start;
+ off_t size;
+
+ bool test;
+
+ int i;
+
+
+ compil_unit cu;
+
+
+
+ result = true;
+
+ test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_info", &start, &size, NULL);
+
+ offset = start;
+
+
+ printf(" -> offset=%d size=%d\n", offset, size);
+
+
+
+ for (i = 0; i < size; i++)
+ {
+ if (i % 25 == 0) printf("\n");
+ printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]);
+ }
+
+ printf("\n");
+
+
+
+ while (offset < (start + size) && result)
+ {
+ printf("-------------\n");
+
+ result = read_dwarf_compilation_unit(format, &offset, &cu);
+
+ if (result)
+ look_for_dwarf_subprograms(format, &offset, &cu);
+
+ //break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à effacer. *
+* *
+* Description : Décharge les informations trouvées dans un DWARF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void unload_dwarf_information(dwarf_format *format)
+{
+
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à compléter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* cu = unité de compilation lue. [OUT] *
+* *
+* Description : Procède à la lecture d'une unité de compilation. *
+* *
+* Retour : true en cas de succès de la lecture, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dwarf_compilation_unit(dwarf_format *format, off_t *pos, compil_unit *cu)
+{
+ bool result; /* Bilan à retourner */
+ off_t ulength; /* Taille de l'unité */
+ uint16_t version; /* Version du format DWARF */
+ off_t abbrev_pos; /* Position dans les abréviat° */
+ uint8_t memsize; /* Taille des adresses mémoire */
+
+ off_t oldpos;
+
+ uint8_t index;
+
+
+
+ result = true;
+
+
+ if (read_unit_length(format, pos, &ulength))
+ printf("Unit Length :: %d (0x%x)\n", ulength, ulength);
+
+ else printf("error ul\n");
+
+ cu->endpos = *pos + ulength;
+
+ oldpos = *pos;
+
+ if (read_uhalf(format, pos, &version))
+ printf("version :: %hd\n", version);
+
+ else printf("error version\n");
+
+ if (version > 3) return false;
+
+ if (read_abbrev_offset(format, pos, &abbrev_pos))
+ printf("abbrev offset :: %d\n", abbrev_pos);
+
+ else printf("error abbrev offset\n");
+
+ if (read_address_size(format, pos, &memsize))
+ printf("mem size :: %hhd\n", memsize);
+
+ else printf("error memsize\n");
+
+
+ cu->offset = abbrev_pos;
+ cu->ptrsize = memsize;
+
+
+ printf(" =+> Next :: 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]);
+
+
+
+ /*
+ *pos = oldpos + ulength;
+ */
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à compléter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* cu = unité de compilation courante. *
+* *
+* Description : Enregistre toutes les déclarations de fonction trouvées. *
+* *
+* Retour : true en cas de succès de la lecture, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_unit *cu)
+{
+ bool result; /* Bilan à retourner */
+ uint8_t index; /* Indice de l'abbréviation */
+
+ result = true;
+
+
+ off_t oldpos;
+
+ const dw_abbrev *abbrev;
+
+
+ uint64_t low_pc;
+ uint64_t high_pc;
+
+
+ while (*pos < cu->endpos)
+ {
+
+ if (read_address_size/*leb128*/(format, pos, &index))
+ printf("abbrev index :: %hhd\n", index);
+ else printf("abbrev index error\n");
+
+ /* Contraintes d'alignement... */
+ if (index == 0) continue;
+
+
+ abbrev = find_dwarf_abbreviations(format, &cu->offset, index);
+
+
+ printf(" --> %p\n", abbrev);
+
+ printf(" == 0x%02x (matched ? %d)\n", abbrev->tag, abbrev->tag == DWT_SUBPROGRAM);
+
+
+ oldpos = *pos;
+
+ if (abbrev->tag == DWT_SUBPROGRAM)
+ {
+
+
+ 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");
+
+ 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");
+
+
+ }
+
+
+
+ if (!skip_dwarf_abbrev(format, pos, abbrev))
+ printf("error skipping :(\n");
+
+
+ printf(" == progress %d\n", *pos - oldpos);
+ printf(" == %d < %d\n", *pos, cu->endpos);
+
+
+ }
+
+
+ printf(" =+> Next :: 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]);
+
+
+
+ return result;
+
+}
diff --git a/src/format/dwarf/info.h b/src/format/dwarf/info.h
new file mode 100644
index 0000000..cf87019
--- /dev/null
+++ b/src/format/dwarf/info.h
@@ -0,0 +1,43 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * info.h - prototypes pour la lecture des informations principales du format DWARF
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _FORMAT_DWARF_INFO_H
+#define _FORMAT_DWARF_INFO_H
+
+
+#include <stdbool.h>
+
+
+#include "d_dwarf.h"
+
+
+
+/* Charge les informations trouvées dans un DWARF. */
+bool load_dwarf_information(dwarf_format *);
+
+/* Décharge les informations trouvées dans un DWARF. */
+void unload_dwarf_information(dwarf_format *);
+
+
+
+#endif /* _FORMAT_DWARF_INFO_H */
diff --git a/src/format/dwarf/utils.c b/src/format/dwarf/utils.c
index b5dbf6b..fa8ef20 100644
--- a/src/format/dwarf/utils.c
+++ b/src/format/dwarf/utils.c
@@ -24,6 +24,9 @@
#include "utils.h"
+#include <string.h>
+
+
#include "dwarf-int.h"
@@ -47,6 +50,7 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value)
int shift; /* Décallage à appliquer */
off_t i; /* Boucle de parcours */
+ shift = 0;
*value = 0;
for (i = 0; i < 8; i++)
@@ -69,3 +73,222 @@ bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value)
return (i < 8);
}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* value = valeur au format LEB128 lue. [OUT] *
+* *
+* Description : Lit une valeur Little Endian Base 128 non signée. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value)
+{
+ int shift; /* Décallage à appliquer */
+ off_t i; /* Boucle de parcours */
+
+ shift = 0;
+ *value = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ /* On évite les débordements... */
+ if ((*pos + i) >= DBG_FORMAT(format)->length) return false;
+
+ *value |= (DBG_FORMAT(format)->content[*pos + i] & 0x7f) << shift;
+
+ shift += 7;
+ (*pos)++;
+
+ if ((DBG_FORMAT(format)->content[*pos] & 0x80) == 0x00) break;
+
+ }
+
+ return (i < 8);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* value = valeur entière lue. [OUT] *
+* *
+* Description : Lit une valeur représentant une longueur d'unité. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : Un peu sale : la sortie est signée et dépend du système, *
+* alors que la valeur est non signée et dépend de la cible. *
+* *
+******************************************************************************/
+
+bool read_unit_length(dwarf_format *format, off_t *pos, off_t *value)
+{
+ bool result; /* Bilan à retourner */
+ uint32_t val32; /* Entier sur 4 octets */
+ uint64_t val64; /* Entier sur 8 octets */
+
+ /* FIXME : Endian... */
+
+ if (format->format == DWF_32_BITS)
+ {
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ memcpy(&val32, &DBG_FORMAT(format)->content[*pos], 4);
+ (*pos) += 4;
+
+ *value = val32;
+
+ }
+
+ }
+ else
+ {
+ result = ((*pos + 4 + 8) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ memcpy(&val64, &DBG_FORMAT(format)->content[*pos + 4], 8);
+ (*pos) += 4 + 8;
+
+ *value = val64;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* value = valeur entière non signée lue. [OUT] *
+* *
+* Description : Lit une valeur non signée sur deux octets. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_uhalf(dwarf_format *format, off_t *pos, uint16_t *value)
+{
+ bool result; /* Bilan à retourner */
+
+ /* FIXME : Endian... */
+
+ result = ((*pos + 2) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ memcpy(value, &DBG_FORMAT(format)->content[*pos], 2);
+ (*pos) += 2;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* value = valeur entière lue. [OUT] *
+* *
+* Description : Lit une valeur indiquant une position dans les abréviations. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : Un peu sale : la sortie est signée et dépend du système, *
+* alors que la valeur est non signée et dépend de la cible. *
+* *
+******************************************************************************/
+
+bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)
+{
+ bool result; /* Bilan à retourner */
+ uint32_t val32; /* Entier sur 4 octets */
+ uint64_t val64; /* Entier sur 8 octets */
+
+ /* FIXME : Endian... */
+
+ if (format->format == DWF_32_BITS)
+ {
+ result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ memcpy(&val32, &DBG_FORMAT(format)->content[*pos], 4);
+ (*pos) += 4;
+
+ *value = val32;
+
+ }
+
+ }
+ else
+ {
+ result = ((*pos + 8) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ memcpy(&val64, &DBG_FORMAT(format)->content[*pos], 8);
+ (*pos) += 8;
+
+ *value = val64;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations de débogage à consulter. *
+* pos = tête de lecture à mettre à jour. [OUT] *
+* value = valeur entière non signée lue. [OUT] *
+* *
+* Description : Lit une valeur indiquant la taille des adresses mémoire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_address_size(dwarf_format *format, off_t *pos, uint8_t *value)
+{
+ bool result; /* Bilan à retourner */
+
+ result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+
+ if (result)
+ {
+ *value = DBG_FORMAT(format)->content[*pos];
+ (*pos)++;
+ }
+
+ return result;
+
+}
diff --git a/src/format/dwarf/utils.h b/src/format/dwarf/utils.h
index 556e4d9..fc5b3fc 100644
--- a/src/format/dwarf/utils.h
+++ b/src/format/dwarf/utils.h
@@ -26,6 +26,7 @@
#include <stdbool.h>
+#include <stdint.h>
#include "d_dwarf.h"
@@ -35,6 +36,21 @@
/* Lit une valeur Little Endian Base 128 signée. */
bool read_leb128(dwarf_format *, off_t *, int64_t *);
+/* Lit une valeur Little Endian Base 128 non signée. */
+bool read_uleb128(dwarf_format *, off_t *, uint64_t *);
+
+/* Lit une valeur représentant une longueur d'unité. */
+bool read_unit_length(dwarf_format *, off_t *, off_t *);
+
+/* Lit une valeur non signée sur deux octets. */
+bool read_uhalf(dwarf_format *, off_t *, uint16_t *);
+
+/* Lit une valeur indiquant une position dans les abréviations. */
+bool read_abbrev_offset(dwarf_format *, off_t *, off_t *);
+
+/* Lit une valeur indiquant la taille des adresses mémoire. */
+bool read_address_size(dwarf_format *, off_t *, uint8_t *);
+
#endif /* _FORMAT_DWARF_UTILS_H */