summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--src/arch/target.c43
-rw-r--r--src/format/elf/strings.c18
-rw-r--r--src/format/format.c12
-rw-r--r--src/format/format.h2
5 files changed, 76 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index b8cd12c..94c99d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+17-03-22 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/arch/target.c:
+ Ensure all string symbols referenced by instructions get a label.
+
+ * src/format/elf/strings.c:
+ Avoid to allocate memory for reading binary content which can be read
+ directly.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ Use the internal format content instead of a provided one when creating
+ labels.
+
17-03-21 Cyrille Bagard <nocbos@gmail.com>
* src/glibext/gbufferline.c:
diff --git a/src/arch/target.c b/src/arch/target.c
index 63ae295..3632b76 100644
--- a/src/arch/target.c
+++ b/src/arch/target.c
@@ -24,6 +24,7 @@
#include "target.h"
+#include <assert.h>
#include <inttypes.h>
#include <malloc.h>
#include <stdarg.h>
@@ -305,12 +306,54 @@ void g_target_operand_get_addr(const GTargetOperand *operand, vmpa2t *addr)
bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict)
{
bool result; /* Bilan à retourner */
+ GBinSymbol *symbol; /* Facilités d'accès au symbole*/
+ SymbolType stype; /* Type de symbole trouvé */
+ const mrange_t *range; /* Couverture du symbole */
+ char *label; /* Désignation de la chaîne */
if (operand->symbol != NULL)
g_object_unref(G_OBJECT(operand->symbol));
result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
+ /**
+ * Si plusieurs chaînes se suivent, la seconde et les suivantes bénéficient
+ * d'une étiquette si et seulement si elles sont détachées des précédentes
+ * par un octet nul.
+ *
+ * S'il y a juste un retour à la ligne ("\n"), alors aucune séparation n'est
+ * considérée, et le bloc de chaînes est uniforme.
+ *
+ * Aussi, si une référence renvoie vers une ligne de ce bloc, alors on
+ * attribue à cette ligne une étiquette propre.
+ */
+
+ if (result && operand->diff == 0)
+ {
+ symbol = operand->symbol;
+
+ stype = g_binary_symbol_get_target_type(symbol);
+
+ if (stype == STP_STRING || stype == STP_RO_STRING)
+ {
+ if (g_binary_symbol_get_label(symbol) == NULL)
+ {
+ range = g_binary_symbol_get_range(symbol);
+
+ assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0);
+
+ label = create_string_label(format, get_mrange_addr(range), get_mrange_length(range));
+
+ g_binary_symbol_set_alt_label(symbol, label);
+
+ free(label);
+
+ }
+
+ }
+
+ }
+
return result;
}
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c
index 755163e..9bcb87f 100644
--- a/src/format/elf/strings.c
+++ b/src/format/elf/strings.c
@@ -152,7 +152,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
{
bool result; /* Bilan à faire remonter */
GBinContent *content; /* Contenu binaire à lire */
- char *data; /* Données copiées à traiter */
+ const bin_t *data; /* Contenu complet et original */
vmpa2t pos; /* Tête de lecture */
bool cut; /* Séparation nette ? */
off_t i; /* Boucle de parcours */
@@ -161,7 +161,8 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
GBinSymbol *symbol; /* Symbole à intégrer */
char *label; /* Désignation de la chaîne */
- if (address == 0) return false;
+ if (address == 0)
+ return false;
result = false;
@@ -169,11 +170,11 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
content = g_binary_format_get_content(G_BIN_FORMAT(format));
- data = (char *)malloc(size * sizeof(char));
-
init_vmpa(&pos, start, address);
- if (!g_binary_content_read_raw(content, &pos, size, (bin_t *)data))
+ data = g_binary_content_get_raw_access(content, &pos, size);
+
+ if (data == NULL)
goto pesd_error;
/* Boucle de parcours */
@@ -194,8 +195,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
init_vmpa(&pos, start + i, address + i);
- instr = g_raw_instruction_new_array(G_BIN_FORMAT(format)->content, MDS_8_BITS,
- end - i, &pos, format->endian);
+ instr = g_raw_instruction_new_array(content, MDS_8_BITS, end - i, &pos, format->endian);
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
@@ -207,7 +207,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
{
init_vmpa(&pos, start + i, address + i);
- label = create_string_label(G_BIN_FORMAT(format), &pos, &data[i], end - i);
+ label = create_string_label(G_BIN_FORMAT(format), &pos, end - i);
g_binary_symbol_set_alt_label(symbol, label);
@@ -229,8 +229,6 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
g_object_unref(G_OBJECT(content));
- free(data);
-
return result;
}
diff --git a/src/format/format.c b/src/format/format.c
index 327b28e..978a3d2 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -546,7 +546,6 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count
* *
* Paramètres : format = informations chargées à consulter. *
* addr = adresse liée à la chaîne à traiter. *
-* base = contenu complet et original d'une chaîne. *
* length = taille de la chaîne à représenter. *
* *
* Description : Construit une désignation pour chaîne de caractères. *
@@ -557,9 +556,11 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count
* *
******************************************************************************/
-char *create_string_label(GBinFormat *format, const vmpa2t *addr, const char *base, size_t length)
+char *create_string_label(GBinFormat *format, const vmpa2t *addr, size_t length)
{
char *result; /* Nouvelle chaîne à retourner */
+ vmpa2t pos; /* Tête de lecture modifiable */
+ const bin_t *base; /* Contenu complet et original */
unsigned int wc; /* Nombre de mots rencontrés */
size_t iter; /* Tête d'écriture de recopie */
size_t i; /* Boucle de parcours */
@@ -567,6 +568,13 @@ char *create_string_label(GBinFormat *format, const vmpa2t *addr, const char *ba
GBinSymbol *found; /* Symbole similaire trouvé */
VMPA_BUFFER(last_sfx); /* Dernier suffixe à intégrer */
+ copy_vmpa(&pos, addr);
+
+ base = g_binary_content_get_raw_access(format->content, &pos, length);
+
+ if (base == NULL)
+ return NULL;
+
result = (char *)calloc(length + 5 + VMPA_MAX_LEN + 1, sizeof(char));
wc = 0;
diff --git a/src/format/format.h b/src/format/format.h
index d97f542..c2ef895 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -77,7 +77,7 @@ void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
/* Construit une désignation pour chaîne de caractères. */
-char *create_string_label(GBinFormat *, const vmpa2t *, const char *, size_t);
+char *create_string_label(GBinFormat *, const vmpa2t *, size_t);
/* Recherche le symbole correspondant à une étiquette. */
bool g_binary_format_find_symbol_by_label(GBinFormat *, const char *, GBinSymbol **);