summaryrefslogtreecommitdiff
path: root/plugins/dwarf/utils.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/utils.c
parent59b1bdfdc9b64dac8fd1450c51aa5014c8c469f0 (diff)
Updated the DWARF support.
Diffstat (limited to 'plugins/dwarf/utils.c')
-rw-r--r--plugins/dwarf/utils.c255
1 files changed, 73 insertions, 182 deletions
diff --git a/plugins/dwarf/utils.c b/plugins/dwarf/utils.c
index b767970..444d3a6 100644
--- a/plugins/dwarf/utils.c
+++ b/plugins/dwarf/utils.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* utils.h - prototypes pour les fonctions d'aisance vis à vis du format DWARF
*
- * Copyright (C) 2008-2017 Cyrille Bagard
+ * Copyright (C) 2008-2018 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -24,192 +24,109 @@
#include "utils.h"
-#include <string.h>
-
-
-#include "dwarf-int.h"
-
-
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à consulter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* value = valeur au format LEB128 lue. [OUT] *
-* update = indique si la position est à mettre à jour. *
+* Paramètres : content = contenu binaire à consulter. *
+* pos = position de début de lecture. [OUT] *
+* endian = boutisme reconnu dans le format. *
+* header = en-tête à déterminer. [OUT] *
+* next = position du prochain en-tête. [OUT] *
* *
-* Description : Lit une valeur Little Endian Base 128 signée. *
+* Description : Procède à la lecture de l'en-tête d'un contenu binaire DWARF.*
* *
* Retour : Bilan de l'opération. *
* *
-* Remarques : En cas d'échec, la tête de lecture est indéterminée. *
+* Remarques : - *
* *
******************************************************************************/
-bool read_leb128(dwarf_format *format, off_t *pos, int64_t *value, bool update)
+bool read_dwarf_section_header(const GBinContent *content, vmpa2t *pos, SourceEndian endian, dw_section_header *header, vmpa2t *next)
{
- off_t curpos; /* Tête de lecture effective */
- int shift; /* Décalage à appliquer */
- off_t i; /* Boucle de parcours */
-
- curpos = *pos;
- shift = 0;
- *value = 0;
-
- for (i = 0; i < 8; i++)
- {
- /* On évite les débordements... */
- if (curpos >= DBG_FORMAT(format)->length) return false;
+ bool result; /* Bilan à retourner */
+ uint32_t first; /* Premier paquet d'octets */
+ bool status; /* Bilan d'opération */
- *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift;
+ result = false;
- shift += 7;
- curpos++;
+ status = g_binary_content_read_u32(content, pos, endian, &first);
+ if (!status) goto rdsh_exit;
- if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break;
+ if (first >= 0xfffffff0 && first != 0xffffffff)
+ goto rdsh_exit;
+ if (first == 0xffffffff)
+ {
+ result = g_binary_content_read_u64(content, pos, endian, &header->unit_length);
+ header->is_32b = false;
}
-
- if ((shift < 64) && (DBG_FORMAT(format)->content[curpos - 1] & 0x40) == 0x40)
- *value |= - (1 << shift);
-
- if (update) *pos = curpos;
-
- 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] *
-* update = indique si la position est à mettre à jour. *
-* *
-* Description : Lit une valeur Little Endian Base 128 non signée. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : En cas d'échec, la tête de lecture est indéterminée. *
-* *
-******************************************************************************/
-
-bool read_uleb128(dwarf_format *format, off_t *pos, uint64_t *value, bool update)
-{
- off_t curpos; /* Tête de lecture effective */
- int shift; /* Décalage à appliquer */
- off_t i; /* Boucle de parcours */
-
- curpos = *pos;
- shift = 0;
- *value = 0;
-
- for (i = 0; i < 8; i++)
+ else
{
- /* On évite les débordements... */
- if (curpos >= DBG_FORMAT(format)->length) return false;
-
- *value |= (DBG_FORMAT(format)->content[curpos] & 0x7f) << shift;
-
- shift += 7;
- curpos++;
-
- if ((DBG_FORMAT(format)->content[*pos + i] & 0x80) == 0x00) break;
+ result = true;
+ header->unit_length = first;
+ header->is_32b = true;
+ }
+ if (next != NULL)
+ {
+ copy_vmpa(next, pos);
+ advance_vmpa(next, header->unit_length);
}
- if (update) *pos = curpos;
+ result &= g_binary_content_read_u16(content, pos, endian, &header->version);
+
+ rdsh_exit:
- return (i < 8);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à consulter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* value = valeur entière lue. [OUT] *
+* Paramètres : content = contenu binaire à consulter. *
+* pos = position de début de lecture. [OUT] *
+* endian = boutisme reconnu dans le format. *
+* header = en-tête à déterminer. [OUT] *
+* next = position du prochain en-tête. [OUT] *
* *
-* Description : Lit une valeur représentant une longueur d'unité. *
+* Description : Procède à la lecture de l'en-tête d'une unité de compilation.*
* *
* 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. *
+* Remarques : - *
* *
******************************************************************************/
-bool read_unit_length(dwarf_format *format, off_t *pos, off_t *value)
+bool read_dwarf_compil_unit_header(GBinContent *content, vmpa2t *pos, SourceEndian endian, dw_compil_unit_header *header, vmpa2t *next)
{
bool result; /* Bilan à retourner */
- uint32_t val32; /* Entier sur 4 octets */
- uint64_t val64; /* Entier sur 8 octets */
+ uint32_t val32; /* Premier paquet d'octets */
+ bool status; /* Bilan d'opération */
- /* FIXME : Endian... */
+ result = false;
- 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;
+ status = read_dwarf_section_header(content, pos, endian, (dw_section_header *)header, next);
+ if (!status) goto rdcuh_exit;
- *value = val32;
+ if (header->is_32b)
+ {
+ status = g_binary_content_read_u32(content, pos, endian, &val32);
+ if (!status) goto rdcuh_exit;
- }
+ header->debug_abbrev_offset = 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;
-
- }
+ status = g_binary_content_read_u64(content, pos, endian, &header->debug_abbrev_offset);
+ if (!status) goto rdcuh_exit;
}
- 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 = g_binary_content_read_u8(content, pos, &header->address_size);
- result = ((*pos + 2) <= DBG_FORMAT(format)->length);
-
- if (result)
- {
- memcpy(value, &DBG_FORMAT(format)->content[*pos], 2);
- (*pos) += 2;
- }
+ rdcuh_exit:
return result;
@@ -218,53 +135,30 @@ bool read_uhalf(dwarf_format *format, off_t *pos, uint16_t *value)
/******************************************************************************
* *
-* Paramètres : format = informations de débogage à consulter. *
-* pos = tête de lecture à mettre à jour. [OUT] *
-* value = valeur entière lue. [OUT] *
+* Paramètres : content = contenu binaire à consulter. *
+* pos = position de début de lecture. [OUT] *
+* decl = structure lue à retourner. [OUT] *
* *
-* Description : Lit une valeur indiquant une position dans les abréviations. *
+* Description : Procède à la lecture d'une déclaration d'abréviation DWARF. *
* *
* 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. *
+* Remarques : - *
* *
******************************************************************************/
-bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)
+bool read_dwarf_abbrev_decl(const GBinContent *content, vmpa2t *pos, dw_abbrev_decl *decl)
{
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;
+ result = g_binary_content_read_uleb128(content, pos, &decl->code);
- }
-
- }
- else
+ if (result && decl->code > 0)
{
- result = ((*pos + 8) <= DBG_FORMAT(format)->length);
+ result = g_binary_content_read_uleb128(content, pos, &decl->tag);
if (result)
- {
- memcpy(&val64, &DBG_FORMAT(format)->content[*pos], 8);
- (*pos) += 8;
-
- *value = val64;
-
- }
+ result = g_binary_content_read_u8(content, pos, &decl->has_children);
}
@@ -275,11 +169,11 @@ bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)
/******************************************************************************
* *
-* 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] *
+* Paramètres : content = contenu binaire à consulter. *
+* pos = position de début de lecture. [OUT] *
+* attr = structure lue à retourner. [OUT] *
* *
-* Description : Lit une valeur indiquant la taille des adresses mémoire. *
+* Description : Procède à la lecture d'un attribut d'abréviation DWARF. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -287,17 +181,14 @@ bool read_abbrev_offset(dwarf_format *format, off_t *pos, off_t *value)
* *
******************************************************************************/
-bool read_address_size(dwarf_format *format, off_t *pos, uint8_t *value)
+bool read_dwarf_abbrev_attr(const GBinContent *content, vmpa2t *pos, dw_abbrev_raw_attr *attr)
{
bool result; /* Bilan à retourner */
- result = ((*pos + 1) <= DBG_FORMAT(format)->length);
+ result = g_binary_content_read_uleb128(content, pos, &attr->name);
if (result)
- {
- *value = DBG_FORMAT(format)->content[*pos];
- (*pos)++;
- }
+ result = g_binary_content_read_uleb128(content, pos, &attr->form);
return result;