diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-01-27 23:22:49 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-01-27 23:22:49 (GMT) |
commit | 2b8f655628652f3cfb61c8b82d4b54fbf3ed9869 (patch) | |
tree | ecc32e82287a3402542c6bb204618a523e775889 /src/arch/instruction-int.h | |
parent | 36a006b2ac60c0cc1a2e2bea00d88508294be7f0 (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.h | 62 |
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 */ + }; |