diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-05-13 12:32:03 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-05-13 12:32:03 (GMT) |
commit | 118a668adbf6ca9d4c549618e54f58330f46ce58 (patch) | |
tree | 10e75f1a7e83ab48aba82a5a595441a065a6037e /src/arch/immediate.c | |
parent | e56b4db3aae87f0458319019635dea4968a5c529 (diff) |
Supported Dalvik VM / DEX (partially).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@155 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r-- | src/arch/immediate.c | 143 |
1 files changed, 81 insertions, 62 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 07f848f..1a32748 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -41,7 +41,7 @@ struct _GImmOperand { GArchOperand parent; /* Instance parente */ - AsmOperandSize size; /* Taille de l'opérande */ + MemoryDataSize size; /* Taille de l'opérande */ /** * Note : dans le cas d'une valeur signée, @@ -148,6 +148,7 @@ static void g_imm_operand_init(GImmOperand *operand) * data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale 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. * @@ -158,7 +159,7 @@ static void g_imm_operand_init(GImmOperand *operand) * * ******************************************************************************/ -GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, SourceEndian endian) +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian) { GImmOperand *result; /* Opérande à retourner */ @@ -168,42 +169,52 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data switch (size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + if (!read_u4(&result->unsigned_imm.val8, data, pos, len, low, endian)) + goto gionfd_error; + break; + + case MDS_8_BITS_UNSIGNED: if (!read_u8(&result->unsigned_imm.val8, data, pos, len, endian)) goto gionfd_error; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: if (!read_u16(&result->unsigned_imm.val16, data, pos, len, endian)) goto gionfd_error; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: if (!read_u32(&result->unsigned_imm.val32, data, pos, len, endian)) goto gionfd_error; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: if (!read_u64(&result->unsigned_imm.val64, data, pos, len, endian)) goto gionfd_error; break; - case AOS_8_BITS_SIGNED: + case MDS_4_BITS_SIGNED: + if (!read_s4(&result->signed_imm.val8, data, pos, len, low, endian)) + goto gionfd_error; + break; + + case MDS_8_BITS_SIGNED: if (!read_s8(&result->signed_imm.val8, data, pos, len, endian)) goto gionfd_error; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: if (!read_s16(&result->signed_imm.val16, data, pos, len, endian)) goto gionfd_error; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: if (!read_s32(&result->signed_imm.val32, data, pos, len, endian)) goto gionfd_error; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: if (!read_s64(&result->signed_imm.val64, data, pos, len, endian)) goto gionfd_error; break; @@ -218,7 +229,7 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data gionfd_error: - /* TODO : free */ + g_object_unref(G_OBJECT(result)); return NULL; @@ -238,7 +249,7 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data * * ******************************************************************************/ -GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) +GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...) { GImmOperand *result; /* Opérande à retourner */ va_list ap; /* Liste des compléments */ @@ -251,7 +262,7 @@ GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) int32_t sval32; /* Valeur sur 32 bits */ int64_t sval64; /* Valeur sur 64 bits */ - if (size == AOS_UNDEFINED) return NULL; + if (size == MDS_UNDEFINED) return NULL; result = g_object_new(G_TYPE_IMM_OPERAND, NULL); @@ -262,37 +273,37 @@ GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) switch (size) { /* Pour GCC... */ - case AOS_UNDEFINED: + case MDS_UNDEFINED: break; - case AOS_8_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: uval8 = (uint8_t)va_arg(ap, unsigned int); result->unsigned_imm.val8 = uval8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: uval16 = (uint16_t)va_arg(ap, unsigned int); result->unsigned_imm.val16 = uval16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: uval32 = (uint32_t)va_arg(ap, unsigned int); result->unsigned_imm.val32 = uval32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: uval64 = (uint64_t)va_arg(ap, unsigned int); result->unsigned_imm.val64 = uval64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: sval8 = (int8_t)va_arg(ap, int); result->signed_imm.val8 = sval8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: sval16 = (int16_t)va_arg(ap, int); result->signed_imm.val16 = sval16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: sval32 = (int32_t)va_arg(ap, int); result->signed_imm.val32 = sval32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: sval64 = (int64_t)va_arg(ap, int); result->signed_imm.val64 = sval64; break; @@ -323,16 +334,19 @@ bool g_imm_operand_is_negative(const GImmOperand *operand) switch (operand->size) { - case AOS_8_BITS_SIGNED: + case MDS_4_BITS_SIGNED: + result = (operand->signed_imm.val8 & 0x08); + break; + case MDS_8_BITS_SIGNED: result = (operand->signed_imm.val8 & 0x80); break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (operand->signed_imm.val16 & 0x8000); break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (operand->signed_imm.val32 & 0x80000000); break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (operand->signed_imm.val64 & 0x8000000000000000ll); break; default: @@ -371,37 +385,38 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt case MDS_UNDEFINED: result = snprintf(value, VMPA_MAX_SIZE, "0x???"); break; - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8); break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16); break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32); break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64); break; - case AOS_8_BITS_SIGNED: + case MDS_8_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 AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: 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 AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: 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 AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: if (g_imm_operand_is_negative(operand)) result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1); else @@ -416,28 +431,29 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt case MDS_UNDEFINED: result = snprintf(value, VMPA_MAX_SIZE, "$0x???"); break; - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8); break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16); break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32); break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64); break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1); break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1); break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1); break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1); break; } @@ -528,16 +544,17 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr) switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: *addr = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: *addr = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: *addr = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: *addr = operand->unsigned_imm.val64; break; default: @@ -572,35 +589,36 @@ bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *ne switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = (sizeof(size_t) >= 1); if (result) *value = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = (sizeof(size_t) >= 2); if (result) *value = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = (sizeof(size_t) >= 4); if (result) *value = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = (sizeof(size_t) >= 8); if (result) *value = operand->unsigned_imm.val64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = (sizeof(size_t) >= 1); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (sizeof(size_t) >= 2); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (sizeof(size_t) >= 4); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (sizeof(size_t) >= 8); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val64; break; @@ -636,35 +654,36 @@ bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *nega switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = (sizeof(off_t) >= 1); if (result) *value = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = (sizeof(off_t) >= 2); if (result) *value = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = (sizeof(off_t) >= 4); if (result) *value = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = (sizeof(off_t) >= 8); if (result) *value = operand->unsigned_imm.val64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = (sizeof(off_t) >= 1); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (sizeof(off_t) >= 2); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (sizeof(off_t) >= 4); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (sizeof(off_t) >= 8); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val64; break; |