summaryrefslogtreecommitdiff
path: root/plugins/dwarf/abbrev.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-11-24 14:28:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-11-24 14:28:22 (GMT)
commitdd851e1fb743d77b421519ee5915534aed2d2c4f (patch)
tree9a9f91c09438467ade7a67c5e2188b4051d23569 /plugins/dwarf/abbrev.c
parent59b1bdfdc9b64dac8fd1450c51aa5014c8c469f0 (diff)
Updated the DWARF support.
Diffstat (limited to 'plugins/dwarf/abbrev.c')
-rw-r--r--plugins/dwarf/abbrev.c1181
1 files changed, 159 insertions, 1022 deletions
diff --git a/plugins/dwarf/abbrev.c b/plugins/dwarf/abbrev.c
index f214430..e755acf 100644
--- a/plugins/dwarf/abbrev.c
+++ b/plugins/dwarf/abbrev.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* abbrev.c - manipulation des abréviation DWARF
*
- * Copyright (C) 2008-2017 Cyrille Bagard
+ * Copyright (C) 2008-2018 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -24,13 +24,16 @@
#include "abbrev.h"
-#include <malloc.h>
+#include <analysis/contents/restricted.h>
-#include "dwarf-int.h"
+#include "checks.h"
+#include "format-int.h"
+#include "utils.h"
+/* ----------------------- TRAITEMENT D'ABREVIATION A L'UNITE ----------------------- */
/* Description d'un attribut d'une abréviation */
@@ -41,78 +44,59 @@ typedef struct _dw_abbrev_attr
} dw_abbrev_attr;
-
/* Description d'une abréviation */
struct _dw_abbrev
{
uleb128_t code; /* Identifiant attribué */
DwarfTag tag; /* Sujet de l'élément */
- dw_abbrev_attr *attribs; /* Liste des attributs */
- size_t attribs_count; /* Nombre de ces attributs */
+ bool has_children; /* Présence de sous-éléments ? */
- struct _dw_abbrev **children; /* Liste des sous-éléments */
- size_t children_count; /* Nombre de ces enfants */
+ dw_abbrev_attr *attribs; /* Liste des attributs */
+ size_t count; /* Nombre de ces attributs */
};
+/* Charge une abréviation valide pour un DWARF en mémoire. */
+static bool load_dwarf_abbreviation(GDwarfFormat *, const dw_compil_unit_header *, GBinContent *, vmpa2t *, dw_abbrev **);
-
+/* Supprime de la mémoire toute trace d'une abréviation DWARF. */
+static void free_dwarf_abbrev(dw_abbrev *);
/* Procède à la conversion de base d'une abréviation DWARF. */
-static bool check_abbreviation_decl(const GDwarfFormat *, const dw_abbrev_decl *, dw_abbrev *);
+static bool conv_abbrev_decl(GDwarfFormat *, const dw_compil_unit_header *, const dw_abbrev_decl *, dw_abbrev *, const vmpa2t *);
/* Procède à la conversion d'un attribut d'abréviation DWARF. */
-static bool check_abbreviation_attrib(const GDwarfFormat *, const dw_abbrev_raw_attr *, dw_abbrev_attr *);
+static bool conv_abbrev_attrib(GDwarfFormat *, const dw_compil_unit_header *, const dw_abbrev_raw_attr *, dw_abbrev_attr *, const vmpa2t *);
+/* ----------------------- TRAITEMENT D'ABREVIATIONS PAR LOTS ----------------------- */
-/******************************************************************************
-* *
-* Paramètres : format = informations de débogage à constituer. *
-* *
-* Description : Charge toutes les abbréviations présentes dans un DWARF. *
-* *
-* Retour : Bilan de l'opération, potentiellement un succès sans sortie. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_all_dwarf_abbreviations(GDwarfFormat *format)
+/* Brochette d'abréviations */
+struct _dw_abbrev_brotherhood
{
- bool result; /* Bilan à faire remonter */
- mrange_t range; /* Couverture d'une section */
- vmpa2t *pos; /* Position de tête de lecture */
+ dw_abbrev **abbrevs; /* Liste des sous-éléments */
+ size_t count; /* Nombre de ces éléments */
- result = g_exe_format_get_section_range_by_name(G_DBG_FORMAT(format)->executable, ".debug_abbrev", &range);
-
- pos = get_mrange_addr(&range);
-
- printf("start :: 0x%08x\n", (unsigned int)pos->physical);
-
- result &= load_dwarf_abbreviation(format, pos, &format->abbreviations);
-
- printf("abbrevs :: %p\n", format->abbreviations);
+};
- if (format->abbreviations != NULL)
- printf(" -> children : %zu\n", format->abbreviations->children_count);
- else
- printf(" -> (nothing)\n");
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* TRAITEMENT D'ABREVIATION A L'UNITE */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à consulter. *
-* pos = tête de lecture à faire évoluer. *
-* abbrev = abréviation lue et complète, NULL si aucune. [OUT] *
+* Paramètres : format = informations de débogage à consulter. *
+* cu = unité de compilation parente. *
+* content = contenu binaire borné à parcourir. *
+* pos = tête de lecture à faire évoluer. [OUT] *
+* abbrev = abréviation lue et complète, NULL si aucune. [OUT] *
* *
* Description : Charge une abréviation valide pour un DWARF en mémoire. *
* *
@@ -122,14 +106,15 @@ bool load_all_dwarf_abbreviations(GDwarfFormat *format)
* *
******************************************************************************/
-bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev **abbrev)
+static bool load_dwarf_abbreviation(GDwarfFormat *format, const dw_compil_unit_header *cu, GBinContent *content, vmpa2t *pos, dw_abbrev **abbrev)
{
+ vmpa2t old; /* Mémorisation d'une position */
+ dw_abbrev *new; /* Nouvelle abréviation */
dw_abbrev_decl decl; /* En-tête d'abréviation */
- bool status; /* Bilan d'une lecture */
dw_abbrev_raw_attr attr; /* Attribut de l'abréviation */
- dw_abbrev *child; /* Rejeton à intégrer */
+ bool status; /* Bilan d'une lecture */
- *abbrev = NULL;
+ new = NULL;
/**
* Cette routine est la transcription du paragraphe 7.5.3 ("Abbreviations Tables"),
@@ -139,77 +124,58 @@ bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev
*
* As mentioned in Section 2.3, each chain of sibling entries is terminated by a null entry.
*
- * Cependant, ce formalisme n'est pas constaté dans la pratique. D'ailleurs, readelf
- * comporte le commentaire suivant dans le fichier 'dwarf_reader.cc' :
+ * Par ailleurs, readelf comporte le commentaire suivant dans le fichier 'dwarf_reader.cc' :
*
* Read the abbrev code. A zero here indicates the end of the abbrev table.
*
*/
- if (!read_dwarf_abbrev_decl(format, pos, &decl))
+ copy_vmpa(&old, pos);
+
+ if (!read_dwarf_abbrev_decl(content, pos, &decl))
goto lda_bad_exit;
if (decl.code == 0)
goto lda_exit;
- *abbrev = (dw_abbrev *)calloc(1, sizeof(dw_abbrev));
+ new = (dw_abbrev *)calloc(1, sizeof(dw_abbrev));
- if (!check_abbreviation_decl(format, &decl, *abbrev))
+ if (!conv_abbrev_decl(format, cu, &decl, new, &old))
goto lda_bad_exit;
/* Chargement des attributs */
for (;;)
{
- status = read_dwarf_abbrev_attr(format, pos, &attr);
- if (!status) goto lda_bad_exit;
+ copy_vmpa(&old, pos);
- printf(" -- [0x%llx] [0x%llx] name = %u\tform = %u\n",
- (unsigned long long)pos->physical,
- (unsigned long long)decl.code,
- (unsigned int)attr.name, (unsigned int)attr.form);
+ status = read_dwarf_abbrev_attr(content, pos, &attr);
+ if (!status) goto lda_bad_exit;
- if (attr.name == DW_ATTR_invalid && attr.form == DW_FORM_invalid)
+ if (attr.name == 0 && attr.form == 0)
break;
- (*abbrev)->attribs_count++;
- (*abbrev)->attribs = (dw_abbrev_attr *)realloc((*abbrev)->attribs,
- (*abbrev)->attribs_count * sizeof(dw_abbrev_attr));
+ new->count++;
+ new->attribs = (dw_abbrev_attr *)realloc(new->attribs,
+ new->count * sizeof(dw_abbrev_attr));
- status = check_abbreviation_attrib(format, &attr,
- &(*abbrev)->attribs[(*abbrev)->attribs_count - 1]);
+ status = conv_abbrev_attrib(format, cu, &attr, &new->attribs[new->count - 1], &old);
if (!status) goto lda_bad_exit;
}
- /* Chargement des enfants */
-
- printf(" || children ? %d vs %d\n", (int)decl.has_children, (int)DW_CHILDREN_yes);
-
- if (decl.has_children == DW_CHILDREN_yes)
- for (;;)
- {
- status = load_dwarf_abbreviation(format, pos, &child);
- if (!status) goto lda_bad_exit;
-
- if (child == NULL)
- break;
-
- (*abbrev)->children_count++;
- (*abbrev)->children = (dw_abbrev **)realloc((*abbrev)->children,
- (*abbrev)->children_count * sizeof(dw_abbrev));
-
- (*abbrev)->children[(*abbrev)->children_count - 1] = child;
-
- }
-
lda_exit:
+ *abbrev = new;
+
return true;
lda_bad_exit:
- free_dwarf_abbreviation(*abbrev);
+ if (new != NULL)
+ free_dwarf_abbrev(new);
+
+ *abbrev = NULL;
return false;
@@ -228,22 +194,11 @@ bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev
* *
******************************************************************************/
-void free_dwarf_abbreviation(dw_abbrev *abbrev)
+static void free_dwarf_abbrev(dw_abbrev *abbrev)
{
- size_t i; /* Boucle de parcours */
-
if (abbrev->attribs != NULL)
free(abbrev->attribs);
- if (abbrev->children != NULL)
- {
- for (i = 0; i < abbrev->children_count; i++)
- free_dwarf_abbreviation(abbrev->children[i]);
-
- free(abbrev->attribs);
-
- }
-
free(abbrev);
}
@@ -251,9 +206,11 @@ void free_dwarf_abbreviation(dw_abbrev *abbrev)
/******************************************************************************
* *
-* Paramètres : format = informations chargées à consulter. *
+* Paramètres : format = informations de débogage à consulter. *
+* cu = unité de compilation parente. *
* decl = structure brute dont le contenu est à valider. *
* abbrev = abréviation à constituer à partir du brut. [OUT] *
+* pos = emplacement de l'élément à vérifier dans le binaire.*
* *
* Description : Procède à la conversion de base d'une abréviation DWARF. *
* *
@@ -263,21 +220,19 @@ void free_dwarf_abbreviation(dw_abbrev *abbrev)
* *
******************************************************************************/
-static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_decl *decl, dw_abbrev *abbrev)
+static bool conv_abbrev_decl(GDwarfFormat *format, const dw_compil_unit_header *cu, const dw_abbrev_decl *decl, dw_abbrev *abbrev, const vmpa2t *pos)
{
bool result; /* Validité à retourner */
- result = (decl->has_children == DW_CHILDREN_no
- || decl->has_children == DW_CHILDREN_yes);
-
-
- /* TODO : vérifier les bornes de 'tag' */
-
+ result = check_dwarf_abbrev_decl(format, decl, cu->version, pos);
if (result)
{
abbrev->code = decl->code;
abbrev->tag = decl->tag;
+
+ abbrev->has_children = (decl->has_children == DW_CHILDREN_yes);
+
}
return result;
@@ -287,9 +242,11 @@ static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_
/******************************************************************************
* *
-* Paramètres : format = informations chargées à consulter. *
+* Paramètres : format = informations de débogage à consulter. *
+* cu = unité de compilation parente. *
* decl = structure brute dont le contenu est à valider. *
* abbrev = abréviation à constituer à partir du brut. [OUT] *
+* pos = emplacement de l'élément à vérifier dans le binaire.*
* *
* Description : Procède à la conversion d'un attribut d'abréviation DWARF. *
* *
@@ -299,23 +256,16 @@ static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_
* *
******************************************************************************/
-static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib)
+static bool conv_abbrev_attrib(GDwarfFormat *format, const dw_compil_unit_header *cu, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib, const vmpa2t *pos)
{
bool result; /* Validité à retourner */
- result = true;
-
-
- /* TODO : vérifier les bornes de 'name' et 'form' */
-
+ result = check_dwarf_abbrev_attrib(format, attr, cu->version, pos);
if (result)
{
attrib->name = attr->name;
attrib->form = attr->form;
-
-
-
}
return result;
@@ -323,31 +273,6 @@ static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbre
}
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : abbrev = abréviation chargée en mémoire à consulter. *
-* *
-* Description : Fournit l'étiquette associée à l'ensemble des attributs. *
-* *
-* Retour : Etiquette officielle de l'ensemble représenté. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *abbrev)
-{
- return abbrev->tag;
-
-}
-
-
/******************************************************************************
* *
* Paramètres : abbrev = abréviation chargée en mémoire à consulter. *
@@ -362,178 +287,18 @@ DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *abbrev)
size_t dwarf_abbreviation_count_attribs(const dw_abbrev *abbrev)
{
- return abbrev->attribs_count;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : abbrev = abréviation chargée en mémoire à consulter. *
-* attrib = désignation de l'attribut à retrouver. *
-* index = indice de cet attribut dans l'ensemble. [OUT] *
-* *
-* Description : Recherche un attribut dans une abréviation. *
-* *
-* Retour : Indication sur le bilan des recherches. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool dwarf_abbreviation_get_attrib_index(const dw_abbrev *abbrev, DwarfAttrib attrib, size_t *index)
-{
- bool result; /* Etat de validité à renvoyer */
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < abbrev->attribs_count; i++)
- if (abbrev->attribs[i].name == attrib)
- break;
-
- if (i < abbrev->attribs_count)
- {
- result = true;
- *index = i;
- }
- else
- result = false;
-
- return result;
+ return abbrev->count;
}
-
-
-
-
/******************************************************************************
* *
-* Paramètres : abbrev = abréviation chargée en mémoire à consulter. *
-* attrib = désignation de l'attribut à retrouver. *
-* index = indice de cet attribut dans l'ensemble. *
-* form = type de valeur attendu pour un attribut donné. [OUT]*
-* *
-* Description : Détermine le type d'un attribut dans une abréviation. *
-* *
-* Retour : Indication sur le bilan des accès. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool dwarf_abbreviation_get_form_for_index(const dw_abbrev *abbrev, size_t index, DwarfForm *form)
-{
- if (index >= abbrev->attribs_count)
- return false;
-
- *form = abbrev->attribs[index].form;
-
- return true;
-
-}
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : abbrev = abréviation chargée en mémoire à consulter. *
-* *
-* Description : Indique si une abbréviation comporte des sous-définitions. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool dwarf_abbreviation_has_children(const dw_abbrev *abbrev)
-{
- return (abbrev->children_count > 0);
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations de débogage à consulter. *
-* code = identifiant de l'abbréviation recherchée. *
-* *
-* 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 GDwarfFormat *format, uleb128_t code)
-{
- const dw_abbrev *result; /* Trouvaille à retourner */
-
- if (format->abbreviations->code == code)
- result = format->abbreviations;
-
- else
- {
- const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uleb128_t c)
- {
- const dw_abbrev *found; /* Trouvaille à retourner */
- size_t i; /* Boucle de parcours */
-
- if (abbrev->code == c)
- found = abbrev;
- else
- {
- found = NULL;
-
- for (i = 0; i < abbrev->children_count && found == NULL; i++)
- found = _find_dwarf_abbreviations(abbrev->children[i], c);
-
- }
-
- return found;
-
- }
-
- result = _find_dwarf_abbreviations(format->abbreviations, code);
-
- }
-
- return result;
-
-}
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = contenu binaire de débogage à parcourir. *
-* cu = unité de compilation parente. *
-* form = nature de la valeur à lire. *
-* pos = tête de lecture au sein des données. [OUT] *
-* value = valeur au format donné lue. [OUT] *
+* Paramètres : abbrev = abréviation à consulter. *
+* format = contenu binaire de débogage à parcourir. *
+* content = contenu encadré à parcourir. *
+* pos = tête de lecture au sein des données. [OUT] *
+* cu = unité de compilation parente. *
* *
* Description : Lit la valeur correspondant à un type donné. *
* *
@@ -543,37 +308,28 @@ const dw_abbrev *find_dwarf_abbreviations(const GDwarfFormat *format, uleb128_t
* *
******************************************************************************/
-dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw_abbrev *abbrev, const dw_compil_unit_header *cu, vmpa2t *pos)
+dw_value *translate_abbrev_attribs(const dw_abbrev *abbrev, const GDwarfFormat *format, GBinContent *content, vmpa2t *pos, const dw_compil_unit_header *cu)
{
dw_value *result; /* Valeurs lues retournées */
size_t i; /* Boucle de parcours */
bool status; /* Bilan d'une lecture */
- result = (dw_value *)calloc(abbrev->attribs_count, sizeof(dw_value));
+ result = (dw_value *)calloc(abbrev->count, sizeof(dw_value));
- for (i = 0; i < abbrev->attribs_count; i++)
+ for (i = 0; i < abbrev->count; i++)
{
result[i].attrib = abbrev->attribs[i].name;
- printf("-- loading attrib %x (%u) -- form = %x (%u) -- pos = %llx --\n",
- (unsigned int)abbrev->attribs[i].name,
- (unsigned int)abbrev->attribs[i].name,
- (unsigned int)abbrev->attribs[i].form,
- (unsigned int)abbrev->attribs[i].form,
- (unsigned long long)(pos->physical - 0x1039));
-
- status = G_DWARF_FORMAT_GET_CLASS(format)->read_form(format, cu,
- abbrev->attribs[i].form, pos, &result[i].value);
- if (!status) printf("[%zu] failed for %x\n", i, abbrev->attribs[i].form);
- if (status) printf("[%zu] success for %x\n", i, abbrev->attribs[i].form);
- printf(" current pos :: %llx\n", (unsigned long long)(pos->physical - 0x1039));
+ status = read_dwarf_form_value(format, content, pos, cu,
+ abbrev->attribs[i].form, &result[i].value);
+
if (!status) break;
}
- if (i != abbrev->attribs_count)
+ if (i != abbrev->count)
{
- free(result);
+ free_abbrev_attribs(result, abbrev->count);
result = NULL;
}
@@ -582,195 +338,12 @@ dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-
-#include <malloc.h>
-#include <stdarg.h>
-#include <string.h>
-
-
-#include "utils.h"
-
-
-
-#include <ctype.h>
-
-
-
-/* Libère de la mémoire une abréviation DWARF. */
-void free_dwarf_abbrev(dw_abbrev *);
-
-/* Charge une abréviations DWARF. */
-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, ...);
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations de débogage à compléter. *
-* *
-* Description : Charge les abréviations trouvées pour un DWARF. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_dwarf_abbreviations(dwarf_format *format)
-{
- bool result; /* Bilan à renvoyer */
-
-
-
-
- off_t offset;
- off_t start;
- off_t size;
-
- bool test;
-
- int i;
-
-
- dw_abbrev *abbrev;
- uint64_t index;
-
- printf("Searching...\n");
-
-
- result = true;
-
- test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_abbrev", &start, &size, NULL);
-
- offset = start;
-
-
- printf(" -> offset=%d size=%d\n", offset, size);
-
-
-
- for (i = 0; i < size; i++)
- {
- if (i % 10 == 0) printf("\n");
- printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]);
- }
-
- printf("\n");
-
-
-
-
- while (offset < (start + size))
- {
- abbrev = read_dwarf_abbreviations(format, &offset, &index);
-
- offset++; /* 0x00 */
-
- printf("abbrev :: %p\n", abbrev);
-
- 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;
-
- printf(" %d attribs, %d children\n", abbrev->attribs_count, abbrev->children_count);
-
- }
- else
- {
- unload_dwarf_abbreviations(format);
- result = false;
- break;
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations de débogage à effacer. *
-* *
-* Description : Décharge les abréviations trouvées pour un DWARF. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void unload_dwarf_abbreviations(dwarf_format *format)
-{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < format->abbrevs_count; i++)
- free_dwarf_abbrev(format->abbrevs[i]);
-
-}
-
-
/******************************************************************************
* *
-* Paramètres : abbrev = élément à supprimer de la mémoire. *
+* Paramètres : values = liste de valeurs typées à traiter. *
+* count = nombre d'éléments de la liste. *
* *
-* Description : Libère de la mémoire une abréviation DWARF. *
+* Description : Supprime de la mémoire une liste de valeurs typées. *
* *
* Retour : - *
* *
@@ -778,511 +351,118 @@ void unload_dwarf_abbreviations(dwarf_format *format)
* *
******************************************************************************/
-void free_dwarf_abbrev(dw_abbrev *abbrev)
+void free_abbrev_attribs(dw_value *values, size_t count)
{
size_t i; /* Boucle de parcours */
- for (i = 0; i < abbrev->children_count; i++)
- free_dwarf_abbrev(abbrev->children[i]);
-
- free(abbrev->attribs);
- free(abbrev->children);
+ for (i = 0; i < count; i++)
+ if (values[i].value != NULL)
+ free_dwarf_form_value(values[i].value);
- free(abbrev);
+ free(values);
}
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à compléter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* index = code de l'abréviation. [OUT] *
+* Paramètres : abbrev = abréviation à consulter. *
* *
-* Description : Charge une abréviation DWARF. *
+* Description : Détermine si l'abréviation possède des enfants. *
* *
-* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
+* Retour : true si des sous-éléments sont présents. *
* *
* Remarques : - *
* *
******************************************************************************/
-dw_abbrev *read_dwarf_abbreviations(dwarf_format *format, off_t *pos, uint64_t *index)
+bool has_abbrev_children(const dw_abbrev *abbrev)
{
- dw_abbrev *result; /* Abréviation à retourner */
- bool has_children; /* Indique la présence de fils */
- 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));
-
- result->offset = *pos;
-
- /* Code de l'élément */
- if (!read_uleb128(format, pos, index, true)) goto rda_error;
-
- if (!read_uleb128(format, pos, &value1, true)) 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)
- {
- 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));
-
- result->attribs[result->attribs_count - 1].attrib = value1;
- result->attribs[result->attribs_count - 1].form = value2;
-
- }
-
- (*pos) += 2; /* 0x00 0x00 */
-
- /* Chargement des sous-éléments */
-
- if (has_children)
- while (DBG_FORMAT(format)->content[*pos] != 0x00)
- {
- child = read_dwarf_abbreviations(format, pos, &sub_index);
-
- if (child == NULL) 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 *));
+ bool result; /* Bilan à retourner */
- result->children[result->children_count - 1] = child;
-
- }
+ result = abbrev->has_children;
return result;
- rda_error:
-
- free_dwarf_abbrev(result);
-
- 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;
-}
+/* ---------------------------------------------------------------------------------- */
+/* TRAITEMENT D'ABREVIATIONS PAR LOTS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à consulter. *
-* offset = position dans les abréviations. *
-* pos = position dans le flux binaire courant. [OUT] *
+* Paramètres : format = informations de débogage à constituer. *
+* cu = en-tête de description de l'unité à traiter. *
* *
-* Description : Recherche une abréviation DWARF donnée. *
+* Description : Charge une série d'abréviations présentes dans un DWARF. *
* *
-* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
+* Retour : Structure mise en place, ou NULL en cas d'erreur. *
* *
-* Remarques : - *
+* Remarques : Le décalage est positionné à VMPA_NO_PHYSICAL en cas de fin. *
* *
******************************************************************************/
-const dw_abbrev *find_dwarf_abbreviations(dwarf_format *format, const off_t *offset, off_t *pos)
+dw_abbrev_brotherhood *load_all_dwarf_abbreviations(GDwarfFormat *format, const dw_compil_unit_header *cu)
{
- const dw_abbrev *result; /* Structure à retourner */
- uint64_t index; /* Code de l'abréviation */
- size_t i; /* Boucle de parcours */
+ dw_abbrev_brotherhood *result; /* Abréviations à retourner */
+ GExeFormat *exe; /* Exécutable associé */
+ mrange_t range; /* Couverture d'une section */
+ bool status; /* Bilan d'un appel */
+ GBinContent *content; /* Contenu binaire à lire */
+ GBinContent *restricted; /* Limitation des traitements */
+ vmpa2t pos; /* Position de tête de lecture */
+ dw_abbrev *abbrev; /* Nouvelle abréviation */
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;
-
- if (i < format->abbrevs_count)
- {
- index--;
- result = _find_dwarf_abbreviations(format->abbrevs[i], &index);
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : abbrev = informations à parcourir. *
-* attrib = attribut visé par la lecture. *
-* *
-* Description : Indique la présence ou l'absence d'un attribut donné. *
-* *
-* Retour : true si l'attribut est présent, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool test_dwarf_abbrev_attribute(const dw_abbrev *abbrev, DwarfAttrib attrib)
-{
- bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
-
- result = false;
-
- for (i = 0; i < abbrev->attribs_count && !result; i++)
- result = (abbrev->attribs[i].attrib == attrib);
-
- return result;
-
-}
+ exe = G_DBG_FORMAT(format)->executable;
+ status = g_exe_format_get_section_range_by_name(exe, ".debug_abbrev", &range);
-/******************************************************************************
-* *
-* Paramètres : format = informations de débogage à compléter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* form = format des données à lire. *
-* ... = 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, ...)
-{
- 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 */
- uint64_t *sval64; /* Données sur 64 bits (signée)*/
- 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 stmp64; /* Données sur 64 bits (signée)*/
- uint64_t size_to_read; /* Nombre d'octets à lire */
- off_t offset; /* Décalage dans une zone */
- char **strval; /* Chaîne de caractères */
- size_t length; /* Taille d'une chaîne */
-
- va_start(ap, form);
-
- switch (form)
+ if (status)
{
- 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)
- {
- 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;
+ /* Définition d'un zone de travail */
- 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;
+ content = G_BIN_FORMAT(format)->content;
+ restricted = g_restricted_content_new(content, &range);
- 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;
+ copy_vmpa(&pos, get_mrange_addr(&range));
+ advance_vmpa(&pos, cu->debug_abbrev_offset);
- 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;
+ /* Lecture de toutes les abréviations */
- 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);
- *strval = NULL;
- }
-
- }
-
- break;
-
- case DWF_BLOCK:
- result = read_uleb128(format, pos, &size_to_read, true);
- 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:
- sval64 = va_arg(ap, int64_t *);
- if (sval64 == NULL) sval64 = &stmp64;
- result = read_uleb128(format, pos, sval64, true);
- break;
-
- case DWF_STRP:
- 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);
- */
- }
- break;
-
- case DWF_UDATA:
- val64 = va_arg(ap, uint64_t *);
- if (val64 == NULL) val64 = &tmp64;
- result = read_uleb128(format, pos, val64, true);
- break;
-
- case DWF_REF_ADDR:
- result = ((*pos + 4) <= DBG_FORMAT(format)->length);
-
- printf("bad at %d\n", __LINE__); 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 at %d\n", __LINE__); exit(0);
-
- break;
+ result = calloc(1, sizeof(dw_abbrev_brotherhood));
+ while (true)
+ {
+ status = load_dwarf_abbreviation(format, cu, restricted, &pos, &abbrev);
+ if (!status) break;
- case DWF_INDIRECT:
- result = ((*pos + 4) <= DBG_FORMAT(format)->length);
+ if (abbrev == NULL)
+ break;
- printf("bad at %d\n", __LINE__); exit(0);
+ result->abbrevs = realloc(result->abbrevs, ++result->count * sizeof(dw_abbrev *));
- break;
+ result->abbrevs[result->count - 1] = abbrev;
+ }
+ /* Nettoyage */
+ if (!status)
+ {
+ free_all_dwarf_abbreviations(result);
+ result = NULL;
+ }
- default:
- result = false;
- break;
+ g_object_unref(G_OBJECT(restricted));
}
- va_end(ap);
-
return result;
}
@@ -1290,101 +470,58 @@ 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] *
+* Paramètres : list = série d'abréviations chargées en mémoire à traiter. *
* *
-* Description : Lit la valeur d'un attribut DWARF. *
+* Description : Supprime de la mémoire toute trace d'abréviations DWARF. *
* *
-* Retour : true si la lecture est un succès, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool read_dwarf_abbrev_attribute(dwarf_format *format, off_t *pos, bool update, const dw_abbrev *abbrev, DwarfAttrib attrib, ...)
+void free_all_dwarf_abbreviations(dw_abbrev_brotherhood *list)
{
- 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, &curpos, abbrev->attribs[i].form, NULL);
-
- if (result)
- {
- va_start(ap, attrib);
-
- if (i < abbrev->attribs_count)
- result = _read_dwarf_abbrev_attribute(format, &curpos, abbrev->attribs[i].form, va_arg(ap, void *));
- else
- result = false;
- va_end(ap);
+ for (i = 0; i < list->count; i++)
+ free_dwarf_abbrev(list->abbrevs[i]);
- }
-
- if (result && update) *pos = curpos;
+ if (list->abbrevs != NULL)
+ free(list->abbrevs);
- return result;
+ free(list);
}
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à compléter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* abbrev = informations à survoler. *
+* Paramètres : list = série d'abréviations à consulter. *
+* code = identifiant de l'abbréviation recherchée. *
* *
-* Description : Fait avancer la tête de lecture d'une seule abréviation. *
+* Description : Recherche une abréviation DWARF donnée. *
* *
-* Retour : true si l'opération est un succès, false sinon. *
+* Retour : Adresse d'une abréviation ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev)
+const dw_abbrev *find_dwarf_abbreviation(const dw_abbrev_brotherhood *list, uleb128_t code)
{
- bool result; /* Bilan à revoyer */
+ const dw_abbrev *result; /* Trouvaille à retourner */
size_t i; /* Boucle de parcours */
- uint64_t index; /* Code de padding */
-
- result = true;
-
- /* Ecartement du corps */
- for (i = 0; i < abbrev->attribs_count && result; i++)
- result = _read_dwarf_abbrev_attribute(format, pos, abbrev->attribs[i].form, NULL);
-
- /* Ecartement du padding */
+ result = NULL;
- do
- {
- if (!read_uleb128(format, pos, &index, false))
+ for (i = 0; i < list->count; i++)
+ if (list->abbrevs[i]->code == code)
{
- printf("error skipping padding...\n");
- return false;
+ result = list->abbrevs[i];
+ break;
}
- if (index == 0)
- read_uleb128(format, pos, &index, true);
-
- }
- while (index == 0);
-
return result;
}
-
-#endif