summaryrefslogtreecommitdiff
path: root/plugins/fmtp/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/fmtp/parser.c')
-rw-r--r--plugins/fmtp/parser.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index b484a0e..8fc693f 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -33,8 +33,7 @@
/* Effectue l'interprétation d'une définition de champ. */
-static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *);
-
+static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *, void *);
@@ -43,6 +42,7 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* Paramètres : def = définition de champ à considérer. *
* format = description de l'exécutable à compléter. *
* pos = tête de lecture pour les données. *
+* data = infos complémentaires éventuellement fournies. *
* *
* Description : Effectue l'interprétation d'une définition de champ. *
* *
@@ -52,10 +52,11 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* *
******************************************************************************/
-static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos)
+static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos, void *data)
{
GBinContent *content; /* Contenu binaire à lire */
SourceEndian endian; /* Boutisme utilisé */
+ vmpa2t mod; /* Position modifiable */
bool result; /* Bilan à retourner */
GArchInstruction *instr; /* Instruction décodée */
GImmOperand *imm; /* Opérande à transformer */
@@ -74,9 +75,28 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
content = g_binary_format_get_content(format);
endian = g_binary_format_get_endianness(format);
- assert(def->repeat > 0);
+ if (def->get_value != NULL)
+ {
+ copy_vmpa(&mod, pos);
+
+ result = def->get_value(def, content, &mod, endian, data);
+
+ if (!result)
+ goto pfd_exit;
+
+ }
+
+ if (def->is_uleb128)
+ instr = g_raw_instruction_new_uleb128(content, pos);
+
+ else if (def->is_leb128)
+ instr = g_raw_instruction_new_sleb128(content, pos);
- instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+ else
+ {
+ assert(def->repeat > 0);
+ instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+ }
result = (instr != NULL);
@@ -88,7 +108,9 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
if (def->has_display_rules)
{
- assert(def->disp_count <= def->repeat);
+ assert((def->is_uleb128 && def->disp_count == 1)
+ || (def->is_leb128 && def->disp_count == 1)
+ || (!def->is_uleb128 && !def->is_leb128 && def->disp_count <= def->repeat));
for (i = 0; i < def->disp_count; i++)
{
@@ -198,6 +220,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* count = taille de cette liste. *
* format = description de l'exécutable à compléter. *
* pos = tête de lecture pour les données. *
+* data = infos complémentaires éventuellement fournies. *
* *
* Description : Lance l'interprétation d'une série de définitions de champs. *
* *
@@ -207,7 +230,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* *
******************************************************************************/
-bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos)
+bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos, void *data)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -215,7 +238,7 @@ bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat
result = true;
for (i = 0; i < count && result; i++)
- result = parse_field_definition(defs + i, format, pos);
+ result = parse_field_definition(defs + i, format, pos, data);
return result;