From 36fdf5b8960c071d01bdf40db8fbecb11747357e Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 29 May 2012 19:41:39 +0000 Subject: [PATCH] Improving ARM (de-)assembly --- src/arch/arm.h | 19 +++++++++++++- src/arch/arm.ins | 68 ++++++++++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/arch/arm.h b/src/arch/arm.h index 40f225e..08573c4 100644 --- a/src/arch/arm.h +++ b/src/arch/arm.h @@ -36,6 +36,7 @@ static void _decode_reg_reg_reg(AsmArchPlugin * plugin, AsmArchInstructionCall * call, uint32_t opcode); static void _decode_reg_reg_u12(AsmArchPlugin * plugin, AsmArchInstructionCall * call, uint32_t opcode); +static void _decode_s24(AsmArchInstructionCall * call, uint32_t opcode); static void _decode_u24(AsmArchInstructionCall * call, uint32_t opcode); static void _decode_u4_u4_reg(AsmArchPlugin * plugin, AsmArchInstructionCall * call, uint32_t opcode); @@ -74,12 +75,18 @@ static int _arm_decode(AsmArchPlugin * plugin, AsmArchInstructionCall * call) } /* bits 27, 25, 24 are set */ else if((op = (opcode & OPBL(0x0))) == OPBL(0x0)) + { ai = helper->get_instruction_by_opcode(helper->arch, 32, opcode & OPBL(0xf)); + _decode_s24(call, opcode); + } /* bits 27, 25 are set */ else if((op = (opcode & OPB(0x0))) == OPB(0x0)) + { ai = helper->get_instruction_by_opcode(helper->arch, 32, opcode & OPB(0xf)); + _decode_s24(call, opcode); + } /* bits 26, 25, 22, 20 */ else if((op = (opcode & OPSDTLB(0x0))) == OPSDTLB(0x0)) ai = helper->get_instruction_by_opcode(helper->arch, 32, @@ -232,6 +239,14 @@ static void _decode_reg_reg_u12(AsmArchPlugin * plugin, call->operands[2].value.immediate.value = opcode & 0xfff; } +static void _decode_s24(AsmArchInstructionCall * call, uint32_t opcode) +{ + call->operands[0].value.immediate.value = opcode & 0x00ffffff; + /* FIXME properly restore the sign */ + if(opcode & 0x00800000) + call->operands[0].value.immediate.negative = 1; +} + static void _decode_u24(AsmArchInstructionCall * call, uint32_t opcode) { call->operands[0].value.immediate.value = opcode & 0x00ffffff; @@ -273,7 +288,9 @@ static int _arm_encode(AsmArchPlugin * plugin, AsmArchInstruction * instruction, /* branch, branch with link */ case OPB(0): /* b */ case OPBL(0): /* bl */ - opcode |= call->operands[0].value.immediate.value; + /* FIXME properly keep the sign */ + opcode |= (call->operands[0].value.immediate.value + & 0x00ffffff); break; /* branch and exchange */ case OPBX(0): /* bx */ diff --git a/src/arch/arm.ins b/src/arch/arm.ins index 9387274..73e60b9 100644 --- a/src/arch/arm.ins +++ b/src/arch/arm.ins @@ -50,10 +50,10 @@ /* branch, branch with link */ #define OPB(cond) ((cond << 28) | (0x5 << 25)) #define OPBF (32 << AOD_SIZE) -#define OPB_S26 AO_IMMEDIATE(AOF_SIGNED, 26, 0) +#define OPB_S24 AO_IMMEDIATE(AOF_SIGNED, 26, 0) #define OPBL(cond) ((cond << 28) | (0x5 << 25) | (0x1 << 24)) #define OPBLF (32 << AOD_SIZE) -#define OPBL_S26 AO_IMMEDIATE(AOF_SIGNED, 26, 0) +#define OPBL_S24 AO_IMMEDIATE(AOF_SIGNED, 26, 0) /* branch and exchange */ #define OPBX(cond) ((cond << 28) | (0x12fff1 << 4)) @@ -350,22 +350,22 @@ { "andles", OPDPIS(le,and), OPDPISF,AO_3(OP_R, OP_R, OPDPIS_U12) }, { "andals", OPDPIS(al,and), OPDPISF,AO_3(OP_R, OP_R, OPDPIS_U12) }, /* b */ -{ "b", OPB(al), OPBF, AO_1(OPB_S26) }, -{ "beq", OPB(eq), OPBF, AO_1(OPB_S26) }, -{ "bne", OPB(ne), OPBF, AO_1(OPB_S26) }, -{ "bcs", OPB(cs), OPBF, AO_1(OPB_S26) }, -{ "bcc", OPB(cc), OPBF, AO_1(OPB_S26) }, -{ "bmi", OPB(mi), OPBF, AO_1(OPB_S26) }, -{ "bpl", OPB(pl), OPBF, AO_1(OPB_S26) }, -{ "bvs", OPB(vs), OPBF, AO_1(OPB_S26) }, -{ "bvc", OPB(vc), OPBF, AO_1(OPB_S26) }, -{ "bhi", OPB(hi), OPBF, AO_1(OPB_S26) }, -{ "bls", OPB(ls), OPBF, AO_1(OPB_S26) }, -{ "bge", OPB(ge), OPBF, AO_1(OPB_S26) }, -{ "blt", OPB(lt), OPBF, AO_1(OPB_S26) }, -{ "bgt", OPB(gt), OPBF, AO_1(OPB_S26) }, -{ "ble", OPB(le), OPBF, AO_1(OPB_S26) }, -{ "bal", OPB(al), OPBF, AO_1(OPB_S26) }, +{ "b", OPB(al), OPBF, AO_1(OPB_S24) }, +{ "beq", OPB(eq), OPBF, AO_1(OPB_S24) }, +{ "bne", OPB(ne), OPBF, AO_1(OPB_S24) }, +{ "bcs", OPB(cs), OPBF, AO_1(OPB_S24) }, +{ "bcc", OPB(cc), OPBF, AO_1(OPB_S24) }, +{ "bmi", OPB(mi), OPBF, AO_1(OPB_S24) }, +{ "bpl", OPB(pl), OPBF, AO_1(OPB_S24) }, +{ "bvs", OPB(vs), OPBF, AO_1(OPB_S24) }, +{ "bvc", OPB(vc), OPBF, AO_1(OPB_S24) }, +{ "bhi", OPB(hi), OPBF, AO_1(OPB_S24) }, +{ "bls", OPB(ls), OPBF, AO_1(OPB_S24) }, +{ "bge", OPB(ge), OPBF, AO_1(OPB_S24) }, +{ "blt", OPB(lt), OPBF, AO_1(OPB_S24) }, +{ "bgt", OPB(gt), OPBF, AO_1(OPB_S24) }, +{ "ble", OPB(le), OPBF, AO_1(OPB_S24) }, +{ "bal", OPB(al), OPBF, AO_1(OPB_S24) }, /* bic */ { "bic", OPDP(al,bic), OPDPF, AO_3(OP_R, OP_R, OP_R) }, { "biceq", OPDP(eq,bic), OPDPF, AO_3(OP_R, OP_R, OP_R) }, @@ -432,22 +432,22 @@ { "bicles", OPDPIS(le,bic), OPDPISF,AO_3(OP_R, OP_R, OPDPIS_U12) }, { "bicals", OPDPIS(al,bic), OPDPISF,AO_3(OP_R, OP_R, OPDPIS_U12) }, /* bl */ -{ "bl", OPBL(al), OPBLF, AO_1(OPBL_S26) }, -{ "bleq", OPBL(eq), OPBLF, AO_1(OPBL_S26) }, -{ "blne", OPBL(ne), OPBLF, AO_1(OPBL_S26) }, -{ "blcs", OPBL(cs), OPBLF, AO_1(OPBL_S26) }, -{ "blcc", OPBL(cc), OPBLF, AO_1(OPBL_S26) }, -{ "blmi", OPBL(mi), OPBLF, AO_1(OPBL_S26) }, -{ "blpl", OPBL(pl), OPBLF, AO_1(OPBL_S26) }, -{ "blvs", OPBL(vs), OPBLF, AO_1(OPBL_S26) }, -{ "blvc", OPBL(vc), OPBLF, AO_1(OPBL_S26) }, -{ "blhi", OPBL(hi), OPBLF, AO_1(OPBL_S26) }, -{ "blls", OPBL(ls), OPBLF, AO_1(OPBL_S26) }, -{ "blge", OPBL(ge), OPBLF, AO_1(OPBL_S26) }, -{ "bllt", OPBL(lt), OPBLF, AO_1(OPBL_S26) }, -{ "blgt", OPBL(gt), OPBLF, AO_1(OPBL_S26) }, -{ "blle", OPBL(le), OPBLF, AO_1(OPBL_S26) }, -{ "blal", OPBL(al), OPBLF, AO_1(OPBL_S26) }, +{ "bl", OPBL(al), OPBLF, AO_1(OPBL_S24) }, +{ "bleq", OPBL(eq), OPBLF, AO_1(OPBL_S24) }, +{ "blne", OPBL(ne), OPBLF, AO_1(OPBL_S24) }, +{ "blcs", OPBL(cs), OPBLF, AO_1(OPBL_S24) }, +{ "blcc", OPBL(cc), OPBLF, AO_1(OPBL_S24) }, +{ "blmi", OPBL(mi), OPBLF, AO_1(OPBL_S24) }, +{ "blpl", OPBL(pl), OPBLF, AO_1(OPBL_S24) }, +{ "blvs", OPBL(vs), OPBLF, AO_1(OPBL_S24) }, +{ "blvc", OPBL(vc), OPBLF, AO_1(OPBL_S24) }, +{ "blhi", OPBL(hi), OPBLF, AO_1(OPBL_S24) }, +{ "blls", OPBL(ls), OPBLF, AO_1(OPBL_S24) }, +{ "blge", OPBL(ge), OPBLF, AO_1(OPBL_S24) }, +{ "bllt", OPBL(lt), OPBLF, AO_1(OPBL_S24) }, +{ "blgt", OPBL(gt), OPBLF, AO_1(OPBL_S24) }, +{ "blle", OPBL(le), OPBLF, AO_1(OPBL_S24) }, +{ "blal", OPBL(al), OPBLF, AO_1(OPBL_S24) }, /* bx */ { "bx", OPBX(al), OPBXF, AO_1(OP_R) }, { "bxeq", OPBX(eq), OPBXF, AO_1(OP_R) },