summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-08-19 20:25:20 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-08-19 20:25:20 (GMT)
commit2425953ed7330c8f92ec7d04a5f248db1ed98a9d (patch)
treef389f040f6bcc9f88d837e0e2f37cbd49758f610 /src/arch
parenta0a7b6c1e05c78ae433f353d15e3366107b67d03 (diff)
Added a demo symbol when loading an ELF header.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@390 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/Makefile.am1
-rw-r--r--src/arch/archbase.h26
-rw-r--r--src/arch/immediate.c544
-rw-r--r--src/arch/immediate.h25
-rw-r--r--src/arch/instruction-int.h1
-rw-r--r--src/arch/instruction.c30
-rw-r--r--src/arch/instruction.h9
-rw-r--r--src/arch/raw.c246
-rw-r--r--src/arch/raw.h60
9 files changed, 649 insertions, 293 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index e87247e..7dd51b9 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -13,6 +13,7 @@ libarch_la_SOURCES = \
operand.h operand.c \
processor-int.h \
processor.h processor.c \
+ raw.h raw.c \
register-int.h \
register.h register.c \
translate.h \
diff --git a/src/arch/archbase.h b/src/arch/archbase.h
index 1a8b507..24cfd77 100644
--- a/src/arch/archbase.h
+++ b/src/arch/archbase.h
@@ -55,21 +55,25 @@ typedef enum _MemoryDataSize
{
MDS_UNDEFINED, /* Taille non définie */
- MDS_4_BITS_UNSIGNED, /* Opérande sur 4 bits n.-s. */
- MDS_8_BITS_UNSIGNED, /* Opérande sur 8 bits n.-s. */
- MDS_16_BITS_UNSIGNED, /* Opérande sur 16 bits n.-s. */
- MDS_32_BITS_UNSIGNED, /* Opérande sur 32 bits n.-s. */
- MDS_64_BITS_UNSIGNED, /* Opérande sur 64 bits n.-s. */
-
- MDS_4_BITS_SIGNED, /* Opérande sur 4 bits signés */
- MDS_8_BITS_SIGNED, /* Opérande sur 8 bits signés */
- MDS_16_BITS_SIGNED, /* Opérande sur 16 bits signés */
- MDS_32_BITS_SIGNED, /* Opérande sur 32 bits signés */
- MDS_64_BITS_SIGNED /* Opérande sur 64 bits signés */
+ MDS_4_BITS_UNSIGNED = 0x01, /* Opérande sur 4 bits n.-s. */
+ MDS_8_BITS_UNSIGNED = 0x02, /* Opérande sur 8 bits n.-s. */
+ MDS_16_BITS_UNSIGNED = 0x03, /* Opérande sur 16 bits n.-s. */
+ MDS_32_BITS_UNSIGNED = 0x04, /* Opérande sur 32 bits n.-s. */
+ MDS_64_BITS_UNSIGNED = 0x05, /* Opérande sur 64 bits n.-s. */
+
+ MDS_4_BITS_SIGNED = 0x81, /* Opérande sur 4 bits signés */
+ MDS_8_BITS_SIGNED = 0x82, /* Opérande sur 8 bits signés */
+ MDS_16_BITS_SIGNED = 0x83, /* Opérande sur 16 bits signés */
+ MDS_32_BITS_SIGNED = 0x84, /* Opérande sur 32 bits signés */
+ MDS_64_BITS_SIGNED = 0x85 /* Opérande sur 64 bits signés */
} MemoryDataSize;
+#define MDS_RANGE(mds) ((mds & 0xf) - 1)
+#define MDS_IS_SIGNED(mds) (mds & 0x80)
+
+
#define MDS_4_BITS MDS_4_BITS_UNSIGNED
#define MDS_8_BITS MDS_8_BITS_UNSIGNED
#define MDS_16_BITS MDS_16_BITS_UNSIGNED
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 46abe62..88a0f4b 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -69,6 +69,7 @@ struct _GImmOperand
} signed_imm;
bool zpad; /* Ajoute des 0 à l'impression */
+ ImmOperandDisplay display; /* Format général d'affichage */
};
@@ -139,6 +140,7 @@ static void g_imm_operand_init(GImmOperand *operand)
arch->print = (operand_print_fc)g_imm_operand_print;
operand->zpad = false;
+ operand->display = IOD_HEX;
}
@@ -237,6 +239,110 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : size = taille de l'opérande souhaitée. *
+* data = flux de données à analyser. *
+* addr = position courante dans ce flux. [OUT] *
+* end = limite des données à analyser. *
+* low = position éventuelle des 4 bits visés. [OUT] *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Crée un opérande réprésentant une valeur numérique. *
+* *
+* Retour : Instruction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
+{
+ GImmOperand *result; /* Opérande à retourner */
+ off_t old; /* Ancienne tête de lecture */
+ off_t pos; /* Position physique */
+
+ result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
+
+ result->size = size;
+
+ pos = get_phy_addr(addr);
+ old = pos;
+
+ switch (size)
+ {
+ case MDS_4_BITS_UNSIGNED:
+ if (!read_u4(&result->unsigned_imm.val8, data, &pos, end, low, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_8_BITS_UNSIGNED:
+ if (!read_u8(&result->unsigned_imm.val8, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_16_BITS_UNSIGNED:
+ if (!read_u16(&result->unsigned_imm.val16, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_32_BITS_UNSIGNED:
+ if (!read_u32(&result->unsigned_imm.val32, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_64_BITS_UNSIGNED:
+ if (!read_u64(&result->unsigned_imm.val64, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_4_BITS_SIGNED:
+ if (!read_s4(&result->signed_imm.val8, data, &pos, end, low, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_8_BITS_SIGNED:
+ if (!read_s8(&result->signed_imm.val8, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_16_BITS_SIGNED:
+ if (!read_s16(&result->signed_imm.val16, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_32_BITS_SIGNED:
+ if (!read_s32(&result->signed_imm.val32, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_64_BITS_SIGNED:
+ if (!read_s64(&result->signed_imm.val64, data, &pos, end, endian))
+ goto gionfd_error;
+ break;
+
+ case MDS_UNDEFINED:
+ goto gionfd_error;
+ break;
+
+ }
+
+ advance_vmpa(addr, pos - old);
+
+ return G_ARCH_OPERAND(result);
+
+ gionfd_error:
+
+ g_object_unref(G_OBJECT(result));
+
+ return NULL;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : size = taille de l'opérande souhaitée. *
@@ -321,7 +427,27 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
/******************************************************************************
* *
-* Paramètres : state = true si des zéro sont à ajouter, false sinon. *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* *
+* Retour : Taille de la valeur représentée en mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+{
+ return operand->size;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à définir. *
+* state = true si des zéro sont à ajouter, false sinon. *
* *
* Description : Précise si des zéro doivent compléter l'affichage ou non. *
* *
@@ -340,7 +466,7 @@ void g_imm_operand_pad(GImmOperand *operand, bool state)
/******************************************************************************
* *
-* Paramètres : operand = structure dont le contenu est à définir. *
+* Paramètres : operand = structure dont le contenu est à consulter. *
* *
* Description : Indique le signe d'une valeur immédiate. *
* *
@@ -359,6 +485,45 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
/******************************************************************************
* *
+* Paramètres : operand = structure dont le contenu est à définir. *
+* display = format global d'un affichage de valeur. *
+* *
+* Description : Définit la grande ligne du format textuel de la valeur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
+{
+ operand->display = display;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Indique la grande ligne du format textuel de la valeur. *
+* *
+* Retour : Format global d'un affichage de valeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
+{
+ return operand->display;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = structure dont le contenu est à consulter. *
* *
* Description : Indique le signe d'une valeur immédiate. *
@@ -475,288 +640,105 @@ bool g_imm_operand_is_null(const GImmOperand *operand)
static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[VMPA_MAX_SIZE])
{
size_t result; /* Longueur à retourner */
+ unsigned int range; /* Catégorie de la taille */
+ const char *prefix; /* Entrée en matière */
+ const char *suffix; /* Sortie de matière */
+ const char *alternate; /* Préfixe de forme alternative*/
+ const char *zpad; /* Remplissage par des zéros */
+ const char *lmod; /* Modification de longueur */
+ const char *conv; /* Opérateur de conversion */
+ char format[16]; /* Format d'impression final */
+
+ static const char *zpad_defs[] = { "", "02", "04", "08", "016" };
+ static const char *lmod_defs[] = { "hh", "hh", "h", "", __PRI64_PREFIX };
+ static const char *conv_si_defs[] = { "c", "d", "x", "o" };
+ static const char *conv_us_defs[] = { "c", "u", "x", "o" };
+
+ result = 0; /* Gcc... */
+
+ range = MDS_RANGE(operand->size);
+
+ /* Encadrement pour les caractères */
+ if (operand->display == IOD_CHAR)
+ {
+ prefix = (syntax == ASX_ATT ? "$'" : "'");
+ suffix = "'";
+ }
+ else
+ {
+ prefix = (syntax == ASX_ATT ? "$" : "");
+ suffix = "";
+ }
+
+ /* Préfix de forme '0x' ou '0' */
+ if (operand->display == IOD_HEX)
+ alternate = "0x";
+ else if (operand->display == IOD_OCT)
+ alternate = "0";
+ else
+ alternate = "";
+
+ /* Drapeau de remplissage ? */
+ if (operand->display == IOD_HEX)
+ zpad = (operand->zpad ? zpad_defs[range] : "");
+ else
+ zpad = "";
+
+ /* Modification de la longueur fournie */
+ lmod = lmod_defs[range];
- /* Pour gcc (Debian 4.4.5-8) 4.4.5 */
- result = 0;
+ /* Spécification de la conversion */
+ if (MDS_IS_SIGNED(operand->size))
+ conv = conv_si_defs[operand->display];
+ else
+ conv = conv_us_defs[operand->display];
- switch (syntax)
+ snprintf(format, sizeof(format), "%s%s%%%s%s%s%s", prefix, alternate, zpad, lmod, conv, suffix);
+
+ switch (operand->size)
{
- case ASX_INTEL:
- switch (operand->size)
- {
- case MDS_UNDEFINED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x???");
- break;
-
- case MDS_4_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
-
- case MDS_8_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", operand->unsigned_imm.val8);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
- break;
-
- case MDS_16_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", operand->unsigned_imm.val16);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);
- break;
-
- case MDS_32_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", operand->unsigned_imm.val32);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);
- break;
-
- case MDS_64_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "0x%016" PRIx64, operand->unsigned_imm.val64);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%" PRIx64, operand->unsigned_imm.val64);
- break;
-
- case MDS_4_BITS_SIGNED:
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
- break;
-
- case MDS_8_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", operand->signed_imm.val8);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
- }
- break;
-
- case MDS_16_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", ~operand->signed_imm.val16 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", operand->signed_imm.val16);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);
- }
- break;
-
- case MDS_32_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", ~operand->signed_imm.val32 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", operand->signed_imm.val32);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);
- }
- break;
-
- case MDS_64_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%016" PRIx64, ~operand->signed_imm.val64 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%016" PRIx64, operand->signed_imm.val64);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%" PRIx64, ~operand->signed_imm.val64 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%" PRIx64, operand->signed_imm.val64);
- }
- break;
- }
- break;
-
- case ASX_ATT:
- switch (operand->size)
- {
- case MDS_UNDEFINED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x???");
- break;
-
- case MDS_4_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
-
- case MDS_8_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", operand->unsigned_imm.val8);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
- break;
-
- case MDS_16_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", operand->unsigned_imm.val16);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);
- break;
-
- case MDS_32_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", operand->unsigned_imm.val32);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);
- break;
-
- case MDS_64_BITS_UNSIGNED:
- if (operand->zpad)
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%016" PRIx64, operand->unsigned_imm.val64);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%" PRIx64, operand->unsigned_imm.val64);
- break;
-
- case MDS_4_BITS_SIGNED:
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->signed_imm.val8);
- break;
-
- case MDS_8_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", operand->signed_imm.val8);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->signed_imm.val8);
- }
- break;
-
- case MDS_16_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", ~operand->signed_imm.val16 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", operand->signed_imm.val16);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->signed_imm.val16);
- }
- break;
-
- case MDS_32_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", ~operand->signed_imm.val32 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", operand->signed_imm.val32);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->signed_imm.val32);
- }
- break;
-
- case MDS_64_BITS_SIGNED:
- if (operand->zpad)
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%016" PRIx64, ~operand->signed_imm.val64 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%016" PRIx64, operand->signed_imm.val64);
- }
- else
- {
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%" PRIx64, ~operand->signed_imm.val64 + 1);
- else
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%" PRIx64, operand->signed_imm.val64);
- }
- break;
- }
- break;
-
- case ASX_COUNT:
- switch (operand->size)
- {
- case MDS_UNDEFINED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x???");
- break;
-
- case MDS_4_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hhu", operand->unsigned_imm.val8);
-
- case MDS_8_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hhu", operand->unsigned_imm.val8);
- break;
-
- case MDS_16_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hu", operand->unsigned_imm.val16);
- break;
-
- case MDS_32_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%u", operand->unsigned_imm.val32);
- break;
-
- case MDS_64_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%" PRIu64, operand->unsigned_imm.val64);
- break;
-
- case MDS_4_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hhd", operand->signed_imm.val8);
- break;
-
- case MDS_8_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hhd", operand->signed_imm.val8);
- break;
-
- case MDS_16_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%hd", operand->signed_imm.val16);
- break;
-
- case MDS_32_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%d", operand->signed_imm.val32);
- break;
-
- case MDS_64_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "%" PRId64, operand->signed_imm.val64);
- break;
- }
+ case MDS_UNDEFINED:
+ result = snprintf(value, VMPA_MAX_SIZE, "<? undef value ?>");
+ break;
+
+ case MDS_4_BITS_UNSIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ break;
+
+ case MDS_8_BITS_UNSIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ break;
+
+ case MDS_16_BITS_UNSIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val16);
+ break;
+
+ case MDS_32_BITS_UNSIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val32);
+ break;
+
+ case MDS_64_BITS_UNSIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val64);
+ break;
+
+ case MDS_4_BITS_SIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ break;
+
+ case MDS_8_BITS_SIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ break;
+
+ case MDS_16_BITS_SIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val16);
+ break;
+
+ case MDS_32_BITS_SIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val32);
+ break;
+
+ case MDS_64_BITS_SIGNED:
+ result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val64);
break;
}
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 01971fd..71d482a 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -35,6 +35,17 @@
+/* Grande ligne d'un format d'affichage */
+typedef enum _ImmOperandDisplay
+{
+ IOD_CHAR,
+ IOD_DEC,
+ IOD_HEX,
+ IOD_OCT
+
+} ImmOperandDisplay;
+
+
#define G_TYPE_IMM_OPERAND g_imm_operand_get_type()
#define G_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_imm_operand_get_type(), GImmOperand))
#define G_IS_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_imm_operand_get_type()))
@@ -57,14 +68,28 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t
#define g_imm_operand_new_from_data(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
/* Crée un opérande réprésentant une valeur numérique. */
+GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian);
+
+#define g_imm_operand_new_from_data2(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
+
+/* Crée un opérande réprésentant une valeur numérique. */
GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...);
+/* Renseigne la taille de la valeur indiquée à la construction. */
+MemoryDataSize g_imm_operand_get_size(const GImmOperand *);
+
/* Précise si des zéro doivent compléter l'affichage ou non. */
void g_imm_operand_pad(GImmOperand *, bool);
/* Indique le signe d'une valeur immédiate. */
bool g_imm_operand_does_padding(const GImmOperand *);
+/* Définit la grande ligne du format textuel de la valeur. */
+void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display);
+
+/* Indique la grande ligne du format textuel de la valeur. */
+ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *);
+
/* Indique le signe d'une valeur immédiate. */
bool g_imm_operand_is_negative(const GImmOperand *);
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 076eec2..8730792 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -97,6 +97,7 @@ struct _GArchInstructionClass
#define ainstr_list_prev_iter(iter, head) dl_list_prev_iter(iter, head, GArchInstruction, flow)
#define ainstr_list_next_iter(iter, head) dl_list_next_iter(iter, head, GArchInstruction, flow)
#define ainstr_list_add_tail(new, head) dl_list_add_tail(new, head, GArchInstruction, flow)
+#define ainstr_list_merge(head1, head2) dl_list_merge(head1, head2, GArchInstruction, flow)
#define ainstr_list_for_each(pos, head) dl_list_for_each(pos, head, GArchInstruction, flow)
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 3a62a90..95910ba 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -171,6 +171,32 @@ void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *addr
}
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* offset = position physique dans le code binaire/NULL. [OUT] *
+* length = taille de l'instruction ou NULL. [OUT] *
+* address = adresse virtuelle ou position physique/NULL. [OUT] *
+* *
+* Description : Fournit la localisation d'une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *instr, off_t *length)
+{
+ if (length != NULL) *length = instr->length;
+
+ return &instr->address2;
+
+}
+
+
+
/******************************************************************************
* *
* Paramètres : instr = instruction quelconque à consulter. *
@@ -854,9 +880,13 @@ GArchInstruction *g_arch_instruction_get_next_iter(const GArchInstruction *list,
result = ainstr_list_next_iter(iter, list);
+ /* FIXME : utiliser les nouvelles adresses !
+
if (result != NULL && result->address >= max)
result = NULL;
+ */
+
return result;
}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index a059161..08135a9 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -34,7 +34,7 @@
#include "../analysis/type.h"
#include "../decomp/context.h"
#include "../decomp/instruction.h"
-#include "../format/executable.h"
+//#include "../format/executable.h"
@@ -59,6 +59,13 @@ GType g_arch_instruction_get_type(void);
/* Définit la localisation d'une instruction. */
void g_arch_instruction_set_location(GArchInstruction *, const vmpa2t *, off_t);
+
+
+/* Fournit la localisation d'une instruction. */
+const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *, off_t *);
+
+
+
/* Fournit la localisation d'une instruction. */
void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, vmpa_t *);
diff --git a/src/arch/raw.c b/src/arch/raw.c
new file mode 100644
index 0000000..0d6ae4a
--- /dev/null
+++ b/src/arch/raw.c
@@ -0,0 +1,246 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * artificial.c - instructions pures vues de l'esprit
+ *
+ * Copyright (C) 2009-2012 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "raw.h"
+
+
+#include "immediate.h"
+#include "instruction-int.h"
+
+
+
+/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
+
+
+/* Définition générique d'une instruction d'architecture inconnue (instance) */
+struct _GRawInstruction
+{
+ GArchInstruction parent; /* A laisser en premier */
+
+};
+
+/* Définition générique d'une instruction d'architecture inconnue (classe) */
+struct _GRawInstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe générique des opérandes. */
+static void g_raw_instruction_class_init(GRawInstructionClass *);
+
+/* Initialise une instance d'opérande d'architecture. */
+static void g_raw_instruction_init(GRawInstruction *);
+
+/* Supprime toutes les références externes. */
+static void g_raw_instruction_dispose(GRawInstruction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_raw_instruction_finalize(GRawInstruction *);
+
+/* Fournit le nom humain de l'instruction manipulée. */
+static const char *g_raw_instruction_get_keyword(const GRawInstruction *, AsmSyntax);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INSTRUCTION INCONNUE / DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une instruction inconnue d'architecture. */
+G_DEFINE_TYPE(GRawInstruction, g_raw_instruction, G_TYPE_ARCH_INSTRUCTION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe générique des opérandes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_raw_instruction_class_init(GRawInstructionClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GArchInstructionClass *instr; /* Encore une autre vision... */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_raw_instruction_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_raw_instruction_finalize;
+
+ instr = G_ARCH_INSTRUCTION_CLASS(klass);
+
+ instr->get_key = (get_instruction_keyword_fc)g_raw_instruction_get_keyword;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à initialiser. *
+* *
+* Description : Initialise une instance d'instruction d'architecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_raw_instruction_init(GRawInstruction *instr)
+{
+ GArchInstruction *parent; /* Instance parente */
+
+ parent = G_ARCH_INSTRUCTION(instr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_raw_instruction_dispose(GRawInstruction *instr)
+{
+ G_OBJECT_CLASS(g_raw_instruction_parent_class)->dispose(G_OBJECT(instr));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_raw_instruction_finalize(GRawInstruction *instr)
+{
+ G_OBJECT_CLASS(g_raw_instruction_parent_class)->finalize(G_OBJECT(instr));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* size = taille de chacun des éléments à représenter. *
+* count = nombre de ces éléments. *
+* addr = position courante dans ce flux. [OUT] *
+* end = limite des données à analyser. *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Crée une instruction de type 'db/dw/etc' étendue. *
+* *
+* Retour : Instruction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ vmpa2t *old; /* Sauvegarde de la position */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *operand; /* Octet non décodé à afficher */
+
+ /* Par soucis de cohérence */
+ if (count == 0) return NULL;
+
+ result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
+
+ old = dup_vmpa(addr);
+
+ for (i = 0; i < count; i++)
+ {
+ operand = g_imm_operand_new_from_data2(size, data, addr, end, endian);
+ if (operand == NULL) goto grina_error;
+
+ g_imm_operand_pad(G_IMM_OPERAND(operand), true);
+
+ g_arch_instruction_attach_extra_operand(result, operand);
+ }
+
+ g_arch_instruction_set_location(result, old, compute_vmpa_diff(addr, old));
+
+ delete_vmpa(old);
+
+ return result;
+
+ grina_error:
+
+ g_object_unref(G_OBJECT(result));
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à traiter. *
+* format = format du binaire manipulé. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Fournit le nom humain de l'instruction manipulée. *
+* *
+* Retour : Mot clef de bas niveau. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, AsmSyntax syntax)
+{
+ GArchOperand *operand; /* Octet décodé à afficher */
+ MemoryDataSize size; /* Taille de valeur associée */
+
+ static char *defines[] = { "dn", "db", "dw", "dd", "dq" };
+
+ operand = g_arch_instruction_get_operand(instr, 0);
+ size = g_imm_operand_get_size(G_IMM_OPERAND(operand));
+
+ return defines[MDS_RANGE(size)];
+
+}
diff --git a/src/arch/raw.h b/src/arch/raw.h
new file mode 100644
index 0000000..08dc620
--- /dev/null
+++ b/src/arch/raw.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * raw.h - prototypes pour les instructions pures vues de l'esprit
+ *
+ * Copyright (C) 2009-2012 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_RAW_H
+#define _ARCH_RAW_H
+
+
+#include <glib-object.h>
+
+
+#include "instruction.h"
+#include "vmpa.h"
+
+
+
+/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
+
+
+#define G_TYPE_RAW_INSTRUCTION g_raw_instruction_get_type()
+#define G_RAW_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_raw_instruction_get_type(), GRawInstruction))
+#define G_IS_RAW_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_raw_instruction_get_type()))
+#define G_RAW_INSTRUCTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_raw_instruction_get_type(), GRawInstructionIface))
+
+
+/* Définition générique d'une instruction d'architecture inconnue (instance) */
+typedef struct _GRawInstruction GRawInstruction;
+
+/* Définition générique d'une instruction d'architecture inconnue (classe) */
+typedef struct _GRawInstructionClass GRawInstructionClass;
+
+
+/* Indique le type défini pour une instruction inconnue d'architecture. */
+GType g_raw_instruction_get_type(void);
+
+/* Crée une instruction de type 'db/dw/etc' étendue. */
+GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian);
+
+
+
+#endif /* _ARCH_RAW_H */