Skip to content

Commit

Permalink
Fix ARCompact disassembly
Browse files Browse the repository at this point in the history
  • Loading branch information
radare committed Oct 24, 2013
1 parent dd050b3 commit 84481c5
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 12 deletions.
70 changes: 66 additions & 4 deletions libr/anal/p/anal_arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
#include <r_anal.h>

static int arcompact_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
/* ARCompact ISA */
const ut8 *b = (ut8 *)data;
ut8 subopcode = ((b[1]&0xf)>>2) << 1;
ut8 basecode = (b[3] & 0xf8) >> 3;
int lowbyte, highbyte;

/* ARCompact ISA */
lowbyte = anal->big_endian? 0: 1;
highbyte = anal->big_endian? 1: 0;

Expand All @@ -19,16 +21,76 @@ static int arcompact_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, in
} else {
op->length = 4;
}
// XXX: compact instructions can be >4 !??
// some ops are 6 and others are 8 byte length
op->fail = addr + 4;
ut8 basecode = (b[3] & 0xf8) >> 3;
ut8 subopcode = ((b[1]&0xf)>>2)<<1;
//eprintf ("----> ST %x\n", subopcode);
//eprintf ("BC = 0x%x\n", basecode);
if (!memcmp (b, "\x4a\x26\x00\x70", 4)) {
op->type = R_ANAL_OP_TYPE_NOP;
return 4;
}
/* ARCompact ISA */
op->fail = addr + 4;
switch (basecode) {
case 0x0:
{
ut64 imm = ((((b[0] & 0xc0) >> 6) | (b[1] << 2)) << 11) |
((((b[2] & 0xfe) >> 1) | ((b[3] & 0x7) << 8)) << 1);
imm = addr + 8+ (b[3] * 4);
if (imm != 0) {
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = imm;
}
}
break;
case 0x01:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = 0;
break;
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
break;
default:
/* This is 16 bit instruction */
op->length = 2;
op->fail = addr + 2;
basecode = (b[1] & 0xf8) >> 3;
switch (basecode) {
case 0x0c:
case 0x0d:
op->type = R_ANAL_OP_TYPE_ADD;
break;
case 0x0e:
op->type = R_ANAL_OP_TYPE_MOV;
break;
case 0x1b:
op->type = R_ANAL_OP_TYPE_MOV;
break;
case 0x1c:
if (b[0] & 0x80)
op->type = R_ANAL_OP_TYPE_CMP;
else
op->type = R_ANAL_OP_TYPE_ADD;
break;
case 0x1d:
case 0x1e:
case 0x1f:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = 0;
break;
default:
break;
}
break;
}
return op->length;
}

Expand Down
8 changes: 5 additions & 3 deletions libr/asm/p/asm_arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@

static unsigned long Offset = 0;
static char *buf_global = NULL;
static unsigned char bytes[4];
static unsigned char bytes[32];

static int arc_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;
if ((delta+length)>sizeof (bytes)) return -1;
memcpy (myaddr, bytes+delta, length);
return 0;
}
Expand Down Expand Up @@ -59,7 +59,9 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
if (len<4) return -1;
buf_global = op->buf_asm;
Offset = a->pc;
memcpy (bytes, buf, 4); // TODO handle compact
if (len>sizeof (bytes))
len = sizeof (bytes);
memcpy (bytes, buf, len); // TODO handle compact

/* prepare disassembler */
memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
Expand Down
4 changes: 2 additions & 2 deletions libr/core/cmd_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,7 @@ R_API void r_print_offset(RPrint *p, ut64 off, int invert, int opt) {
r_cons_printf ("%s%04x:%04x"Color_RESET,
k, s&0xFFFF, a&0xFFFF);
} else r_cons_printf ("%s0x%08"PFMT64x""Color_RESET, k, off);
r_cons_puts (" ");
} else r_cons_printf ("0x%08"PFMT64x" ", off);
r_cons_puts (" ");
} else r_cons_printf ("0x%08"PFMT64x" ", off);
}

2 changes: 1 addition & 1 deletion libr/core/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ r_config_set (cfg, "asm.arch", R_SYS_ARCH);
r_config_desc (cfg, "asm.stackptr", "Show stack pointer at disassembly");
r_config_set (cfg, "asm.dwarf", "false");
r_config_desc (cfg, "asm.dwarf", "Show dwarf comment at disassembly");
r_config_set_i (cfg, "asm.nbytes", 8);
r_config_set_i (cfg, "asm.nbytes", 6);
r_config_set (cfg, "asm.tabs", "false");
r_config_desc (cfg, "asm.nbytes", "Number of bytes for each opcode at disassembly");
r_config_set (cfg, "asm.pseudo", "false"); // DEPRECATED ???
Expand Down
4 changes: 2 additions & 2 deletions libr/core/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,8 +881,8 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
pad[j] = '\0';
}
if (show_color)
r_cons_printf (" %s %s %s"Color_RESET, pad, str, extra);
else r_cons_printf (" %s %s %s", pad, str, extra);
r_cons_printf ("%s %s %s"Color_RESET, pad, str, extra);
else r_cons_printf ("%s %s %s", pad, str, extra);
free (str);
}

Expand Down

0 comments on commit 84481c5

Please sign in to comment.