diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/instruction-int.h | 63 | ||||
-rw-r--r-- | src/arch/instruction.c | 108 | ||||
-rw-r--r-- | src/arch/instruction.h | 3 | ||||
-rw-r--r-- | src/common/cpp.h | 7 | ||||
-rw-r--r-- | src/glibext/Makefile.am | 1 | ||||
-rw-r--r-- | src/glibext/objhole.h | 71 |
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 */ |