diff options
Diffstat (limited to 'src/arch')
-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 |
3 files changed, 161 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 *); |