summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/instruction-int.h63
-rw-r--r--src/arch/instruction.c108
-rw-r--r--src/arch/instruction.h3
-rw-r--r--src/common/cpp.h7
-rw-r--r--src/glibext/Makefile.am1
-rw-r--r--src/glibext/objhole.h71
6 files changed, 240 insertions, 13 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index af897b0..fcb5453 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -27,6 +27,7 @@
#include "instruction.h"
#include "../common/array.h"
+#include "../glibext/objhole.h"
@@ -58,6 +59,38 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe
typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef union _instr_obj_extra
+{
+ struct
+ {
+ itid_t uid; /* Identifiant unique du type */
+
+ ArchInstrFlag flags; /* Informations complémentaires*/
+
+ };
+
+ gint lock; /* Gestion d'accès aux fanions */
+
+} instr_obj_extra;
+
+/**
+ * Choix du bit de verrou pour le champ "lock".
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+# define INSTR_EXTRA_LOCK_BIT 31
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+# define INSTR_EXTRA_LOCK_BIT 0
+
+#else
+
+# error "Unknown byte order"
+
+#endif
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
@@ -93,12 +126,38 @@ struct _GArchInstruction
flat_array_t *from; /* Origines des références */
flat_array_t *to; /* Instructions visées */
- itid_t uid; /* Identifiant unique du type */
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
- ArchInstrFlag flags; /* Informations complémentaires*/
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ instr_obj_extra extra; /* Externalisation embarquée */
+
+#endif
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0
+
+# define GET_ARCH_INSTR_EXTRA(ins) &ins->extra
+
+#else
+
+# define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
+
+# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra)
+
+#endif
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index f571330..d3ac97e 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -139,6 +139,8 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
+ INIT_ARCH_INSTR_EXTRA(instr);
+
instr->operands = NULL;
instr->from = NULL;
@@ -278,9 +280,20 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
- instr->flags |= flag;
+ bool result; /* Bilan à retourner */
+ instr_obj_extra *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ extra->flags |= flag;
+
+ result = true;
- return true;
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ return result;
}
@@ -301,8 +314,15 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
- result = (instr->flags & flag);
+ result = (extra->flags & flag);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
return result;
@@ -323,7 +343,46 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
- return instr->flags;
+ ArchInstrFlag result; /* Fanions à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extra->flags;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* uid = identifiant unique par type d'instruction. *
+* *
+* Description : Définit l'identifiant unique pour un ensemble d'instructions.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
+{
+ instr_obj_extra *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ extra->uid = uid;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
}
@@ -343,8 +402,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
{
itid_t result; /* Numéro à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- result = instr->uid;
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extra->uid;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
return result;
@@ -1409,6 +1475,7 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
GArchOperand *op; /* Opérande à traiter */
instr_link_t link; /* Lien vers une instruction */
packed_buffer ins_pbuf; /* Tampon des données à écrire */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
result = unpack_mrange(&instr->range, pbuf);
@@ -1489,10 +1556,19 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
}
if (result)
- result = extract_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+ {
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- if (result)
- result = extract_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), true);
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ }
return result;
@@ -1561,6 +1637,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
off64_t pos; /* Position dans le flux */
size_t kept; /* Nombre de liens conservés */
const instr_link_t *link; /* Lien vers une instruction */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
result = pack_mrange(&instr->range, pbuf);
@@ -1661,10 +1738,19 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
}
if (result)
- result = extend_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+ {
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- if (result)
- result = extend_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), true);
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ }
return result;
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index af6b03a..6c04acb 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -93,6 +93,9 @@ bool g_arch_instruction_has_flag(const GArchInstruction *, ArchInstrFlag);
/* Fournit les informations complémentaires d'une instruction. */
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
+/* Définit l'identifiant unique pour un ensemble d'instructions. */
+void g_arch_instruction_set_unique_id(GArchInstruction *, itid_t);
+
/* Fournit l'identifiant unique pour un ensemble d'instructions. */
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *);
diff --git a/src/common/cpp.h b/src/common/cpp.h
index dc0c208..2305b29 100644
--- a/src/common/cpp.h
+++ b/src/common/cpp.h
@@ -47,5 +47,12 @@
#define SIZE_T_MAXLEN strlen(XSTR(LONG_MAX))
+/**
+ * Emprunt au noyau Linux (cf. include/linux/bug.h) pour les vérifications à la compilation.
+ */
+
+#define BUILD_BUG_ON(cond) (((void)sizeof(char[1 - 2 * !!(cond)])))
+
+
#endif /* _COMMON_CPP_H */
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 127f60c..af4f876 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -25,6 +25,7 @@ libglibext_la_SOURCES = \
linegen-int.h \
linegen.h linegen.c \
linesegment.h linesegment.c \
+ objhole.h \
proto.h \
seq.h seq.c \
signal.h signal.c
diff --git a/src/glibext/objhole.h b/src/glibext/objhole.h
new file mode 100644
index 0000000..184e599
--- /dev/null
+++ b/src/glibext/objhole.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * objhole.h - prototypes pour l'utilisation d'un espace inutilisé dans la structure GObject
+ *
+ * Copyright (C) 2019 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 _GLIBEXT_OBJHOLE_H
+#define _GLIBEXT_OBJHOLE_H
+
+
+#include <glib-object.h>
+
+
+#include "../common/cpp.h"
+
+
+
+/**
+ * Une structure GObject a la définition suivante :
+ *
+ * struct _GObject
+ * {
+ * GTypeInstance g_type_instance;
+ * volatile guint ref_count;
+ * GData *qdata;
+ * };
+ *
+ * L'espace entre les deux derniers champs est exploité ici.
+ */
+
+
+#define INIT_GOBJECT_EXTRA(obj) \
+ do \
+ { \
+ guint *___space; \
+ ___space = (((guint *)&obj->ref_count) + 1); \
+ BUILD_BUG_ON((___space + 1) == (guint *)&obj->qdata); \
+ *___space = 0; \
+ } \
+ while (0)
+
+
+#define GET_GOBJECT_EXTRA(obj, tp) \
+ ({ \
+ BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \
+ tp *___result; \
+ ___result = (tp *)(((guint *)&obj->ref_count) + 1); \
+ BUILD_BUG_ON((___result + 1) == (tp *)&obj->qdata); \
+ ___result; \
+ })
+
+
+
+#endif /* _GLIBEXT_OBJHOLE_H */