summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/instruction-int.h5
-rw-r--r--src/arch/instruction.c91
-rw-r--r--src/arch/instruction.h2
-rw-r--r--src/arch/raw.c31
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*/);
}