summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-06 18:48:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-06 18:48:16 (GMT)
commit12b8a066d1d8dd8cbef587dc6fafed870604f49f (patch)
tree3eb6cfbab886b430a8479fda9a721f75ae806a4d /src/arch
parent0320d85e480882c58f254640a54c6c6e190dbf47 (diff)
Locked access to instruction operands when needed.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/v7/fetch.c15
-rw-r--r--src/arch/arm/v7/post.c13
-rw-r--r--src/arch/dalvik/link.c8
-rw-r--r--src/arch/instruction-int.h1
-rw-r--r--src/arch/instruction.c147
-rw-r--r--src/arch/instruction.h58
-rw-r--r--src/arch/link.c24
-rw-r--r--src/arch/post.c8
-rw-r--r--src/arch/raw.c8
9 files changed, 214 insertions, 68 deletions
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 15707e3..6675706 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -388,13 +388,16 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
break;
}
- op = g_arch_instruction_get_operand(instr, 1);
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, 1);
assert(G_IS_IMM_OPERAND(op));
ret = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset);
if (!ret)
{
assert(0);
+ g_arch_instruction_unlock_operands(instr);
return;
}
@@ -405,6 +408,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &sym_addr))
{
assert(0);
+ g_arch_instruction_unlock_operands(instr);
return;
}
@@ -427,7 +431,11 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
ret = g_binary_content_read_u32(content, &pos, SRE_LITTLE /* FIXME */, &target);
g_object_unref(G_OBJECT(content));
- if (!ret) return;
+ if (!ret)
+ {
+ g_arch_instruction_unlock_operands(instr);
+ return;
+ }
/* Réalise l'intégration du symbole associé */
@@ -480,8 +488,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
- g_arch_instruction_replace_operand(instr, new, op);
+ _g_arch_instruction_replace_operand(instr, new, op);
+ g_arch_instruction_unlock_operands(instr);
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 5ac3c62..6c63832 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -56,11 +56,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
- op = g_arch_instruction_get_operand(instr, 1);
+ g_arch_instruction_lock_operands(instr);
+ op = _g_arch_instruction_get_operand(instr, 1);
- if (!G_IS_IMM_OPERAND(op)) return;
-
+ if (!G_IS_IMM_OPERAND(op))
+ goto ppli_release;
if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)
&& g_exe_format_translate_address_into_vmpa(format, addr, &target))
@@ -92,8 +93,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
}
- g_arch_instruction_replace_operand(instr, new, op);
+ _g_arch_instruction_replace_operand(instr, new, op);
}
+ ppli_release:
+
+ g_arch_instruction_unlock_operands(instr);
+
}
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index f92541b..d1404d0 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -101,9 +101,13 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
char *int_val; /* Valeur en chaîne de carac. */
GDbComment *item; /* Indication sur la condition */
- assert(g_arch_instruction_count_operands(instr) == 2);
+ g_arch_instruction_lock_operands(instr);
- op = g_arch_instruction_get_operand(instr, 1);
+ assert(_g_arch_instruction_count_operands(instr) == 2);
+
+ op = _g_arch_instruction_get_operand(instr, 1);
+
+ g_arch_instruction_unlock_operands(instr);
defined = false;
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 5f6758f..8dbdd18 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -56,6 +56,7 @@ struct _GArchInstruction
GArchOperand **operands; /* Liste des opérandes */
size_t operands_count; /* Nbre. d'opérandes utilisées */
+ gint operands_lock; /* Verrouillage des accès */
/**
* 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 7df72bf..339364f 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -145,6 +145,8 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
+ instr->operands_lock = 0;
+
instr->from_count = 0;
instr->to_count = 0;
@@ -409,6 +411,91 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse
}
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à consulter. *
+* rregs = liste des rgistres lus. [OUT] *
+* rcount = nombre de registres lus. [OUT] *
+* wregs = liste des rgistres écrits. [OUT] *
+* wcount = nombre de registres écrits. [OUT] *
+* *
+* Description : Liste les registres lus et écrits par l'instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : Les compteurs de références sont à décrémenter après usage ! *
+* *
+******************************************************************************/
+
+void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount)
+{
+#if 0
+
+ size_t i; /* Boucle de parcours */
+
+ *rregs = NULL;
+ *rcount = 0;
+ *wregs = NULL;
+ *wcount = 0;
+
+ instr->get_rw_regs(instr, rregs, rcount, wregs, wcount);
+
+ for (i = 0; i < *rcount; i++)
+ g_object_ref(G_OBJECT((*rregs)[i]));
+
+ for (i = 0; i < *wcount; i++)
+ g_object_ref(G_OBJECT((*wregs)[i]));
+
+#endif
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION DES OPERANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à mettre à jour. *
+* *
+* Description : Verrouille les accès la liste des opérandes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_lock_operands(GArchInstruction *instr)
+{
+ g_bit_lock(&instr->operands_lock, 0);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à mettre à jour. *
+* *
+* Description : Déverrouille les accès la liste des opérandes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_unlock_operands(GArchInstruction *instr)
+{
+ g_bit_unlock(&instr->operands_lock, 0);
+
+}
+
+
/******************************************************************************
* *
* Paramètres : instr = instance à mettre à jour. *
@@ -424,11 +511,15 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse
void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)
{
+ 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;
+ g_arch_instruction_unlock_operands(instr);
+
}
@@ -444,8 +535,10 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera
* *
******************************************************************************/
-size_t g_arch_instruction_count_operands(const GArchInstruction *instr)
+size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)
{
+ assert(instr->operands_lock != 0);
+
return instr->operands_count;
}
@@ -464,10 +557,12 @@ size_t g_arch_instruction_count_operands(const GArchInstruction *instr)
* *
******************************************************************************/
-GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)
+GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)
{
GArchOperand *result; /* Opérande à retourner */
+ assert(instr->operands_lock != 0);
+
if (index >= instr->operands_count) result = NULL;
else result = instr->operands[index];
@@ -492,10 +587,12 @@ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size
* *
******************************************************************************/
-void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old)
+void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old)
{
size_t i; /* Boucle de parcours */
+ assert(instr->operands_lock != 0);
+
for (i = 0; i < instr->operands_count; i++)
if (instr->operands[i] == old)
break;
@@ -522,10 +619,12 @@ void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *n
* *
******************************************************************************/
-void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand)
+void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand)
{
size_t i; /* Boucle de parcours */
+ assert(instr->operands_lock != 0);
+
for (i = 0; i < instr->operands_count; i++)
if (instr->operands[i] == operand)
break;
@@ -540,46 +639,6 @@ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *op
}
-/******************************************************************************
-* *
-* Paramètres : instr = instruction à consulter. *
-* rregs = liste des rgistres lus. [OUT] *
-* rcount = nombre de registres lus. [OUT] *
-* wregs = liste des rgistres écrits. [OUT] *
-* wcount = nombre de registres écrits. [OUT] *
-* *
-* Description : Liste les registres lus et écrits par l'instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : Les compteurs de références sont à décrémenter après usage ! *
-* *
-******************************************************************************/
-
-void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount)
-{
-#if 0
-
- size_t i; /* Boucle de parcours */
-
- *rregs = NULL;
- *rcount = 0;
- *wregs = NULL;
- *wcount = 0;
-
- instr->get_rw_regs(instr, rregs, rcount, wregs, wcount);
-
- for (i = 0; i < *rcount; i++)
- g_object_ref(G_OBJECT((*rregs)[i]));
-
- for (i = 0; i < *wcount; i++)
- g_object_ref(G_OBJECT((*wregs)[i]));
-
-#endif
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 6388f94..fad6c72 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -123,23 +123,67 @@ void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *,
+/* Liste les registres lus et écrits par l'instruction. */
+void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated));
+
+
+
+/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */
+
+
+/* Verrouille les accès la liste des opérandes. */
+void g_arch_instruction_lock_operands(GArchInstruction *);
+
+/* Déverrouille les accès la liste des opérandes. */
+void g_arch_instruction_unlock_operands(GArchInstruction *);
+
/* Attache un opérande supplémentaire à une instruction. */
void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);
/* Indique la quantité d'opérandes présents dans l'instruction. */
-size_t g_arch_instruction_count_operands(const GArchInstruction *);
+size_t _g_arch_instruction_count_operands(const GArchInstruction *);
/* Fournit un opérande donné d'une instruction. */
-GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *, size_t);
+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 *, const GArchOperand *);
/* Détache un opérande liée d'une instruction. */
-void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
-
-/* Liste les registres lus et écrits par l'instruction. */
-void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated));
+void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
+
+
+#define g_arch_instruction_count_operands(ins) \
+ ({ \
+ size_t __result; \
+ g_arch_instruction_lock_operands(ins); \
+ __result = _g_arch_instruction_count_operands(ins); \
+ g_arch_instruction_unlock_operands(ins); \
+ __result; \
+ })
+
+#define g_arch_instruction_get_operand(ins, idx) \
+ ({ \
+ GArchOperand *__result; \
+ g_arch_instruction_lock_operands(ins); \
+ __result = _g_arch_instruction_get_operand(ins, idx); \
+ g_arch_instruction_unlock_operands(ins); \
+ __result; \
+ })
+
+#define g_arch_instruction_replace_operand(ins, n, o) \
+ ({ \
+ g_arch_instruction_lock_operands(ins); \
+ _g_arch_instruction_replace_operand(ins, n, o); \
+ g_arch_instruction_unlock_operands(ins); \
+ })
+
+#define g_arch_instruction_detach_operand(ins, o) \
+ ({ \
+ g_arch_instruction_lock_operands(ins); \
+ _g_arch_instruction_detach_operand(ins, o); \
+ g_arch_instruction_unlock_operands(ins); \
+ })
diff --git a/src/arch/link.c b/src/arch/link.c
index dfc2bd5..fbcd391 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -53,9 +53,13 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
vmpa2t addr; /* Adresse de destination */
GArchInstruction *target; /* Ligne visée par la référence*/
- assert(g_arch_instruction_count_operands(instr) > 0);
+ g_arch_instruction_lock_operands(instr);
- op = g_arch_instruction_get_operand(instr, 0);
+ assert(_g_arch_instruction_count_operands(instr) > 0);
+
+ op = _g_arch_instruction_get_operand(instr, 0);
+
+ g_arch_instruction_unlock_operands(instr);
if (!G_IS_IMM_OPERAND(op)) return;
@@ -102,9 +106,13 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
const mrange_t *range; /* Emplacement d'instruction */
vmpa2t next; /* Position suivante */
- assert(g_arch_instruction_count_operands(instr) > index);
+ g_arch_instruction_lock_operands(instr);
+
+ assert(_g_arch_instruction_count_operands(instr) > index);
- op = g_arch_instruction_get_operand(instr, index);
+ op = _g_arch_instruction_get_operand(instr, index);
+
+ g_arch_instruction_unlock_operands(instr);
defined = false;
@@ -175,9 +183,13 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
vmpa2t addr; /* Adresse de destination */
GArchInstruction *target; /* Ligne visée par la référence*/
- assert(g_arch_instruction_count_operands(instr) > 0);
+ g_arch_instruction_lock_operands(instr);
+
+ assert(_g_arch_instruction_count_operands(instr) > 0);
+
+ op = _g_arch_instruction_get_operand(instr, 0);
- op = g_arch_instruction_get_operand(instr, 0);
+ g_arch_instruction_unlock_operands(instr);
if (!G_IS_IMM_OPERAND(op)) return;
diff --git a/src/arch/post.c b/src/arch/post.c
index 59ed40e..babe6a9 100644
--- a/src/arch/post.c
+++ b/src/arch/post.c
@@ -63,7 +63,9 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
- op = g_arch_instruction_get_operand(instr, index);
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, index);
assert(G_IS_IMM_OPERAND(op));
if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr)
@@ -109,8 +111,10 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro
}
- g_arch_instruction_replace_operand(instr, new, op);
+ _g_arch_instruction_replace_operand(instr, new, op);
}
+ g_arch_instruction_unlock_operands(instr);
+
}
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 63dadab..f22645f 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -512,6 +512,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
first = true;
+ g_arch_instruction_lock_operands(base);
+
for (i = 0; i < base->operands_count; i++)
{
status = g_imm_operand_get_value(G_IMM_OPERAND(base->operands[i]), MDS_8_BITS, &byte);
@@ -558,6 +560,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
}
+ g_arch_instruction_unlock_operands(base);
+
/* Si une chaîne reste encore */
if (iter > 1)
{
@@ -581,6 +585,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
else
{
+ g_arch_instruction_lock_operands(base);
+
if (base->operands_count > 0)
{
g_arch_operand_print(base->operands[0], line, 0/*syntax*/);
@@ -596,6 +602,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
}
+ g_arch_instruction_unlock_operands(base);
+
}
}