summaryrefslogtreecommitdiff
path: root/src/format/dwarf/abbrev.c
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 /src/format/dwarf/abbrev.c
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
Diffstat (limited to 'src/format/dwarf/abbrev.c')
-rw-r--r--src/format/dwarf/abbrev.c488
1 files changed, 471 insertions, 17 deletions
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;
+
+}