summaryrefslogtreecommitdiff
path: root/src/arch/operands/target.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/operands/target.c')
-rw-r--r--src/arch/operands/target.c223
1 files changed, 153 insertions, 70 deletions
diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c
index 5edc805..61f683a 100644
--- a/src/arch/operands/target.c
+++ b/src/arch/operands/target.c
@@ -37,13 +37,17 @@
#include "targetable-int.h"
#include "../../analysis/routine.h"
#include "../../common/extstr.h"
+#include "../../common/sort.h"
#include "../../format/format.h"
#include "../../format/strsym.h"
#include "../../glibext/gbinarycursor.h"
-#include "../../gtkext/gtkblockdisplay.h"
+#include "../../core/columns.h"
+/* ------------------------- POINTAGE D'UN SYMBOLE EXISTANT ------------------------- */
+
+
/* Initialise la classe des opérandes ciblant des symboles. */
static void g_target_operand_class_init(GTargetOperandClass *);
@@ -59,25 +63,32 @@ static void g_target_operand_dispose(GTargetOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_target_operand_finalize(GTargetOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *);
+static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Construit un petit résumé concis de l'opérande. */
static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *);
+#endif
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_target_operand_hash(const GTargetOperand *, bool);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
-
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_target_operand_unserialize(GTargetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_target_operand_load(GTargetOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_target_operand_serialize(const GTargetOperand *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_target_operand_store(GTargetOperand *, GObjectStorage *, packed_buffer_t *);
@@ -89,6 +100,11 @@ static bool g_target_operand_get_addr(const GTargetOperand *, const vmpa2t *, GB
+/* ---------------------------------------------------------------------------------- */
+/* POINTAGE D'UN SYMBOLE EXISTANT */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Indique le type défini pour un opérande de valeur numérique. */
G_DEFINE_TYPE_WITH_CODE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND,
G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_target_operand_targetable_interface_init));
@@ -120,10 +136,14 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
operand->compare = (operand_compare_fc)g_target_operand_compare;
operand->print = (operand_print_fc)g_target_operand_print;
+#ifdef INCLUDE_GTK_SUPPORT
operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip;
+#endif
+
+ operand->hash = (operand_hash_fc)g_target_operand_hash;
- operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_target_operand_serialize;
+ operand->load = (load_operand_fc)g_target_operand_load;
+ operand->store = (store_operand_fc)g_target_operand_store;
}
@@ -142,10 +162,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
static void g_target_operand_init(GTargetOperand *operand)
{
- operand->size = MDS_UNDEFINED;
+ GET_TARGET_OP_EXTRA(operand)->size = MDS_UNDEFINED;
+
init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
- operand->strict = true;
operand->symbol = NULL;
operand->diff = 0;
@@ -211,8 +231,9 @@ static void g_target_operand_finalize(GTargetOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -222,56 +243,56 @@ static void g_target_operand_finalize(GTargetOperand *operand)
* *
******************************************************************************/
-static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b)
+static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ tarop_extra_data_t *ea; /* Données insérées à modifier */
+ tarop_extra_data_t *eb; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = cmp_vmpa(&a->addr, &b->addr);
- if (result != 0) goto gtoc_done;
+ ea = GET_TARGET_OP_EXTRA(a);
+ eb = GET_TARGET_OP_EXTRA(b);
- if (a->size < b->size)
+ if (lock)
{
- result = -1;
- goto gtoc_done;
- }
- else if (a->size > b->size)
- {
- result = 1;
- goto gtoc_done;
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
}
- if (a->symbol == NULL && b->symbol != NULL)
- {
- result = -1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol == NULL)
- {
- result = 1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol != NULL)
+ result = sort_unsigned_long(ea->size, eb->size);
+
+ if (result == 0)
+ result = cmp_vmpa(&a->addr, &b->addr);
+
+ if (result == 0)
{
- result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
- (const GBinSymbol *[]) { b->symbol });
- if (result != 0) goto gtoc_done;
+ if (a->symbol == NULL && b->symbol != NULL)
+ result = -1;
+
+ else if (a->symbol != NULL && b->symbol == NULL)
+ result = 1;
+
+ else if (a->symbol != NULL && b->symbol != NULL)
+ result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
+ (const GBinSymbol *[]) { b->symbol });
+
}
- if (a->diff < b->diff)
+ if (result == 0)
+ result = sort_uint64_t(a->diff, b->diff);
+
+ if (result == 0)
{
- result = -1;
- goto gtoc_done;
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
- else if (a->diff > b->diff)
+
+ if (lock)
{
- result = 1;
- goto gtoc_done;
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
}
- result = 0;
-
- gtoc_done:
-
return result;
}
@@ -296,6 +317,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
vmpa2t tmp; /* Coquille vide pour argument */
VMPA_BUFFER(value); /* Adresse brute à imprimer */
size_t len; /* Taille de l'élément inséré */
+ MemoryDataSize size; /* Taille retenue */
label = g_binary_symbol_get_label(operand->symbol);
@@ -322,7 +344,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
}
else
{
- vmpa2_to_string(&operand->addr, operand->size, value, &len);
+ size = g_target_operand_get_size(operand);
+
+ vmpa2_to_string(&operand->addr, size, value, &len);
g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_LABEL, G_OBJECT(operand));
@@ -355,7 +379,8 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
assert(size != MDS_UNDEFINED);
- result->size = size;
+ GET_TARGET_OP_EXTRA(result)->size = size;
+
copy_vmpa(&result->addr, addr);
return G_ARCH_OPERAND(result);
@@ -363,6 +388,9 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
}
+#ifdef INCLUDE_GTK_SUPPORT
+
+
/******************************************************************************
* *
* Paramètres : operand = opérande à consulter. *
@@ -443,6 +471,9 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const
}
+#endif
+
+
/******************************************************************************
* *
* Paramètres : operand = structure dont le contenu est à consulter. *
@@ -457,7 +488,18 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const
MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
{
- return operand->size;
+ MemoryDataSize result; /* Taille à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à consulter*/
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->size;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
}
@@ -485,7 +527,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
const mrange_t *range; /* Couverture du symbole */
#endif
- operand->strict = strict;
+ if (strict)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
+ else
+ g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
@@ -569,20 +614,55 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d
}
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+static guint g_target_operand_hash(const GTargetOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->size;
+
+ result ^= g_direct_hash(operand->symbol);
+
+ result ^= (operand->diff & 0xffffffff);
+ result ^= (operand->diff >> 32);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -590,7 +670,7 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d
* *
******************************************************************************/
-static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_target_operand_load(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
@@ -617,11 +697,11 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -629,9 +709,10 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s
* *
******************************************************************************/
-static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_target_operand_store(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ MemoryDataSize size; /* Taille retenue */
GArchOperand *original; /* Opérande d'origine */
/**
@@ -639,12 +720,14 @@ static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorag
* par la position physique.
*/
+ size = g_target_operand_get_size(operand);
+
if (has_virt_addr(&operand->addr))
- original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_virt_addr(&operand->addr));
else
- original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_phy_addr(&operand->addr));
- result = g_arch_operand_store(original, storage, pbuf);
+ result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(original), pbuf);
g_object_unref(G_OBJECT(original));