summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-07-07 06:32:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-07-07 06:32:43 (GMT)
commit4c10dfa2a95cea6fc704d68066d0c284cfd79342 (patch)
tree5827bbc411459800747e21929daecdf99fde7dfd /src/analysis
parent3f996be1e5858b54740bf92515795982a16b169a (diff)
Rewrite core parts of the ROST API.
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/scan/Makefile.am6
-rw-r--r--src/analysis/scan/conds/Makefile.am16
-rw-r--r--src/analysis/scan/conds/binop-int.h54
-rw-r--r--src/analysis/scan/conds/binop.c265
-rw-r--r--src/analysis/scan/conds/binop.h68
-rw-r--r--src/analysis/scan/conds/counter-int.h53
-rw-r--r--src/analysis/scan/conds/counter.c232
-rw-r--r--src/analysis/scan/conds/counter.h58
-rw-r--r--src/analysis/scan/context.c8
-rw-r--r--src/analysis/scan/core.c21
-rw-r--r--src/analysis/scan/expr-int.h6
-rw-r--r--src/analysis/scan/expr.c54
-rw-r--r--src/analysis/scan/expr.h3
-rw-r--r--src/analysis/scan/exprs/Makefile.am6
-rw-r--r--src/analysis/scan/exprs/access-int.h69
-rw-r--r--src/analysis/scan/exprs/access.c471
-rw-r--r--src/analysis/scan/exprs/access.h63
-rw-r--r--src/analysis/scan/exprs/arithmop-int.h4
-rw-r--r--src/analysis/scan/exprs/arithmop.c210
-rw-r--r--src/analysis/scan/exprs/boolop.c161
-rw-r--r--src/analysis/scan/exprs/call-int.h13
-rw-r--r--src/analysis/scan/exprs/call.c223
-rw-r--r--src/analysis/scan/exprs/call.h7
-rw-r--r--src/analysis/scan/exprs/literal-int.h2
-rw-r--r--src/analysis/scan/exprs/literal.c113
-rw-r--r--src/analysis/scan/exprs/literal.h3
-rw-r--r--src/analysis/scan/exprs/relop-int.h4
-rw-r--r--src/analysis/scan/exprs/relop.c156
-rw-r--r--src/analysis/scan/exprs/strop-int.h (renamed from src/analysis/scan/exprs/str-int.h)15
-rw-r--r--src/analysis/scan/exprs/strop.c (renamed from src/analysis/scan/exprs/str.c)258
-rw-r--r--src/analysis/scan/exprs/strop.h (renamed from src/analysis/scan/exprs/str.h)8
-rw-r--r--src/analysis/scan/func-int.h51
-rw-r--r--src/analysis/scan/func.c126
-rw-r--r--src/analysis/scan/func.h52
-rw-r--r--src/analysis/scan/funcs/Makefile.am15
-rw-r--r--src/analysis/scan/grammar.y61
-rw-r--r--src/analysis/scan/item-int.h14
-rw-r--r--src/analysis/scan/item.c131
-rw-r--r--src/analysis/scan/item.h12
-rw-r--r--src/analysis/scan/items/Makefile.am15
-rw-r--r--src/analysis/scan/items/datasize.c (renamed from src/analysis/scan/funcs/datasize.c)90
-rw-r--r--src/analysis/scan/items/datasize.h (renamed from src/analysis/scan/funcs/datasize.h)17
-rw-r--r--src/analysis/scan/items/uint-int.h (renamed from src/analysis/scan/funcs/uint-int.h)16
-rw-r--r--src/analysis/scan/items/uint.c (renamed from src/analysis/scan/funcs/uint.c)189
-rw-r--r--src/analysis/scan/items/uint.h (renamed from src/analysis/scan/funcs/uint.h)12
-rw-r--r--src/analysis/scan/patterns/backend-int.h2
-rw-r--r--src/analysis/scan/patterns/backend.c5
-rw-r--r--src/analysis/scan/patterns/backend.h2
-rw-r--r--src/analysis/scan/patterns/backends/acism.c10
-rw-r--r--src/analysis/scan/patterns/backends/bitap.c50
-rw-r--r--src/analysis/scan/rule.c4
-rw-r--r--src/analysis/scan/rule.h2
-rw-r--r--src/analysis/scan/scanner.c4
-rw-r--r--src/analysis/scan/scope.h37
-rw-r--r--src/analysis/scan/space-int.h6
-rw-r--r--src/analysis/scan/space.c143
-rw-r--r--src/analysis/scan/space.h4
-rw-r--r--src/analysis/scan/tokens.l15
58 files changed, 1897 insertions, 1818 deletions
diff --git a/src/analysis/scan/Makefile.am b/src/analysis/scan/Makefile.am
index bcec986..d4d7aa4 100644
--- a/src/analysis/scan/Makefile.am
+++ b/src/analysis/scan/Makefile.am
@@ -24,8 +24,6 @@ libanalysisscan_la_SOURCES = \
core.h core.c \
expr-int.h \
expr.h expr.c \
- func-int.h \
- func.h func.c \
item-int.h \
item.h item.c \
match-int.h \
@@ -45,7 +43,7 @@ libanalysisscan_la_SOURCES = \
libanalysisscan_la_LIBADD = \
exprs/libanalysisscanexprs.la \
- funcs/libanalysisscanfuncs.la \
+ items/libanalysisscanitems.la \
matches/libanalysisscanmatches.la \
patterns/libanalysisscanpatterns.la
@@ -64,4 +62,4 @@ CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
EXTRA_DIST = tokens.h
-SUBDIRS = exprs funcs matches patterns
+SUBDIRS = exprs items matches patterns
diff --git a/src/analysis/scan/conds/Makefile.am b/src/analysis/scan/conds/Makefile.am
deleted file mode 100644
index 402deac..0000000
--- a/src/analysis/scan/conds/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-
-noinst_LTLIBRARIES = libanalysisscanconds.la
-
-
-libanalysisscanconds_la_SOURCES = \
- binop-int.h \
- binop.h binop.c \
- counter-int.h \
- counter.h counter.c
-
-libanalysisscanconds_la_CFLAGS = $(LIBGOBJ_CFLAGS)
-
-
-devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
-
-dev_HEADERS = $(libanalysisscanconds_la_SOURCES:%c=)
diff --git a/src/analysis/scan/conds/binop-int.h b/src/analysis/scan/conds/binop-int.h
deleted file mode 100644
index 0fc5940..0000000
--- a/src/analysis/scan/conds/binop-int.h
+++ /dev/null
@@ -1,54 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * binop-int.h - prototypes internes pour les opérations booléennes impliquant deux opérandes
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_CONDS_BINOP_INT_H
-#define _ANALYSIS_SCAN_CONDS_BINOP_INT_H
-
-
-#include "binop.h"
-
-
-#include "../cond-int.h"
-
-
-
-/* Opération booléenne impliquant deux opérandes (instance) */
-struct _GBinaryOperation
-{
- GMatchCondition parent; /* A laisser en premier */
-
- GMatchCondition *conds[2]; /* Opérandes à manipuler */
- BinOpType type; /* Type de manipulation */
-
-};
-
-/* Opération booléenne impliquant deux opérandes (classe) */
-struct _GBinaryOperationClass
-{
- GMatchConditionClass parent; /* A laisser en premier */
-
-};
-
-
-
-#endif /* _ANALYSIS_SCAN_CONDS_BINOP_INT_H */
diff --git a/src/analysis/scan/conds/binop.c b/src/analysis/scan/conds/binop.c
deleted file mode 100644
index 01e99d9..0000000
--- a/src/analysis/scan/conds/binop.c
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * binop.c - opérations booléennes impliquant deux opérandes
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "binop.h"
-
-
-#include "binop-int.h"
-
-
-
-/* --------------------- INSTANCIATION D'UNE FORME DE CONDITION --------------------- */
-
-
-/* Initialise la classe des opérations booléennes. */
-static void g_binary_operation_class_init(GBinaryOperationClass *);
-
-/* Initialise une instance d'opération booléenne. */
-static void g_binary_operation_init(GBinaryOperation *);
-
-/* Supprime toutes les références externes. */
-static void g_binary_operation_dispose(GBinaryOperation *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_binary_operation_finalize(GBinaryOperation *);
-
-
-
-/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-
-
-/* Indique le statut d'une condition de validation. */
-static bool g_binary_operation_resolve(const GBinaryOperation *);
-
-/* Lance l'analyse de contenu binaire selon un motif donné. */
-static void g_binary_operation_analyze(const GBinaryOperation *, const bin_t *, phys_t, phys_t, bool);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* INSTANCIATION D'UNE FORME DE CONDITION */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour une opération booléenne de validation. */
-G_DEFINE_TYPE(GBinaryOperation, g_binary_operation, G_TYPE_MATCH_CONDITION);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des opérations booléennes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_binary_operation_class_init(GBinaryOperationClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GMatchConditionClass *cond; /* Classe parente directe */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_operation_dispose;
- object->finalize = (GObjectFinalizeFunc)g_binary_operation_finalize;
-
- cond = G_MATCH_CONDITION_CLASS(klass);
-
- cond->resolve = (resolve_cond_fc)g_binary_operation_resolve;
- cond->analyze = (analyze_cond_fc)g_binary_operation_analyze;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance à initialiser. *
-* *
-* Description : Initialise une instance d'opération booléenne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_binary_operation_init(GBinaryOperation *op)
-{
- op->conds[0] = NULL;
- op->conds[1] = NULL;
-
- op->type = BOT_AND;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_binary_operation_dispose(GBinaryOperation *op)
-{
- g_clear_object(&op->conds[0]);
- g_clear_object(&op->conds[1]);
-
- G_OBJECT_CLASS(g_binary_operation_parent_class)->dispose(G_OBJECT(op));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_binary_operation_finalize(GBinaryOperation *op)
-{
- G_OBJECT_CLASS(g_binary_operation_parent_class)->finalize(G_OBJECT(op));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op1 = premier opérande à intégrer. *
-* op2 = second opérande à intégrer. *
-* type = type d'opération à prendre en compte. *
-* *
-* Description : Met en place une représentation d'opération booléenne. *
-* *
-* Retour : Condition mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBinaryOperation *g_binary_operation_new(GMatchCondition *op1, GMatchCondition *op2, BinOpType type)
-{
- GBinaryOperation *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_BINARY_OPERATION, NULL);
-
- result->conds[0] = op1;
- g_object_ref(G_OBJECT(op1));
-
- result->conds[1] = op2;
- g_object_ref(G_OBJECT(op2));
-
- result->type = type;
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : op = condition à consulter. *
-* *
-* Description : Indique le statut d'une condition de validation. *
-* *
-* Retour : Validation de la condition considérée. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_binary_operation_resolve(const GBinaryOperation *op)
-{
- bool result; /* Bilan à retourner */
-
- result = g_match_condition_resolve(op->conds[0]);
-
- switch (op->type)
- {
- case BOT_AND:
- default:
- if (result)
- result = g_match_condition_resolve(op->conds[1]);
- break;
-
- case BOT_OR:
- if (!result)
- result = g_match_condition_resolve(op->conds[1]);
- break;
-
- case BOT_XOR:
- result ^= g_match_condition_resolve(op->conds[1]);
- break;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = condition à considérer. *
-* data = données binaires brutes à considérer. *
-* size = quantité de ces données. *
-* pos = position du point d'étude courant. *
-* full = force une recherche pleine et entière. *
-* *
-* Description : Lance l'analyse de contenu binaire selon un motif donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_binary_operation_analyze(const GBinaryOperation *op, const bin_t *data, phys_t size, phys_t pos, bool full)
-{
- g_match_condition_analyze(op->conds[0], data, size, pos, full);
-
- if (full || !g_binary_operation_resolve(op))
- g_match_condition_analyze(op->conds[1], data, size, pos, full);
-
-}
diff --git a/src/analysis/scan/conds/binop.h b/src/analysis/scan/conds/binop.h
deleted file mode 100644
index 55cb515..0000000
--- a/src/analysis/scan/conds/binop.h
+++ /dev/null
@@ -1,68 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * binop.h - prototypes pour les opérations booléennes impliquant deux opérandes
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_CONDS_BINOP_H
-#define _ANALYSIS_SCAN_CONDS_BINOP_H
-
-
-#include <glib-object.h>
-
-
-#include "../cond.h"
-
-
-
-#define G_TYPE_BINARY_OPERATION g_binary_operation_get_type()
-#define G_BINARY_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BINARY_OPERATION, GBinaryOperation))
-#define G_IS_BINARY_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BINARY_OPERATION))
-#define G_BINARY_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_OPERATION, GBinaryOperationClass))
-#define G_IS_BINARY_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_OPERATION))
-#define G_BINARY_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_OPERATION, GBinaryOperationClass))
-
-
-/* Opération booléenne impliquant deux opérandes (instance) */
-typedef struct _GBinaryOperation GBinaryOperation;
-
-/* Opération booléenne impliquant deux opérandes (classe) */
-typedef struct _GBinaryOperationClass GBinaryOperationClass;
-
-
-/* Types d'opérations booléennes disponibles */
-typedef enum _BinOpType
-{
- BOT_AND,
- BOT_OR,
- BOT_XOR,
-
-} BinOpType;
-
-
-/* Indique le type défini pour une opération booléenne de validation. */
-GType g_binary_operation_get_type(void);
-
-/* Met en place une représentation d'opération booléenne. */
-GBinaryOperation *g_binary_operation_new(GMatchCondition *, GMatchCondition *, BinOpType);
-
-
-
-#endif /* _ANALYSIS_SCAN_CONDS_BINOP_H */
diff --git a/src/analysis/scan/conds/counter-int.h b/src/analysis/scan/conds/counter-int.h
deleted file mode 100644
index a706fca..0000000
--- a/src/analysis/scan/conds/counter-int.h
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter-int.h - prototypes internes pour le décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_CONDS_COUNTER_INT_H
-#define _ANALYSIS_SCAN_CONDS_COUNTER_INT_H
-
-
-#include "counter.h"
-
-
-#include "../cond-int.h"
-
-
-
-/* Décompte des identifications de motifs (instance) */
-struct _GMatchCounter
-{
- GMatchCondition parent; /* A laisser en premier */
-
- GSearchPattern *pattern; /* Motif associé */
-
-};
-
-/* Décompte des identifications de motifs (classe) */
-struct _GMatchCounterClass
-{
- GMatchConditionClass parent; /* A laisser en premier */
-
-};
-
-
-
-#endif /* _ANALYSIS_SCAN_CONDS_COUNTER_INT_H */
diff --git a/src/analysis/scan/conds/counter.c b/src/analysis/scan/conds/counter.c
deleted file mode 100644
index 7cf36b8..0000000
--- a/src/analysis/scan/conds/counter.c
+++ /dev/null
@@ -1,232 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter.c - décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "counter.h"
-
-
-#include "counter-int.h"
-
-
-
-/* --------------------- INSTANCIATION D'UNE FORME DE CONDITION --------------------- */
-
-
-/* Initialise la classe des opérations booléennes. */
-static void g_match_counter_class_init(GMatchCounterClass *);
-
-/* Initialise une instance d'opération booléenne. */
-static void g_match_counter_init(GMatchCounter *);
-
-/* Supprime toutes les références externes. */
-static void g_match_counter_dispose(GMatchCounter *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_match_counter_finalize(GMatchCounter *);
-
-
-
-/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-
-
-/* Indique le statut d'une condition de validation. */
-static unsigned long long g_match_counter_resolve_as_number(const GMatchCounter *);
-
-/* Lance l'analyse de contenu binaire selon un motif donné. */
-static void g_match_counter_analyze(const GMatchCounter *, const bin_t *, phys_t, phys_t, bool);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* INSTANCIATION D'UNE FORME DE CONDITION */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
-G_DEFINE_TYPE(GMatchCounter, g_match_counter, G_TYPE_MATCH_CONDITION);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des opérations booléennes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_match_counter_class_init(GMatchCounterClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GMatchConditionClass *cond; /* Classe parente directe */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_match_counter_dispose;
- object->finalize = (GObjectFinalizeFunc)g_match_counter_finalize;
-
- cond = G_MATCH_CONDITION_CLASS(klass);
-
- cond->resolve_as_num = (resolve_cond_as_number_fc)g_match_counter_resolve_as_number;
- cond->analyze = (analyze_cond_fc)g_match_counter_analyze;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance à initialiser. *
-* *
-* Description : Initialise une instance d'opération booléenne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_match_counter_init(GMatchCounter *counter)
-{
- counter->pattern = NULL;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_match_counter_dispose(GMatchCounter *counter)
-{
- g_clear_object(&counter->pattern);
-
- G_OBJECT_CLASS(g_match_counter_parent_class)->dispose(G_OBJECT(counter));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_match_counter_finalize(GMatchCounter *counter)
-{
- G_OBJECT_CLASS(g_match_counter_parent_class)->finalize(G_OBJECT(counter));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : pattern = motif à impliquer. *
-* *
-* Description : Met en place un décompte de correspondances obtenues. *
-* *
-* Retour : Condition mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GMatchCounter *g_match_counter_new(GSearchPattern *pattern)
-{
- GMatchCounter *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_MATCH_COUNTER, NULL);
-
- result->pattern = pattern;
- g_object_ref(G_OBJECT(pattern));
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : op = condition à consulter. *
-* *
-* Description : Indique le statut d'une condition de validation. *
-* *
-* Retour : Forme numérique de la condition considérée pour validation. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static unsigned long long g_match_counter_resolve_as_number(const GMatchCounter *counter)
-{
- unsigned long long result; /* Valeur à retourner */
-
- result = g_search_pattern_count_matchs(counter->pattern);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : counter = condition à considérer. *
-* data = données binaires brutes à considérer. *
-* size = quantité de ces données. *
-* pos = position du point d'étude courant. *
-* full = force une recherche pleine et entière. *
-* *
-* Description : Lance l'analyse de contenu binaire selon un motif donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_match_counter_analyze(const GMatchCounter *counter, const bin_t *data, phys_t size, phys_t pos, bool full)
-{
- //g_search_pattern_analyze(counter->pattern, data, size, pos);
-
-}
diff --git a/src/analysis/scan/conds/counter.h b/src/analysis/scan/conds/counter.h
deleted file mode 100644
index 033ac99..0000000
--- a/src/analysis/scan/conds/counter.h
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter.h - prototypes pour le décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_CONDS_COUNTER_H
-#define _ANALYSIS_SCAN_CONDS_COUNTER_H
-
-
-#include <glib-object.h>
-
-
-#include "../pattern.h"
-
-
-
-#define G_TYPE_MATCH_COUNTER g_match_counter_get_type()
-#define G_MATCH_COUNTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MATCH_COUNTER, GMatchCounter))
-#define G_IS_MATCH_COUNTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MATCH_COUNTER))
-#define G_MATCH_COUNTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MATCH_COUNTER, GMatchCounterClass))
-#define G_IS_MATCH_COUNTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MATCH_COUNTER))
-#define G_MATCH_COUNTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_MATCH_COUNTER, GMatchCounterClass))
-
-
-/* Décompte des identifications de motifs (instance) */
-typedef struct _GMatchCounter GMatchCounter;
-
-/* Décompte des identifications de motifs (classe) */
-typedef struct _GMatchCounterClass GMatchCounterClass;
-
-
-/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
-GType g_match_counter_get_type(void);
-
-/* Met en place une représentation d'opération booléenne. */
-GMatchCounter *g_match_counter_new(GSearchPattern *);
-
-
-
-#endif /* _ANALYSIS_SCAN_CONDS_COUNTER_H */
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c
index aec654a..c19b76c 100644
--- a/src/analysis/scan/context.c
+++ b/src/analysis/scan/context.c
@@ -499,7 +499,7 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)
cond = NULL;
- for (i = 0; context->cond_count; i++)
+ for (i = 0; i < context->cond_count; i++)
if (strcmp(name, context->conditions[i].name) == 0)
{
cond = &context->conditions[i];
@@ -513,16 +513,14 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)
if (!cond->final_reduced)
{
- new = g_scan_expression_reduce(cond->expr, context, false);
+ cond->final_reduced = g_scan_expression_reduce(cond->expr, context, NULL, &new);
- if (new != NULL)
+ if (cond->final_reduced && new != NULL)
{
g_object_unref(G_OBJECT(cond->expr));
cond->expr = new;
}
- cond->final_reduced = true;
-
}
/* Tentative de récupération d'un bilan final */
diff --git a/src/analysis/scan/core.c b/src/analysis/scan/core.c
index 3b6c2c9..aef9abd 100644
--- a/src/analysis/scan/core.c
+++ b/src/analysis/scan/core.c
@@ -24,8 +24,8 @@
#include "core.h"
-#include "funcs/datasize.h"
-#include "funcs/uint.h"
+#include "items/datasize.h"
+#include "items/uint.h"
@@ -47,20 +47,21 @@ bool populate_main_scan_namespace(GScanNamespace *space)
result = true;
-#define REGISTER_FUNC(s, f, n) \
+#define REGISTER_FUNC(s, f) \
({ \
bool __result; \
- __result = g_scan_namespace_register(s, G_REGISTERED_ITEM(f), n); \
+ __result = g_scan_namespace_register_item(s, G_REGISTERED_ITEM(f)); \
+ g_object_unref(G_OBJECT(f)); \
__result; \
})
- if (result) result = REGISTER_FUNC(space, g_datasize_function_new(), "datasize");
- if (result) result = REGISTER_FUNC(space, g_datasize_function_new(), "filesize"); /* Alias */
+ if (result) result = REGISTER_FUNC(space, g_datasize_function_new());
+ //if (result) result = REGISTER_FUNC(space, g_datasize_function_new(), "filesize"); /* Alias */
- if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_8_BITS_UNSIGNED), "uint8");
- if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_16_BITS_UNSIGNED), "uint16");
- if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_32_BITS_UNSIGNED), "uint32");
- if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_64_BITS_UNSIGNED), "uint64");
+ if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_8_BITS_UNSIGNED));
+ if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_16_BITS_UNSIGNED));
+ if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_32_BITS_UNSIGNED));
+ if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_64_BITS_UNSIGNED));
return result;
diff --git a/src/analysis/scan/expr-int.h b/src/analysis/scan/expr-int.h
index 4323693..dbfea6e 100644
--- a/src/analysis/scan/expr-int.h
+++ b/src/analysis/scan/expr-int.h
@@ -44,8 +44,11 @@ typedef bool (* check_expr_validity_fc) (const GScanExpression *);
/* Reproduit une expression en place dans une nouvelle instance. */
typedef GScanExpression * (* dup_expr_fc) (const GScanExpression *);
+/* Reproduit une expression en place dans une nouvelle instance. */
+typedef void (* copy_expr_fc) (GScanExpression *, const GScanExpression *);
+
/* Réduit une expression à une forme plus simple. */
-typedef GScanExpression * (* reduce_expr_fc) (GScanExpression *, GScanContext *, bool);
+typedef bool (* reduce_expr_fc) (GScanExpression *, GScanContext *, GScanScope *, GScanExpression **);
/* Expression d'évaluation généraliste (instance) */
@@ -64,6 +67,7 @@ struct _GScanExpressionClass
compare_expr_rich_fc cmp_rich; /* Comparaison de façon précise*/
check_expr_validity_fc check; /* Validation de la cohérence */
+ copy_expr_fc copy; /* Reproduction d'expression */
dup_expr_fc dup; /* Reproduction d'expression */
reduce_expr_fc reduce; /* Simplification d'expression */
diff --git a/src/analysis/scan/expr.c b/src/analysis/scan/expr.c
index 0b81e01..52d2c42 100644
--- a/src/analysis/scan/expr.c
+++ b/src/analysis/scan/expr.c
@@ -24,6 +24,9 @@
#include "expr.h"
+#include <assert.h>
+
+
#include "expr-int.h"
@@ -46,6 +49,10 @@ static void g_scan_expression_dispose(GScanExpression *);
/* Procède à la libération totale de la mémoire. */
static void g_scan_expression_finalize(GScanExpression *);
+/* Reproduit une expression en place dans une nouvelle instance. */
+static void g_scan_expression_copy(GScanExpression *, const GScanExpression *);
+
+
/* ----------------------- INTERFACE OFFRANT DES COMPARAISONS ----------------------- */
@@ -86,6 +93,8 @@ static void g_scan_expression_class_init(GScanExpressionClass *klass)
object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_expression_dispose;
object->finalize = (GObjectFinalizeFunc)g_scan_expression_finalize;
+ klass->copy = g_scan_expression_copy;
+
}
@@ -241,6 +250,26 @@ bool g_scan_expression_check_validity(const GScanExpression *expr)
/******************************************************************************
* *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_expression_copy(GScanExpression *dest, const GScanExpression *src)
+{
+ dest->value_type = src->value_type;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : expr = expression à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
@@ -254,11 +283,16 @@ bool g_scan_expression_check_validity(const GScanExpression *expr)
GScanExpression *g_scan_expression_duplicate(const GScanExpression *expr)
{
GScanExpression *result; /* Instance copiée à retourner */
+ GType type; /* Type d'objet à copier */
GScanExpressionClass *class; /* Classe à activer */
+ type = G_TYPE_FROM_INSTANCE(expr);
+
+ result = g_object_new(type, NULL);
+
class = G_SCAN_EXPRESSION_GET_CLASS(expr);
- result = class->dup(expr);
+ class->copy(result, expr);
return result;
@@ -269,24 +303,32 @@ GScanExpression *g_scan_expression_duplicate(const GScanExpression *expr)
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = indique une ultime conversion dans le cycle en cours.*
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_scan_expression_reduce(GScanExpression *expr, GScanContext *ctx, bool final)
+bool g_scan_expression_reduce(GScanExpression *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
GScanExpressionClass *class; /* Classe à activer */
+ *out = NULL;
+
class = G_SCAN_EXPRESSION_GET_CLASS(expr);
- result = class->reduce(expr, ctx, final);
+ result = class->reduce(expr, ctx, scope, out);
+
+#ifndef NDEBUG
+ if (*out != NULL)
+ assert(result);
+#endif
return result;
diff --git a/src/analysis/scan/expr.h b/src/analysis/scan/expr.h
index 98e7f7d..d596222 100644
--- a/src/analysis/scan/expr.h
+++ b/src/analysis/scan/expr.h
@@ -30,6 +30,7 @@
#include "context.h"
+#include "scope.h"
@@ -77,7 +78,7 @@ bool g_scan_expression_check_validity(const GScanExpression *);
GScanExpression *g_scan_expression_duplicate(const GScanExpression *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_scan_expression_reduce(GScanExpression *, GScanContext *, bool);
+bool g_scan_expression_reduce(GScanExpression *, GScanContext *, GScanScope *, GScanExpression **);
diff --git a/src/analysis/scan/exprs/Makefile.am b/src/analysis/scan/exprs/Makefile.am
index f164864..efe25fc 100644
--- a/src/analysis/scan/exprs/Makefile.am
+++ b/src/analysis/scan/exprs/Makefile.am
@@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libanalysisscanexprs.la
libanalysisscanexprs_la_SOURCES = \
+ access-int.h \
+ access.h access.c \
arithmop-int.h \
arithmop.h arithmop.c \
boolop-int.h \
@@ -13,8 +15,8 @@ libanalysisscanexprs_la_SOURCES = \
literal.h literal.c \
relop-int.h \
relop.h relop.c \
- str-int.h \
- str.h str.c
+ strop-int.h \
+ strop.h strop.c
libanalysisscanexprs_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
diff --git a/src/analysis/scan/exprs/access-int.h b/src/analysis/scan/exprs/access-int.h
new file mode 100644
index 0000000..2212b48
--- /dev/null
+++ b/src/analysis/scan/exprs/access-int.h
@@ -0,0 +1,69 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * access-int.h - prototypes internes pour l'accès à un élément d'expression sous-jacent
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_ACCESS_INT_H
+#define _ANALYSIS_SCAN_EXPRS_ACCESS_INT_H
+
+
+#include "access.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Accès à un élément d'expression sous-jacent (instance) */
+struct _GNamedAccess
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ union
+ {
+ GRegisteredItem *base; /* Base de recherche */
+ GRegisteredItem *resolved; /* Elément ciblé au final */
+ GObject *any; /* Accès indistinct */
+ };
+
+ char *target; /* Cible dans l'espace */
+
+ struct _GNamedAccess *next; /* Evnetuel prochain élément */
+
+};
+
+/* Accès à un élément d'expression sous-jacent (classe) */
+struct _GNamedAccessClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression d'accès. */
+bool g_named_access_create(GNamedAccess *, const sized_string_t *);
+
+/* Réduit une expression à une forme plus simple. */
+bool _g_named_access_reduce(GNamedAccess *, GScanContext *, GScanScope *, GScanExpression **);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_ACCESS_INT_H */
diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c
new file mode 100644
index 0000000..ad66f60
--- /dev/null
+++ b/src/analysis/scan/exprs/access.c
@@ -0,0 +1,471 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * access.c - accès à un élément d'expression sous-jacent
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "access.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "access-int.h"
+#include "../../../core/global.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des appels de fonction avec arguments. */
+static void g_named_access_class_init(GNamedAccessClass *);
+
+/* Initialise une instance d'appel de fonction avec arguments. */
+static void g_named_access_init(GNamedAccess *);
+
+/* Supprime toutes les références externes. */
+static void g_named_access_dispose(GNamedAccess *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_named_access_finalize(GNamedAccess *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static void g_named_access_copy(GNamedAccess *, const GNamedAccess *);
+
+/* Réduit une expression à une forme plus simple. */
+static bool g_named_access_reduce(GNamedAccess *, GScanContext *, GScanScope *, GScanExpression **);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+G_DEFINE_TYPE(GNamedAccess, g_named_access, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des appels de fonction avec arguments. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_named_access_class_init(GNamedAccessClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_named_access_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_named_access_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)NULL;
+ expr->copy = (copy_expr_fc)g_named_access_copy;
+ expr->reduce = (reduce_expr_fc)g_named_access_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = instance à initialiser. *
+* *
+* Description : Initialise une instance d'appel de fonction avec arguments. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_named_access_init(GNamedAccess *access)
+{
+ access->any = NULL;
+ access->target = NULL;
+
+ access->next = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_named_access_dispose(GNamedAccess *access)
+{
+ g_clear_object(&access->any);
+
+ g_clear_object(&access->next);
+
+ G_OBJECT_CLASS(g_named_access_parent_class)->dispose(G_OBJECT(access));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_named_access_finalize(GNamedAccess *access)
+{
+ if (access->target != NULL)
+ free(access->target);
+
+ G_OBJECT_CLASS(g_named_access_parent_class)->finalize(G_OBJECT(access));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de l'objet d'appel à identifier. *
+* *
+* Description : Organise un accès à un élément d'expression sous-jacent. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_named_access_new(const sized_string_t *target)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_NAMED_ACCESS, NULL);
+
+ if (!g_named_access_create(G_NAMED_ACCESS(result), target))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = instance à initialiser pleinement. *
+* target = désignation de l'objet d'appel à identifier. *
+* *
+* Description : Met en place une expression d'accès. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_named_access_create(GNamedAccess *access, const sized_string_t *target)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_scan_expression_create(G_SCAN_EXPRESSION(access), EVT_PENDING);
+ if (!result) goto exit;
+
+ access->target = strndup(target->data, target->len);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = expression d'appel à actualiser. *
+* base = zone de recherche pour la résolution à venir. *
+* *
+* Description : Définit une base de recherche pour la cible d'accès. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_named_access_set_base(GNamedAccess *access, GRegisteredItem *base)
+{
+ g_clear_object(&access->base);
+
+ access->base = base;
+ g_object_ref(G_OBJECT(base));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : access = expression d'appel à compléter. *
+* next = expression d'appel suivante dans la chaîne. *
+* *
+* Description : Complète la chaine d'accès à des expressions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_named_access_attach_next(GNamedAccess *access, GNamedAccess *next)
+{
+ if (access->next != NULL)
+ g_named_access_attach_next(access->next, next);
+
+ else
+ {
+ access->next = next;
+ g_object_ref(G_OBJECT(next));
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_named_access_copy(GNamedAccess *dest, const GNamedAccess *src)
+{
+ GScanExpressionClass *class; /* Classe parente à solliciter */
+
+ class = G_SCAN_EXPRESSION_CLASS(g_named_access_parent_class);
+
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ if (src->any != NULL)
+ {
+ dest->any = src->any;
+ g_object_ref(src->any);
+ }
+
+ if (src->target != NULL)
+ dest->target = strdup(src->target);
+
+ if (src->next != NULL)
+ dest->next = G_NAMED_ACCESS(g_scan_expression_duplicate(G_SCAN_EXPRESSION(src->next)));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+ bool result; /* Bilan à retourner */
+ GRegisteredItem *base; /* Base de recherche courante */
+ GRegisteredItem *resolved; /* Cible concrète obtenue */
+ GNamedAccess *new; /* Copie mise en place */
+
+ result = true;
+
+ if (expr->target != NULL)
+ {
+ if (expr->base != NULL)
+ {
+ base = expr->base;
+ g_object_ref(G_OBJECT(base));
+ }
+ else
+ base = G_REGISTERED_ITEM(get_rost_root_namespace());
+
+ result = g_registered_item_resolve(base, expr->target, ctx, scope, &resolved);
+
+ g_object_unref(G_OBJECT(base));
+
+ if (result && resolved != NULL)
+ {
+ new = G_NAMED_ACCESS(g_scan_expression_duplicate(G_SCAN_EXPRESSION(expr)));
+
+ g_clear_object(&new->base);
+
+ free(new->target);
+ new->target = NULL;
+
+ new->resolved = resolved;
+
+ *out = G_SCAN_EXPRESSION(new);
+
+ }
+
+ }
+
+ /**
+ * Si plus aucune indication n'est diponible pour avancer dans les réductions,
+ * c'est que l'opération est déjà conclue.
+ */
+ else
+ {
+ assert(expr->resolved != NULL);
+
+ *out = G_SCAN_EXPRESSION(expr);
+ g_object_ref(G_OBJECT(*out));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+ bool result; /* Bilan à retourner */
+ GNamedAccess *new; /* Eventuel étage suivant */
+ GScanExpression *final; /* Expression d'évaluation */
+ GScanExpression *new_next; /* Nouvelle version du suivant */
+
+ result = _g_named_access_reduce(expr, ctx, scope, out);
+
+ if (result && *out != NULL)
+ {
+ assert(G_IS_NAMED_ACCESS(*out));
+
+ new = G_NAMED_ACCESS(*out);
+ *out = NULL;
+
+ assert(new->target == NULL);
+ assert(G_IS_NAMED_ACCESS(new));
+ assert(G_IS_REGISTERED_ITEM(new->resolved));
+
+ /**
+ * Si l'élément résolu se trouve en fin de chaîne, alors cet élément
+ * est sollicité pour obtenir une expression d'évaluation classique.
+ * Le produit de cette réduction finale bénéficie d'une promotion et
+ * représente à lui seul la réduction produite pour la chaîne.
+ */
+ if (new->next == NULL)
+ {
+ result = g_registered_item_reduce(new->resolved, ctx, scope, &final);
+
+ if (result && final != NULL)
+ {
+ g_clear_object(out);
+ *out = final;
+ }
+
+ }
+
+ /**
+ * Sinon, l'élément résolu constitue une base pour l'étage suivant de
+ * la chaîne de résolution.
+ */
+ else
+ {
+ new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(new->next));
+ assert(G_IS_NAMED_ACCESS(new_next));
+
+ g_named_access_set_base(G_NAMED_ACCESS(new_next), new->resolved);
+
+ g_clear_object(out);
+
+ result = g_scan_expression_reduce(new_next, ctx, scope, out);
+
+ if (result && *out == NULL)
+ *out = new_next;
+
+ }
+
+ g_object_unref(G_OBJECT(new));
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/access.h b/src/analysis/scan/exprs/access.h
new file mode 100644
index 0000000..a04adc7
--- /dev/null
+++ b/src/analysis/scan/exprs/access.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * access.h - prototypes pour l'accès à un élément d'expression sous-jacent
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_ACCESS_H
+#define _ANALYSIS_SCAN_EXPRS_ACCESS_H
+
+
+#include "../expr.h"
+#include "../item.h"
+#include "../../../common/szstr.h"
+
+
+
+#define G_TYPE_NAMED_ACCESS g_named_access_get_type()
+#define G_NAMED_ACCESS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_NAMED_ACCESS, GNamedAccess))
+#define G_IS_NAMED_ACCESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_NAMED_ACCESS))
+#define G_NAMED_ACCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_NAMED_ACCESS, GNamedAccessClass))
+#define G_IS_NAMED_ACCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_NAMED_ACCESS))
+#define G_NAMED_ACCESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_NAMED_ACCESS, GNamedAccessClass))
+
+
+/* Accès à un élément d'expression sous-jacent (instance) */
+typedef struct _GNamedAccess GNamedAccess;
+
+/* Accès à un élément d'expression sous-jacent (classe) */
+typedef struct _GNamedAccessClass GNamedAccessClass;
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+GType g_named_access_get_type(void);
+
+/* Organise un accès à un élément d'expression sous-jacent. */
+GScanExpression *g_named_access_new(const sized_string_t *);
+
+/* Définit une base de recherche pour la cible d'accès. */
+void g_named_access_set_base(GNamedAccess *, GRegisteredItem *);
+
+/* Complète la chaine d'accès à des expressions. */
+void g_named_access_attach_next(GNamedAccess *, GNamedAccess *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_ACCESS_H */
diff --git a/src/analysis/scan/exprs/arithmop-int.h b/src/analysis/scan/exprs/arithmop-int.h
index 75f1dbb..031de84 100644
--- a/src/analysis/scan/exprs/arithmop-int.h
+++ b/src/analysis/scan/exprs/arithmop-int.h
@@ -39,8 +39,8 @@ struct _GArithmOperation
ArithmeticExpressionOperator operator; /* Type d'opération menée */
- GScanExpression *first; /* Expression impactée #1 */
- GScanExpression *second; /* Expression impactée #2 */
+ GScanExpression *left; /* Expression impactée #1 */
+ GScanExpression *right; /* Expression impactée #2 */
};
diff --git a/src/analysis/scan/exprs/arithmop.c b/src/analysis/scan/exprs/arithmop.c
index f57e260..5f9e3f1 100644
--- a/src/analysis/scan/exprs/arithmop.c
+++ b/src/analysis/scan/exprs/arithmop.c
@@ -52,11 +52,11 @@ static void g_arithmetic_operation_finalize(GArithmOperation *);
/* Réalise une comparaison entre objets selon un critère précis. */
static bool g_arithmetic_operation_compare_rich(const GArithmOperation *, const GArithmOperation *, RichCmpOperation, bool *);
-/* Initialise une instance d'opération de relation. */
-static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *);
+/* Reproduit une expression en place dans une nouvelle instance. */
+static void g_arithmetic_operation_copy(GArithmOperation *, const GArithmOperation *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *, GScanContext *, bool);
+static bool g_arithmetic_operation_reduce(GArithmOperation *, GScanContext *, GScanScope *, GScanExpression **);
@@ -94,7 +94,7 @@ static void g_arithmetic_operation_class_init(GArithmOperationClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)g_arithmetic_operation_compare_rich;
- expr->dup = (dup_expr_fc)g_arithmetic_operation_duplicate;
+ expr->copy = (copy_expr_fc)g_arithmetic_operation_copy;
expr->reduce = (reduce_expr_fc)g_arithmetic_operation_reduce;
}
@@ -114,8 +114,8 @@ static void g_arithmetic_operation_class_init(GArithmOperationClass *klass)
static void g_arithmetic_operation_init(GArithmOperation *op)
{
- op->first = NULL;
- op->second = NULL;
+ op->left = NULL;
+ op->right = NULL;
}
@@ -134,8 +134,8 @@ static void g_arithmetic_operation_init(GArithmOperation *op)
static void g_arithmetic_operation_dispose(GArithmOperation *op)
{
- g_clear_object(&op->first);
- g_clear_object(&op->second);
+ g_clear_object(&op->left);
+ g_clear_object(&op->right);
G_OBJECT_CLASS(g_arithmetic_operation_parent_class)->dispose(G_OBJECT(op));
@@ -164,8 +164,8 @@ static void g_arithmetic_operation_finalize(GArithmOperation *op)
/******************************************************************************
* *
* Paramètres : operator = type d'opération arithmétique à représenter. *
-* first = premier opérande concerné. *
-* second = éventuel second opérande impliqué ou NULL. *
+* left = premier opérande concerné. *
+* right = éventuel second opérande impliqué ou NULL. *
* *
* Description : Organise une opération arithmétique entre expressions. *
* *
@@ -175,13 +175,13 @@ static void g_arithmetic_operation_finalize(GArithmOperation *op)
* *
******************************************************************************/
-GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operator, GScanExpression *left, GScanExpression *right)
{
GScanExpression *result; /* Structure à retourner */
result = g_object_new(G_TYPE_ARITHMETIC_OPERATION, NULL);
- if (!g_arithmetic_operation_create(G_ARITHMETIC_OPERATION(result), operator, first, second))
+ if (!g_arithmetic_operation_create(G_ARITHMETIC_OPERATION(result), operator, left, right))
g_clear_object(&result);
return result;
@@ -193,8 +193,8 @@ GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operato
* *
* Paramètres : op = instance à initialiser pleinement. *
* operator = type d'opération booléenne à représenter. *
-* first = premier opérande concerné. *
-* second = éventuel second opérande impliqué ou NULL. *
+* left = premier opérande concerné. *
+* right = éventuel second opérande impliqué ou NULL. *
* *
* Description : Met en place une opération arithmétique entre expressions. *
* *
@@ -204,19 +204,19 @@ GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operato
* *
******************************************************************************/
-bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOperator operator, GScanExpression *left, GScanExpression *right)
{
bool result; /* Bilan à retourner */
ExprValueType vtype; /* Type de valeur portée */
result = false;
- vtype = g_scan_expression_get_value_type(first);
+ vtype = g_scan_expression_get_value_type(left);
if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
goto exit;
- vtype = g_scan_expression_get_value_type(second);
+ vtype = g_scan_expression_get_value_type(right);
if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
goto exit;
@@ -226,11 +226,11 @@ bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOpe
op->operator = operator;
- op->first = first;
- g_object_ref(G_OBJECT(op->first));
+ op->left = left;
+ g_object_ref(G_OBJECT(op->left));
- op->second = second;
- g_object_ref(G_OBJECT(op->second));
+ op->right = right;
+ g_object_ref(G_OBJECT(op->right));
result = true;
@@ -265,9 +265,9 @@ bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOpe
static bool g_arithmetic_operation_compare_rich(const GArithmOperation *item, const GArithmOperation *other, RichCmpOperation op, bool *status)
{
bool result; /* Etat à retourner */
- bool equal; /* Bilan intermédiaire */
- result = true; // TODO : cmp parent()->type
+ result = g_type_is_a(G_TYPE_FROM_INSTANCE(other), G_TYPE_ARITHMETIC_OPERATION);
+ if (!result) goto done;
if (item->operator != other->operator)
{
@@ -275,18 +275,16 @@ static bool g_arithmetic_operation_compare_rich(const GArithmOperation *item, co
goto done;
}
- equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
- if (!equal)
- {
- result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
- G_COMPARABLE_ITEM(other->first),
- op, status);
- goto done;
- }
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->left),
+ G_COMPARABLE_ITEM(other->left),
+ op, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
- result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
- G_COMPARABLE_ITEM(other->second),
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->right),
+ G_COMPARABLE_ITEM(other->right),
op, status);
done:
@@ -298,23 +296,29 @@ static bool g_arithmetic_operation_compare_rich(const GArithmOperation *item, co
/******************************************************************************
* *
-* Paramètres : expr = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *expr)
+static void g_arithmetic_operation_copy(GArithmOperation *dest, const GArithmOperation *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
- result = g_arithmetic_operation_new(expr->operator, expr->first, expr->second);
+ class = G_SCAN_EXPRESSION_CLASS(g_arithmetic_operation_parent_class);
- return result;
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ dest->operator = src->operator;
+
+ dest->left = g_scan_expression_duplicate(src->left);
+ dest->right = g_scan_expression_duplicate(src->right);
}
@@ -323,92 +327,110 @@ static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = impose une conversion finale de dernier tour. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *expr, GScanContext *ctx, bool final)
+static bool g_arithmetic_operation_reduce(GArithmOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
- GScanExpression *new; /* Nouvelle expression obtenue */
+ bool result; /* Bilan à retourner */
+ GScanExpression *new_left; /* Expression réduite (gauche) */
+ GScanExpression *new_right; /* Expression réduite (droite) */
+ GLiteralExpression *op_left; /* Opérande gauche final */
+ GLiteralExpression *op_right; /* Opérande droite final */
unsigned long long val_1; /* Première valeur à traiter */
- unsigned long long val_2; /* Second valeur à traiter */
- bool valid; /* Validité de ce bilan obtenu */
+ unsigned long long val_2; /* Seconde valeur à traiter */
unsigned long long reduced; /* Valeur réduite finale */
- result = NULL;
-
/* Réduction des éléments considérés */
- new = g_scan_expression_reduce(expr->first, ctx, final);
-
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->first));
- expr->first = new;
- }
+ new_left = NULL;
+ new_right = NULL;
- if (expr->second != NULL)
- {
- new = g_scan_expression_reduce(expr->second, ctx, final);
+ result = g_scan_expression_reduce(expr->left, ctx, scope, &new_left);
+ if (!result) goto exit;
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->second));
- expr->second = new;
- }
-
- }
+ result = g_scan_expression_reduce(expr->right, ctx, scope, &new_right);
+ if (!result) goto exit;
/* Construction d'une réduction locale ? */
- if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ if (G_IS_LITERAL_EXPRESSION(new_left) && G_IS_LITERAL_EXPRESSION(new_right))
{
- valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->first), &val_1);
+ op_left = G_LITERAL_EXPRESSION(new_left);
+ op_right = G_LITERAL_EXPRESSION(new_right);
- if (valid)
- valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->second), &val_2);
+ result = g_literal_expression_get_integer_value(op_left, &val_1);
+ if (!result) goto exit;
- if (valid)
- switch (expr->operator)
- {
- case AEO_PLUS:
- reduced = val_1 + val_2;
- break;
+ result = g_literal_expression_get_integer_value(op_right, &val_2);
+ if (!result) goto exit;
- case AEO_MINUS:
- reduced = val_1 - val_2;
- break;
+ switch (expr->operator)
+ {
+ case AEO_PLUS:
+ reduced = val_1 + val_2;
+ break;
+
+ case AEO_MINUS:
+ reduced = val_1 - val_2;
+ break;
+
+ case AEO_MUL:
+ reduced = val_1 * val_2;
+ break;
+
+ case AEO_DIV:
+ result = (val_2 != 0);
+ if (result)
+ reduced = val_1 / val_2;
+ break;
+
+ case AEO_MOD:
+ result = (val_2 != 0);
+ if (result)
+ reduced = val_1 % val_2;
+ break;
- case AEO_MUL:
- reduced = val_1 * val_2;
- break;
+ }
- case AEO_DIV:
- valid = (val_2 != 0);
- if (valid)
- reduced = val_1 / val_2;
- break;
+ if (result)
+ *out = g_literal_expression_new(EVT_INTEGER, &reduced);
- case AEO_MOD:
- valid = (val_2 != 0);
- if (valid)
- reduced = val_1 % val_2;
- break;
+ }
- }
+ /* Mise à jour de la progression ? */
- if (valid)
- result = g_literal_expression_new(EVT_INTEGER, &reduced);
+ else if ((new_left != NULL && new_left != expr->left) || (new_right != NULL && new_right != expr->right))
+ {
+ if (new_left == NULL)
+ {
+ new_left = expr->left;
+ g_object_ref(G_OBJECT(new_left));
+ }
+
+ if (new_right == NULL)
+ {
+ new_right = expr->right;
+ g_object_ref(G_OBJECT(new_right));
+ }
+
+ *out = g_arithmetic_operation_new(expr->operator, new_left, new_right);
}
+ exit:
+
+ g_clear_object(&new_left);
+ g_clear_object(&new_right);
+
return result;
}
diff --git a/src/analysis/scan/exprs/boolop.c b/src/analysis/scan/exprs/boolop.c
index 2902fdd..f6a80dd 100644
--- a/src/analysis/scan/exprs/boolop.c
+++ b/src/analysis/scan/exprs/boolop.c
@@ -56,10 +56,10 @@ static void g_boolean_operation_finalize(GBoolOperation *);
static bool g_boolean_operation_compare_rich(const GBoolOperation *, const GBoolOperation *, RichCmpOperation, bool *);
/* Reproduit une expression en place dans une nouvelle instance. */
-static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *);
+static void g_boolean_operation_copy(GBoolOperation *, const GBoolOperation *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_boolean_operation_reduce(GBoolOperation *, GScanContext *, bool);
+static bool g_boolean_operation_reduce(GBoolOperation *, GScanContext *, GScanScope *, GScanExpression **);
@@ -97,7 +97,7 @@ static void g_boolean_operation_class_init(GBoolOperationClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)g_boolean_operation_compare_rich;
- expr->dup = (dup_expr_fc)g_boolean_operation_duplicate;
+ expr->copy = (copy_expr_fc)g_boolean_operation_copy;
expr->reduce = (reduce_expr_fc)g_boolean_operation_reduce;
}
@@ -278,9 +278,9 @@ bool g_boolean_operation_create(GBoolOperation *op, BooleanOperationType type, G
static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const GBoolOperation *other, RichCmpOperation op, bool *status)
{
bool result; /* Etat à retourner */
- bool equal; /* Bilan intermédiaire */
- result = true;
+ result = g_type_is_a(G_TYPE_FROM_INSTANCE(other), G_TYPE_BOOLEAN_OPERATION);
+ if (!result) goto done;
if (item->type != other->type)
{
@@ -288,15 +288,13 @@ static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const G
goto done;
}
- equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
- if (!equal)
- {
- *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
- G_COMPARABLE_ITEM(other->first),
- op, status);
- goto done;
- }
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+ G_COMPARABLE_ITEM(other->first),
+ op, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
if (item->second == NULL)
{
@@ -321,9 +319,9 @@ static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const G
}
else
- *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
- G_COMPARABLE_ITEM(other->second),
- op, status);
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+ G_COMPARABLE_ITEM(other->second),
+ op, status);
done:
@@ -334,23 +332,31 @@ static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const G
/******************************************************************************
* *
-* Paramètres : expr = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *expr)
+static void g_boolean_operation_copy(GBoolOperation *dest, const GBoolOperation *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
- result = g_boolean_operation_new(expr->type, expr->first, expr->second);
+ class = G_SCAN_EXPRESSION_CLASS(g_boolean_operation_parent_class);
- return result;
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ dest->type = src->type;
+
+ dest->first = g_scan_expression_duplicate(src->first);
+
+ if (src->second != NULL)
+ dest->second = g_scan_expression_duplicate(src->second);
}
@@ -359,92 +365,115 @@ static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *expr
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = impose une conversion finale de dernier tour. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_boolean_operation_reduce(GBoolOperation *expr, GScanContext *ctx, bool final)
+static bool g_boolean_operation_reduce(GBoolOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
- GScanExpression *new; /* Nouvelle expression obtenue */
+ bool result; /* Bilan à retourner */
+ GScanExpression *new_first; /* Expression réduite (gauche) */
+ GScanExpression *new_second; /* Expression réduite (droite) */
bool values[2]; /* Valeurs des éléments portés */
bool valid[2]; /* Validité de ces valeurs */
- result = NULL;
-
/* Réduction des éléments considérés */
- new = g_scan_expression_reduce(expr->first, ctx, final);
+ new_first = NULL;
+ new_second = NULL;
+
+ result = g_scan_expression_reduce(expr->first, ctx, scope, &new_first);
+ if (!result) goto exit;
- if (new != NULL)
+ if (expr->second == NULL)
+ new_second = NULL;
+ else
{
- g_object_unref(G_OBJECT(expr->first));
- expr->first = new;
+ result = g_scan_expression_reduce(expr->second, ctx, scope, &new_second);
+ if (!result) goto exit;
}
- if (expr->second != NULL)
- {
- new = g_scan_expression_reduce(expr->second, ctx, final);
+ /* Construction d'une réduction locale ? */
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->second));
- expr->second = new;
- }
+ valid[0] = G_IS_LITERAL_EXPRESSION(new_first);
- }
+ if (valid[0])
+ valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(new_first), &values[0]);
- /* Construction d'une réduction locale ? */
+ valid[1] = G_IS_LITERAL_EXPRESSION(new_second);
+
+ if (valid[1])
+ valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(new_second), &values[1]);
switch (expr->type)
{
case BOT_AND:
- if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
- {
- valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
- valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+ if (valid[0] && valid[1])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] && values[1] });
- if (valid[0] && valid[1])
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] && values[1] });
+ else if (valid[0] && !values[0])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
- else
- /* Etre malin si 0 && x => bilan (si ctx->quick) */
- ;
+ else if (valid[1] && !values[1])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
- }
break;
case BOT_OR:
- if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
- {
- valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
- valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+ if (valid[0] && valid[1])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] || values[1] });
- if (valid[0] && valid[1])
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] || values[1] });
+ else if (valid[0] && values[0])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { true });
+
+ else if (valid[1] && values[1])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { true });
- }
break;
case BOT_NOT:
- if (G_IS_LITERAL_EXPRESSION(expr->first))
- {
- valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+ if (valid[0])
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { !values[0] });
+ break;
- if (valid[0])
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { !values[1] });
+ }
+
+ /* Mise à jour de la progression ? */
+
+ if (*out == NULL)
+ {
+ if ((new_first != NULL && new_first != expr->first) || (new_second != NULL && new_second != expr->second))
+ {
+ if (new_first == NULL)
+ {
+ new_first = expr->first;
+ g_object_ref(G_OBJECT(new_first));
+ }
+ if (new_second == NULL)
+ {
+ new_second = expr->second;
+ g_object_ref(G_OBJECT(new_second));
}
- break;
+
+ *out = g_boolean_operation_new(expr->type, new_first, new_second);
+
+ }
}
+ exit:
+
+ g_clear_object(&new_first);
+ g_clear_object(&new_second);
+
return result;
}
diff --git a/src/analysis/scan/exprs/call-int.h b/src/analysis/scan/exprs/call-int.h
index d68977f..631a25b 100644
--- a/src/analysis/scan/exprs/call-int.h
+++ b/src/analysis/scan/exprs/call-int.h
@@ -28,35 +28,30 @@
#include "call.h"
-#include "../expr-int.h"
+#include "access-int.h"
/* Exécution d'une fonction auxiliaire d'analyse (instance) */
struct _GPendingCall
{
- GScanExpression parent; /* A laisser en premier */
-
- GRegisteredItem *base; /* Base de recherche */
- char *target; /* Cible dans l'espace */
+ GNamedAccess parent; /* A laisser en premier */
GScanExpression **args; /* Arguments d'appel fournis */
size_t count; /* Quantité de ces arguments */
- struct _GPendingCall *next; /* Evnetuel prochain élément */
-
};
/* Exécution d'une fonction auxiliaire d'analyse (classe) */
struct _GPendingCallClass
{
- GScanExpressionClass parent; /* A laisser en premier */
+ GNamedAccessClass parent; /* A laisser en premier */
};
/* Met en place une expression d'appel. */
-bool g_pending_call_create(GPendingCall *, const char *, size_t, GScanExpression **, size_t);
+bool g_pending_call_create(GPendingCall *, const sized_string_t *, GScanExpression **, size_t);
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
index 76f5fc3..dde627c 100644
--- a/src/analysis/scan/exprs/call.c
+++ b/src/analysis/scan/exprs/call.c
@@ -24,6 +24,7 @@
#include "call.h"
+#include <assert.h>
#include <malloc.h>
#include <string.h>
@@ -48,19 +49,16 @@ static void g_pending_call_dispose(GPendingCall *);
/* Procède à la libération totale de la mémoire. */
static void g_pending_call_finalize(GPendingCall *);
-/* Définit une base de recherche pour la cible d'appel. */
-static void g_pending_call_set_base(GPendingCall *, GRegisteredItem *);
-
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
/* Reproduit une expression en place dans une nouvelle instance. */
-static GScanExpression *g_pending_call_duplicate(const GPendingCall *);
+static void g_pending_call_copy(GPendingCall *, const GPendingCall *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_pending_call_reduce(GPendingCall *, GScanContext *, bool);
+static bool g_pending_call_reduce(GPendingCall *, GScanContext *, GScanScope *, GScanExpression **);
@@ -70,7 +68,7 @@ GScanExpression *g_pending_call_reduce(GPendingCall *, GScanContext *, bool);
/* Indique le type défini pour un appel de fonction enregistrée. */
-G_DEFINE_TYPE(GPendingCall, g_pending_call, G_TYPE_SCAN_EXPRESSION);
+G_DEFINE_TYPE(GPendingCall, g_pending_call, G_TYPE_NAMED_ACCESS);
/******************************************************************************
@@ -98,7 +96,7 @@ static void g_pending_call_class_init(GPendingCallClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)NULL;
- expr->dup = (dup_expr_fc)g_pending_call_duplicate;
+ expr->copy = (copy_expr_fc)g_pending_call_copy;
expr->reduce = (reduce_expr_fc)g_pending_call_reduce;
}
@@ -118,14 +116,9 @@ static void g_pending_call_class_init(GPendingCallClass *klass)
static void g_pending_call_init(GPendingCall *call)
{
- call->base = NULL;
- call->target = NULL;
-
call->args = NULL;
call->count = 0;
- call->next = NULL;
-
}
@@ -145,13 +138,9 @@ static void g_pending_call_dispose(GPendingCall *call)
{
size_t i; /* Boucle de parcours */
- g_clear_object(&call->base);
-
for (i = 0; i < call->count; i++)
g_clear_object(&call->args[i]);
- g_clear_object(&call->next);
-
G_OBJECT_CLASS(g_pending_call_parent_class)->dispose(G_OBJECT(call));
}
@@ -171,9 +160,6 @@ static void g_pending_call_dispose(GPendingCall *call)
static void g_pending_call_finalize(GPendingCall *call)
{
- if (call->target != NULL)
- free(call->target);
-
if (call->args != NULL)
free(call->args);
@@ -185,7 +171,6 @@ static void g_pending_call_finalize(GPendingCall *call)
/******************************************************************************
* *
* Paramètres : target = désignation de l'objet d'appel à identifier. *
-* len = taille de cette désignation. *
* args = éventuelle liste d'arguments à actionner. *
* count = quantité de ces arguments. *
* *
@@ -197,13 +182,13 @@ static void g_pending_call_finalize(GPendingCall *call)
* *
******************************************************************************/
-GScanExpression *g_pending_call_new(const char *target, size_t len, GScanExpression **args, size_t count)
+GScanExpression *g_pending_call_new(const sized_string_t *target, GScanExpression **args, size_t count)
{
GScanExpression *result; /* Structure à retourner */
result = g_object_new(G_TYPE_PENDING_CALL, NULL);
- if (!g_pending_call_create(G_PENDING_CALL(result), target, len, args, count))
+ if (!g_pending_call_create(G_PENDING_CALL(result), target, args, count))
g_clear_object(&result);
return result;
@@ -215,7 +200,6 @@ GScanExpression *g_pending_call_new(const char *target, size_t len, GScanExpress
* *
* Paramètres : call = instance à initialiser pleinement. *
* target = désignation de l'objet d'appel à identifier. *
-* len = taille de cette désignation. *
* args = éventuelle liste d'arguments à actionner. *
* count = quantité de ces arguments. *
* *
@@ -227,16 +211,14 @@ GScanExpression *g_pending_call_new(const char *target, size_t len, GScanExpress
* *
******************************************************************************/
-bool g_pending_call_create(GPendingCall *call, const char *target, size_t len, GScanExpression **args, size_t count)
+bool g_pending_call_create(GPendingCall *call, const sized_string_t *target, GScanExpression **args, size_t count)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
- result = g_scan_expression_create(G_SCAN_EXPRESSION(call), EVT_PENDING);
+ result = g_named_access_create(G_NAMED_ACCESS(call), target);
if (!result) goto exit;
- call->target = strndup(target, len);
-
call->args = malloc(count * sizeof(GScanExpression *));
call->count = count;
@@ -253,48 +235,6 @@ bool g_pending_call_create(GPendingCall *call, const char *target, size_t len, G
}
-/******************************************************************************
-* *
-* Paramètres : call = expression d'appel à actualiser. *
-* base = zone de recherche pour la résolution à venir. *
-* *
-* Description : Définit une base de recherche pour la cible d'appel. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_pending_call_set_base(GPendingCall *call, GRegisteredItem *base)
-{
- call->base = base;
- g_object_ref(G_OBJECT(base));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : call = expression d'appel à compléter. *
-* next = expression d'appel suivante dans la chaîne. *
-* *
-* Description : Complète la chaine d'expressions d'appel. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_pending_call_attach_next(GPendingCall *call, GPendingCall *next)
-{
- call->next = next;
- g_object_ref(G_OBJECT(next));
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
@@ -303,23 +243,31 @@ void g_pending_call_attach_next(GPendingCall *call, GPendingCall *next)
/******************************************************************************
* *
-* Paramètres : expr = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_pending_call_duplicate(const GPendingCall *expr)
+static void g_pending_call_copy(GPendingCall *dest, const GPendingCall *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
+ size_t i; /* Boucle de parcours */
- result = g_pending_call_new(expr->target, strlen(expr->target), expr->args, expr->count);
+ class = G_SCAN_EXPRESSION_CLASS(g_pending_call_parent_class);
- return result;
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ dest->args = malloc(src->count * sizeof(GScanExpression *));
+ dest->count = src->count;
+
+ for (i = 0; i < src->count; i++)
+ dest->args[i] = g_scan_expression_duplicate(src->args[i]);
}
@@ -328,99 +276,100 @@ static GScanExpression *g_pending_call_duplicate(const GPendingCall *expr)
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = indique une ultime conversion dans le cycle en cours.*
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_pending_call_reduce(GPendingCall *expr, GScanContext *ctx, bool final)
+static bool g_pending_call_reduce(GPendingCall *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
+ GNamedAccess *new; /* Eventuel étage suivant */
+ GPendingCall *new_call; /* Version en appel */
size_t i; /* Boucle de parcours */
- GScanExpression *new; /* Nouvelle expression obtenue */
- bool last; /* Détection de fin de chaîne */
- GRegisteredItem *base; /* Base de recherche courante */
- GRegisteredItem *rebase; /* Nouvelle base résolue */
+ GScanExpression *arg; /* Argument réduit à échanger */
+ GObject *final; /* Expression ou élément ? */
GScanExpression *new_next; /* Nouvelle version du suivant */
- for (i = 0; i < expr->count; i++)
+ result = _g_named_access_reduce(G_NAMED_ACCESS(expr), ctx, scope, out);
+
+ if (result && *out != NULL)
{
- new = g_scan_expression_reduce(expr->args[i], ctx, final);
+ assert(G_IS_NAMED_ACCESS(*out));
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->args[i]));
- expr->args[i] = new;
- }
+ new = G_NAMED_ACCESS(*out);
+ *out = NULL;
- }
+ assert(new->target == NULL);
+ assert(G_IS_PENDING_CALL(new));
+ assert(G_IS_REGISTERED_ITEM(new->resolved));
- last = (expr->next == NULL);
+ new_call = G_PENDING_CALL(new);
- if (!last)
- new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(expr->next));
- else
- new_next = NULL;
-
- if (expr->target != NULL)
- {
- if (expr->base != NULL)
+ for (i = 0; i < new_call->count; i++)
{
- base = expr->base;
- g_object_ref(G_OBJECT(base));
- }
- else
- base = G_REGISTERED_ITEM(get_rost_root_namespace());
+ result = g_scan_expression_reduce(new_call->args[i], ctx, scope, &arg);
+ if (!result) goto exit;
- rebase = g_registered_item_resolve(base, expr->target, ctx,
- last ? NULL : expr->args, last ? 0 : expr->count,
- last, final);
+ if (arg != NULL)
+ {
+ g_object_unref(G_OBJECT(new_call->args[i]));
+ new_call->args[i] = arg;
+ }
- g_object_unref(G_OBJECT(base));
- if (rebase == NULL)
- {
- result = NULL;
- goto done;
}
- if (last)
- {
- g_pending_call_set_base(expr, rebase);
+ result = g_registered_item_run_call(new->resolved,
+ new_call->args,
+ new_call->count,
+ ctx, scope, &final);
- free(expr->target);
- expr->target = NULL;
+ if (result && final != NULL)
+ {
+ /**
+ * Si le produit de l'appel à la fonction est une expression d'évaluation
+ * classique, alors ce produit constitue la réduction finale de la chaîne.
+ *
+ * Ce cas de figure ne se rencontre normalement qu'en bout de chaîne.
+ */
+ if (!G_IS_REGISTERED_ITEM(final))
+ {
+ assert(new->next == NULL);
+ *out = G_SCAN_EXPRESSION(final);
+ }
+ else
+ {
+ assert(new->next != NULL);
+
+ new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(new->next));
+ assert(G_IS_NAMED_ACCESS(new_next));
+
+ g_named_access_set_base(G_NAMED_ACCESS(new_next), G_REGISTERED_ITEM(final));
+
+ result = g_scan_expression_reduce(new_next, ctx, scope, out);
+
+ if (result && *out == NULL)
+ *out = new_next;
+ else
+ g_object_unref(G_OBJECT(new_next));
+
+ }
}
- else
- g_pending_call_set_base(G_PENDING_CALL(new_next), rebase);
-
- }
- if (last)
- result = g_registered_item_reduce(expr->base, ctx, expr->args, expr->count, final);
+ exit:
- else
- {
- result = g_scan_expression_reduce(new_next, ctx, final);
-
- if (result == NULL)
- {
- g_object_ref(G_OBJECT(new_next));
- result = new_next;
- }
+ g_object_unref(G_OBJECT(new));
}
- done:
-
- g_clear_object(&new_next);
-
return result;
}
diff --git a/src/analysis/scan/exprs/call.h b/src/analysis/scan/exprs/call.h
index b69ca85..c344036 100644
--- a/src/analysis/scan/exprs/call.h
+++ b/src/analysis/scan/exprs/call.h
@@ -26,7 +26,7 @@
#include "../expr.h"
-#include "../item.h"
+#include "../../../common/szstr.h"
@@ -49,10 +49,7 @@ typedef struct _GPendingCallClass GPendingCallClass;
GType g_pending_call_get_type(void);
/* Organise un appel de fonction avec ses arguments. */
-GScanExpression *g_pending_call_new(const char *, size_t, GScanExpression **, size_t);
-
-/* Complète la chaine d'expressions d'appel. */
-void g_pending_call_attach_next(GPendingCall *, GPendingCall *);
+GScanExpression *g_pending_call_new(const sized_string_t *, GScanExpression **, size_t);
diff --git a/src/analysis/scan/exprs/literal-int.h b/src/analysis/scan/exprs/literal-int.h
index d803d30..875b3de 100644
--- a/src/analysis/scan/exprs/literal-int.h
+++ b/src/analysis/scan/exprs/literal-int.h
@@ -46,7 +46,7 @@ struct _GLiteralExpression
{
bool boolean; /* Valeur booléenne */
unsigned long long integer; /* Valeur entière 64 bits */
- char *string; /* Chaîne de caractères */
+ sized_string_t string; /* Chaîne de caractères */
struct
{
char *regex; /* Formulation d'origine */
diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c
index f40747d..119b871 100644
--- a/src/analysis/scan/exprs/literal.c
+++ b/src/analysis/scan/exprs/literal.c
@@ -57,10 +57,10 @@ static void g_literal_expression_finalize(GLiteralExpression *);
static bool g_literal_expression_compare_rich(const GLiteralExpression *, const GLiteralExpression *, RichCmpOperation, bool *);
/* Reproduit une expression en place dans une nouvelle instance. */
-static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *);
+static void g_literal_expression_copy(GLiteralExpression *, const GLiteralExpression *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_literal_expression_reduce(GLiteralExpression *, GScanContext *, bool);
+static bool g_literal_expression_reduce(GLiteralExpression *, GScanContext *, GScanScope *, GScanExpression **);
@@ -98,7 +98,7 @@ static void g_literal_expression_class_init(GLiteralExpressionClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)g_literal_expression_compare_rich;
- expr->dup = (dup_expr_fc)g_literal_expression_duplicate;
+ expr->copy = (copy_expr_fc)g_literal_expression_copy;
expr->reduce = (reduce_expr_fc)g_literal_expression_reduce;
}
@@ -215,7 +215,8 @@ bool g_literal_expression_create(GLiteralExpression *expr, ExprValueType vtype,
va_list ap; /* Liste d'arguements */
const bool *boolean; /* Valeur booléenne */
const unsigned long long *integer; /* Valeur entière 64 bits */
- const char *string; /* Chaîne de caractères */
+ const sized_string_t *string; /* Chaîne de caractères */
+ const char *raw; /* Chaîne de caractères brute */
size_t len; /* Taille de la chaîne */
int cflags; /* Détails de compilation */
unsigned int i; /* Boucle de parcours */
@@ -241,15 +242,15 @@ bool g_literal_expression_create(GLiteralExpression *expr, ExprValueType vtype,
break;
case EVT_STRING:
- string = va_arg(ap, const char *);
- expr->value.string = strdup(string);
+ string = va_arg(ap, const sized_string_t *);
+ szstrdup(&expr->value.string, string);
break;
case EVT_REG_EXPR:
- string = va_arg(ap, const char *);
- len = strlen(string);
+ raw = va_arg(ap, const char *);
+ len = strlen(raw);
- result = (len > 2 && string[0] == '/');
+ result = (len > 2 && raw[0] == '/');
cflags = REG_EXTENDED | REG_NOSUB;
@@ -257,38 +258,38 @@ bool g_literal_expression_create(GLiteralExpression *expr, ExprValueType vtype,
{
result = (len > 2);
- if (string[len - 1] == 'i')
+ if (raw[len - 1] == 'i')
{
cflags |= REG_ICASE;
len -= 1;
}
- else if (string[len - 1] == 's')
+ else if (raw[len - 1] == 's')
{
cflags |= REG_NEWLINE;
len -= 1;
}
- else if (string[len - 1] == '/')
+ else if (raw[len - 1] == '/')
break;
}
if (result)
- result = (string[len - 1] == '/');
+ result = (raw[len - 1] == '/');
if (result)
{
assert(len > 2);
- tmp = strndup(&string[1], len - 2);
+ tmp = strndup(&raw[1], len - 2);
ret = regcomp(&expr->value.preg, tmp, cflags);
free(tmp);
result = (ret == 0);
if (result)
- expr->value.regex = strdup(string);
+ expr->value.regex = strdup(raw);
}
@@ -378,14 +379,14 @@ bool g_literal_expression_get_integer_value(const GLiteralExpression *item, unsi
* *
******************************************************************************/
-bool g_literal_expression_get_string_value(const GLiteralExpression *item, const char **value)
+bool g_literal_expression_get_string_value(const GLiteralExpression *item, const sized_string_t **value)
{
bool result; /* Etat à retourner */
result = (item->value_type == EVT_STRING);
if (result)
- *value = item->value.string;
+ *value = &item->value.string;
return result;
@@ -445,10 +446,12 @@ static bool g_literal_expression_compare_rich(const GLiteralExpression *item, co
bool result; /* Etat à retourner */
int cmp; /* Bilan intermédiaire */
+ result = g_type_is_a(G_TYPE_FROM_INSTANCE(other), G_TYPE_LITERAL_EXPRESSION);
+ if (!result) goto done;
+
if (item->value_type != other->value_type)
{
*status = compare_rich_integer_values(item->value_type, other->value_type, op);
- result = true;
goto done;
}
@@ -480,7 +483,7 @@ static bool g_literal_expression_compare_rich(const GLiteralExpression *item, co
break;
case EVT_STRING:
- cmp = strcmp(item->value.string, other->value.string);
+ cmp = szstrcmp(&item->value.string, &other->value.string);
*status = compare_rich_integer_values(cmp, 0, op);
result = true;
break;
@@ -506,51 +509,51 @@ static bool g_literal_expression_compare_rich(const GLiteralExpression *item, co
/******************************************************************************
* *
-* Paramètres : expr = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *expr)
+static void g_literal_expression_copy(GLiteralExpression *dest, const GLiteralExpression *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
- const void *ptr; /* Pointeur vers des données */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
+
+ class = G_SCAN_EXPRESSION_CLASS(g_literal_expression_parent_class);
+
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
- switch (expr->value_type)
+ dest->value_type = src->value_type;
+
+ switch (src->value_type)
{
case EVT_BOOLEAN:
- ptr = &expr->value.boolean;
+ dest->value.boolean = src->value.boolean;
break;
case EVT_INTEGER:
- ptr = &expr->value.integer;
+ dest->value.integer = src->value.integer;
break;
case EVT_STRING:
- ptr = &expr->value.string;
+ szstrdup(&dest->value.string, &src->value.string);
break;
case EVT_REG_EXPR:
- ptr = &expr->value.regex;
+ /*ptr = &expr->value.regex*//* FIXME */;
break;
default:
- ptr = NULL;
+ assert(false);
break;
}
- assert(ptr != NULL);
-
- result = g_literal_expression_new(expr->value_type, ptr);
-
- return result;
-
}
@@ -558,47 +561,25 @@ static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* force = impose une conversion en booléen si possible. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_literal_expression_reduce(GLiteralExpression *expr, GScanContext *ctx, bool force)
+static bool g_literal_expression_reduce(GLiteralExpression *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
-
- if (!force)
- result = NULL;
-
- else
- switch (expr->value_type)
- {
- case EVT_BOOLEAN:
- result = NULL;
- break;
-
- case EVT_INTEGER:
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { expr->value.integer > 0 });
- break;
-
- case EVT_STRING:
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.string) > 0 });
- break;
-
- case EVT_REG_EXPR:
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.regex) > 0 });
- break;
+ bool result; /* Bilan à retourner */
- default:
- result = NULL;
- break;
+ result = true;
- }
+ *out = G_SCAN_EXPRESSION(expr);
+ g_object_ref(G_OBJECT(expr));
return result;
diff --git a/src/analysis/scan/exprs/literal.h b/src/analysis/scan/exprs/literal.h
index ac5724f..7120c07 100644
--- a/src/analysis/scan/exprs/literal.h
+++ b/src/analysis/scan/exprs/literal.h
@@ -29,6 +29,7 @@
#include "../expr.h"
+#include "../../../common/szstr.h"
@@ -60,7 +61,7 @@ bool g_literal_expression_get_boolean_value(const GLiteralExpression *, bool *);
bool g_literal_expression_get_integer_value(const GLiteralExpression *, unsigned long long *);
/* Indique la valeur portée par une expression de chaîne. */
-bool g_literal_expression_get_string_value(const GLiteralExpression *, const char **);
+bool g_literal_expression_get_string_value(const GLiteralExpression *, const sized_string_t **);
/* Indique la valeur portée par une expression rationnelle. */
bool g_literal_expression_get_regex_value(const GLiteralExpression *, const regex_t **);
diff --git a/src/analysis/scan/exprs/relop-int.h b/src/analysis/scan/exprs/relop-int.h
index 273b543..3adbcf0 100644
--- a/src/analysis/scan/exprs/relop-int.h
+++ b/src/analysis/scan/exprs/relop-int.h
@@ -39,8 +39,8 @@ struct _GRelOperation
RichCmpOperation rel_type; /* Type de relation étudiée */
- GScanExpression *first; /* Expression impactée #1 */
- GScanExpression *second; /* Expression impactée #2 */
+ GScanExpression *left; /* Expression impactée #1 */
+ GScanExpression *right; /* Expression impactée #2 */
};
diff --git a/src/analysis/scan/exprs/relop.c b/src/analysis/scan/exprs/relop.c
index 94ce77d..7dc6864 100644
--- a/src/analysis/scan/exprs/relop.c
+++ b/src/analysis/scan/exprs/relop.c
@@ -52,11 +52,11 @@ static void g_relational_operation_finalize(GRelOperation *);
/* Réalise une comparaison entre objets selon un critère précis. */
static bool g_relational_operation_compare_rich(const GRelOperation *, const GRelOperation *, RichCmpOperation, bool *);
-/* Initialise une instance d'opération de relation. */
-static GScanExpression *g_relational_operation_duplicate(const GRelOperation *);
+/* Reproduit une expression en place dans une nouvelle instance. */
+static void g_relational_operation_copy(GRelOperation *, const GRelOperation *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_relational_operation_reduce(GRelOperation *, GScanContext *, bool);
+static bool g_relational_operation_reduce(GRelOperation *, GScanContext *, GScanScope *, GScanExpression **);
@@ -94,7 +94,7 @@ static void g_relational_operation_class_init(GRelOperationClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)g_relational_operation_compare_rich;
- expr->dup = (dup_expr_fc)g_relational_operation_duplicate;
+ expr->copy = (copy_expr_fc)g_relational_operation_copy;
expr->reduce = (reduce_expr_fc)g_relational_operation_reduce;
}
@@ -114,8 +114,8 @@ static void g_relational_operation_class_init(GRelOperationClass *klass)
static void g_relational_operation_init(GRelOperation *op)
{
- op->first = NULL;
- op->second = NULL;
+ op->left = NULL;
+ op->right = NULL;
}
@@ -134,8 +134,8 @@ static void g_relational_operation_init(GRelOperation *op)
static void g_relational_operation_dispose(GRelOperation *op)
{
- g_clear_object(&op->first);
- g_clear_object(&op->second);
+ g_clear_object(&op->left);
+ g_clear_object(&op->right);
G_OBJECT_CLASS(g_relational_operation_parent_class)->dispose(G_OBJECT(op));
@@ -163,9 +163,9 @@ static void g_relational_operation_finalize(GRelOperation *op)
/******************************************************************************
* *
-* Paramètres : type = type d'opération booléenne à représenter. *
-* first = premier opérande concerné. *
-* second = éventuel second opérande impliqué ou NULL. *
+* Paramètres : type = type d'opération booléenne à représenter. *
+* left = premier opérande concerné. *
+* right = éventuel second opérande impliqué ou NULL. *
* *
* Description : Organise une opération relationnelle entre expressions. *
* *
@@ -175,13 +175,13 @@ static void g_relational_operation_finalize(GRelOperation *op)
* *
******************************************************************************/
-GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpression *left, GScanExpression *right)
{
GScanExpression *result; /* Structure à retourner */
result = g_object_new(G_TYPE_RELATIONAL_OPERATION, NULL);
- if (!g_relational_operation_create(G_RELATIONAL_OPERATION(result), type, first, second))
+ if (!g_relational_operation_create(G_RELATIONAL_OPERATION(result), type, left, right))
g_clear_object(&result);
return result;
@@ -191,10 +191,10 @@ GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpressi
/******************************************************************************
* *
-* Paramètres : op = instance à initialiser pleinement. *
-* type = type d'opération booléenne à représenter. *
-* first = premier opérande concerné. *
-* second = éventuel second opérande impliqué ou NULL. *
+* Paramètres : op = instance à initialiser pleinement. *
+* type = type d'opération booléenne à représenter. *
+* left = premier opérande concerné. *
+* right = éventuel second opérande impliqué ou NULL. *
* *
* Description : Met en place une opération relationnelle entre expressions. *
* *
@@ -204,13 +204,13 @@ GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpressi
* *
******************************************************************************/
-bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GScanExpression *left, GScanExpression *right)
{
bool result; /* Bilan à retourner */
result = false;
- if (g_scan_expression_get_value_type(first) != g_scan_expression_get_value_type(first))
+ if (g_scan_expression_get_value_type(left) != g_scan_expression_get_value_type(left))
goto exit;
if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN))
@@ -218,11 +218,11 @@ bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GSc
op->rel_type = type;
- op->first = first;
- g_object_ref(G_OBJECT(op->first));
+ op->left = left;
+ g_object_ref(G_OBJECT(op->left));
- op->second = second;
- g_object_ref(G_OBJECT(op->second));
+ op->right = right;
+ g_object_ref(G_OBJECT(op->right));
result = true;
@@ -257,28 +257,26 @@ bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GSc
static bool g_relational_operation_compare_rich(const GRelOperation *item, const GRelOperation *other, RichCmpOperation op, bool *status)
{
bool result; /* Etat à retourner */
- bool equal; /* Bilan intermédiaire */
- result = true; // TODO : cmp parent()->type
+ result = g_type_is_a(G_TYPE_FROM_INSTANCE(other), G_TYPE_RELATIONAL_OPERATION);
+ if (!result) goto done;
if (item->rel_type != other->rel_type)
{
- result = compare_rich_integer_values(item->rel_type, other->rel_type, op);
+ *status = compare_rich_integer_values(item->rel_type, other->rel_type, op);
goto done;
}
- equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
- if (!equal)
- {
- result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
- G_COMPARABLE_ITEM(other->first),
- op, status);
- goto done;
- }
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->left),
+ G_COMPARABLE_ITEM(other->left),
+ op, status);
+ if (!result || STATUS_NOT_EQUAL(*status, op)) goto done;
- result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
- G_COMPARABLE_ITEM(other->second),
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->right),
+ G_COMPARABLE_ITEM(other->right),
op, status);
done:
@@ -290,23 +288,29 @@ static bool g_relational_operation_compare_rich(const GRelOperation *item, const
/******************************************************************************
* *
-* Paramètres : expr = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_relational_operation_duplicate(const GRelOperation *expr)
+static void g_relational_operation_copy(GRelOperation *dest, const GRelOperation *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
- result = g_relational_operation_new(expr->rel_type, expr->first, expr->second);
+ class = G_SCAN_EXPRESSION_CLASS(g_relational_operation_parent_class);
- return result;
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ dest->rel_type = src->rel_type;
+
+ dest->left = g_scan_expression_duplicate(src->left);
+ dest->right = g_scan_expression_duplicate(src->right);
}
@@ -315,60 +319,74 @@ static GScanExpression *g_relational_operation_duplicate(const GRelOperation *ex
* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = impose une conversion finale de dernier tour. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_relational_operation_reduce(GRelOperation *expr, GScanContext *ctx, bool final)
+static bool g_relational_operation_reduce(GRelOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
- GScanExpression *new; /* Nouvelle expression obtenue */
+ bool result; /* Bilan à retourner */
+ GScanExpression *new_left; /* Expression réduite (gauche) */
+ GScanExpression *new_right; /* Expression réduite (droite) */
bool status; /* Bilan d'une comparaison */
bool valid; /* Validité de ce bilan obtenu */
- result = NULL;
-
/* Réduction des éléments considérés */
- new = g_scan_expression_reduce(expr->first, ctx, final);
+ new_left = NULL;
+ new_right = NULL;
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->first));
- expr->first = new;
- }
+ result = g_scan_expression_reduce(expr->left, ctx, scope, &new_left);
+ if (!result) goto exit;
+
+ result = g_scan_expression_reduce(expr->right, ctx, scope, &new_right);
+ if (!result) goto exit;
+
+ /* Construction d'une réduction locale ? */
- if (expr->second != NULL)
+ if (G_IS_LITERAL_EXPRESSION(new_left) && G_IS_LITERAL_EXPRESSION(new_right))
{
- new = g_scan_expression_reduce(expr->second, ctx, final);
+ valid = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(new_left),
+ G_COMPARABLE_ITEM(new_right),
+ expr->rel_type, &status);
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(expr->second));
- expr->second = new;
- }
+ if (valid)
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { status });
}
- /* Construction d'une réduction locale ? */
+ /* Mise à jour de la progression ? */
- if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ else if ((new_left != NULL && new_left != expr->left) || (new_right != NULL && new_right != expr->right))
{
- valid = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(expr->first),
- G_COMPARABLE_ITEM(expr->second),
- expr->rel_type, &status);
+ if (new_left == NULL)
+ {
+ new_left = expr->left;
+ g_object_ref(G_OBJECT(new_left));
+ }
- if (valid)
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { status });
+ if (new_right == NULL)
+ {
+ new_right = expr->right;
+ g_object_ref(G_OBJECT(new_right));
+ }
+
+ *out = g_relational_operation_new(expr->rel_type, new_left, new_right);
}
+ exit:
+
+ g_clear_object(&new_left);
+ g_clear_object(&new_right);
+
return result;
}
diff --git a/src/analysis/scan/exprs/str-int.h b/src/analysis/scan/exprs/strop-int.h
index 9bed5cf..234ae8f 100644
--- a/src/analysis/scan/exprs/str-int.h
+++ b/src/analysis/scan/exprs/strop-int.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * str-int.h - prototypes internes pour la gestion des opérations booléennes
+ * strop-int.h - prototypes internes pour la gestion des opérations booléennes
*
* Copyright (C) 2022 Cyrille Bagard
*
@@ -21,14 +21,15 @@
*/
-#ifndef _ANALYSIS_SCAN_EXPRS_STR_INT_H
-#define _ANALYSIS_SCAN_EXPRS_STR_INT_H
+#ifndef _ANALYSIS_SCAN_EXPRS_STROP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_STROP_INT_H
-#include "str.h"
+#include "strop.h"
#include "../expr-int.h"
+#include "../../../common/extstr.h"
@@ -40,8 +41,8 @@ struct _GStringOperation
StringOperationType type; /* Type d'opération menée */
bool case_sensitive; /* Respect de la casse ? */
- GScanExpression *first; /* Expression impactée #1 */
- GScanExpression *second; /* Expression impactée #2 */
+ GScanExpression *left; /* Expression impactée #1 */
+ GScanExpression *right; /* Expression impactée #2 */
};
@@ -58,4 +59,4 @@ bool g_string_operation_create(GStringOperation *, StringOperationType, GScanExp
-#endif /* _ANALYSIS_SCAN_EXPRS_STR_INT_H */
+#endif /* _ANALYSIS_SCAN_EXPRS_STROP_INT_H */
diff --git a/src/analysis/scan/exprs/str.c b/src/analysis/scan/exprs/strop.c
index 675b2f6..145e8da 100644
--- a/src/analysis/scan/exprs/str.c
+++ b/src/analysis/scan/exprs/strop.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * str.c - gestion des opérations booléennes
+ * strop.c - gestion des opérations booléennes
*
* Copyright (C) 2022 Cyrille Bagard
*
@@ -21,7 +21,7 @@
*/
-#include "str.h"
+#include "strop.h"
#include <assert.h>
@@ -29,7 +29,7 @@
#include <strings.h>
-#include "str-int.h"
+#include "strop-int.h"
#include "literal.h"
@@ -55,10 +55,10 @@ static void g_string_operation_finalize(GStringOperation *);
/* Reproduit une expression en place dans une nouvelle instance. */
-static GScanExpression *g_string_operation_duplicate(const GStringOperation *);
+static void g_string_operation_copy(GStringOperation *, const GStringOperation *);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_string_operation_reduce(GStringOperation *, GScanContext *, bool);
+static bool g_string_operation_reduce(GStringOperation *, GScanContext *, GScanScope *, GScanExpression **);
@@ -96,7 +96,7 @@ static void g_string_operation_class_init(GStringOperationClass *klass)
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)NULL;
- expr->dup = (dup_expr_fc)g_string_operation_duplicate;
+ expr->copy = (copy_expr_fc)g_string_operation_copy;
expr->reduce = (reduce_expr_fc)g_string_operation_reduce;
}
@@ -116,8 +116,8 @@ static void g_string_operation_class_init(GStringOperationClass *klass)
static void g_string_operation_init(GStringOperation *op)
{
- op->first = NULL;
- op->second = NULL;
+ op->left = NULL;
+ op->right = NULL;
}
@@ -136,8 +136,8 @@ static void g_string_operation_init(GStringOperation *op)
static void g_string_operation_dispose(GStringOperation *op)
{
- g_clear_object(&op->first);
- g_clear_object(&op->second);
+ g_clear_object(&op->left);
+ g_clear_object(&op->right);
G_OBJECT_CLASS(g_string_operation_parent_class)->dispose(G_OBJECT(op));
@@ -196,9 +196,9 @@ GScanExpression *g_string_operation_new(StringOperationType type, GScanExpressio
* *
* Paramètres : op = instance à initialiser pleinement. *
* type = type d'opération booléenne à représenter. *
-* first = premier opérande concerné. *
-* second = éventuel second opérande impliqué ou NULL. *
-* sensitive = détermine la prise en compte de la casse. *
+* left = premier opérande concerné. *
+* right = éventuel second opérande impliqué ou NULL. *
+* sensitive = détermine la prise en compte de la casse. *
* *
* Description : Met en place une expression d'opération traite une chaîne. *
* *
@@ -208,19 +208,19 @@ GScanExpression *g_string_operation_new(StringOperationType type, GScanExpressio
* *
******************************************************************************/
-bool g_string_operation_create(GStringOperation *op, StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+bool g_string_operation_create(GStringOperation *op, StringOperationType type, GScanExpression *left, GScanExpression *right, bool sensitive)
{
bool result; /* Bilan à retourner */
ExprValueType vtype; /* Type de valeur portée */
result = false;
- vtype = g_scan_expression_get_value_type(first);
+ vtype = g_scan_expression_get_value_type(left);
if (vtype != EVT_STRING && vtype != EVT_PENDING)
goto exit;
- vtype = g_scan_expression_get_value_type(second);
+ vtype = g_scan_expression_get_value_type(right);
if (vtype != EVT_STRING && vtype != EVT_REG_EXPR && vtype != EVT_PENDING)
goto exit;
@@ -245,11 +245,11 @@ bool g_string_operation_create(GStringOperation *op, StringOperationType type, G
}
- op->first = first;
- g_object_ref(G_OBJECT(op->first));
+ op->left = left;
+ g_object_ref(G_OBJECT(op->left));
- op->second = second;
- g_object_ref(G_OBJECT(op->second));
+ op->right = right;
+ g_object_ref(G_OBJECT(op->right));
result = true;
@@ -268,170 +268,202 @@ bool g_string_operation_create(GStringOperation *op, StringOperationType type, G
/******************************************************************************
* *
-* Paramètres : op = expression à copier. *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
* *
* Description : Reproduit une expression en place dans une nouvelle instance.*
* *
-* Retour : Nouvelle instance d'expression. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_string_operation_duplicate(const GStringOperation *op)
+static void g_string_operation_copy(GStringOperation *dest, const GStringOperation *src)
{
- GScanExpression *result; /* Instance copiée à retourner */
+ GScanExpressionClass *class; /* Classe parente à solliciter */
- result = g_string_operation_new(op->type, op->first, op->second, op->case_sensitive);
+ class = G_SCAN_EXPRESSION_CLASS(g_string_operation_parent_class);
- return result;
+ class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
+
+ dest->type = src->type;
+ dest->case_sensitive = src->case_sensitive;
+
+ dest->left = g_scan_expression_duplicate(src->left);
+ dest->right = g_scan_expression_duplicate(src->right);
}
/******************************************************************************
* *
-* Paramètres : op = expression à consulter. *
+* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
-* final = impose une conversion finale de dernier tour. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_string_operation_reduce(GStringOperation *op, GScanContext *ctx, bool final)
+static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
- GScanExpression *new; /* Nouvelle expression obtenue */
- const char *strings[2]; /* Chaînes en jeu */
- bool status; /* Bilan intermédiaire */
- char *found; /* Eventuelle portion trouvée */
- size_t len[2]; /* Tailles max. de comparaison */
- int ret; /* Bilan de comparaison */
+ bool result; /* Bilan à retourner */
+ GScanExpression *new_left; /* Expression réduite (gauche) */
+ GScanExpression *new_right; /* Expression réduite (droite) */
+ GLiteralExpression *op_left; /* Opérande gauche final */
+ GLiteralExpression *op_right; /* Opérande droite final */
+ const sized_string_t *strings[2]; /* Chaînes en jeu */
+ const void *found; /* Présence d'une bribe ? */
+ bool status; /* Bilan de comparaison #1 */
+ size_t offset; /* Point de départ d'analyse */
const regex_t *preg; /* Expression rationnelle */
-
- result = NULL;
+ int ret; /* Bilan de comparaison #2 */
/* Réduction des éléments considérés */
- new = g_scan_expression_reduce(op->first, ctx, final);
+ new_left = NULL;
+ new_right = NULL;
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(op->first));
- op->first = new;
- }
+ result = g_scan_expression_reduce(expr->left, ctx, scope, &new_left);
+ if (!result) goto exit;
- new = g_scan_expression_reduce(op->second, ctx, final);
-
- if (new != NULL)
- {
- g_object_unref(G_OBJECT(op->second));
- op->second = new;
- }
+ result = g_scan_expression_reduce(expr->right, ctx, scope, &new_right);
+ if (!result) goto exit;
/* Construction d'une réduction locale ? */
- if (!G_IS_LITERAL_EXPRESSION(op->first))
- goto exit;
+ if (G_IS_LITERAL_EXPRESSION(new_left) && G_IS_LITERAL_EXPRESSION(new_right))
+ {
+ op_left = G_LITERAL_EXPRESSION(new_left);
+ op_right = G_LITERAL_EXPRESSION(new_right);
- if (!G_IS_LITERAL_EXPRESSION(op->second))
- goto exit;
+ result = g_literal_expression_get_string_value(op_left, &strings[0]);
+ if (!result) goto exit;
- status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->first), &strings[0]);
- if (!status) goto exit;
+ switch (expr->type)
+ {
+ case SOT_CONTAINS:
- switch (op->type)
- {
- case SOT_CONTAINS:
+ result = g_literal_expression_get_string_value(op_right, &strings[1]);
+ if (!result) goto exit;
- status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
- if (!status) goto exit;
+ if (expr->case_sensitive)
+ found = memmem(strings[0]->data, strings[0]->len, strings[1]->data, strings[1]->len);
- if (op->case_sensitive)
- found = strstr(strings[0], strings[1]);
- else
- found = strcasestr(strings[0], strings[1]);
+ else
+ found = memcasemem(strings[0]->data, strings[0]->len, strings[1]->data, strings[1]->len);
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { found != NULL });
- break;
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { found != NULL });
+ break;
- case SOT_STARTSWITH:
+ case SOT_STARTSWITH:
- status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
- if (!status) goto exit;
+ result = g_literal_expression_get_string_value(op_right, &strings[1]);
+ if (!result) goto exit;
- len[1] = strlen(strings[1]);
+ if (strings[0]->len < strings[1]->len)
+ status = false;
- if (op->case_sensitive)
- ret = strncmp(strings[0], strings[1], len[1]);
- else
- ret = strncasecmp(strings[0], strings[1], len[1]);
+ else
+ {
+ if (expr->case_sensitive)
+ ret = memcmp(strings[0]->data, strings[1]->data, strings[1]->len);
+ else
+ ret = memcasecmp(strings[0]->data, strings[1]->data, strings[1]->len);
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
- break;
+ status = (ret == 0);
- case SOT_ENDSWITH:
+ }
- len[0] = strlen(strings[0]);
+ result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ break;
- status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
- if (!status) goto exit;
+ case SOT_ENDSWITH:
- len[1] = strlen(strings[1]);
+ result = g_literal_expression_get_string_value(op_right, &strings[1]);
+ if (!result) goto exit;
- if (len[0] < len[1])
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+ if (strings[0]->len < strings[1]->len)
+ status = false;
- else
- {
- if (op->case_sensitive)
- ret = strncmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
else
- ret = strncasecmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
+ {
+ offset = strings[0]->len - strings[1]->len;
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+ if (expr->case_sensitive)
+ ret = memcmp(strings[0]->data + offset, strings[1]->data, strings[1]->len);
+ else
+ ret = memcasecmp(strings[0]->data + offset, strings[1]->data, strings[1]->len);
- }
- break;
+ status = (ret == 0);
- case SOT_MATCHES:
+ }
- status = g_literal_expression_get_regex_value(G_LITERAL_EXPRESSION(op->second), &preg);
- if (!status) goto exit;
+ result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ break;
- ret = regexec(preg, strings[0], 0, NULL, 0);
+ case SOT_MATCHES:
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
- break;
+ result = g_literal_expression_get_regex_value(op_right, &preg);
+ if (!result) goto exit;
- case SOT_IEQUALS:
+ ret = regexec(preg, strings[0]->data, 0, NULL, 0);
- len[0] = strlen(strings[0]);
+ *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
+ break;
- status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
- if (!status) goto exit;
+ case SOT_IEQUALS:
- len[1] = strlen(strings[1]);
+ result = g_literal_expression_get_string_value(op_right, &strings[1]);
+ if (!result) goto exit;
- if (len[0] != len[1])
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+ if (strings[0]->len != strings[1]->len)
+ status = false;
- else
- {
- ret = strcasecmp(strings[0], strings[1]);
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
- }
- break;
+ else
+ {
+ ret = memcasecmp(strings[0]->data, strings[1]->data, strings[1]->len);
+ status = (ret == 0);
+ }
+
+ result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ break;
+
+ }
+
+ }
+
+ /* Mise à jour de la progression ? */
+
+ else if ((new_left != NULL && new_left != expr->left) || (new_right != NULL && new_right != expr->right))
+ {
+ if (new_left == NULL)
+ {
+ new_left = expr->left;
+ g_object_ref(G_OBJECT(new_left));
+ }
+
+ if (new_right == NULL)
+ {
+ new_right = expr->right;
+ g_object_ref(G_OBJECT(new_right));
+ }
+
+ *out = g_string_operation_new(expr->type, new_left, new_right, expr->case_sensitive);
}
exit:
+ g_clear_object(&new_left);
+ g_clear_object(&new_right);
+
return result;
}
diff --git a/src/analysis/scan/exprs/str.h b/src/analysis/scan/exprs/strop.h
index 195f941..c7c0813 100644
--- a/src/analysis/scan/exprs/str.h
+++ b/src/analysis/scan/exprs/strop.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * str.h - prototypes pour la gestion des opérations booléennes
+ * strop.h - prototypes pour la gestion des opérations booléennes
*
* Copyright (C) 2022 Cyrille Bagard
*
@@ -21,8 +21,8 @@
*/
-#ifndef _ANALYSIS_SCAN_EXPRS_STR_H
-#define _ANALYSIS_SCAN_EXPRS_STR_H
+#ifndef _ANALYSIS_SCAN_EXPRS_STROP_H
+#define _ANALYSIS_SCAN_EXPRS_STROP_H
#include "../expr.h"
@@ -64,4 +64,4 @@ GScanExpression *g_string_operation_new(StringOperationType, GScanExpression *,
-#endif /* _ANALYSIS_SCAN_EXPRS_STR_H */
+#endif /* _ANALYSIS_SCAN_EXPRS_STROP_H */
diff --git a/src/analysis/scan/func-int.h b/src/analysis/scan/func-int.h
deleted file mode 100644
index 6591ba4..0000000
--- a/src/analysis/scan/func-int.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * func-int.h - prototypes internes pour la définition d'une fonction ciblant une propriété pendant un scan
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_FUNC_INT_H
-#define _ANALYSIS_SCAN_FUNC_INT_H
-
-
-#include "func.h"
-
-
-#include "item-int.h"
-
-
-
-/* Fonction apportant un support d'analyse pendant un scan (instance) */
-struct _GScanFunction
-{
- GRegisteredItem parent; /* A laisser en premier */
-
-};
-
-/* Fonction apportant un support d'analyse pendant un scan (classe) */
-struct _GScanFunctionClass
-{
- GRegisteredItemClass parent; /* A laisser en premier */
-
-};
-
-
-
-#endif /* _ANALYSIS_SCAN_FUNC_INT_H */
diff --git a/src/analysis/scan/func.c b/src/analysis/scan/func.c
deleted file mode 100644
index b839d1d..0000000
--- a/src/analysis/scan/func.c
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * func.c - définition d'une fonction ciblant une propriété pendant un scan
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "func.h"
-
-
-#include "func-int.h"
-
-
-
-/* Initialise la classe des fonctions de support pour scan. */
-static void g_scan_function_class_init(GScanFunctionClass *);
-
-/* Initialise une instance de fonction de support pour scan. */
-static void g_scan_function_init(GScanFunction *);
-
-/* Supprime toutes les références externes. */
-static void g_scan_function_dispose(GScanFunction *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_scan_function_finalize(GScanFunction *);
-
-
-
-/* Indique le type défini pour une définition de fonction de scan. */
-G_DEFINE_TYPE(GScanFunction, g_scan_function, G_TYPE_REGISTERED_ITEM);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des fonctions de support pour scan. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_function_class_init(GScanFunctionClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_function_dispose;
- object->finalize = (GObjectFinalizeFunc)g_scan_function_finalize;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : func = instance à initialiser. *
-* *
-* Description : Initialise une instance de fonction de support pour scan. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_function_init(GScanFunction *func)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : func = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_function_dispose(GScanFunction *func)
-{
- G_OBJECT_CLASS(g_scan_function_parent_class)->dispose(G_OBJECT(func));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : func = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_function_finalize(GScanFunction *func)
-{
- G_OBJECT_CLASS(g_scan_function_parent_class)->finalize(G_OBJECT(func));
-
-}
diff --git a/src/analysis/scan/func.h b/src/analysis/scan/func.h
deleted file mode 100644
index bfc823a..0000000
--- a/src/analysis/scan/func.h
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * func.h - prototypes pour la définition d'une fonction ciblant une propriété pendant un scan
- *
- * Copyright (C) 2022 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_FUNC_H
-#define _ANALYSIS_SCAN_FUNC_H
-
-
-#include <glib-object.h>
-
-
-
-#define G_TYPE_SCAN_FUNCTION g_scan_function_get_type()
-#define G_SCAN_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_FUNCTION, GScanFunction))
-#define G_IS_SCAN_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_FUNCTION))
-#define G_SCAN_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_FUNCTION, GScanFunctionClass))
-#define G_IS_SCAN_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_FUNCTION))
-#define G_SCAN_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_FUNCTION, GScanFunctionClass))
-
-
-/* Fonction apportant un support d'analyse pendant un scan (instance) */
-typedef struct _GScanFunction GScanFunction;
-
-/* Fonction apportant un support d'analyse pendant un scan (classe) */
-typedef struct _GScanFunctionClass GScanFunctionClass;
-
-
-/* Indique le type défini pour une définition de fonction de scan. */
-GType g_scan_function_get_type(void);
-
-
-
-#endif /* _ANALYSIS_SCAN_FUNC_H */
diff --git a/src/analysis/scan/funcs/Makefile.am b/src/analysis/scan/funcs/Makefile.am
deleted file mode 100644
index be370ba..0000000
--- a/src/analysis/scan/funcs/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-
-noinst_LTLIBRARIES = libanalysisscanfuncs.la
-
-
-libanalysisscanfuncs_la_SOURCES = \
- datasize.h datasize.c \
- uint-int.h \
- uint.h uint.c
-
-libanalysisscanfuncs_la_CFLAGS = $(LIBGOBJ_CFLAGS)
-
-
-devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
-
-dev_HEADERS = $(libanalysisscanfuncs_la_SOURCES:%c=)
diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y
index ab64ad8..525c5d1 100644
--- a/src/analysis/scan/grammar.y
+++ b/src/analysis/scan/grammar.y
@@ -17,12 +17,12 @@ static int yyerror(GContentScanner *, yyscan_t, GScanRule **, void/*GBytesPatter
typedef void *yyscan_t;
#include "scanner.h"
-#include "conds/counter.h"
+#include "exprs/access.h"
#include "exprs/arithmop.h"
#include "exprs/boolop.h"
#include "exprs/call.h"
#include "exprs/literal.h"
-#include "exprs/str.h"
+#include "exprs/strop.h"
#include "exprs/relop.h"
#include "patterns/tokens/plain.h"
@@ -46,14 +46,16 @@ typedef void *yyscan_t;
%union {
- //char *string; /* Chaîne de caractères #1 */
- const char *cstring; /* Chaîne de caractères #2 */
+ unsigned long long unsigned_integer; /* Valeur entière #1 */
+ signed long long signed_integer; /* Valeur entière #2 */
+ double floating_number; /* Valeur à virgule flottante */
+ sized_string_t sized_cstring; /* Chaîne de caractères */
+ char byte; /* Octet unique */
+
+
+
unsigned long long integer; /* Valeur entière */
- struct {
- const char *cstring; /* Chaîne de caractères #3 */
- size_t len; /* Taille correspondante */
- } sized_cstring;
GScanRule *rule; /* Nouvelle règle à intégrer */
void/*GBytesPattern*/ *pattern; /* Nouveau motif à considérer */
@@ -97,8 +99,6 @@ YY_DECL;
%token BRACE_IN BRACE_OUT ASSIGN COLON
-%token RAW_BLOCK
-
%token PLAIN_STRING
%token MASKED_STRING
@@ -147,8 +147,7 @@ YY_DECL;
%token THEM "them"
-%type <cstring> RULE_NAME
-%type <cstring> RAW_BLOCK
+%type <sized_cstring> RULE_NAME
%type <sized_cstring> IDENTIFIER
@@ -156,7 +155,7 @@ YY_DECL;
%type <integer> INTEGER
-%type <cstring> STRING
+%type <sized_cstring> STRING
%type <rule> rule
@@ -165,7 +164,7 @@ YY_DECL;
%type <expr> cexpression
%type <expr> literal
-%type <expr> callable
+%type <expr> item_chain
%type <args_list> call_args
%type <expr> bool_expr
%type <expr> rel_expr
@@ -214,7 +213,7 @@ rules : /* empty */
rule : RAW_RULE RULE_NAME
{
- *built_rule = g_scan_rule_new($2);
+ *built_rule = g_scan_rule_new($2.data);
$<rule>$ = *built_rule;
}
BRACE_IN strings condition BRACE_OUT
@@ -238,8 +237,8 @@ string_decls : string_decl
string_decl : IDENTIFIER ASSIGN PLAIN_STRING
{
GSearchPattern *__pat;
- __pat = g_plain_bytes_new((uint8_t *)$3.cstring, $3.len);
- g_search_pattern_set_name(__pat, $1.cstring, $1.len);
+ __pat = g_plain_bytes_new((uint8_t *)$3.data, $3.len);
+ g_search_pattern_set_name(__pat, $1.data, $1.len);
g_scan_rule_add_local_variable(*built_rule, __pat);
g_object_unref(G_OBJECT(__pat));
@@ -300,7 +299,7 @@ cexpression : IDENTIFIER
*/
}
| literal { $$ = $1; }
- | callable { $$ = $1; }
+ | item_chain { $$ = $1; }
| bool_expr { $$ = $1; }
| rel_expr { $$ = $1; }
| str_expr { $$ = $1; }
@@ -315,42 +314,42 @@ literal : "true" { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ true })
| INTEGER KB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1024 }); }
| INTEGER MB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1048576 }); }
| INTEGER GB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1073741824 }); }
- | STRING { $$ = g_literal_expression_new(EVT_STRING, $1); }
+ | STRING { $$ = g_literal_expression_new(EVT_STRING, &$1); }
;
-callable : NAME { $$ = g_pending_call_new($1.cstring, $1.len, NULL, 0); }
- | NAME "(" ")" { $$ = g_pending_call_new($1.cstring, $1.len, NULL, 0); }
+item_chain : NAME { $$ = g_named_access_new(&$1); }
+ | NAME "(" ")" { $$ = g_pending_call_new(&$1, NULL, 0); }
| NAME "(" call_args ")"
{
size_t __i;
- $$ = g_pending_call_new($1.cstring, $1.len, $3.args, $3.count);
+ $$ = g_pending_call_new(&$1, $3.args, $3.count);
for (__i = 0; __i < $3.count; __i++)
g_object_unref(G_OBJECT($3.args[__i]));
free($3.args);
}
- | callable "." NAME
+ | item_chain "." NAME
{
GScanExpression *__next;
- __next = g_pending_call_new($3.cstring, $3.len, NULL, 0);
- g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+ __next = g_named_access_new(&$3);
+ g_named_access_attach_next(G_NAMED_ACCESS($1), G_NAMED_ACCESS(__next));
$$ = $1;
}
- | callable "." NAME "(" ")"
+ | item_chain "." NAME "(" ")"
{
GScanExpression *__next;
- __next = g_pending_call_new($3.cstring, $3.len, NULL, 0);
- g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+ __next = g_pending_call_new(&$3, NULL, 0);
+ g_named_access_attach_next(G_NAMED_ACCESS($1), G_NAMED_ACCESS(__next));
$$ = $1;
}
- | callable "." NAME "(" call_args ")"
+ | item_chain "." NAME "(" call_args ")"
{
GScanExpression *__next;
size_t __i;
- __next = g_pending_call_new($3.cstring, $3.len, $5.args, $5.count);
+ __next = g_pending_call_new(&$3, $5.args, $5.count);
for (__i = 0; __i < $5.count; __i++)
g_object_unref(G_OBJECT($5.args[__i]));
free($5.args);
- g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+ g_named_access_attach_next(G_NAMED_ACCESS($1), G_NAMED_ACCESS(__next));
$$ = $1;
}
;
diff --git a/src/analysis/scan/item-int.h b/src/analysis/scan/item-int.h
index d1151f2..0ec4e46 100644
--- a/src/analysis/scan/item-int.h
+++ b/src/analysis/scan/item-int.h
@@ -32,11 +32,17 @@
-/* Lance une résolution d'élément à appeler. */
-typedef GRegisteredItem * (* resolve_registered_item_fc) (GRegisteredItem *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+/* Indique le nom associé à une expression d'évaluation. */
+typedef char * (* get_registered_item_name_fc) (const GRegisteredItem *);
+
+/* Lance une résolution d'élément à solliciter. */
+typedef bool (* resolve_registered_item_fc) (GRegisteredItem *, const char *, GScanContext *, GScanScope *, GRegisteredItem **);
/* Réduit une expression à une forme plus simple. */
-typedef GScanExpression * (* reduce_registered_item_fc) (GRegisteredItem *, GScanContext *, GScanExpression **, size_t, bool);
+typedef bool (* reduce_registered_item_fc) (GRegisteredItem *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Effectue un appel à une fonction enregistrée. */
+typedef bool (* run_registered_item_call_fc) (GRegisteredItem *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
/* Expression d'évaluation généraliste (instance) */
@@ -51,8 +57,10 @@ struct _GRegisteredItemClass
{
GObjectClass parent; /* A laisser en premier */
+ get_registered_item_name_fc get_name; /* Obtention du nom associé */
resolve_registered_item_fc resolve; /* Opération de résolution */
reduce_registered_item_fc reduce; /* Opération de réduction */
+ run_registered_item_call_fc run_call; /* Appel à une fonction connue */
};
diff --git a/src/analysis/scan/item.c b/src/analysis/scan/item.c
index c0b1532..d819f59 100644
--- a/src/analysis/scan/item.c
+++ b/src/analysis/scan/item.c
@@ -24,6 +24,9 @@
#include "item.h"
+#include <assert.h>
+
+
#include "item-int.h"
@@ -136,33 +139,67 @@ static void g_registered_item_finalize(GRegisteredItem *item)
/******************************************************************************
* *
+* Paramètres : item = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *g_registered_item_get_name(const GRegisteredItem *item)
+{
+ char *result; /* Désignation à retourner */
+ GRegisteredItemClass *class; /* Classe à activer */
+
+ class = G_REGISTERED_ITEM_GET_CLASS(item);
+
+ result = class->get_name(item);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : item = élément d'appel à consulter. *
* target = désignation de l'objet d'appel à identifier. *
* ctx = contexte de suivi de l'analyse courante. *
-* args = liste d'éventuels arguments fournis. *
-* count = taille de cette liste. *
-* last = l'élément est-il le dernier d'une chaîne d'appels ? *
-* final = indique une ultime conversion dans le cycle en cours.*
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
* *
-* Description : Lance une résolution d'élément à appeler. *
+* Description : Lance une résolution d'élément à solliciter. *
* *
-* Retour : Nouvel élément d'appel identifié ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GRegisteredItem *g_registered_item_resolve(GRegisteredItem *item, const char *target, GScanContext *ctx, GScanExpression **args, size_t count, bool last, bool final)
+bool g_registered_item_resolve(GRegisteredItem *item, const char *target, GScanContext *ctx, GScanScope *scope, GRegisteredItem **out)
{
- GRegisteredItem *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
GRegisteredItemClass *class; /* Classe à activer */
+ *out = NULL;
+
class = G_REGISTERED_ITEM_GET_CLASS(item);
if (class->resolve == NULL)
- result = NULL;
+ result = false;
else
- result = class->resolve(item, target, ctx, args, count, last, final);
+ {
+ result = class->resolve(item, target, ctx, scope, out);
+
+#ifndef NDEBUG
+ if (*out != NULL)
+ assert(result);
+#endif
+
+ }
return result;
@@ -171,28 +208,84 @@ GRegisteredItem *g_registered_item_resolve(GRegisteredItem *item, const char *ta
/******************************************************************************
* *
-* Paramètres : item = élément d'appel à consulter. *
-* ctx = contexte de suivi de l'analyse courante. *
-* args = liste d'éventuels arguments fournis. *
-* count = taille de cette liste. *
-* final = indique une ultime conversion dans le cycle en cours.*
+* Paramètres : item = élément d'appel à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GScanExpression *g_registered_item_reduce(GRegisteredItem *item, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+bool g_registered_item_reduce(GRegisteredItem *item, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
GRegisteredItemClass *class; /* Classe à activer */
+ *out = NULL;
+
class = G_REGISTERED_ITEM_GET_CLASS(item);
- result = class->reduce(item, ctx, args, count, final);
+ if (class->reduce == NULL)
+ result = false;
+ else
+ {
+ result = class->reduce(item, ctx, scope, out);
+
+#ifndef NDEBUG
+ if (*out != NULL)
+ assert(result);
+#endif
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* args = liste d'éventuels arguments fournis. *
+* count = taille de cette liste. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT] *
+* *
+* Description : Effectue un appel à une fonction enregistrée. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_registered_item_run_call(GRegisteredItem *item, GScanExpression **args, size_t count, GScanContext *ctx, GScanScope *scope, GObject **out)
+{
+ bool result; /* Bilan à retourner */
+ GRegisteredItemClass *class; /* Classe à activer */
+
+ *out = NULL;
+
+ class = G_REGISTERED_ITEM_GET_CLASS(item);
+
+ if (class->run_call == NULL)
+ result = false;
+ else
+ {
+ result = class->run_call(item, args, count, ctx, scope, out);
+
+#ifndef NDEBUG
+ if (*out != NULL)
+ assert(result);
+#endif
+
+ }
return result;
diff --git a/src/analysis/scan/item.h b/src/analysis/scan/item.h
index e3e02e6..fee1e2c 100644
--- a/src/analysis/scan/item.h
+++ b/src/analysis/scan/item.h
@@ -52,11 +52,17 @@ typedef struct _GRegisteredItemClass GRegisteredItemClass;
/* Indique le type défini pour un élément appelable et enregistré. */
GType g_registered_item_get_type(void);
-/* Lance une résolution d'élément à appeler. */
-GRegisteredItem *g_registered_item_resolve(GRegisteredItem *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+/* Indique le nom associé à une expression d'évaluation. */
+char *g_registered_item_get_name(const GRegisteredItem *);
+
+/* Lance une résolution d'élément à solliciter. */
+bool g_registered_item_resolve(GRegisteredItem *, const char *, GScanContext *, GScanScope *, GRegisteredItem **);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_registered_item_reduce(GRegisteredItem *, GScanContext *, GScanExpression **, size_t, bool);
+bool g_registered_item_reduce(GRegisteredItem *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Effectue un appel à une fonction enregistrée. */
+bool g_registered_item_run_call(GRegisteredItem *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
diff --git a/src/analysis/scan/items/Makefile.am b/src/analysis/scan/items/Makefile.am
new file mode 100644
index 0000000..3a6bb62
--- /dev/null
+++ b/src/analysis/scan/items/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libanalysisscanitems.la
+
+
+libanalysisscanitems_la_SOURCES = \
+ datasize.h datasize.c \
+ uint-int.h \
+ uint.h uint.c
+
+libanalysisscanitems_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanitems_la_SOURCES:%c=)
diff --git a/src/analysis/scan/funcs/datasize.c b/src/analysis/scan/items/datasize.c
index 7e63095..618d0c3 100644
--- a/src/analysis/scan/funcs/datasize.c
+++ b/src/analysis/scan/items/datasize.c
@@ -24,7 +24,7 @@
#include "datasize.h"
-#include "../func-int.h"
+#include "../item-int.h"
#include "../exprs/literal.h"
@@ -49,8 +49,14 @@ static void g_datasize_function_finalize(GDatasizeFunction *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_datasize_function_get_name(const GDatasizeFunction *);
+
+/* Réduit une expression à une forme plus simple. */
+static bool g_datasize_function_reduce(GDatasizeFunction *, GScanContext *, GScanScope *, GScanExpression **);
+
/* Réduit une expression à une forme plus simple. */
-static GScanExpression *g_datasize_function_reduce(GDatasizeFunction *, GScanContext *, GScanExpression **, size_t, bool);
+static bool g_datasize_function_run_call(GDatasizeFunction *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
@@ -60,7 +66,7 @@ static GScanExpression *g_datasize_function_reduce(GDatasizeFunction *, GScanCon
/* Indique le type défini pour une mesure de quantité de données scannées. */
-G_DEFINE_TYPE(GDatasizeFunction, g_datasize_function, G_TYPE_SCAN_FUNCTION);
+G_DEFINE_TYPE(GDatasizeFunction, g_datasize_function, G_TYPE_REGISTERED_ITEM);
/******************************************************************************
@@ -87,7 +93,9 @@ static void g_datasize_function_class_init(GDatasizeFunctionClass *klass)
registered = G_REGISTERED_ITEM_CLASS(klass);
+ registered->get_name = (get_registered_item_name_fc)g_datasize_function_get_name;
registered->reduce = (reduce_registered_item_fc)g_datasize_function_reduce;
+ registered->run_call = (run_registered_item_call_fc)g_datasize_function_run_call;
}
@@ -160,9 +168,9 @@ static void g_datasize_function_finalize(GDatasizeFunction *func)
* *
******************************************************************************/
-GScanFunction *g_datasize_function_new(void)
+GDatasizeFunction *g_datasize_function_new(void)
{
- GScanFunction *result; /* Structure à retourner */
+ GDatasizeFunction *result; /* Structure à retourner */
result = g_object_new(G_TYPE_DATASIZE_FUNCTION, NULL);
@@ -179,36 +187,86 @@ GScanFunction *g_datasize_function_new(void)
/******************************************************************************
* *
-* Paramètres : func = élément d'appel à consulter. *
-* target = désignation de l'objet d'appel à identifier. *
-* ctx = contexte de suivi de l'analyse courante. *
-* args = liste d'éventuels arguments fournis. *
-* count = taille de cette liste. *
-* last = l'élément est-il le dernier d'une chaîne d'appels ? *
-* final = indique une ultime conversion dans le cycle en cours.*
+* Paramètres : item = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_datasize_function_get_name(const GDatasizeFunction *item)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("datasize");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
-* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-static GScanExpression *g_datasize_function_reduce(GDatasizeFunction *func, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+static bool g_datasize_function_reduce(GDatasizeFunction *item, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- GScanExpression *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
GBinContent *content; /* Contenu à manipuler */
phys_t size; /* Quantité de données liées */
+ result = true;
+
content = g_scan_context_get_content(ctx);
size = g_binary_content_compute_size(content);
- result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ size });
+ *out = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ size });
g_object_unref(G_OBJECT(content));
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* args = liste d'éventuels arguments fournis. *
+* count = taille de cette liste. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_datasize_function_run_call(GDatasizeFunction *item, GScanExpression **args, size_t count, GScanContext *ctx, GScanScope *scope, GObject **out)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_datasize_function_reduce(item, ctx, scope, (GScanExpression **)out);
+
+ return result;
+
+}
diff --git a/src/analysis/scan/funcs/datasize.h b/src/analysis/scan/items/datasize.h
index bdd813d..bd8e185 100644
--- a/src/analysis/scan/funcs/datasize.h
+++ b/src/analysis/scan/items/datasize.h
@@ -21,11 +21,14 @@
*/
-#ifndef _ANALYSIS_SCAN_FUNCS_DATASIZE_H
-#define _ANALYSIS_SCAN_FUNCS_DATASIZE_H
+#ifndef _ANALYSIS_SCAN_ITEMS_DATASIZE_H
+#define _ANALYSIS_SCAN_ITEMS_DATASIZE_H
-#include "../func.h"
+#include <glib-object.h>
+
+
+#include "../item.h"
@@ -38,18 +41,18 @@
/* Mesure de la quantité de données scannées (instance) */
-typedef GScanFunction GDatasizeFunction;
+typedef GRegisteredItem GDatasizeFunction;
/* Mesure de la quantité de données scannées (classe) */
-typedef GScanFunctionClass GDatasizeFunctionClass;
+typedef GRegisteredItemClass GDatasizeFunctionClass;
/* Indique le type défini pour une mesure de quantité de données scannées. */
GType g_datasize_function_get_type(void);
/* Constitue une fonction de récupération de taille de données. */
-GScanFunction *g_datasize_function_new(void);
+GDatasizeFunction *g_datasize_function_new(void);
-#endif /* _ANALYSIS_SCAN_FUNCS_DATASIZE_H */
+#endif /* _ANALYSIS_SCAN_ITEMS_DATASIZE_H */
diff --git a/src/analysis/scan/funcs/uint-int.h b/src/analysis/scan/items/uint-int.h
index 0817805..1fa83c5 100644
--- a/src/analysis/scan/funcs/uint-int.h
+++ b/src/analysis/scan/items/uint-int.h
@@ -21,21 +21,21 @@
*/
-#ifndef _ANALYSIS_SCAN_FUNCS_UINT_INT_H
-#define _ANALYSIS_SCAN_FUNCS_UINT_INT_H
+#ifndef _ANALYSIS_SCAN_ITEMS_UINT_INT_H
+#define _ANALYSIS_SCAN_ITEMS_UINT_INT_H
#include "uint.h"
-#include "../func-int.h"
+#include "../item-int.h"
/* Fonction conduisant à la lecture d'un mot (instance) */
struct _GUintFunction
{
- GScanFunction parent; /* A laisser en premier */
+ GRegisteredItem parent; /* A laisser en premier */
MemoryDataSize size; /* Taille du mot à lire */
SourceEndian endian; /* Boutisme à respecter */
@@ -45,10 +45,14 @@ struct _GUintFunction
/* Fonction conduisant à la lecture d'un mot (classe) */
struct _GUintFunctionClass
{
- GScanFunctionClass parent; /* A laisser en premier */
+ GRegisteredItemClass parent; /* A laisser en premier */
};
+/* Met en place un nouvelle fonction de lecture d'entiers. */
+bool g_uint_function_create(GUintFunction *, MemoryDataSize);
-#endif /* _ANALYSIS_SCAN_FUNCS_UINT_INT_H */
+
+
+#endif /* _ANALYSIS_SCAN_ITEMS_UINT_INT_H */
diff --git a/src/analysis/scan/funcs/uint.c b/src/analysis/scan/items/uint.c
index 6421f52..4fea494 100644
--- a/src/analysis/scan/funcs/uint.c
+++ b/src/analysis/scan/items/uint.c
@@ -24,6 +24,9 @@
#include "uint.h"
+#include <assert.h>
+
+
#include "uint-int.h"
#include "../exprs/literal.h"
@@ -49,8 +52,11 @@ static void g_uint_function_finalize(GUintFunction *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_uint_function_get_name(const GUintFunction *);
+
/* Réduit une expression à une forme plus simple. */
-static GScanExpression *g_uint_function_reduce(GUintFunction *, GScanContext *, GScanExpression **, size_t, bool);
+static bool g_uint_function_run_call(GUintFunction *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
@@ -60,7 +66,7 @@ static GScanExpression *g_uint_function_reduce(GUintFunction *, GScanContext *,
/* Indique le type défini pour une lecture de mot à partir de données binaires. */
-G_DEFINE_TYPE(GUintFunction, g_uint_function, G_TYPE_SCAN_FUNCTION);
+G_DEFINE_TYPE(GUintFunction, g_uint_function, G_TYPE_REGISTERED_ITEM);
/******************************************************************************
@@ -87,7 +93,8 @@ static void g_uint_function_class_init(GUintFunctionClass *klass)
registered = G_REGISTERED_ITEM_CLASS(klass);
- registered->reduce = (reduce_registered_item_fc)g_uint_function_reduce;
+ registered->get_name = (get_registered_item_name_fc)g_uint_function_get_name;
+ registered->run_call = (run_registered_item_call_fc)g_uint_function_run_call;
}
@@ -162,13 +169,40 @@ static void g_uint_function_finalize(GUintFunction *func)
* *
******************************************************************************/
-GScanFunction *g_uint_function_new(MemoryDataSize size)
+GUintFunction *g_uint_function_new(MemoryDataSize size)
{
- GScanFunction *result; /* Structure à retourner */
+ GUintFunction *result; /* Structure à retourner */
result = g_object_new(G_TYPE_UINT_FUNCTION, NULL);
- G_UINT_FUNCTION(result)->size = size;
+ if (!g_uint_function_create(result, size))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : func = encadrement d'un parcours de correspondances. *
+* size = taille du mot à venir lire dans les données. *
+* *
+* Description : Met en place un nouvelle fonction de lecture d'entiers. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_uint_function_create(GUintFunction *func, MemoryDataSize size)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ func->size = size;
return result;
@@ -183,13 +217,58 @@ GScanFunction *g_uint_function_new(MemoryDataSize size)
/******************************************************************************
* *
-* Paramètres : func = élément d'appel à consulter. *
-* target = désignation de l'objet d'appel à identifier. *
-* ctx = contexte de suivi de l'analyse courante. *
-* args = liste d'éventuels arguments fournis. *
-* count = taille de cette liste. *
-* last = l'élément est-il le dernier d'une chaîne d'appels ? *
-* final = indique une ultime conversion dans le cycle en cours.*
+* Paramètres : item = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_uint_function_get_name(const GUintFunction *item)
+{
+ char *result; /* Désignation à retourner */
+
+ switch (item->size)
+ {
+ case MDS_8_BITS_UNSIGNED:
+ result = strdup("uint8");
+ break;
+
+ case MDS_16_BITS_UNSIGNED:
+ result = strdup("uint16");
+ break;
+
+ case MDS_32_BITS_UNSIGNED:
+ result = strdup("uint32");
+ break;
+
+ case MDS_64_BITS_UNSIGNED:
+ result = strdup("uint64");
+ break;
+
+ default:
+ assert(false);
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* args = liste d'éventuels arguments fournis. *
+* count = taille de cette liste. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT] *
* *
* Description : Réduit une expression à une forme plus simple. *
* *
@@ -199,11 +278,10 @@ GScanFunction *g_uint_function_new(MemoryDataSize size)
* *
******************************************************************************/
-static GScanExpression *g_uint_function_reduce(GUintFunction *func, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+static bool g_uint_function_run_call(GUintFunction *item, GScanExpression **args, size_t count, GScanContext *ctx, GScanScope *scope, GObject **out)
{
- GScanExpression *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
unsigned long long offset; /* Position du mot ciblé */
- bool status; /* Bilan d'une opération */
GBinContent *content; /* Contenu à manipuler */
vmpa2t pos; /* Tête de lecture */
uint8_t val_8; /* Valeur entière sur 8 bits */
@@ -211,54 +289,51 @@ static GScanExpression *g_uint_function_reduce(GUintFunction *func, GScanContext
uint32_t val_32; /* Valeur entière sur 32 bits */
uint64_t val_64; /* Valeur entière sur 64 bits */
- result = NULL;
-
- if (count == 1 && G_IS_LITERAL_EXPRESSION(args[0]))
- {
- status = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(args[0]), &offset);
- if (!status) goto exit;
-
- content = g_scan_context_get_content(ctx);
-
- g_binary_content_compute_start_pos(content, &pos);
- advance_vmpa(&pos, offset);
+ result = (count == 1 && G_IS_LITERAL_EXPRESSION(args[0]));
+ if (!result) goto exit;
- switch (func->size)
- {
- case MDS_8_BITS_UNSIGNED:
- status = g_binary_content_read_u8(content, &pos, &val_8);
- if (status)
- result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_8 });
- break;
+ result = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(args[0]), &offset);
+ if (!result) goto exit;
- case MDS_16_BITS_UNSIGNED:
- status = g_binary_content_read_u16(content, &pos, func->endian, &val_16);
- if (status)
- result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_16 });
- break;
+ content = g_scan_context_get_content(ctx);
- case MDS_32_BITS_UNSIGNED:
- status = g_binary_content_read_u32(content, &pos, func->endian, &val_32);
- if (status)
- result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_32 });
- break;
+ g_binary_content_compute_start_pos(content, &pos);
+ advance_vmpa(&pos, offset);
-
- case MDS_64_BITS_UNSIGNED:
- status = g_binary_content_read_u64(content, &pos, func->endian, &val_64);
- if (status)
- result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_64 });
- break;
-
- default:
- break;
-
- }
-
- g_object_unref(G_OBJECT(content));
+ switch (item->size)
+ {
+ case MDS_8_BITS_UNSIGNED:
+ result = g_binary_content_read_u8(content, &pos, &val_8);
+ if (result)
+ *out = G_OBJECT(g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_8 }));
+ break;
+
+ case MDS_16_BITS_UNSIGNED:
+ result = g_binary_content_read_u16(content, &pos, item->endian, &val_16);
+ if (result)
+ *out = G_OBJECT(g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_16 }));
+ break;
+
+ case MDS_32_BITS_UNSIGNED:
+ result = g_binary_content_read_u32(content, &pos, item->endian, &val_32);
+ if (result)
+ *out = G_OBJECT(g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_32 }));
+ break;
+
+
+ case MDS_64_BITS_UNSIGNED:
+ result = g_binary_content_read_u64(content, &pos, item->endian, &val_64);
+ if (result)
+ *out = G_OBJECT(g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_64 }));
+ break;
+
+ default:
+ break;
}
+ g_object_unref(G_OBJECT(content));
+
exit:
return result;
diff --git a/src/analysis/scan/funcs/uint.h b/src/analysis/scan/items/uint.h
index fe6cb52..60f2975 100644
--- a/src/analysis/scan/funcs/uint.h
+++ b/src/analysis/scan/items/uint.h
@@ -21,11 +21,13 @@
*/
-#ifndef _ANALYSIS_SCAN_FUNCS_UINT_H
-#define _ANALYSIS_SCAN_FUNCS_UINT_H
+#ifndef _ANALYSIS_SCAN_ITEMS_UINT_H
+#define _ANALYSIS_SCAN_ITEMS_UINT_H
+
+
+#include <glib-object.h>
-#include "../func.h"
#include "../../../arch/archbase.h"
@@ -49,8 +51,8 @@ typedef struct _GUintFunctionClass GUintFunctionClass;
GType g_uint_function_get_type(void);
/* Constitue une fonction de lecture de valeur entière. */
-GScanFunction *g_uint_function_new(MemoryDataSize);
+GUintFunction *g_uint_function_new(MemoryDataSize);
-#endif /* _ANALYSIS_SCAN_FUNCS_UINT_H */
+#endif /* _ANALYSIS_SCAN_ITEMS_UINT_H */
diff --git a/src/analysis/scan/patterns/backend-int.h b/src/analysis/scan/patterns/backend-int.h
index 698ba5f..b2587df 100644
--- a/src/analysis/scan/patterns/backend-int.h
+++ b/src/analysis/scan/patterns/backend-int.h
@@ -39,7 +39,7 @@ typedef patid_t (* enroll_plain_into_backend_fc) (GEngineBackend *, GScanContext
typedef void (* warm_up_backend_fc) (GEngineBackend *);
/* Parcours un contenu binaire à la recherche de motifs. */
-typedef void (* run_backend_scan_fc) (const GEngineBackend *, GScanContext *, GBinContent *);
+typedef void (* run_backend_scan_fc) (const GEngineBackend *, GScanContext *);
/* Imprime quelques faits quant aux éléments mis en place. */
typedef void (* output_backend_stats_fc) (const GEngineBackend *);
diff --git a/src/analysis/scan/patterns/backend.c b/src/analysis/scan/patterns/backend.c
index 800d0aa..0ecc7fe 100644
--- a/src/analysis/scan/patterns/backend.c
+++ b/src/analysis/scan/patterns/backend.c
@@ -209,7 +209,6 @@ void g_engine_backend_warm_up(GEngineBackend *backend)
* *
* Paramètres : backend = moteur de recherche à manipuler. *
* context = lieu d'enregistrement des résultats. *
-* content = données binaires à analyser. *
* *
* Description : Parcours un contenu binaire à la recherche de motifs. *
* *
@@ -219,13 +218,13 @@ void g_engine_backend_warm_up(GEngineBackend *backend)
* *
******************************************************************************/
-void g_engine_backend_run_scan(const GEngineBackend *backend, GScanContext *context, GBinContent *content)
+void g_engine_backend_run_scan(const GEngineBackend *backend, GScanContext *context)
{
GEngineBackendClass *class; /* Classe à activer */
class = G_ENGINE_BACKEND_GET_CLASS(backend);
- class->run_scan(backend, context, content);
+ class->run_scan(backend, context);
}
diff --git a/src/analysis/scan/patterns/backend.h b/src/analysis/scan/patterns/backend.h
index 700366e..8f6b929 100644
--- a/src/analysis/scan/patterns/backend.h
+++ b/src/analysis/scan/patterns/backend.h
@@ -63,7 +63,7 @@ patid_t g_engine_backend_enroll_plain_pattern(GEngineBackend *, GScanContext *,
void g_engine_backend_warm_up(GEngineBackend *);
/* Parcours un contenu binaire à la recherche de motifs. */
-void g_engine_backend_run_scan(const GEngineBackend *, GScanContext *, GBinContent *);
+void g_engine_backend_run_scan(const GEngineBackend *, GScanContext *);
/* Imprime quelques faits quant aux éléments mis en place. */
void g_engine_backend_output_stats(const GEngineBackend *);
diff --git a/src/analysis/scan/patterns/backends/acism.c b/src/analysis/scan/patterns/backends/acism.c
index 12339f2..eef681a 100644
--- a/src/analysis/scan/patterns/backends/acism.c
+++ b/src/analysis/scan/patterns/backends/acism.c
@@ -96,7 +96,7 @@ static void g_acism_backend_build_interleave_array(GAcismBackend *);
static void g_acism_backend_warm_up(GAcismBackend *);
/* Parcours un contenu binaire à la recherche de motifs. */
-static void g_acism_backend_run_scan(const GAcismBackend *, GScanContext *, GBinContent *);
+static void g_acism_backend_run_scan(const GAcismBackend *, GScanContext *);
/* Affiche les caractéristques d'un noeud et de ses enfants. */
static void visit_and_output_node(const acism_trie_node_t *, unsigned int);
@@ -1125,7 +1125,6 @@ static void g_acism_backend_warm_up(GAcismBackend *backend)
* *
* Paramètres : backend = moteur de recherche à manipuler. *
* context = lieu d'enregistrement des résultats. *
-* content = données binaires à analyser. *
* *
* Description : Parcours un contenu binaire à la recherche de motifs. *
* *
@@ -1135,8 +1134,9 @@ static void g_acism_backend_warm_up(GAcismBackend *backend)
* *
******************************************************************************/
-static void g_acism_backend_run_scan(const GAcismBackend *backend, GScanContext *context, GBinContent *content)
+static void g_acism_backend_run_scan(const GAcismBackend *backend, GScanContext *context)
{
+ GBinContent *content; /* Contenu binaire manipulé */
phys_t dlen; /* Quantité de données */
vmpa2t pos; /* Point de départ ciblé */
const bin_t *data; /* Données à analyser */
@@ -1151,6 +1151,8 @@ static void g_acism_backend_run_scan(const GAcismBackend *backend, GScanContext
acism_state_t *iter; /* Boucle de parcours #2 */
acism_state_t *test; /* Test de validité alternative*/
+ content = g_scan_context_get_content(context);
+
dlen = g_binary_content_compute_size(content);
g_binary_content_compute_start_pos(content, &pos);
@@ -1238,6 +1240,8 @@ static void g_acism_backend_run_scan(const GAcismBackend *backend, GScanContext
}
+ g_object_unref(G_OBJECT(content));
+
}
diff --git a/src/analysis/scan/patterns/backends/bitap.c b/src/analysis/scan/patterns/backends/bitap.c
index bd80fb0..adf66d6 100644
--- a/src/analysis/scan/patterns/backends/bitap.c
+++ b/src/analysis/scan/patterns/backends/bitap.c
@@ -63,7 +63,7 @@ size_t g_bitap_backend_get_atom_max_size(const GBitapBackend *);
static patid_t g_bitap_backend_enroll_plain_pattern(GBitapBackend *, GScanContext *, const uint8_t *, size_t);
/* Parcours un contenu binaire à la recherche de motifs. */
-static void g_bitap_backend_run_scan(const GBitapBackend *, GScanContext *, GBinContent *);
+static void g_bitap_backend_run_scan(const GBitapBackend *, GScanContext *);
/* Imprime quelques faits quant aux éléments mis en place. */
static void g_bitap_backend_output_stats(const GBitapBackend *);
@@ -80,7 +80,7 @@ static void extend_grouped_strings_avx2(grouped_strings_avx2_t ***, size_t *);
static patid_t enroll_plain_pattern_avx2(GBitapBackend *, GScanContext *, const bin_t *, size_t);
/* Parcours un contenu binaire à la recherche de motifs. */
-static void run_scan_avx2(const GBitapBackend *, GScanContext *, GBinContent *);
+static void run_scan_avx2(const GBitapBackend *, GScanContext *, const bin_t *, phys_t);
@@ -96,7 +96,7 @@ static void extend_grouped_strings_avx512(grouped_strings_avx512_t ***, size_t *
static patid_t enroll_plain_pattern_avx512(GBitapBackend *, GScanContext *, const bin_t *, size_t);
/* Parcours un contenu binaire à la recherche de motifs. */
-static void run_scan_avx512(const GBitapBackend *, GScanContext *, GBinContent *);
+static void run_scan_avx512(const GBitapBackend *, GScanContext *, const bin_t *, phys_t);
@@ -295,7 +295,6 @@ static patid_t g_bitap_backend_enroll_plain_pattern(GBitapBackend *backend, GSca
* *
* Paramètres : backend = moteur de recherche à manipuler. *
* context = lieu d'enregistrement des résultats. *
-* content = données binaires à analyser. *
* *
* Description : Parcours un contenu binaire à la recherche de motifs. *
* *
@@ -305,12 +304,16 @@ static patid_t g_bitap_backend_enroll_plain_pattern(GBitapBackend *backend, GSca
* *
******************************************************************************/
-static void g_bitap_backend_run_scan(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+static void g_bitap_backend_run_scan(const GBitapBackend *backend, GScanContext *context)
{
cpu_set_t old_mask; /* Cartographie des CPU #1 */
int ret; /* Bilan d'un appel */
unsigned int cpu; /* Processeur courant */
cpu_set_t new_mask; /* Cartographie des CPU #2 */
+ GBinContent *content; /* Contenu binaire manipulé */
+ phys_t dlen; /* Quantité de données */
+ vmpa2t pos; /* Point de départ ciblé */
+ const bin_t *data; /* Données à analyser */
ret = sched_getaffinity(0, sizeof(cpu_set_t), &old_mask);
@@ -339,16 +342,24 @@ static void g_bitap_backend_run_scan(const GBitapBackend *backend, GScanContext
goto exit;
}
+ content = g_scan_context_get_content(context);
+
+ dlen = g_binary_content_compute_size(content);
+
+ g_binary_content_compute_start_pos(content, &pos);
+ data = g_binary_content_get_raw_access(content, &pos, dlen);
+ assert(data != NULL);
if (0)
- run_scan_avx2(backend, context, content);
+ run_scan_avx2(backend, context, data, dlen);
else
- run_scan_avx512(backend, context, content);
+ run_scan_avx512(backend, context, data, dlen);
+ g_object_unref(G_OBJECT(content));
exit:
@@ -515,7 +526,8 @@ static patid_t enroll_plain_pattern_avx2(GBitapBackend *backend, GScanContext *c
* *
* Paramètres : backend = moteur de recherche à manipuler. *
* context = lieu d'enregistrement des résultats. *
-* content = données binaires à analyser. *
+* data = données à analyser. *
+* dlen = quantité de ces données. *
* *
* Description : Parcours un contenu binaire à la recherche de motifs. *
* *
@@ -525,12 +537,9 @@ static patid_t enroll_plain_pattern_avx2(GBitapBackend *backend, GScanContext *c
* *
******************************************************************************/
-static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, const bin_t *data, phys_t dlen)
{
const group_manager_avx2_t *manager; /* Accès simplifié */
- phys_t dlen; /* Quantité de données */
- vmpa2t pos; /* Point de départ ciblé */
- const bin_t *data; /* Données à analyser */
register __m256i zero asm("ymm11"); /* Constante 0 sur 256 bits */
size_t k; /* Boucle de parcours #1 */
@@ -570,11 +579,6 @@ static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, G
manager = &backend->manager_avx2;
- dlen = g_binary_content_compute_size(content);
-
- g_binary_content_compute_start_pos(content, &pos);
- data = g_binary_content_get_raw_access(content, &pos, dlen);
-
zero = _mm256_set1_epi16(0);
asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
@@ -1622,7 +1626,8 @@ static patid_t enroll_plain_pattern_avx512(GBitapBackend *backend, GScanContext
* *
* Paramètres : backend = moteur de recherche à manipuler. *
* context = lieu d'enregistrement des résultats. *
-* content = données binaires à analyser. *
+* data = données à analyser. *
+* dlen = quantité de ces données. *
* *
* Description : Parcours un contenu binaire à la recherche de motifs. *
* *
@@ -1632,12 +1637,9 @@ static patid_t enroll_plain_pattern_avx512(GBitapBackend *backend, GScanContext
* *
******************************************************************************/
-static void run_scan_avx512(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+static void run_scan_avx512(const GBitapBackend *backend, GScanContext *context, const bin_t *data, phys_t dlen)
{
const group_manager_avx512_t *manager; /* Accès simplifié */
- phys_t dlen; /* Quantité de données */
- vmpa2t pos; /* Point de départ ciblé */
- const bin_t *data; /* Données à analyser */
//register __m512i zero asm("zmm19"); /* Constante 0 sur 512 bits */
@@ -1674,10 +1676,6 @@ static void run_scan_avx512(const GBitapBackend *backend, GScanContext *context,
manager = &backend->manager_avx512;
- dlen = g_binary_content_compute_size(content);
-
- g_binary_content_compute_start_pos(content, &pos);
- data = g_binary_content_get_raw_access(content, &pos, dlen);
diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c
index 6c771fb..bf37585 100644
--- a/src/analysis/scan/rule.c
+++ b/src/analysis/scan/rule.c
@@ -338,7 +338,7 @@ bool g_scan_rule_setup_backend(GScanRule *rule, GEngineBackend *backend, GScanCo
* *
******************************************************************************/
-void g_scan_rule_analyze(GScanRule *rule, GEngineBackend *backend, GScanContext *context)
+void g_scan_rule_check(GScanRule *rule, GEngineBackend *backend, GScanContext *context)
{
GBinContent *content; /* Contenu à manipuler */
pending_matches_t matches; /* Suivi de correspondances */
@@ -350,8 +350,6 @@ void g_scan_rule_analyze(GScanRule *rule, GEngineBackend *backend, GScanContext
content = g_scan_context_get_content(context);
- g_engine_backend_run_scan(backend, context, content);
-
/* Consolidation des résultats */
for (i = 0; i < rule->data_used; i++)
diff --git a/src/analysis/scan/rule.h b/src/analysis/scan/rule.h
index edd57b3..e240da9 100644
--- a/src/analysis/scan/rule.h
+++ b/src/analysis/scan/rule.h
@@ -70,7 +70,7 @@ void g_scan_rule_set_match_condition(GScanRule *, GScanExpression *);
bool g_scan_rule_setup_backend(GScanRule *, GEngineBackend *, GScanContext *);
/* Lance une analyse d'un contenu binaire selon une règle. */
-void g_scan_rule_analyze(GScanRule *, GEngineBackend *, GScanContext *);
+void g_scan_rule_check(GScanRule *, GEngineBackend *, GScanContext *);
diff --git a/src/analysis/scan/scanner.c b/src/analysis/scan/scanner.c
index ae3cb9a..d52c0fc 100644
--- a/src/analysis/scan/scanner.c
+++ b/src/analysis/scan/scanner.c
@@ -332,8 +332,10 @@ GScanContext *g_content_scanner_analyze(GContentScanner *scanner, GScanOptions *
g_scan_context_set_content(result, content);
+ g_engine_backend_run_scan(scanner->data_backend, result);
+
for (i = 0; i < scanner->rule_count; i++)
- g_scan_rule_analyze(scanner->rules[i], scanner->data_backend, result);
+ g_scan_rule_check(scanner->rules[i], scanner->data_backend, result);
exit:
diff --git a/src/analysis/scan/scope.h b/src/analysis/scan/scope.h
new file mode 100644
index 0000000..1e5de2c
--- /dev/null
+++ b/src/analysis/scan/scope.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scope.h - prototypes pour la définition d'une portée locale de variables
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_SCOPE_H
+#define _ANALYSIS_SCAN_SCOPE_H
+
+
+
+
+
+typedef void *GScanScope;
+
+
+
+
+
+#endif /* _ANALYSIS_SCAN_SCOPE_H */
diff --git a/src/analysis/scan/space-int.h b/src/analysis/scan/space-int.h
index fa4437d..386785d 100644
--- a/src/analysis/scan/space-int.h
+++ b/src/analysis/scan/space-int.h
@@ -37,6 +37,8 @@ struct _GScanNamespace
{
GRegisteredItem parent; /* A laisser en premier */
+ char *name; /* Désignation de l'espace */
+
GRegisteredItem **children; /* Sous-éléments inscrits */
char **names; /* Désignations correspondantes*/
size_t count; /* Quantité de sous-éléments */
@@ -51,5 +53,9 @@ struct _GScanNamespaceClass
};
+/* Met en place un nouvel espace de noms pour scan. */
+bool g_scan_namespace_create(GScanNamespace *, const char *);
+
+
#endif /* _ANALYSIS_SCAN_SPACE_INT_H */
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
index 34b67fe..dc9a237 100644
--- a/src/analysis/scan/space.c
+++ b/src/analysis/scan/space.c
@@ -52,11 +52,14 @@ static void g_scan_namespace_finalize(GScanNamespace *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* Lance une résolution d'élément à appeler. */
-GRegisteredItem *g_scan_namespace_resolve(GScanNamespace *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_scan_namespace_get_name(const GScanNamespace *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_scan_namespace_resolve(GScanNamespace *, const char *, GScanContext *, GScanScope *, GRegisteredItem **);
/* Réduit une expression à une forme plus simple. */
-GScanExpression *g_scan_namespace_reduce(GScanNamespace *, GScanContext *, GScanExpression **, size_t, bool);
+static GScanExpression *g_scan_namespace_reduce(GScanNamespace *, GScanContext *, GScanExpression **, size_t, bool);
@@ -93,6 +96,7 @@ static void g_scan_namespace_class_init(GScanNamespaceClass *klass)
registered = G_REGISTERED_ITEM_CLASS(klass);
+ registered->get_name = (get_registered_item_name_fc)g_scan_namespace_get_name;
registered->resolve = (resolve_registered_item_fc)g_scan_namespace_resolve;
registered->reduce = (reduce_registered_item_fc)g_scan_namespace_reduce;
@@ -113,6 +117,8 @@ static void g_scan_namespace_class_init(GScanNamespaceClass *klass)
static void g_scan_namespace_init(GScanNamespace *space)
{
+ space->name = NULL;
+
space->children = NULL;
space->names = NULL;
space->count = 0;
@@ -160,6 +166,9 @@ static void g_scan_namespace_finalize(GScanNamespace *space)
{
size_t i; /* Boucle de parcours */
+ if (space->name != NULL)
+ free(space->name);
+
if (space->children != NULL)
free(space->children);
@@ -176,7 +185,7 @@ static void g_scan_namespace_finalize(GScanNamespace *space)
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : name = désignation du futur espace de noms. *
* *
* Description : Construit un nouvel espace de noms pour scan. *
* *
@@ -186,12 +195,42 @@ static void g_scan_namespace_finalize(GScanNamespace *space)
* *
******************************************************************************/
-GScanNamespace *g_scan_namespace_new(void)
+GScanNamespace *g_scan_namespace_new(const char *name)
{
GScanNamespace *result; /* Instance à retourner */
result = g_object_new(G_TYPE_SCAN_NAMESPACE, NULL);
+ if (!g_scan_namespace_create(result, name))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : space = instance d'espace de noms à initialiser. *
+* name = désignation du futur espace de noms. *
+* *
+* Description : Met en place un nouvel espace de noms pour scan. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_namespace_create(GScanNamespace *space, const char *name)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (name != NULL)
+ space->name = strdup(name);
+
return result;
}
@@ -200,8 +239,7 @@ GScanNamespace *g_scan_namespace_new(void)
/******************************************************************************
* *
* Paramètres : space = espace de noms à compléter. *
-* type = type d'élément à intégrer. *
-* name = nom du futur espace ou NULL pour une racine. *
+* child = élément d'évaluation à intégrer. *
* *
* Description : Intègre un nouvel élément dans l'esapce de noms. *
* *
@@ -211,19 +249,39 @@ GScanNamespace *g_scan_namespace_new(void)
* *
******************************************************************************/
-bool g_scan_namespace_register(GScanNamespace *space, GRegisteredItem *child, const char *name)
+bool g_scan_namespace_register_item(GScanNamespace *space, GRegisteredItem *child)
{
bool result; /* Bilan à retourner */
+ char *name; /* Nom de l'élément à ajouter */
+ size_t i; /* Boucle de parcours */
- result = true;
+ name = g_registered_item_get_name(child);
+
+ /* Validation de l'unicité du nom */
+
+ for (i = 0; i < space->count; i++)
+ if (strcmp(name, space->names[i]) == 0)
+ break;
- space->count++;
+ result = (i == space->count);
- space->children = realloc(space->children, space->count * sizeof(GRegisteredItem *));
- space->children[space->count - 1] = child;
+ /* Inscription de l'élément ? */
- space->names = realloc(space->names, space->count * sizeof(char *));
- space->names[space->count - 1] = strdup(name);
+ if (!result)
+ free(name);
+
+ else
+ {
+ space->count++;
+
+ space->children = realloc(space->children, space->count * sizeof(GRegisteredItem *));
+ space->children[space->count - 1] = child;
+ g_object_ref(G_OBJECT(child));
+
+ space->names = realloc(space->names, space->count * sizeof(char *));
+ space->names[space->count - 1] = strdup(name);
+
+ }
return result;
@@ -238,34 +296,59 @@ bool g_scan_namespace_register(GScanNamespace *space, GRegisteredItem *child, co
/******************************************************************************
* *
-* Paramètres : space = élément d'appel à consulter. *
+* Paramètres : space = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_scan_namespace_get_name(const GScanNamespace *space)
+{
+ char *result; /* Désignation à retourner */
+
+ if (space->name != NULL)
+ result = strdup(space->name);
+
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
* target = désignation de l'objet d'appel à identifier. *
* ctx = contexte de suivi de l'analyse courante. *
-* args = liste d'éventuels arguments fournis. *
-* count = taille de cette liste. *
-* last = l'élément est-il le dernier d'une chaîne d'appels ? *
-* final = indique une ultime conversion dans le cycle en cours.*
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
* *
-* Description : Lance une résolution d'élément à appeler. *
+* Description : Lance une résolution d'élément à solliciter. *
* *
-* Retour : Nouvel élément d'appel identifié ou NULL. *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
* *
* Remarques : - *
* *
******************************************************************************/
-GRegisteredItem *g_scan_namespace_resolve(GScanNamespace *space, const char *target, GScanContext *ctx, GScanExpression **args, size_t count, bool last, bool final)
+static bool g_scan_namespace_resolve(GScanNamespace *item, const char *target, GScanContext *ctx, GScanScope *scope, GRegisteredItem **out)
{
- GRegisteredItem *result; /* Instance à renvoyer */
+ bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
- result = NULL;
+ result = true;
- for (i = 0; i < space->count; i++)
- if (strcmp(target, space->names[i]) == 0)
+ for (i = 0; i < item->count; i++)
+ if (strcmp(target, item->names[i]) == 0)
{
- result = space->children[i];
- g_object_ref(G_OBJECT(result));
+ *out = item->children[i];
+ g_object_ref(G_OBJECT(*out));
break;
}
@@ -290,11 +373,11 @@ GRegisteredItem *g_scan_namespace_resolve(GScanNamespace *space, const char *tar
* *
******************************************************************************/
-GScanExpression *g_scan_namespace_reduce(GScanNamespace *space, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+static GScanExpression *g_scan_namespace_reduce(GScanNamespace *space, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
{
GScanExpression *result; /* Instance à renvoyer */
- assert(false);
+ assert(false); /* REMME */
result = NULL;
diff --git a/src/analysis/scan/space.h b/src/analysis/scan/space.h
index 9058959..7a99387 100644
--- a/src/analysis/scan/space.h
+++ b/src/analysis/scan/space.h
@@ -52,10 +52,10 @@ typedef struct _GScanNamespaceClass GScanNamespaceClass;
GType g_scan_namespace_get_type(void);
/* Construit un nouvel espace de noms pour scan. */
-GScanNamespace *g_scan_namespace_new(void);
+GScanNamespace *g_scan_namespace_new(const char *);
/* Intègre un nouvel élément dans l'esapce de noms. */
-bool g_scan_namespace_register(GScanNamespace *, GRegisteredItem *, const char *);
+bool g_scan_namespace_register_item(GScanNamespace *, GRegisteredItem *);
diff --git a/src/analysis/scan/tokens.l b/src/analysis/scan/tokens.l
index 92a5340..b541786 100644
--- a/src/analysis/scan/tokens.l
+++ b/src/analysis/scan/tokens.l
@@ -107,7 +107,11 @@
"rule" { PUSH_STATE(rule_intro); return RAW_RULE; }
-<rule_intro>[A-Za-z0-9_]+ { yylval->cstring = yytext; return RULE_NAME; }
+<rule_intro>[A-Za-z0-9_]+ {
+ yylval->sized_cstring.data = yytext;
+ yylval->sized_cstring.len = yyleng;
+ return RULE_NAME;
+ }
<rule_intro>[ \t]* { }
<rule_intro>"{" { POP_STATE; PUSH_STATE(raw_block); return BRACE_IN; }
@@ -139,7 +143,8 @@
POP_STATE;
EXTEND_BUFFER_IF_NEEDED(1);
(*buf)[(*used)++] = '\0';
- yylval->cstring = *buf;
+ yylval->sized_cstring.data = *buf;
+ yylval->sized_cstring.len = *used;
return STRING;
}
@@ -206,12 +211,12 @@
<strings,condition>$[A-Za-z0-9_]* {
- yylval->sized_cstring.cstring = yytext + 1;
+ yylval->sized_cstring.data = yytext + 1;
yylval->sized_cstring.len = yyleng - 1;
return IDENTIFIER;
}
<condition>[A-Za-z_][A-Za-z0-9_]* {
- yylval->sized_cstring.cstring = yytext;
+ yylval->sized_cstring.data = yytext;
yylval->sized_cstring.len = yyleng;
return NAME;
}
@@ -221,7 +226,7 @@
<strval>\"[^\"\\]+\" {
POP_STATE;
- yylval->sized_cstring.cstring = yytext + 1;
+ yylval->sized_cstring.data = yytext + 1;
yylval->sized_cstring.len = yyleng - 2;
return PLAIN_STRING;
}