summaryrefslogtreecommitdiff
path: root/src/arch/instruction-int.h
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-01-27 23:22:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-01-27 23:22:49 (GMT)
commit2b8f655628652f3cfb61c8b82d4b54fbf3ed9869 (patch)
treeecc32e82287a3402542c6bb204618a523e775889 /src/arch/instruction-int.h
parent36a006b2ac60c0cc1a2e2bea00d88508294be7f0 (diff)
Avoided deadlocks in access to instruction sources and destinations.
Diffstat (limited to 'src/arch/instruction-int.h')
-rw-r--r--src/arch/instruction-int.h62
1 files changed, 42 insertions, 20 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 2d829c0..e7d5ba0 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -27,24 +27,21 @@
#include "archbase.h"
#include "instruction.h"
-#include "../common/dllist.h"
-/* Liste les registres lus et écrits par l'instruction. */
-typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
-
/* Indique l'encodage d'une instruction de façon détaillée. */
typedef const char * (* get_instruction_encoding_fc) (const GArchInstruction *);
+/* Fournit le nom humain de l'instruction manipulée. */
+typedef const char * (* get_instruction_keyword_fc) (GArchInstruction *, AsmSyntax );
+
/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBufferLine *, size_t, size_t);
-/* Fournit le nom humain de l'instruction manipulée. */
-typedef const char * (* get_instruction_keyword_fc) (GArchInstruction *, AsmSyntax );
+/* Liste les registres lus et écrits par l'instruction. */
+typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
-/* Informe sur une éventuelle référence à une autre instruction. */
-typedef InstructionLinkType (* get_instruction_link_fc) (const GArchInstruction *, vmpa_t *);
/* Définition générique d'une instruction d'architecture (instance) */
@@ -61,26 +58,49 @@ struct _GArchInstruction
GArchOperand **operands; /* Liste des opérandes */
size_t operands_count; /* Nbre. d'opérandes utilisées */
+ /**
+ * Il existe le besoin indéniable d'un verrou pour les accès aux instructions
+ * liées. Il faut par ailleurs un verrou distinct pour les sources et les
+ * destination car une même instruction peut boucler sur elle même et la
+ * fonction g_arch_instruction_change_link() pose des verrous sur les
+ * deux extrémités.
+ *
+ * Par ailleurs, la consommation mémoire augmente vite : GRWLock pèse 16
+ * octets et size_t mesure la taille d'un long sur 64 bits.
+ *
+ * Que ce soit avec les pointeurs (un allocateur aligne généralement les
+ * adresses retournées) ou avec les tailles (il est peu probable d'avoir
+ * 0x80000000 instructions d'origine), on dispose d'espace mémoire inutilisé
+ * adapté pour compresser la structure GArchInstruction.
+ *
+ * La GLib propose incidemment des fonctions g_bit_lock() / g_bit_unlock()...
+ *
+ * On perd au passage la distinction entre les accès en lecture et ceux en
+ * écriture, mais tant pis : la réduction de l'empreinte mémoire prime !
+ *
+ * Par contre la documentation indique :
+ *
+ * """
+ * Attempting to lock on two different bits within the same integer is not supported.
+ * """
+ *
+ * Donc on conserve un compteur distinct pour chaque extrémité.
+ */
+
instr_link_t *from; /* Origines des références */
- size_t from_count; /* Nombre de ces origines */
instr_link_t *to; /* Instructions visées */
- size_t to_count; /* Nombre de ces destinations */
- GRWLock link_access; /* Verrou de protection */
-#ifndef NDEBUG
- gint hold_link_access; /* Suivi des verrouillages */
-#endif
+ gint from_count; /* Nombre de ces origines */
+ gint to_count; /* Nombre de ces destinations */
ArchInstrFlag flags; /* Informations complémentaires*/
- //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */
- //print_instruction_fc print; /* Imprime l'ensemble */
- //get_instruction_keyword_fc get_key; /* Texte humain équivalent */
- //is_instruction_return_fc is_return; /* Retour de fonction ou pas ? */
- //decomp_instr_fc decomp; /* Procédure de décompilation */
-
};
+/* Bit de verrou pour les champs (from|to)_count */
+#define INSTR_LINK_LOCK_BIT 31
+
+
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
{
@@ -91,6 +111,8 @@ struct _GArchInstructionClass
print_instruction_fc print; /* Imprime l'ensemble */
+ //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */
+
};