summaryrefslogtreecommitdiff
path: root/src/arch/immediate.c
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/immediate.c
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/immediate.c')
-rw-r--r--src/arch/immediate.c544
1 files changed, 263 insertions, 281 deletions
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;
}