mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-24 06:48:46 +00:00
Update the GNU ARM disassembler from Binutils (GIT)
This commit is contained in:
parent
1b74b8f8a3
commit
321e51fa6a
@ -11,7 +11,7 @@
|
||||
#include "../asm/arch/arm/asm-arm.h"
|
||||
#include "../asm/arch/arm/winedbg/be_arm.h"
|
||||
|
||||
static unsigned int disarm_branch_offset (unsigned int pc, unsigned int insoff) {
|
||||
static unsigned int disarm_branch_offset(unsigned int pc, unsigned int insoff) {
|
||||
unsigned int add = insoff << 2;
|
||||
/* zero extend if higher is 1 (0x02000000) */
|
||||
if ((add & 0x02000000) == 0x02000000) {
|
||||
@ -20,25 +20,25 @@ static unsigned int disarm_branch_offset (unsigned int pc, unsigned int insoff)
|
||||
return add + pc + 8;
|
||||
}
|
||||
|
||||
#define IS_BRANCH(x) ((x&ARM_BRANCH_I_MASK) == ARM_BRANCH_I)
|
||||
#define IS_BRANCHL(x) (IS_BRANCH(x) && (x&ARM_BRANCH_LINK) == ARM_BRANCH_LINK)
|
||||
#define IS_RETURN(x) ((x&(ARM_DTM_I_MASK|ARM_DTM_LOAD|(1<<15))) == (ARM_DTM_I|ARM_DTM_LOAD|(1<<15)))
|
||||
//if ( (inst & ( ARM_DTX_I_MASK | ARM_DTX_LOAD | ( ARM_DTX_RD_MASK ) ) ) == ( ARM_DTX_LOAD | ARM_DTX_I | ( ARM_PC << 12 ) ) )
|
||||
#define IS_UNKJMP(x) (( (( ARM_DTX_RD_MASK ) ) ) == ( ARM_DTX_LOAD | ARM_DTX_I | ( ARM_PC << 12 ) ))
|
||||
#define IS_LOAD(x) ((x&ARM_DTX_LOAD) == (ARM_DTX_LOAD))
|
||||
#define IS_CONDAL(x) ((x&ARM_COND_MASK)==ARM_COND_AL)
|
||||
#define IS_BRANCH(x) ((x & ARM_BRANCH_I_MASK) == ARM_BRANCH_I)
|
||||
#define IS_BRANCHL(x) (IS_BRANCH (x) && (x & ARM_BRANCH_LINK) == ARM_BRANCH_LINK)
|
||||
#define IS_RETURN(x) ((x & (ARM_DTM_I_MASK | ARM_DTM_LOAD | (1 << 15))) == (ARM_DTM_I | ARM_DTM_LOAD | (1 << 15)))
|
||||
// if ( (inst & ( ARM_DTX_I_MASK | ARM_DTX_LOAD | ( ARM_DTX_RD_MASK ) ) ) == ( ARM_DTX_LOAD | ARM_DTX_I | ( ARM_PC << 12 ) ) )
|
||||
#define IS_UNKJMP(x) ((((ARM_DTX_RD_MASK))) == (ARM_DTX_LOAD | ARM_DTX_I | (ARM_PC << 12)))
|
||||
#define IS_LOAD(x) ((x & ARM_DTX_LOAD) == (ARM_DTX_LOAD))
|
||||
#define IS_CONDAL(x) ((x & ARM_COND_MASK) == ARM_COND_AL)
|
||||
#define IS_EXITPOINT(x) (IS_BRANCH (x) || IS_RETURN (x) || IS_UNKJMP (x))
|
||||
|
||||
#define API static
|
||||
|
||||
static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
int op_code;
|
||||
ut16 *_ins = (ut16*)data;
|
||||
ut16 *_ins = (ut16 *) data;
|
||||
ut16 ins = *_ins;
|
||||
ut32 *_ins32 = (ut32*)data;
|
||||
ut32 *_ins32 = (ut32 *) data;
|
||||
ut32 ins32 = *_ins32;
|
||||
|
||||
struct winedbg_arm_insn *arminsn = arm_new();
|
||||
struct winedbg_arm_insn *arminsn = arm_new ();
|
||||
arm_set_thumb (arminsn, true);
|
||||
arm_set_input_buffer (arminsn, data);
|
||||
arm_set_pc (arminsn, addr);
|
||||
@ -48,13 +48,13 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
op->size = arm_disasm_one_insn (arminsn);
|
||||
op->jump = arminsn->jmp;
|
||||
op->fail = arminsn->fail;
|
||||
arm_free(arminsn);
|
||||
arm_free (arminsn);
|
||||
|
||||
// TODO: handle 32bit instructions (branches are not correctly decoded //
|
||||
|
||||
/* CMP */
|
||||
if (((ins & B4(B1110,0,0,0)) == B4(B0010,0,0,0) )
|
||||
&& (1 == (ins & B4(1,B1000,0,0)) >> 11)) { // dp3
|
||||
if (((ins & B4 (B1110, 0, 0, 0)) == B4 (B0010, 0, 0, 0))
|
||||
&& (1 == (ins & B4 (1, B1000, 0, 0)) >> 11)) { // dp3
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
return op->size;
|
||||
}
|
||||
@ -76,7 +76,7 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
// TODO: add support for more NOP instructions
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
} else if (((op_code = ((ins & B4 (B1111, B1000, 0, 0)) >> 11)) >= 12 &&
|
||||
op_code <= 17)) {
|
||||
op_code <= 17)) {
|
||||
if (op_code % 2) {
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
} else {
|
||||
@ -91,52 +91,52 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
}
|
||||
} else if ((ins & B4 (B1111, 0, 0, 0)) == B4 (B1101, 0, 0, 0)) {
|
||||
// BNE..
|
||||
int delta = (ins & B4(0,0,B1111,B1111));
|
||||
int delta = (ins & B4 (0, 0, B1111, B1111));
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = addr+4+(delta<<1);
|
||||
op->fail = addr+4;
|
||||
op->jump = addr + 4 + (delta << 1);
|
||||
op->fail = addr + 4;
|
||||
} else if ((ins & B4 (B1111, B1000, 0, 0)) == B4 (B1110, 0, 0, 0)) {
|
||||
// B
|
||||
int delta = (ins & B4(0,0,B1111,B1111));
|
||||
int delta = (ins & B4 (0, 0, B1111, B1111));
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = addr + 4 + (delta << 1);
|
||||
op->fail = addr + 4;
|
||||
op->jump = addr + 4 + (delta << 1);
|
||||
op->fail = addr + 4;
|
||||
} else if ((ins & B4 (B1111, B1111, B1000, 0)) ==
|
||||
B4 (B0100, B0111, B1000, 0)) {
|
||||
B4 (B0100, B0111, B1000, 0)) {
|
||||
// BLX
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
op->fail = addr + 4;
|
||||
} else if ((ins & B4 (B1111, B1111, B1000, 0)) ==
|
||||
B4 (B0100, B0111, 0, 0)) {
|
||||
B4 (B0100, B0111, 0, 0)) {
|
||||
// BX
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->fail = addr + 4;
|
||||
} else if ( (ins & B4(B1111,B1000,0,0)) == B4(B1111,0,0,0) ) {
|
||||
} else if ((ins & B4 (B1111, B1000, 0, 0)) == B4 (B1111, 0, 0, 0)) {
|
||||
// BL The long branch with link, it's in 2 instructions:
|
||||
// prefix: 11110[offset]
|
||||
// suffix: 11111[offset] (11101[offset] for blx)
|
||||
ut16 nextins = (ins32 & 0xFFFF0000) >> 16;
|
||||
ut32 high = (ins & B4 (0, B0111, B1111, B1111)) << 12;
|
||||
ut32 high = (ins & B4 (0, B0111, B1111, B1111)) << 12;
|
||||
if (ins & B4 (0, B0100, 0, 0)) {
|
||||
high |= B4 (B1111, B1000, 0, 0) << 16;
|
||||
}
|
||||
int delta = high + ((nextins & B4(0, B0111, B1111, B1111))*2);
|
||||
op->jump = (int)(addr + 4 + (delta));
|
||||
int delta = high + ((nextins & B4 (0, B0111, B1111, B1111)) * 2);
|
||||
op->jump = (int) (addr + 4 + (delta));
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->fail = addr+4;
|
||||
} else if ( (ins & B4(B1111,B1111,0,0)) == B4(B1011,B1110,0,0) ) {
|
||||
op->fail = addr + 4;
|
||||
} else if ((ins & B4 (B1111, B1111, 0, 0)) == B4 (B1011, B1110, 0, 0)) {
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->val = (ut64)(ins>>8);
|
||||
} else if ( (ins & B4(B1111,B1111,0,0)) == B4(B1101,B1111,0,0)) {
|
||||
op->val = (ut64) (ins >> 8);
|
||||
} else if ((ins & B4 (B1111, B1111, 0, 0)) == B4 (B1101, B1111, 0, 0)) {
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->val = (ut64) (ins >> 8);
|
||||
op->val = (ut64) (ins >> 8);
|
||||
}
|
||||
return op->size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
||||
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv",
|
||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
||||
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv",
|
||||
#endif
|
||||
static int iconds[] = {
|
||||
R_ANAL_COND_EQ,
|
||||
@ -158,24 +158,26 @@ static int iconds[] = {
|
||||
R_ANAL_COND_NV,
|
||||
};
|
||||
|
||||
static int op_cond (const ut8 *data) {
|
||||
ut8 b = data[3] >>4;
|
||||
if (b==0xf) return 0;
|
||||
static int op_cond(const ut8 *data) {
|
||||
ut8 b = data[3] >> 4;
|
||||
if (b == 0xf) {
|
||||
return 0;
|
||||
}
|
||||
return iconds[b];
|
||||
}
|
||||
|
||||
static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
const ut8 *b = (ut8 *)data;
|
||||
const ut8 *b = (ut8 *) data;
|
||||
ut8 ndata[4];
|
||||
ut32 branch_dst_addr, i = 0;
|
||||
ut32* code = (ut32 *)data;
|
||||
ut32 *code = (ut32 *) data;
|
||||
struct winedbg_arm_insn *arminsn;
|
||||
|
||||
if (!data) {
|
||||
return 0;
|
||||
}
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
arminsn = arm_new();
|
||||
arminsn = arm_new ();
|
||||
arm_set_thumb (arminsn, false);
|
||||
arm_set_input_buffer (arminsn, data);
|
||||
arm_set_pc (arminsn, addr);
|
||||
@ -192,23 +194,23 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
ndata[3] = data[0];
|
||||
}
|
||||
if (anal->bits == 16) {
|
||||
arm_free(arminsn);
|
||||
arm_free (arminsn);
|
||||
return op_thumb (anal, op, addr, data, len);
|
||||
}
|
||||
op->size = 4;
|
||||
op->cond = op_cond (data);
|
||||
if (b[2] == 0x8f && b[3] == 0xe2) {
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
#define ROR(x,y) ((int)((x)>>(y)) | (((x)<<(32-(y)))))
|
||||
op->ptr = addr + ROR (b[0], (b[1]&0xf)<<1) + 8;
|
||||
#define ROR(x, y) ((int) ((x) >> (y)) | (((x) << (32 - (y)))))
|
||||
op->ptr = addr + ROR (b[0], (b[1] & 0xf) << 1) + 8;
|
||||
} else if (b[2] >= 0x9c && b[2] <= 0x9f) { // load instruction
|
||||
char ch = b[3]&0xf;
|
||||
char ch = b[3] & 0xf;
|
||||
switch (ch) {
|
||||
case 5:
|
||||
if ((b[3] & 0xf) == 5) {
|
||||
op->ptr = 8 + addr + b[0] + ((b[1] & 0xf) << 8);
|
||||
// XXX: if set it breaks the visual disasm wtf
|
||||
// op->refptr = true;
|
||||
// op->refptr = true;
|
||||
}
|
||||
case 4:
|
||||
case 6:
|
||||
@ -216,9 +218,8 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
case 8:
|
||||
case 9: op->type = R_ANAL_OP_TYPE_LOAD; break;
|
||||
}
|
||||
} else
|
||||
// 0x000037b8 00:0000 0 800000ef svc 0x00000080
|
||||
if (b[2] == 0xa0 && b[3] == 0xe1) {
|
||||
} else // 0x000037b8 00:0000 0 800000ef svc 0x00000080
|
||||
if (b[2] == 0xa0 && b[3] == 0xe1) {
|
||||
int n = (b[0] << 16) + b[1];
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
switch (n) {
|
||||
@ -231,25 +232,27 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
}
|
||||
} else if (b[3] == 0xef) {
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->val = (b[0] | (b[1] << 8) | (b[2] << 2));
|
||||
op->val = (b[0] | (b[1] << 8) | (b[2] << 2));
|
||||
} else if ((b[3] & 0xf) == 5) { // [reg,0xa4]
|
||||
#if 0
|
||||
0x00000000 a4a09fa4 ldrge sl, [pc], 0xa4
|
||||
0x00000000 a4a09fa5 ldrge sl, [pc, 0xa4]
|
||||
0x00000000 a4a09fa6 ldrge sl, [pc], r4, lsr 1
|
||||
0x00000000 a4a09fa7 ldrge sl, [pc, r4, lsr 1]
|
||||
0x00000000 a4a09fe8 ldm pc, {r2, r5, r7, sp, pc}; <UNPREDICT
|
||||
0x00000000 a4a09fa4 ldrge sl, [pc], 0xa4
|
||||
0x00000000 a4a09fa5 ldrge sl, [pc, 0xa4]
|
||||
0x00000000 a4a09fa6 ldrge sl, [pc], r4, lsr 1
|
||||
0x00000000 a4a09fa7 ldrge sl, [pc, r4, lsr 1]
|
||||
0x00000000 a4a09fe8 ldm pc, {
|
||||
r2, r5, r7, sp, pc
|
||||
}; < UNPREDICT
|
||||
#endif
|
||||
if ((b[1] & 0xf0) == 0xf0) {
|
||||
//ldr pc, [pc, #1] ;
|
||||
//op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
// ldr pc, [pc, #1] ;
|
||||
// op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->type = R_ANAL_OP_TYPE_RET; // FAKE FOR FUN
|
||||
//op->stackop = R_ANAL_STACK_SET;
|
||||
// op->stackop = R_ANAL_STACK_SET;
|
||||
op->jump = 1234;
|
||||
//op->ptr = 4+addr+b[0]; // sure? :)
|
||||
//op->ptrptr = true;
|
||||
// op->ptr = 4+addr+b[0]; // sure? :)
|
||||
// op->ptrptr = true;
|
||||
}
|
||||
//eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
|
||||
// eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
|
||||
// 0x0001B4D8, 1eff2fe1 bx lr
|
||||
} else if (b[3] == 0xe2 && b[2] == 0x8d && b[1] == 0xd0) {
|
||||
// ADD SP, SP, ...
|
||||
@ -272,7 +275,7 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->val = -b[0];
|
||||
} else if ((code[i] == 0x1eff2fe1) ||
|
||||
(code[i] == 0xe12fff1e)) { // bx lr
|
||||
(code[i] == 0xe12fff1e)) { // bx lr
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
} else if ((code[i] & ARM_DTX_LOAD)) { // IS_LOAD(code[i])) {
|
||||
ut32 ptr = 0;
|
||||
@ -281,16 +284,18 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
/* XXX pretty incomplete */
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ptr = b[0];
|
||||
//var_add_access(addr, -b[0], 1, 0); // TODO: set/get (the last 0)
|
||||
// var_add_access(addr, -b[0], 1, 0); // TODO: set/get (the last 0)
|
||||
} else {
|
||||
//ut32 oaddr = addr+8+b[0];
|
||||
//XXX TODO ret = radare_read_at(oaddr, (ut8*)&ptr, 4);
|
||||
// ut32 oaddr = addr+8+b[0];
|
||||
// XXX TODO ret = radare_read_at(oaddr, (ut8*)&ptr, 4);
|
||||
if (anal->bits == 32) {
|
||||
b = (ut8*)&ptr;
|
||||
op->ptr = b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
|
||||
//XXX data_xrefs_add(oaddr, op->ptr, 1);
|
||||
//TODO change data type to pointer
|
||||
} else op->ptr = 0;
|
||||
b = (ut8 *) &ptr;
|
||||
op->ptr = b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
|
||||
// XXX data_xrefs_add(oaddr, op->ptr, 1);
|
||||
// TODO change data type to pointer
|
||||
} else {
|
||||
op->ptr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,7 +310,7 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
b = data;
|
||||
branch_dst_addr = disarm_branch_offset (
|
||||
addr, b[0] | (b[1] << 8) |
|
||||
(b[2] << 16)); // code[i]&0x00FFFFFF);
|
||||
(b[2] << 16)); // code[i]&0x00FFFFFF);
|
||||
op->ptr = 0;
|
||||
if ((((code[i] & 0xff) >= 0x10 && (code[i] & 0xff) < 0x20)) &&
|
||||
((code[i] & 0xffffff00) == 0xe12fff00)) {
|
||||
@ -314,7 +319,7 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
if (IS_BRANCH (code[i])) {
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = branch_dst_addr;
|
||||
op->fail = addr + 4 ;
|
||||
op->fail = addr + 4;
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
}
|
||||
@ -329,33 +334,35 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
op->fail = addr + 4;
|
||||
}
|
||||
} else {
|
||||
//unknown jump o return
|
||||
//op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
//op->type = R_ANAL_OP_TYPE_NOP;
|
||||
// unknown jump o return
|
||||
// op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
// op->type = R_ANAL_OP_TYPE_NOP;
|
||||
}
|
||||
}
|
||||
//op->jump = arminsn->jmp;
|
||||
//op->fail = arminsn->fail;
|
||||
// op->jump = arminsn->jmp;
|
||||
// op->fail = arminsn->fail;
|
||||
arm_free (arminsn);
|
||||
return op->size;
|
||||
}
|
||||
|
||||
|
||||
static ut64 getaddr (ut64 addr, const ut8 *d) {
|
||||
if (d[2]>>7) {
|
||||
static ut64 getaddr(ut64 addr, const ut8 *d) {
|
||||
if (d[2] >> 7) {
|
||||
st32 n = (d[0] + (d[1] << 8) + (d[2] << 16) + (0xff << 24));
|
||||
n = -n;
|
||||
return addr - (n*4);
|
||||
return addr - (n * 4);
|
||||
}
|
||||
return addr + (4 * (d[0] + (d[1] << 8) + (d[2] << 16)));
|
||||
}
|
||||
|
||||
static int arm_op64(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *d, int len) {
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
if (d[3]==0) return -1; // invalid
|
||||
if (d[3] == 0) {
|
||||
return -1; // invalid
|
||||
}
|
||||
op->size = 4;
|
||||
op->type = R_ANAL_OP_TYPE_NULL;
|
||||
if (d[0]==0xc0 && d[3]==0xd6) {
|
||||
if (d[0] == 0xc0 && d[3] == 0xd6) {
|
||||
// defaults to x30 reg. but can be different
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
}
|
||||
@ -388,7 +395,7 @@ static int arm_op64(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *d, int len)
|
||||
case 0x14: // b A
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = getaddr (addr, d);
|
||||
op->fail = addr+4;
|
||||
op->fail = addr + 4;
|
||||
break;
|
||||
}
|
||||
return op->size;
|
||||
@ -396,16 +403,16 @@ static int arm_op64(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *d, int len)
|
||||
|
||||
static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
if (anal->bits == 64) {
|
||||
return arm_op64(anal, op, addr, data, len);
|
||||
return arm_op64 (anal, op, addr, data, len);
|
||||
}
|
||||
return arm_op32(anal, op, addr, data, len);
|
||||
return arm_op32 (anal, op, addr, data, len);
|
||||
}
|
||||
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
// TODO: support 64bit profile
|
||||
const char *p32 =
|
||||
"=PC r15\n"
|
||||
"=SP r13\n"
|
||||
"=SP r13\n"
|
||||
"=BP r14\n" // XXX
|
||||
"=A0 r0\n"
|
||||
"=A1 r1\n"
|
||||
@ -467,7 +474,7 @@ RAnalPlugin r_anal_plugin_arm_gnu = {
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_arm_gnu,
|
||||
.version = R2_VERSION
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,287 +0,0 @@
|
||||
/* ARM assembler/disassembler support.
|
||||
Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB and GAS.
|
||||
|
||||
GDB and GAS are 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, or (at
|
||||
your option) any later version.
|
||||
|
||||
GDB and GAS are 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 GDB or GAS; see the file COPYING3. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
/* The following bitmasks control CPU extensions: */
|
||||
#define ARM_EXT_V1 0x00000001 /* All processors (core set). */
|
||||
#define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
|
||||
#define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
|
||||
#define ARM_EXT_V3 0x00000008 /* MSR MRS. */
|
||||
#define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
|
||||
#define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
|
||||
#define ARM_EXT_V4T 0x00000040 /* Thumb. */
|
||||
#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
|
||||
#define ARM_EXT_V5T 0x00000100 /* Improved interworking. */
|
||||
#define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
|
||||
#define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
|
||||
#define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
|
||||
#define ARM_EXT_V6 0x00001000 /* ARM V6. */
|
||||
#define ARM_EXT_V6K 0x00002000 /* ARM V6K. */
|
||||
/* 0x00004000 Was ARM V6Z. */
|
||||
#define ARM_EXT_V8 0x00004000 /* is now ARMv8. */
|
||||
#define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */
|
||||
#define ARM_EXT_DIV 0x00010000 /* Integer division. */
|
||||
/* The 'M' in Arm V7M stands for Microcontroller.
|
||||
On earlier architecture variants it stands for Multiply. */
|
||||
#define ARM_EXT_V5E_NOTM 0x00020000 /* Arm V5E but not Arm V7M. */
|
||||
#define ARM_EXT_V6_NOTM 0x00040000 /* Arm V6 but not Arm V7M. */
|
||||
#define ARM_EXT_V7 0x00080000 /* Arm V7. */
|
||||
#define ARM_EXT_V7A 0x00100000 /* Arm V7A. */
|
||||
#define ARM_EXT_V7R 0x00200000 /* Arm V7R. */
|
||||
#define ARM_EXT_V7M 0x00400000 /* Arm V7M. */
|
||||
#define ARM_EXT_V6M 0x00800000 /* ARM V6M. */
|
||||
#define ARM_EXT_BARRIER 0x01000000 /* DSB/DMB/ISB. */
|
||||
#define ARM_EXT_THUMB_MSR 0x02000000 /* Thumb MSR/MRS. */
|
||||
#define ARM_EXT_V6_DSP 0x04000000 /* ARM v6 (DSP-related),
|
||||
not in v7-M. */
|
||||
#define ARM_EXT_MP 0x08000000 /* Multiprocessing Extensions. */
|
||||
#define ARM_EXT_SEC 0x10000000 /* Security extensions. */
|
||||
#define ARM_EXT_OS 0x20000000 /* OS Extensions. */
|
||||
#define ARM_EXT_ADIV 0x40000000 /* Integer divide extensions in ARM
|
||||
state. */
|
||||
#define ARM_EXT_VIRT 0x80000000 /* Virtualization extensions. */
|
||||
|
||||
/* Co-processor space extensions. */
|
||||
#define ARM_CEXT_XSCALE 0x00000001 /* Allow MIA etc. */
|
||||
#define ARM_CEXT_MAVERICK 0x00000002 /* Use Cirrus/DSP coprocessor. */
|
||||
#define ARM_CEXT_IWMMXT 0x00000004 /* Intel Wireless MMX technology coprocessor. */
|
||||
#define ARM_CEXT_IWMMXT2 0x00000008 /* Intel Wireless MMX technology coprocessor version 2. */
|
||||
|
||||
#define FPU_ENDIAN_PURE 0x80000000 /* Pure-endian doubles. */
|
||||
#define FPU_ENDIAN_BIG 0 /* Double words-big-endian. */
|
||||
#define FPU_FPA_EXT_V1 0x40000000 /* Base FPA instruction set. */
|
||||
#define FPU_FPA_EXT_V2 0x20000000 /* LFM/SFM. */
|
||||
#define FPU_MAVERICK 0x10000000 /* Cirrus Maverick. */
|
||||
#define FPU_VFP_EXT_V1xD 0x08000000 /* Base VFP instruction set. */
|
||||
#define FPU_VFP_EXT_V1 0x04000000 /* Double-precision insns. */
|
||||
#define FPU_VFP_EXT_V2 0x02000000 /* ARM10E VFPr1. */
|
||||
#define FPU_VFP_EXT_V3xD 0x01000000 /* VFPv3 single-precision. */
|
||||
#define FPU_VFP_EXT_V3 0x00800000 /* VFPv3 double-precision. */
|
||||
#define FPU_NEON_EXT_V1 0x00400000 /* Neon (SIMD) insns. */
|
||||
#define FPU_VFP_EXT_D32 0x00200000 /* Registers D16-D31. */
|
||||
#define FPU_VFP_EXT_FP16 0x00100000 /* Half-precision extensions. */
|
||||
#define FPU_NEON_EXT_FMA 0x00080000 /* Neon fused multiply-add */
|
||||
#define FPU_VFP_EXT_FMA 0x00040000 /* VFP fused multiply-add */
|
||||
#define FPU_VFP_EXT_ARMV8 0x00020000 /* FP for ARMv8. */
|
||||
#define FPU_NEON_EXT_ARMV8 0x00010000 /* Neon for ARMv8. */
|
||||
#define FPU_CRYPTO_EXT_ARMV8 0x00008000 /* Crypto for ARMv8. */
|
||||
#define CRC_EXT_ARMV8 0x00004000 /* CRC32 for ARMv8. */
|
||||
|
||||
/* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
|
||||
defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
|
||||
ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
|
||||
three more to cover cores prior to ARM6. Finally, there are cores which
|
||||
implement further extensions in the co-processor space. */
|
||||
#define ARM_AEXT_V1 ARM_EXT_V1
|
||||
#define ARM_AEXT_V2 (ARM_AEXT_V1 | ARM_EXT_V2)
|
||||
#define ARM_AEXT_V2S (ARM_AEXT_V2 | ARM_EXT_V2S)
|
||||
#define ARM_AEXT_V3 (ARM_AEXT_V2S | ARM_EXT_V3)
|
||||
#define ARM_AEXT_V3M (ARM_AEXT_V3 | ARM_EXT_V3M)
|
||||
#define ARM_AEXT_V4xM (ARM_AEXT_V3 | ARM_EXT_V4)
|
||||
#define ARM_AEXT_V4 (ARM_AEXT_V3M | ARM_EXT_V4)
|
||||
#define ARM_AEXT_V4TxM (ARM_AEXT_V4xM | ARM_EXT_V4T)
|
||||
#define ARM_AEXT_V4T (ARM_AEXT_V4 | ARM_EXT_V4T)
|
||||
#define ARM_AEXT_V5xM (ARM_AEXT_V4xM | ARM_EXT_V5)
|
||||
#define ARM_AEXT_V5 (ARM_AEXT_V4 | ARM_EXT_V5)
|
||||
#define ARM_AEXT_V5TxM (ARM_AEXT_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
|
||||
#define ARM_AEXT_V5T (ARM_AEXT_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
|
||||
#define ARM_AEXT_V5TExP (ARM_AEXT_V5T | ARM_EXT_V5ExP)
|
||||
#define ARM_AEXT_V5TE (ARM_AEXT_V5TExP | ARM_EXT_V5E)
|
||||
#define ARM_AEXT_V5TEJ (ARM_AEXT_V5TE | ARM_EXT_V5J)
|
||||
#define ARM_AEXT_V6 (ARM_AEXT_V5TEJ | ARM_EXT_V6)
|
||||
#define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K)
|
||||
#define ARM_AEXT_V6Z (ARM_AEXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6ZK (ARM_AEXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6T2 (ARM_AEXT_V6 \
|
||||
| ARM_EXT_V6T2 | ARM_EXT_V6_NOTM | ARM_EXT_THUMB_MSR \
|
||||
| ARM_EXT_V6_DSP )
|
||||
#define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
|
||||
#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V7_ARM (ARM_AEXT_V6KT2 | ARM_EXT_V7 | ARM_EXT_BARRIER)
|
||||
#define ARM_AEXT_V7A (ARM_AEXT_V7_ARM | ARM_EXT_V7A)
|
||||
#define ARM_AEXT_V7VE (ARM_AEXT_V7A | ARM_EXT_DIV | ARM_EXT_ADIV \
|
||||
| ARM_EXT_VIRT | ARM_EXT_SEC | ARM_EXT_MP)
|
||||
#define ARM_AEXT_V7R (ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
|
||||
#define ARM_AEXT_NOTM \
|
||||
(ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM \
|
||||
| ARM_EXT_V6_DSP )
|
||||
#define ARM_AEXT_V6M_ONLY \
|
||||
((ARM_EXT_BARRIER | ARM_EXT_V6M | ARM_EXT_THUMB_MSR) & ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V6M \
|
||||
((ARM_AEXT_V6K | ARM_AEXT_V6M_ONLY) & ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V6SM (ARM_AEXT_V6M | ARM_EXT_OS)
|
||||
#define ARM_AEXT_V7M \
|
||||
((ARM_AEXT_V7_ARM | ARM_EXT_V6M | ARM_EXT_V7M | ARM_EXT_DIV) \
|
||||
& ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
|
||||
#define ARM_AEXT_V7EM \
|
||||
(ARM_AEXT_V7M | ARM_EXT_V5ExP | ARM_EXT_V6_DSP)
|
||||
#define ARM_AEXT_V8A \
|
||||
(ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC | ARM_EXT_DIV | ARM_EXT_ADIV \
|
||||
| ARM_EXT_VIRT | ARM_EXT_V8)
|
||||
|
||||
/* Processors with specific extensions in the co-processor space. */
|
||||
#define ARM_ARCH_XSCALE ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
|
||||
#define ARM_ARCH_IWMMXT \
|
||||
ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT)
|
||||
#define ARM_ARCH_IWMMXT2 \
|
||||
ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT | ARM_CEXT_IWMMXT2)
|
||||
|
||||
#define FPU_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
|
||||
#define FPU_VFP_V1 (FPU_VFP_V1xD | FPU_VFP_EXT_V1)
|
||||
#define FPU_VFP_V2 (FPU_VFP_V1 | FPU_VFP_EXT_V2)
|
||||
#define FPU_VFP_V3D16 (FPU_VFP_V2 | FPU_VFP_EXT_V3xD | FPU_VFP_EXT_V3)
|
||||
#define FPU_VFP_V3 (FPU_VFP_V3D16 | FPU_VFP_EXT_D32)
|
||||
#define FPU_VFP_V3xD (FPU_VFP_V1xD | FPU_VFP_EXT_V2 | FPU_VFP_EXT_V3xD)
|
||||
#define FPU_VFP_V4D16 (FPU_VFP_V3D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_V4 (FPU_VFP_V3 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_V4_SP_D16 (FPU_VFP_V3xD | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_ARMV8 (FPU_VFP_V4 | FPU_VFP_EXT_ARMV8)
|
||||
#define FPU_NEON_ARMV8 (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA | FPU_NEON_EXT_ARMV8)
|
||||
#define FPU_CRYPTO_ARMV8 (FPU_CRYPTO_EXT_ARMV8)
|
||||
#define FPU_VFP_HARD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2 \
|
||||
| FPU_VFP_EXT_V3xD | FPU_VFP_EXT_FMA | FPU_NEON_EXT_FMA \
|
||||
| FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1 | FPU_VFP_EXT_D32)
|
||||
#define FPU_FPA (FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2)
|
||||
|
||||
/* Deprecated. */
|
||||
#define FPU_ARCH_VFP ARM_FEATURE (0, FPU_ENDIAN_PURE)
|
||||
|
||||
#define FPU_ARCH_FPE ARM_FEATURE (0, FPU_FPA_EXT_V1)
|
||||
#define FPU_ARCH_FPA ARM_FEATURE (0, FPU_FPA)
|
||||
|
||||
#define FPU_ARCH_VFP_V1xD ARM_FEATURE (0, FPU_VFP_V1xD)
|
||||
#define FPU_ARCH_VFP_V1 ARM_FEATURE (0, FPU_VFP_V1)
|
||||
#define FPU_ARCH_VFP_V2 ARM_FEATURE (0, FPU_VFP_V2)
|
||||
#define FPU_ARCH_VFP_V3D16 ARM_FEATURE (0, FPU_VFP_V3D16)
|
||||
#define FPU_ARCH_VFP_V3D16_FP16 \
|
||||
ARM_FEATURE (0, FPU_VFP_V3D16 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_V3 ARM_FEATURE (0, FPU_VFP_V3)
|
||||
#define FPU_ARCH_VFP_V3_FP16 ARM_FEATURE (0, FPU_VFP_V3 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_V3xD ARM_FEATURE (0, FPU_VFP_V3xD)
|
||||
#define FPU_ARCH_VFP_V3xD_FP16 ARM_FEATURE (0, FPU_VFP_V3xD | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_NEON_V1 ARM_FEATURE (0, FPU_NEON_EXT_V1)
|
||||
#define FPU_ARCH_VFP_V3_PLUS_NEON_V1 \
|
||||
ARM_FEATURE (0, FPU_VFP_V3 | FPU_NEON_EXT_V1)
|
||||
#define FPU_ARCH_NEON_FP16 \
|
||||
ARM_FEATURE (0, FPU_VFP_V3 | FPU_NEON_EXT_V1 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_HARD ARM_FEATURE (0, FPU_VFP_HARD)
|
||||
#define FPU_ARCH_VFP_V4 ARM_FEATURE(0, FPU_VFP_V4)
|
||||
#define FPU_ARCH_VFP_V4D16 ARM_FEATURE(0, FPU_VFP_V4D16)
|
||||
#define FPU_ARCH_VFP_V4_SP_D16 ARM_FEATURE(0, FPU_VFP_V4_SP_D16)
|
||||
#define FPU_ARCH_NEON_VFP_V4 \
|
||||
ARM_FEATURE(0, FPU_VFP_V4 | FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)
|
||||
#define FPU_ARCH_VFP_ARMV8 ARM_FEATURE(0, FPU_VFP_ARMV8)
|
||||
#define FPU_ARCH_NEON_VFP_ARMV8 ARM_FEATURE(0, FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
|
||||
#define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8 \
|
||||
ARM_FEATURE(0, FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
|
||||
#define ARCH_CRC_ARMV8 ARM_FEATURE(0, CRC_EXT_ARMV8)
|
||||
|
||||
#define FPU_ARCH_ENDIAN_PURE ARM_FEATURE (0, FPU_ENDIAN_PURE)
|
||||
|
||||
#define FPU_ARCH_MAVERICK ARM_FEATURE (0, FPU_MAVERICK)
|
||||
|
||||
#define ARM_ARCH_V1 ARM_FEATURE (ARM_AEXT_V1, 0)
|
||||
#define ARM_ARCH_V2 ARM_FEATURE (ARM_AEXT_V2, 0)
|
||||
#define ARM_ARCH_V2S ARM_FEATURE (ARM_AEXT_V2S, 0)
|
||||
#define ARM_ARCH_V3 ARM_FEATURE (ARM_AEXT_V3, 0)
|
||||
#define ARM_ARCH_V3M ARM_FEATURE (ARM_AEXT_V3M, 0)
|
||||
#define ARM_ARCH_V4xM ARM_FEATURE (ARM_AEXT_V4xM, 0)
|
||||
#define ARM_ARCH_V4 ARM_FEATURE (ARM_AEXT_V4, 0)
|
||||
#define ARM_ARCH_V4TxM ARM_FEATURE (ARM_AEXT_V4TxM, 0)
|
||||
#define ARM_ARCH_V4T ARM_FEATURE (ARM_AEXT_V4T, 0)
|
||||
#define ARM_ARCH_V5xM ARM_FEATURE (ARM_AEXT_V5xM, 0)
|
||||
#define ARM_ARCH_V5 ARM_FEATURE (ARM_AEXT_V5, 0)
|
||||
#define ARM_ARCH_V5TxM ARM_FEATURE (ARM_AEXT_V5TxM, 0)
|
||||
#define ARM_ARCH_V5T ARM_FEATURE (ARM_AEXT_V5T, 0)
|
||||
#define ARM_ARCH_V5TExP ARM_FEATURE (ARM_AEXT_V5TExP, 0)
|
||||
#define ARM_ARCH_V5TE ARM_FEATURE (ARM_AEXT_V5TE, 0)
|
||||
#define ARM_ARCH_V5TEJ ARM_FEATURE (ARM_AEXT_V5TEJ, 0)
|
||||
#define ARM_ARCH_V6 ARM_FEATURE (ARM_AEXT_V6, 0)
|
||||
#define ARM_ARCH_V6K ARM_FEATURE (ARM_AEXT_V6K, 0)
|
||||
#define ARM_ARCH_V6Z ARM_FEATURE (ARM_AEXT_V6Z, 0)
|
||||
#define ARM_ARCH_V6ZK ARM_FEATURE (ARM_AEXT_V6ZK, 0)
|
||||
#define ARM_ARCH_V6T2 ARM_FEATURE (ARM_AEXT_V6T2, 0)
|
||||
#define ARM_ARCH_V6KT2 ARM_FEATURE (ARM_AEXT_V6KT2, 0)
|
||||
#define ARM_ARCH_V6ZT2 ARM_FEATURE (ARM_AEXT_V6ZT2, 0)
|
||||
#define ARM_ARCH_V6ZKT2 ARM_FEATURE (ARM_AEXT_V6ZKT2, 0)
|
||||
#define ARM_ARCH_V6M ARM_FEATURE (ARM_AEXT_V6M, 0)
|
||||
#define ARM_ARCH_V6SM ARM_FEATURE (ARM_AEXT_V6SM, 0)
|
||||
#define ARM_ARCH_V7 ARM_FEATURE (ARM_AEXT_V7, 0)
|
||||
#define ARM_ARCH_V7A ARM_FEATURE (ARM_AEXT_V7A, 0)
|
||||
#define ARM_ARCH_V7VE ARM_FEATURE (ARM_AEXT_V7VE, 0)
|
||||
#define ARM_ARCH_V7R ARM_FEATURE (ARM_AEXT_V7R, 0)
|
||||
#define ARM_ARCH_V7M ARM_FEATURE (ARM_AEXT_V7M, 0)
|
||||
#define ARM_ARCH_V7EM ARM_FEATURE (ARM_AEXT_V7EM, 0)
|
||||
#define ARM_ARCH_V8A ARM_FEATURE (ARM_AEXT_V8A, 0)
|
||||
|
||||
/* Some useful combinations: */
|
||||
#define ARM_ARCH_NONE ARM_FEATURE (0, 0)
|
||||
#define FPU_NONE ARM_FEATURE (0, 0)
|
||||
#define ARM_ANY ARM_FEATURE (-1, 0) /* Any basic core. */
|
||||
#define FPU_ANY_HARD ARM_FEATURE (0, FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
|
||||
#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2 | ARM_EXT_V7 | ARM_EXT_V7A | ARM_EXT_V7R | ARM_EXT_V7M | ARM_EXT_DIV, 0)
|
||||
/* v7-a+sec. */
|
||||
#define ARM_ARCH_V7A_SEC ARM_FEATURE (ARM_AEXT_V7A | ARM_EXT_SEC, 0)
|
||||
/* v7-a+mp+sec. */
|
||||
#define ARM_ARCH_V7A_MP_SEC \
|
||||
ARM_FEATURE (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC, \
|
||||
0)
|
||||
/* v7-r+idiv. */
|
||||
#define ARM_ARCH_V7R_IDIV ARM_FEATURE (ARM_AEXT_V7R | ARM_EXT_ADIV, 0)
|
||||
/* Features that are present in v6M and v6S-M but not other v6 cores. */
|
||||
#define ARM_ARCH_V6M_ONLY ARM_FEATURE (ARM_AEXT_V6M_ONLY, 0)
|
||||
/* v8-a+fp. */
|
||||
#define ARM_ARCH_V8A_FP ARM_FEATURE (ARM_AEXT_V8A, FPU_ARCH_VFP_ARMV8)
|
||||
/* v8-a+simd (implies fp). */
|
||||
#define ARM_ARCH_V8A_SIMD ARM_FEATURE (ARM_AEXT_V8A, \
|
||||
FPU_ARCH_NEON_VFP_ARMV8)
|
||||
/* v8-a+crypto (implies simd+fp). */
|
||||
#define ARM_ARCH_V8A_CRYPTOV1 ARM_FEATURE (ARM_AEXT_V8A, \
|
||||
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8)
|
||||
|
||||
/* There are too many feature bits to fit in a single word, so use a
|
||||
structure. For simplicity we put all core features in one word and
|
||||
everything else in the other. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long core;
|
||||
unsigned long coproc;
|
||||
} arm_feature_set;
|
||||
|
||||
#define ARM_CPU_HAS_FEATURE(CPU,FEAT) \
|
||||
(((CPU).core & (FEAT).core) != 0 || ((CPU).coproc & (FEAT).coproc) != 0)
|
||||
|
||||
#define ARM_CPU_IS_ANY(CPU) \
|
||||
((CPU).core == ((arm_feature_set)ARM_ANY).core)
|
||||
|
||||
#define ARM_MERGE_FEATURE_SETS(TARG,F1,F2) \
|
||||
do { \
|
||||
(TARG).core = (F1).core | (F2).core; \
|
||||
(TARG).coproc = (F1).coproc | (F2).coproc; \
|
||||
} while (0)
|
||||
|
||||
#define ARM_CLEAR_FEATURE(TARG,F1,F2) \
|
||||
do { \
|
||||
(TARG).core = (F1).core &~ (F2).core; \
|
||||
(TARG).coproc = (F1).coproc &~ (F2).coproc; \
|
||||
} while (0)
|
||||
|
||||
#define ARM_FEATURE(core, coproc) {(core), (coproc)}
|
391
libr/asm/arch/arm/gnu/opcode-arm.h
Normal file
391
libr/asm/arch/arm/gnu/opcode-arm.h
Normal file
@ -0,0 +1,391 @@
|
||||
/* ARM assembler/disassembler support.
|
||||
Copyright (C) 2004-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB and GAS.
|
||||
|
||||
GDB and GAS are 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, or (at
|
||||
your option) any later version.
|
||||
|
||||
GDB and GAS are 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 GDB or GAS; see the file COPYING3. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
/* The following bitmasks control CPU extensions: */
|
||||
#define ARM_EXT_V1 0x00000001 /* All processors (core set). */
|
||||
#define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
|
||||
#define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
|
||||
#define ARM_EXT_V3 0x00000008 /* MSR MRS. */
|
||||
#define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
|
||||
#define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
|
||||
#define ARM_EXT_V4T 0x00000040 /* Thumb. */
|
||||
#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
|
||||
#define ARM_EXT_V5T 0x00000100 /* Improved interworking. */
|
||||
#define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
|
||||
#define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
|
||||
#define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
|
||||
#define ARM_EXT_V6 0x00001000 /* ARM V6. */
|
||||
#define ARM_EXT_V6K 0x00002000 /* ARM V6K. */
|
||||
#define ARM_EXT_V8 0x00004000 /* ARMv8 w/o atomics. */
|
||||
#define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */
|
||||
#define ARM_EXT_DIV 0x00010000 /* Integer division. */
|
||||
/* The 'M' in Arm V7M stands for Microcontroller.
|
||||
On earlier architecture variants it stands for Multiply. */
|
||||
#define ARM_EXT_V5E_NOTM 0x00020000 /* Arm V5E but not Arm V7M. */
|
||||
#define ARM_EXT_V6_NOTM 0x00040000 /* Arm V6 but not Arm V7M. */
|
||||
#define ARM_EXT_V7 0x00080000 /* Arm V7. */
|
||||
#define ARM_EXT_V7A 0x00100000 /* Arm V7A. */
|
||||
#define ARM_EXT_V7R 0x00200000 /* Arm V7R. */
|
||||
#define ARM_EXT_V7M 0x00400000 /* Arm V7M. */
|
||||
#define ARM_EXT_V6M 0x00800000 /* ARM V6M. */
|
||||
#define ARM_EXT_BARRIER 0x01000000 /* DSB/DMB/ISB. */
|
||||
#define ARM_EXT_THUMB_MSR 0x02000000 /* Thumb MSR/MRS. */
|
||||
#define ARM_EXT_V6_DSP 0x04000000 /* ARM v6 (DSP-related),
|
||||
not in v7-M. */
|
||||
#define ARM_EXT_MP 0x08000000 /* Multiprocessing Extensions. */
|
||||
#define ARM_EXT_SEC 0x10000000 /* Security extensions. */
|
||||
#define ARM_EXT_OS 0x20000000 /* OS Extensions. */
|
||||
#define ARM_EXT_ADIV 0x40000000 /* Integer divide extensions in ARM
|
||||
state. */
|
||||
#define ARM_EXT_VIRT 0x80000000 /* Virtualization extensions. */
|
||||
|
||||
#define ARM_EXT2_PAN 0x00000001 /* PAN extension. */
|
||||
#define ARM_EXT2_V8_2A 0x00000002 /* ARM V8.2A. */
|
||||
#define ARM_EXT2_V8M 0x00000004 /* ARM V8M. */
|
||||
#define ARM_EXT2_ATOMICS 0x00000008 /* ARMv8 atomics. */
|
||||
#define ARM_EXT2_V6T2_V8M 0x00000010 /* V8M Baseline from V6T2. */
|
||||
#define ARM_EXT2_FP16_INST 0x00000020 /* ARM V8.2A FP16 instructions. */
|
||||
#define ARM_EXT2_V8M_MAIN 0x00000040 /* ARMv8-M Mainline. */
|
||||
#define ARM_EXT2_RAS 0x00000080 /* RAS extension. */
|
||||
#define ARM_EXT2_V8_3A 0x00000100 /* ARM V8.3A. */
|
||||
|
||||
/* Co-processor space extensions. */
|
||||
#define ARM_CEXT_XSCALE 0x00000001 /* Allow MIA etc. */
|
||||
#define ARM_CEXT_MAVERICK 0x00000002 /* Use Cirrus/DSP coprocessor. */
|
||||
#define ARM_CEXT_IWMMXT 0x00000004 /* Intel Wireless MMX technology coprocessor. */
|
||||
#define ARM_CEXT_IWMMXT2 0x00000008 /* Intel Wireless MMX technology coprocessor version 2. */
|
||||
|
||||
#define FPU_ENDIAN_PURE 0x80000000 /* Pure-endian doubles. */
|
||||
#define FPU_ENDIAN_BIG 0 /* Double words-big-endian. */
|
||||
#define FPU_FPA_EXT_V1 0x40000000 /* Base FPA instruction set. */
|
||||
#define FPU_FPA_EXT_V2 0x20000000 /* LFM/SFM. */
|
||||
#define FPU_MAVERICK 0x10000000 /* Cirrus Maverick. */
|
||||
#define FPU_VFP_EXT_V1xD 0x08000000 /* Base VFP instruction set. */
|
||||
#define FPU_VFP_EXT_V1 0x04000000 /* Double-precision insns. */
|
||||
#define FPU_VFP_EXT_V2 0x02000000 /* ARM10E VFPr1. */
|
||||
#define FPU_VFP_EXT_V3xD 0x01000000 /* VFPv3 single-precision. */
|
||||
#define FPU_VFP_EXT_V3 0x00800000 /* VFPv3 double-precision. */
|
||||
#define FPU_NEON_EXT_V1 0x00400000 /* Neon (SIMD) insns. */
|
||||
#define FPU_VFP_EXT_D32 0x00200000 /* Registers D16-D31. */
|
||||
#define FPU_VFP_EXT_FP16 0x00100000 /* Half-precision extensions. */
|
||||
#define FPU_NEON_EXT_FMA 0x00080000 /* Neon fused multiply-add */
|
||||
#define FPU_VFP_EXT_FMA 0x00040000 /* VFP fused multiply-add */
|
||||
#define FPU_VFP_EXT_ARMV8 0x00020000 /* Double-precision FP for ARMv8. */
|
||||
#define FPU_NEON_EXT_ARMV8 0x00010000 /* Neon for ARMv8. */
|
||||
#define FPU_CRYPTO_EXT_ARMV8 0x00008000 /* Crypto for ARMv8. */
|
||||
#define CRC_EXT_ARMV8 0x00004000 /* CRC32 for ARMv8. */
|
||||
#define FPU_VFP_EXT_ARMV8xD 0x00002000 /* Single-precision FP for ARMv8. */
|
||||
#define FPU_NEON_EXT_RDMA 0x00001000 /* v8.1 Adv.SIMD extensions. */
|
||||
|
||||
/* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
|
||||
defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
|
||||
ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
|
||||
three more to cover cores prior to ARM6. Finally, there are cores which
|
||||
implement further extensions in the co-processor space. */
|
||||
#define ARM_AEXT_V1 ARM_EXT_V1
|
||||
#define ARM_AEXT_V2 (ARM_AEXT_V1 | ARM_EXT_V2)
|
||||
#define ARM_AEXT_V2S (ARM_AEXT_V2 | ARM_EXT_V2S)
|
||||
#define ARM_AEXT_V3 (ARM_AEXT_V2S | ARM_EXT_V3)
|
||||
#define ARM_AEXT_V3M (ARM_AEXT_V3 | ARM_EXT_V3M)
|
||||
#define ARM_AEXT_V4xM (ARM_AEXT_V3 | ARM_EXT_V4)
|
||||
#define ARM_AEXT_V4 (ARM_AEXT_V3M | ARM_EXT_V4)
|
||||
#define ARM_AEXT_V4TxM (ARM_AEXT_V4xM | ARM_EXT_V4T)
|
||||
#define ARM_AEXT_V4T (ARM_AEXT_V4 | ARM_EXT_V4T)
|
||||
#define ARM_AEXT_V5xM (ARM_AEXT_V4xM | ARM_EXT_V5)
|
||||
#define ARM_AEXT_V5 (ARM_AEXT_V4 | ARM_EXT_V5)
|
||||
#define ARM_AEXT_V5TxM (ARM_AEXT_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
|
||||
#define ARM_AEXT_V5T (ARM_AEXT_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
|
||||
#define ARM_AEXT_V5TExP (ARM_AEXT_V5T | ARM_EXT_V5ExP)
|
||||
#define ARM_AEXT_V5TE (ARM_AEXT_V5TExP | ARM_EXT_V5E)
|
||||
#define ARM_AEXT_V5TEJ (ARM_AEXT_V5TE | ARM_EXT_V5J)
|
||||
#define ARM_AEXT_V6 (ARM_AEXT_V5TEJ | ARM_EXT_V6)
|
||||
#define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K)
|
||||
#define ARM_AEXT_V6Z (ARM_AEXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6KZ (ARM_AEXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6T2 (ARM_AEXT_V6 \
|
||||
| ARM_EXT_V6T2 | ARM_EXT_V6_NOTM | ARM_EXT_THUMB_MSR \
|
||||
| ARM_EXT_V6_DSP )
|
||||
#define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
|
||||
#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V6KZT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_SEC)
|
||||
#define ARM_AEXT_V7_ARM (ARM_AEXT_V6KT2 | ARM_EXT_V7 | ARM_EXT_BARRIER)
|
||||
#define ARM_AEXT_V7A (ARM_AEXT_V7_ARM | ARM_EXT_V7A)
|
||||
#define ARM_AEXT_V7VE (ARM_AEXT_V7A | ARM_EXT_DIV | ARM_EXT_ADIV \
|
||||
| ARM_EXT_VIRT | ARM_EXT_SEC | ARM_EXT_MP)
|
||||
#define ARM_AEXT_V7R (ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
|
||||
#define ARM_AEXT_NOTM \
|
||||
(ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM \
|
||||
| ARM_EXT_V6_DSP )
|
||||
#define ARM_AEXT_V6M_ONLY \
|
||||
((ARM_EXT_BARRIER | ARM_EXT_V6M | ARM_EXT_THUMB_MSR) & ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V6M \
|
||||
((ARM_AEXT_V6K | ARM_AEXT_V6M_ONLY) & ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V6SM (ARM_AEXT_V6M | ARM_EXT_OS)
|
||||
#define ARM_AEXT_V7M \
|
||||
((ARM_AEXT_V7_ARM | ARM_EXT_V6M | ARM_EXT_V7M | ARM_EXT_DIV) \
|
||||
& ~(ARM_AEXT_NOTM))
|
||||
#define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
|
||||
#define ARM_AEXT_V7EM \
|
||||
(ARM_AEXT_V7M | ARM_EXT_V5ExP | ARM_EXT_V6_DSP)
|
||||
#define ARM_AEXT_V8A \
|
||||
(ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC | ARM_EXT_DIV | ARM_EXT_ADIV \
|
||||
| ARM_EXT_VIRT | ARM_EXT_V8)
|
||||
#define ARM_AEXT2_V8A (ARM_EXT2_V6T2_V8M | ARM_EXT2_ATOMICS)
|
||||
#define ARM_AEXT2_V8_1A (ARM_AEXT2_V8A | ARM_EXT2_PAN)
|
||||
#define ARM_AEXT2_V8_2A (ARM_AEXT2_V8_1A | ARM_EXT2_V8_2A | ARM_EXT2_RAS)
|
||||
#define ARM_AEXT2_V8_3A (ARM_AEXT2_V8_2A | ARM_EXT2_V8_3A)
|
||||
#define ARM_AEXT_V8M_BASE (ARM_AEXT_V6SM | ARM_EXT_DIV)
|
||||
#define ARM_AEXT_V8M_MAIN ARM_AEXT_V7M
|
||||
#define ARM_AEXT_V8M_MAIN_DSP ARM_AEXT_V7EM
|
||||
#define ARM_AEXT2_V8M (ARM_EXT2_V8M | ARM_EXT2_ATOMICS | ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_AEXT2_V8M_MAIN (ARM_AEXT2_V8M | ARM_EXT2_V8M_MAIN)
|
||||
#define ARM_AEXT2_V8M_MAIN_DSP ARM_AEXT2_V8M_MAIN
|
||||
|
||||
/* Processors with specific extensions in the co-processor space. */
|
||||
#define ARM_ARCH_XSCALE ARM_FEATURE_LOW (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
|
||||
#define ARM_ARCH_IWMMXT \
|
||||
ARM_FEATURE_LOW (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT)
|
||||
#define ARM_ARCH_IWMMXT2 \
|
||||
ARM_FEATURE_LOW (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT \
|
||||
| ARM_CEXT_IWMMXT2)
|
||||
|
||||
#define FPU_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
|
||||
#define FPU_VFP_V1 (FPU_VFP_V1xD | FPU_VFP_EXT_V1)
|
||||
#define FPU_VFP_V2 (FPU_VFP_V1 | FPU_VFP_EXT_V2)
|
||||
#define FPU_VFP_V3D16 (FPU_VFP_V2 | FPU_VFP_EXT_V3xD | FPU_VFP_EXT_V3)
|
||||
#define FPU_VFP_V3 (FPU_VFP_V3D16 | FPU_VFP_EXT_D32)
|
||||
#define FPU_VFP_V3xD (FPU_VFP_V1xD | FPU_VFP_EXT_V2 | FPU_VFP_EXT_V3xD)
|
||||
#define FPU_VFP_V4D16 (FPU_VFP_V3D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_V4 (FPU_VFP_V3 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_V4_SP_D16 (FPU_VFP_V3xD | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)
|
||||
#define FPU_VFP_V5D16 (FPU_VFP_V4D16 | FPU_VFP_EXT_ARMV8xD | FPU_VFP_EXT_ARMV8)
|
||||
#define FPU_VFP_V5_SP_D16 (FPU_VFP_V4_SP_D16 | FPU_VFP_EXT_ARMV8xD)
|
||||
#define FPU_VFP_ARMV8 (FPU_VFP_V4 | FPU_VFP_EXT_ARMV8 | FPU_VFP_EXT_ARMV8xD)
|
||||
#define FPU_NEON_ARMV8 (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA | FPU_NEON_EXT_ARMV8)
|
||||
#define FPU_CRYPTO_ARMV8 (FPU_CRYPTO_EXT_ARMV8)
|
||||
#define FPU_VFP_HARD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2 \
|
||||
| FPU_VFP_EXT_V3xD | FPU_VFP_EXT_FMA | FPU_NEON_EXT_FMA \
|
||||
| FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1 | FPU_VFP_EXT_D32)
|
||||
#define FPU_FPA (FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2)
|
||||
|
||||
/* Deprecated. */
|
||||
#define FPU_ARCH_VFP ARM_FEATURE_COPROC (FPU_ENDIAN_PURE)
|
||||
|
||||
#define FPU_ARCH_FPE ARM_FEATURE_COPROC (FPU_FPA_EXT_V1)
|
||||
#define FPU_ARCH_FPA ARM_FEATURE_COPROC (FPU_FPA)
|
||||
|
||||
#define FPU_ARCH_VFP_V1xD ARM_FEATURE_COPROC (FPU_VFP_V1xD)
|
||||
#define FPU_ARCH_VFP_V1 ARM_FEATURE_COPROC (FPU_VFP_V1)
|
||||
#define FPU_ARCH_VFP_V2 ARM_FEATURE_COPROC (FPU_VFP_V2)
|
||||
#define FPU_ARCH_VFP_V3D16 ARM_FEATURE_COPROC (FPU_VFP_V3D16)
|
||||
#define FPU_ARCH_VFP_V3D16_FP16 \
|
||||
ARM_FEATURE_COPROC (FPU_VFP_V3D16 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_V3 ARM_FEATURE_COPROC (FPU_VFP_V3)
|
||||
#define FPU_ARCH_VFP_V3_FP16 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_V3xD ARM_FEATURE_COPROC (FPU_VFP_V3xD)
|
||||
#define FPU_ARCH_VFP_V3xD_FP16 ARM_FEATURE_COPROC (FPU_VFP_V3xD \
|
||||
| FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_NEON_V1 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1)
|
||||
#define FPU_ARCH_VFP_V3_PLUS_NEON_V1 \
|
||||
ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)
|
||||
#define FPU_ARCH_NEON_FP16 \
|
||||
ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1 | FPU_VFP_EXT_FP16)
|
||||
#define FPU_ARCH_VFP_HARD ARM_FEATURE_COPROC (FPU_VFP_HARD)
|
||||
#define FPU_ARCH_VFP_V4 ARM_FEATURE_COPROC (FPU_VFP_V4)
|
||||
#define FPU_ARCH_VFP_V4D16 ARM_FEATURE_COPROC (FPU_VFP_V4D16)
|
||||
#define FPU_ARCH_VFP_V4_SP_D16 ARM_FEATURE_COPROC (FPU_VFP_V4_SP_D16)
|
||||
#define FPU_ARCH_VFP_V5D16 ARM_FEATURE_COPROC (FPU_VFP_V5D16)
|
||||
#define FPU_ARCH_VFP_V5_SP_D16 ARM_FEATURE_COPROC (FPU_VFP_V5_SP_D16)
|
||||
#define FPU_ARCH_NEON_VFP_V4 \
|
||||
ARM_FEATURE_COPROC (FPU_VFP_V4 | FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)
|
||||
#define FPU_ARCH_VFP_ARMV8 ARM_FEATURE_COPROC (FPU_VFP_ARMV8)
|
||||
#define FPU_ARCH_NEON_VFP_ARMV8 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 \
|
||||
| FPU_VFP_ARMV8)
|
||||
#define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8 \
|
||||
ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
|
||||
#define ARCH_CRC_ARMV8 ARM_FEATURE_COPROC (CRC_EXT_ARMV8)
|
||||
#define FPU_ARCH_NEON_VFP_ARMV8_1 \
|
||||
ARM_FEATURE_COPROC (FPU_NEON_ARMV8 \
|
||||
| FPU_VFP_ARMV8 \
|
||||
| FPU_NEON_EXT_RDMA)
|
||||
#define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1 \
|
||||
ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8 \
|
||||
| FPU_NEON_EXT_RDMA)
|
||||
|
||||
|
||||
#define FPU_ARCH_ENDIAN_PURE ARM_FEATURE_COPROC (FPU_ENDIAN_PURE)
|
||||
|
||||
#define FPU_ARCH_MAVERICK ARM_FEATURE_COPROC (FPU_MAVERICK)
|
||||
|
||||
#define ARM_ARCH_V1 ARM_FEATURE_CORE_LOW (ARM_AEXT_V1)
|
||||
#define ARM_ARCH_V2 ARM_FEATURE_CORE_LOW (ARM_AEXT_V2)
|
||||
#define ARM_ARCH_V2S ARM_FEATURE_CORE_LOW (ARM_AEXT_V2S)
|
||||
#define ARM_ARCH_V3 ARM_FEATURE_CORE_LOW (ARM_AEXT_V3)
|
||||
#define ARM_ARCH_V3M ARM_FEATURE_CORE_LOW (ARM_AEXT_V3M)
|
||||
#define ARM_ARCH_V4xM ARM_FEATURE_CORE_LOW (ARM_AEXT_V4xM)
|
||||
#define ARM_ARCH_V4 ARM_FEATURE_CORE_LOW (ARM_AEXT_V4)
|
||||
#define ARM_ARCH_V4TxM ARM_FEATURE_CORE_LOW (ARM_AEXT_V4TxM)
|
||||
#define ARM_ARCH_V4T ARM_FEATURE_CORE_LOW (ARM_AEXT_V4T)
|
||||
#define ARM_ARCH_V5xM ARM_FEATURE_CORE_LOW (ARM_AEXT_V5xM)
|
||||
#define ARM_ARCH_V5 ARM_FEATURE_CORE_LOW (ARM_AEXT_V5)
|
||||
#define ARM_ARCH_V5TxM ARM_FEATURE_CORE_LOW (ARM_AEXT_V5TxM)
|
||||
#define ARM_ARCH_V5T ARM_FEATURE_CORE_LOW (ARM_AEXT_V5T)
|
||||
#define ARM_ARCH_V5TExP ARM_FEATURE_CORE_LOW (ARM_AEXT_V5TExP)
|
||||
#define ARM_ARCH_V5TE ARM_FEATURE_CORE_LOW (ARM_AEXT_V5TE)
|
||||
#define ARM_ARCH_V5TEJ ARM_FEATURE_CORE_LOW (ARM_AEXT_V5TEJ)
|
||||
#define ARM_ARCH_V6 ARM_FEATURE_CORE_LOW (ARM_AEXT_V6)
|
||||
#define ARM_ARCH_V6K ARM_FEATURE_CORE_LOW (ARM_AEXT_V6K)
|
||||
#define ARM_ARCH_V6Z ARM_FEATURE_CORE_LOW (ARM_AEXT_V6Z)
|
||||
#define ARM_ARCH_V6KZ ARM_FEATURE_CORE_LOW (ARM_AEXT_V6KZ)
|
||||
#define ARM_ARCH_V6T2 ARM_FEATURE_CORE (ARM_AEXT_V6T2, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V6KT2 ARM_FEATURE_CORE (ARM_AEXT_V6KT2, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V6ZT2 ARM_FEATURE_CORE (ARM_AEXT_V6ZT2, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V6KZT2 ARM_FEATURE_CORE (ARM_AEXT_V6KZT2, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V6M ARM_FEATURE_CORE_LOW (ARM_AEXT_V6M)
|
||||
#define ARM_ARCH_V6SM ARM_FEATURE_CORE_LOW (ARM_AEXT_V6SM)
|
||||
#define ARM_ARCH_V7 ARM_FEATURE_CORE (ARM_AEXT_V7, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V7A ARM_FEATURE_CORE (ARM_AEXT_V7A, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V7VE ARM_FEATURE_CORE (ARM_AEXT_V7VE, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V7R ARM_FEATURE_CORE (ARM_AEXT_V7R, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V7M ARM_FEATURE_CORE (ARM_AEXT_V7M, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V7EM ARM_FEATURE_CORE (ARM_AEXT_V7EM, ARM_EXT2_V6T2_V8M)
|
||||
#define ARM_ARCH_V8A ARM_FEATURE_CORE (ARM_AEXT_V8A, ARM_AEXT2_V8A)
|
||||
#define ARM_ARCH_V8A_CRC ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8A, \
|
||||
CRC_EXT_ARMV8)
|
||||
#define ARM_ARCH_V8_1A ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A, \
|
||||
CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
|
||||
#define ARM_ARCH_V8_2A ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_2A, \
|
||||
CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
|
||||
#define ARM_ARCH_V8_3A ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_3A, \
|
||||
CRC_EXT_ARMV8 | FPU_NEON_EXT_RDMA)
|
||||
#define ARM_ARCH_V8M_BASE ARM_FEATURE_CORE (ARM_AEXT_V8M_BASE, ARM_AEXT2_V8M)
|
||||
#define ARM_ARCH_V8M_MAIN ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN, \
|
||||
ARM_AEXT2_V8M_MAIN)
|
||||
#define ARM_ARCH_V8M_MAIN_DSP ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN_DSP, \
|
||||
ARM_AEXT2_V8M_MAIN_DSP)
|
||||
|
||||
/* Some useful combinations: */
|
||||
#define ARM_ARCH_NONE ARM_FEATURE_LOW (0, 0)
|
||||
#define FPU_NONE ARM_FEATURE_LOW (0, 0)
|
||||
#define ARM_ANY ARM_FEATURE (-1, -1, 0) /* Any basic core. */
|
||||
#define ARM_FEATURE_ALL ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features. */
|
||||
#define FPU_ANY_HARD ARM_FEATURE_COPROC (FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
|
||||
/* Extensions containing some Thumb-2 instructions. If any is present, Thumb
|
||||
ISA is Thumb-2. */
|
||||
#define ARM_ARCH_THUMB2 ARM_FEATURE_CORE (ARM_EXT_V6T2 | ARM_EXT_V7 \
|
||||
| ARM_EXT_DIV | ARM_EXT_V8, \
|
||||
ARM_EXT2_ATOMICS | ARM_EXT2_V6T2_V8M)
|
||||
/* v7-a+sec. */
|
||||
#define ARM_ARCH_V7A_SEC \
|
||||
ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_SEC, ARM_EXT2_V6T2_V8M)
|
||||
/* v7-a+mp+sec. */
|
||||
#define ARM_ARCH_V7A_MP_SEC \
|
||||
ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP | ARM_EXT_SEC, ARM_EXT2_V6T2_V8M)
|
||||
/* v7-r+idiv. */
|
||||
#define ARM_ARCH_V7R_IDIV \
|
||||
ARM_FEATURE_CORE (ARM_AEXT_V7R | ARM_EXT_ADIV, ARM_EXT2_V6T2_V8M)
|
||||
/* Features that are present in v6M and v6S-M but not other v6 cores. */
|
||||
#define ARM_ARCH_V6M_ONLY ARM_FEATURE_CORE_LOW (ARM_AEXT_V6M_ONLY)
|
||||
/* v8-a+fp. */
|
||||
#define ARM_ARCH_V8A_FP \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8A, FPU_ARCH_VFP_ARMV8)
|
||||
/* v8-a+simd (implies fp). */
|
||||
#define ARM_ARCH_V8A_SIMD \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8A, FPU_ARCH_NEON_VFP_ARMV8)
|
||||
/* v8-a+crypto (implies simd+fp). */
|
||||
#define ARM_ARCH_V8A_CRYPTOV1 \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8)
|
||||
|
||||
/* v8.1-a+fp. */
|
||||
#define ARM_ARCH_V8_1A_FP \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A, FPU_ARCH_VFP_ARMV8)
|
||||
/* v8.1-a+simd (implies fp). */
|
||||
#define ARM_ARCH_V8_1A_SIMD \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A, FPU_ARCH_NEON_VFP_ARMV8_1)
|
||||
/* v8.1-a+crypto (implies simd+fp). */
|
||||
#define ARM_ARCH_V8_1A_CRYPTOV1 \
|
||||
ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1)
|
||||
|
||||
|
||||
/* There are too many feature bits to fit in a single word, so use a
|
||||
structure. For simplicity we put all core features in array CORE
|
||||
and everything else in the other. All the bits in element core[0]
|
||||
have been occupied, so new feature should use bit in element core[1]
|
||||
and use macro ARM_FEATURE to initialize the feature set variable. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long core[2];
|
||||
unsigned long coproc;
|
||||
} arm_feature_set;
|
||||
|
||||
/* Test whether CPU and FEAT have any features in common. */
|
||||
#define ARM_CPU_HAS_FEATURE(CPU,FEAT) \
|
||||
(((CPU).core[0] & (FEAT).core[0]) != 0 \
|
||||
|| ((CPU).core[1] & (FEAT).core[1]) != 0 \
|
||||
|| ((CPU).coproc & (FEAT).coproc) != 0)
|
||||
|
||||
/* Tests whether the features of A are a subset of B. */
|
||||
#define ARM_FSET_CPU_SUBSET(A,B) \
|
||||
(((A).core[0] & (B).core[0]) == (A).core[0] \
|
||||
&& ((A).core[1] & (B).core[1]) == (A).core[1] \
|
||||
&& ((A).coproc & (B).coproc) == (A).coproc)
|
||||
|
||||
#define ARM_CPU_IS_ANY(CPU) \
|
||||
((CPU).core[0] == ((arm_feature_set)ARM_ANY).core[0] \
|
||||
&& (CPU).core[1] == ((arm_feature_set)ARM_ANY).core[1])
|
||||
|
||||
#define ARM_MERGE_FEATURE_SETS(TARG,F1,F2) \
|
||||
do { \
|
||||
(TARG).core[0] = (F1).core[0] | (F2).core[0];\
|
||||
(TARG).core[1] = (F1).core[1] | (F2).core[1];\
|
||||
(TARG).coproc = (F1).coproc | (F2).coproc; \
|
||||
} while (0)
|
||||
|
||||
#define ARM_CLEAR_FEATURE(TARG,F1,F2) \
|
||||
do { \
|
||||
(TARG).core[0] = (F1).core[0] &~ (F2).core[0];\
|
||||
(TARG).core[1] = (F1).core[1] &~ (F2).core[1];\
|
||||
(TARG).coproc = (F1).coproc &~ (F2).coproc; \
|
||||
} while (0)
|
||||
|
||||
#define ARM_FEATURE_COPY(F1, F2) \
|
||||
do { \
|
||||
(F1).core[0] = (F2).core[0]; \
|
||||
(F1).core[1] = (F2).core[1]; \
|
||||
(F1).coproc = (F2).coproc; \
|
||||
} while (0)
|
||||
|
||||
#define ARM_FEATURE_EQUAL(T1,T2) \
|
||||
((T1).core[0] == (T2).core[0] \
|
||||
&& (T1).core[1] == (T2).core[1] \
|
||||
&& (T1).coproc == (T2).coproc)
|
||||
|
||||
#define ARM_FEATURE_ZERO(T) \
|
||||
((T).core[0] == 0 && (T).core[1] == 0 && (T).coproc == 0)
|
||||
|
||||
#define ARM_FEATURE_CORE_EQUAL(T1, T2) \
|
||||
((T1).core[0] == (T2).core[0] && (T1).core[1] == (T2).core[1])
|
||||
|
||||
#define ARM_FEATURE_LOW(core, coproc) {{(core), 0}, (coproc)}
|
||||
#define ARM_FEATURE_CORE(core1, core2) {{(core1), (core2)}, 0}
|
||||
#define ARM_FEATURE_CORE_LOW(core) {{(core), 0}, 0}
|
||||
#define ARM_FEATURE_CORE_HIGH(core) {{0, (core)}, 0}
|
||||
#define ARM_FEATURE_COPROC(coproc) {{0, 0}, (coproc)}
|
||||
#define ARM_FEATURE(core1, core2, coproc) {{(core1), (core2)}, (coproc)}
|
@ -1,7 +1,6 @@
|
||||
/* Interface between the opcode library and its callers.
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010,
|
||||
2011, 2012 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -33,13 +32,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mybfd.h"
|
||||
|
||||
#define bfd_zalloc calloc
|
||||
#define bfd_malloc malloc
|
||||
#define xmalloc malloc
|
||||
|
||||
|
||||
typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
|
||||
|
||||
enum dis_insn_type
|
||||
@ -218,21 +217,38 @@ typedef struct disassemble_info
|
||||
/* Command line options specific to the target disassembler. */
|
||||
char * disassembler_options;
|
||||
|
||||
/* If non-zero then try not disassemble beyond this address, even if
|
||||
there are values left in the buffer. This address is the address
|
||||
of the nearest symbol forwards from the start of the disassembly,
|
||||
and it is assumed that it lies on the boundary between instructions.
|
||||
If an instruction spans this address then this is an error in the
|
||||
file being disassembled. */
|
||||
bfd_vma stop_vma;
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
/* This struct is used to pass information about valid disassembler options
|
||||
and their descriptions from the target to the generic GDB functions that
|
||||
set and display them. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char **name;
|
||||
const char **description;
|
||||
} disasm_options_t;
|
||||
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of octets processed. */
|
||||
typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
|
||||
|
||||
extern int print_insn_tricore (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_aarch64 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_alpha (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_avr (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_bfin (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_arm (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_mips (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_or32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_nios2 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_powerpc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_score (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_cr16 (bfd_vma, disassemble_info *);
|
||||
@ -243,10 +259,12 @@ extern int print_insn_dlx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_epiphany (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_fr30 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_frv (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_ft32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300h (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300s (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8500 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_lanai (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_hppa (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i370 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i386 (bfd_vma, disassemble_info *);
|
||||
@ -259,8 +277,9 @@ extern int print_insn_ip2k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_iq2000 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_arm (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_mips (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_or32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_nios2 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_powerpc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_riscv (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_score (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_lm32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m32c (bfd_vma, disassemble_info *);
|
||||
@ -273,22 +292,23 @@ extern int print_insn_m68k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m88k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mcore (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mep (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_metag (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_microblaze (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mmix (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mn10200 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mn10300 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_moxie (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_msp430 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_lanai (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mt (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_nds32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_ns32k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_openrisc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_or1k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_pdp11 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_pj (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_pru (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rs6000 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_s390 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_shb (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_shl (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh64 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh64x_media (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sparc (bfd_vma, disassemble_info *);
|
||||
@ -302,6 +322,7 @@ extern int print_insn_tilegx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_tilepro (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_v850 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_vax (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_visium (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_w65 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_xc16x (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_xgate (bfd_vma, disassemble_info *);
|
||||
@ -312,23 +333,29 @@ extern int print_insn_z8001 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_z8002 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g10 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g13 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g14 (bfd_vma, disassemble_info *);
|
||||
|
||||
extern disassembler_ftype arc_get_disassembler (bfd *);
|
||||
extern disassembler_ftype cris_get_disassembler (bfd *);
|
||||
extern disassembler_ftype rl78_get_disassembler (bfd *);
|
||||
|
||||
extern void print_aarch64_disassembler_options (FILE *);
|
||||
extern void print_i386_disassembler_options (FILE *);
|
||||
extern void print_mips_disassembler_options (FILE *);
|
||||
extern void print_ppc_disassembler_options (FILE *);
|
||||
extern void print_riscv_disassembler_options (FILE *);
|
||||
extern void print_arm_disassembler_options (FILE *);
|
||||
extern void parse_arm_disassembler_option (char *);
|
||||
extern void print_arc_disassembler_options (FILE *);
|
||||
extern void print_s390_disassembler_options (FILE *);
|
||||
extern int get_arm_regname_num_options (void);
|
||||
extern int set_arm_regname_option (int);
|
||||
extern int get_arm_regnames (int, const char **, const char **, const char *const **);
|
||||
extern bfd_boolean aarch64_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern void disassemble_init_powerpc (struct disassemble_info *);
|
||||
extern void disassemble_init_s390 (struct disassemble_info *);
|
||||
extern const disasm_options_t *disassembler_options_powerpc (void);
|
||||
extern const disasm_options_t *disassembler_options_arm (void);
|
||||
extern const disasm_options_t *disassembler_options_s390 (void);
|
||||
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
extern disassembler_ftype disassembler (bfd *);
|
||||
@ -340,6 +367,29 @@ extern void disassemble_init_for_target (struct disassemble_info * dinfo);
|
||||
/* Document any target specific options available from the disassembler. */
|
||||
extern void disassembler_usage (FILE *);
|
||||
|
||||
/* Remove whitespace and consecutive commas. */
|
||||
extern char *remove_whitespace_and_extra_commas (char *);
|
||||
|
||||
/* Like STRCMP, but treat ',' the same as '\0' so that we match
|
||||
strings like "foobar" against "foobar,xxyyzz,...". */
|
||||
extern int disassembler_options_cmp (const char *, const char *);
|
||||
|
||||
/* A helper function for FOR_EACH_DISASSEMBLER_OPTION. */
|
||||
static inline char *
|
||||
next_disassembler_option (char *options)
|
||||
{
|
||||
char *opt = strchr (options, ',');
|
||||
if (opt != NULL)
|
||||
opt++;
|
||||
return opt;
|
||||
}
|
||||
|
||||
/* A macro for iterating over each comma separated option in OPTIONS. */
|
||||
#define FOR_EACH_DISASSEMBLER_OPTION(OPT, OPTIONS) \
|
||||
for ((OPT) = (OPTIONS); \
|
||||
(OPT) != NULL; \
|
||||
(OPT) = next_disassembler_option (OPT))
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2015 - pancake */
|
||||
/* radare - LGPL - Copyright 2009-2017 - pancake */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@ -8,7 +8,7 @@
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
#include "dis-asm.h"
|
||||
#include "../arch/arm/gnu/gnu-arm.h"
|
||||
#include "../arch/arm/gnu/opcode-arm.h"
|
||||
|
||||
#if 0
|
||||
#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF }
|
||||
@ -19,48 +19,48 @@ struct arm_arch_option_table {
|
||||
int fpu;
|
||||
};
|
||||
static const struct arm_arch_option_table arm_archs[] = {
|
||||
ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP),
|
||||
/* The official spelling of the ARMv7 profile variants is the dashed form.
|
||||
Accept the non-dashed form for compatibility with old toolchains. */
|
||||
ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
|
||||
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
|
||||
};
|
||||
#endif
|
||||
@ -70,38 +70,44 @@ static unsigned long Offset = 0;
|
||||
static char *buf_global = NULL;
|
||||
static unsigned char bytes[8];
|
||||
|
||||
static int arm_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr,
|
||||
unsigned int length, struct disassemble_info *info) {
|
||||
static int arm_buffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr,
|
||||
unsigned int length, struct disassemble_info *info) {
|
||||
int delta = (memaddr - Offset);
|
||||
if (delta<0) return -1; // disable backward reads
|
||||
if ((delta+length)>4) return -1;
|
||||
memcpy (myaddr, bytes+delta, length);
|
||||
if (delta < 0) {
|
||||
return -1; // disable backward reads
|
||||
}
|
||||
if ((delta + length) > 4) {
|
||||
return -1;
|
||||
}
|
||||
memcpy (myaddr, bytes + delta, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) {
|
||||
static int symbol_at_address(bfd_vma addr, struct disassemble_info *info) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) {
|
||||
//--
|
||||
// --
|
||||
}
|
||||
|
||||
static void print_address(bfd_vma address, struct disassemble_info *info) {
|
||||
char tmp[32];
|
||||
if (!buf_global)
|
||||
if (!buf_global) {
|
||||
return;
|
||||
sprintf (tmp, "0x%08"PFMT64x"", (ut64)address);
|
||||
}
|
||||
sprintf (tmp, "0x%08"PFMT64x "", (ut64) address);
|
||||
strcat (buf_global, tmp);
|
||||
}
|
||||
|
||||
static int buf_fprintf(void *stream, const char *format, ...) {
|
||||
va_list ap;
|
||||
char *tmp;
|
||||
if (!buf_global || !format)
|
||||
if (!buf_global || !format) {
|
||||
return false;
|
||||
}
|
||||
va_start (ap, format);
|
||||
tmp = malloc (strlen (format)+strlen (buf_global)+2);
|
||||
tmp = malloc (strlen (format) + strlen (buf_global) + 2);
|
||||
if (!tmp) {
|
||||
va_end (ap);
|
||||
return false;
|
||||
@ -118,26 +124,45 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
static int oldcpucode = 0;
|
||||
int opsize, cpucode = 0;
|
||||
struct disassemble_info obj;
|
||||
char *options = (a->bits==16)? "force-thumb": "no-force-thumb";
|
||||
char *options = (a->bits == 16)? "force-thumb": "no-force-thumb";
|
||||
|
||||
if (len<2) return -1;
|
||||
if (len < 2) {
|
||||
return -1;
|
||||
}
|
||||
memset (bytes, 0, sizeof (bytes));
|
||||
memcpy (bytes, buf, R_MIN (len, 4));
|
||||
if (a->bits<64 && len<(a->bits/8)) return -1;
|
||||
if (a->bits < 64 && len < (a->bits / 8)) {
|
||||
return -1;
|
||||
}
|
||||
buf_global = op->buf_asm;
|
||||
Offset = a->pc;
|
||||
|
||||
/* prepare disassembler */
|
||||
memset (&obj,'\0', sizeof (struct disassemble_info));
|
||||
memset (&obj, '\0', sizeof (struct disassemble_info));
|
||||
arm_mode = a->bits;
|
||||
#if 0
|
||||
typedef struct {
|
||||
unsigned long core[2];
|
||||
unsigned long coproc;
|
||||
} arm_feature_set;
|
||||
#endif
|
||||
#if 0
|
||||
arm_feature_set afs = ARM_ARCH_V7EM;
|
||||
arm_feature_set afp = FPU_ARCH_VFP_V4D16;
|
||||
printf ("v7em = core { 0x%x, 0x%x } copro 0x%x\n", afs.core[0], afs.core[1], afs.coproc);
|
||||
cpucode = afs.core[0];
|
||||
cpucode = 66471;
|
||||
#endif
|
||||
// printf ("fpu- = 0x%x\n", FPU_ARCH_VFP_V4D16);
|
||||
|
||||
cpucode = oldcpucode;
|
||||
//cpucode = oldcpucode;
|
||||
/* select cpu */
|
||||
if (a->cpu) {
|
||||
if (oldcpu != a->cpu) {
|
||||
cpucode = atoi (a->cpu);
|
||||
if (!strcmp ("v5j", a->cpu))
|
||||
if (!strcmp ("v5j", a->cpu)) {
|
||||
cpucode = 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.arch = 0;
|
||||
@ -153,31 +178,36 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
obj.fprintf_func = &buf_fprintf;
|
||||
obj.stream = stdout;
|
||||
obj.bytes_per_chunk =
|
||||
obj.bytes_per_line = (a->bits/8);
|
||||
obj.bytes_per_line = (a->bits / 8);
|
||||
|
||||
op->buf_asm[0]='\0';
|
||||
if (a->bits==64) {
|
||||
op->buf_asm[0] = '\0';
|
||||
if (a->bits == 64) {
|
||||
obj.disassembler_options = NULL;
|
||||
memcpy (bytes, buf, 4);
|
||||
op->size = print_insn_aarch64 ((bfd_vma)Offset, &obj);
|
||||
op->size = print_insn_aarch64 ((bfd_vma) Offset, &obj);
|
||||
} else {
|
||||
obj.disassembler_options = options;
|
||||
op->size = (obj.endian == BFD_ENDIAN_LITTLE)?
|
||||
print_insn_little_arm ((bfd_vma)Offset, &obj):
|
||||
print_insn_big_arm ((bfd_vma)Offset, &obj);
|
||||
print_insn_little_arm ((bfd_vma) Offset, &obj):
|
||||
print_insn_big_arm ((bfd_vma) Offset, &obj);
|
||||
}
|
||||
opsize = op->size;
|
||||
if (op->size == -1) {
|
||||
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
|
||||
op->size = 4;
|
||||
}
|
||||
if (strstr (op->buf_asm, "UNDEF")) {
|
||||
strcpy (op->buf_asm, "undefined");
|
||||
op->size = 2;
|
||||
opsize = 2;
|
||||
}
|
||||
return opsize;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_arm_gnu = {
|
||||
.name = "arm.gnu",
|
||||
.arch = "arm",
|
||||
.bits = 16|32|64,
|
||||
.bits = 16 | 32 | 64,
|
||||
.endian = R_SYS_ENDIAN_LITTLE | R_SYS_ENDIAN_BIG,
|
||||
.desc = "Acorn RISC Machine CPU",
|
||||
.disassemble = &disassemble,
|
||||
@ -185,7 +215,7 @@ RAsmPlugin r_asm_plugin_arm_gnu = {
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_arm_gnu,
|
||||
.version = R2_VERSION
|
||||
|
Loading…
x
Reference in New Issue
Block a user