diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/instruction-int.h | 5 | ||||
-rw-r--r-- | src/arch/instruction.c | 91 | ||||
-rw-r--r-- | src/arch/instruction.h | 2 | ||||
-rw-r--r-- | src/arch/raw.c | 31 |
4 files changed, 80 insertions, 49 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 8dbdd18..beb6b50 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -27,6 +27,7 @@ #include "archbase.h" #include "instruction.h" +#include "../common/array.h" @@ -54,9 +55,7 @@ struct _GArchInstruction const GBinContent *content; /* Contenu binaire global */ mrange_t range; /* Emplacement en mémoire */ - GArchOperand **operands; /* Liste des opérandes */ - size_t operands_count; /* Nbre. d'opérandes utilisées */ - gint operands_lock; /* Verrouillage des accès */ + flat_array_t *operands; /* Liste des opérandes */ /** * Il existe le besoin indéniable d'un verrou pour les accès aux instructions diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 339364f..a86509c 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -145,7 +145,7 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass) static void g_arch_instruction_init(GArchInstruction *instr) { - instr->operands_lock = 0; + instr->operands = NULL; instr->from_count = 0; instr->to_count = 0; @@ -472,7 +472,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg void g_arch_instruction_lock_operands(GArchInstruction *instr) { - g_bit_lock(&instr->operands_lock, 0); + lock_flat_array(&instr->operands); } @@ -491,7 +491,7 @@ void g_arch_instruction_lock_operands(GArchInstruction *instr) void g_arch_instruction_unlock_operands(GArchInstruction *instr) { - g_bit_unlock(&instr->operands_lock, 0); + unlock_flat_array(&instr->operands); } @@ -513,10 +513,7 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera { g_arch_instruction_lock_operands(instr); - instr->operands_count++; - instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); - - instr->operands[instr->operands_count - 1] = operand; + add_item_to_flat_array(&instr->operands, &operand, sizeof(GArchOperand *)); g_arch_instruction_unlock_operands(instr); @@ -537,9 +534,11 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera size_t _g_arch_instruction_count_operands(const GArchInstruction *instr) { - assert(instr->operands_lock != 0); + size_t result; /* Décompte à retourner */ + + result = count_flat_array_items(instr->operands); - return instr->operands_count; + return result; } @@ -560,11 +559,11 @@ size_t _g_arch_instruction_count_operands(const GArchInstruction *instr) GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index) { GArchOperand *result; /* Opérande à retourner */ + GArchOperand **ptr; /* Adresse dans le tableau */ - assert(instr->operands_lock != 0); + ptr = get_flat_array_item(instr->operands, index, sizeof(GArchOperand *)); - if (index >= instr->operands_count) result = NULL; - else result = instr->operands[index]; + result = *ptr; /* TODO : incrémenter la référence ! */ @@ -587,29 +586,34 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz * * ******************************************************************************/ -void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) +void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, GArchOperand *old) { + size_t count; /* Nombre d'opérandes en place */ size_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande à manipuler */ - assert(instr->operands_lock != 0); + count = _g_arch_instruction_count_operands(instr); + + for (i = 0; i < count; i++) + { + op = _g_arch_instruction_get_operand(instr, i); - for (i = 0; i < instr->operands_count; i++) - if (instr->operands[i] == old) + if (op == old) break; - if (i < instr->operands_count) - { - g_object_unref(G_OBJECT(instr->operands[i])); - instr->operands[i] = new; } + rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *)); + + g_object_unref(G_OBJECT(old)); + } /****************************************************************************** * * -* Paramètres : instr = instance à mettre à jour. * -* opererand = instruction à venir dissocier. * +* Paramètres : instr = instance à mettre à jour. * +* target = instruction à venir dissocier. * * * * Description : Détache un opérande liée d'une instruction. * * * @@ -619,22 +623,26 @@ void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand * * * ******************************************************************************/ -void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) +void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *target) { + size_t count; /* Nombre d'opérandes en place */ size_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande à manipuler */ + + count = _g_arch_instruction_count_operands(instr); - assert(instr->operands_lock != 0); + for (i = 0; i < count; i++) + { + op = _g_arch_instruction_get_operand(instr, i); - for (i = 0; i < instr->operands_count; i++) - if (instr->operands[i] == operand) + if (op == target) break; - if ((i + 1) < instr->operands_count) - memmove(&instr->operands[i], &instr->operands[i + 1], - (instr->operands_count - i - 1) * sizeof(GArchOperand *)); + } + + rem_item_from_flat_array(&instr->operands, i, sizeof(GArchOperand *)); - instr->operands_count--; - instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); + g_object_unref(G_OBJECT(target)); } @@ -1178,7 +1186,9 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line { const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ + size_t count; /* Nombre d'opérandes en place */ size_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande à manipuler */ g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); @@ -1191,21 +1201,32 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); - if (instr->operands_count > 0) + /* Liste des opérandes */ + + g_arch_instruction_lock_operands(instr); + + count = _g_arch_instruction_count_operands(instr); + + if (count > 0) { - g_arch_operand_print(instr->operands[0], line, 0/*syntax*/); + op = _g_arch_instruction_get_operand(instr, 0); + g_arch_operand_print(op, line, 0/*syntax*/); - for (i = 1; i < instr->operands_count; i++) + for (i = 1; i < count; i++) { g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - g_arch_operand_print(instr->operands[i], line, 0/*syntax*/); + op = _g_arch_instruction_get_operand(instr, i); + + g_arch_operand_print(op, line, 0/*syntax*/); } } + g_arch_instruction_unlock_operands(instr); + } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index fad6c72..9299f8c 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -147,7 +147,7 @@ size_t _g_arch_instruction_count_operands(const GArchInstruction *); GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *, size_t); /* Remplace un opérande d'une instruction par un autre. */ -void _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, const GArchOperand *); +void _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *); /* Détache un opérande liée d'une instruction. */ void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *); diff --git a/src/arch/raw.c b/src/arch/raw.c index f22645f..9d9b8de 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -464,10 +464,12 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s phys_t max_displayed_len; /* Quantité de code affichée */ const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ + size_t count; /* Nombre d'opérandes en place */ char *string; /* Chaîne reconstituée */ size_t iter; /* Tête d'écriture */ bool first; /* Mémorise une énumération */ size_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande à manipuler */ char byte; /* Octet à afficher (ou pas) */ bool status; /* Bilan d'une récupération */ @@ -505,18 +507,22 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s else if (instr->is_string) { - string = (char *)calloc(base->operands_count + 3, sizeof(char)); + g_arch_instruction_lock_operands(base); + + count = _g_arch_instruction_count_operands(base); + + string = (char *)calloc(count + 3, sizeof(char)); strcpy(string, "\""); iter = 1; first = true; - g_arch_instruction_lock_operands(base); - - for (i = 0; i < base->operands_count; i++) + for (i = 0; i < count; i++) { - status = g_imm_operand_get_value(G_IMM_OPERAND(base->operands[i]), MDS_8_BITS, &byte); + op = _g_arch_instruction_get_operand(base, i); + + status = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_8_BITS, &byte); assert(status); /* Si le caractère doit apparaître en hexadécimal... */ @@ -551,7 +557,7 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s else first = false; - g_arch_operand_print(base->operands[i], line, 0/*, syntax*/); + g_arch_operand_print(op, line, 0/*, syntax*/); } @@ -587,16 +593,21 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s { g_arch_instruction_lock_operands(base); - if (base->operands_count > 0) + count = _g_arch_instruction_count_operands(base); + + if (count > 0) { - g_arch_operand_print(base->operands[0], line, 0/*syntax*/); + op = _g_arch_instruction_get_operand(base, 0); + g_arch_operand_print(op, line, 0/*syntax*/); - for (i = 1; i < base->operands_count; i++) + for (i = 1; i < count; i++) { g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - g_arch_operand_print(base->operands[i], line, 0/*syntax*/); + op = _g_arch_instruction_get_operand(base, i); + + g_arch_operand_print(op, line, 0/*syntax*/); } |