diff options
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r-- | src/arch/immediate.c | 544 |
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; } |