summaryrefslogtreecommitdiff
path: root/src/arch/immediate.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-05-13 12:32:03 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-05-13 12:32:03 (GMT)
commit118a668adbf6ca9d4c549618e54f58330f46ce58 (patch)
tree10e75f1a7e83ab48aba82a5a595441a065a6037e /src/arch/immediate.c
parente56b4db3aae87f0458319019635dea4968a5c529 (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.c143
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;