diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/Makefile.am | 1 | ||||
-rw-r--r-- | src/arch/archbase.h | 26 | ||||
-rw-r--r-- | src/arch/immediate.c | 544 | ||||
-rw-r--r-- | src/arch/immediate.h | 25 | ||||
-rw-r--r-- | src/arch/instruction-int.h | 1 | ||||
-rw-r--r-- | src/arch/instruction.c | 30 | ||||
-rw-r--r-- | src/arch/instruction.h | 9 | ||||
-rw-r--r-- | src/arch/raw.c | 246 | ||||
-rw-r--r-- | src/arch/raw.h | 60 |
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 */ |