From e36d2d4dcfa4dc4f7b8017c4e7dbf7c299e7e1b8 Mon Sep 17 00:00:00 2001 From: fenugrec Date: Mon, 8 Dec 2014 18:42:38 -0500 Subject: [PATCH] superH analyzer+disasm bigendian support --- libr/anal/p/anal_sh.c | 8 ++++---- libr/asm/arch/include/dis-asm.h | 3 ++- libr/asm/arch/sh/gnu/sh-dis.c | 3 ++- libr/asm/p/asm_sh.c | 8 ++++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libr/anal/p/anal_sh.c b/libr/anal/p/anal_sh.c index 39fcb13ae8..0b5110e137 100644 --- a/libr/anal/p/anal_sh.c +++ b/libr/anal/p/anal_sh.c @@ -433,12 +433,10 @@ static int (*first_nibble_decode[])(RAnal*,RAnalOp*,ut16) = { * routines defined in first_nibble_decode table */ static int sh_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) { - //TODO Check if we must do big or little endian. Also fix in RAsm - ut8 b; + ut8 op_MSB,op_LSB; int ret; if (data == NULL) return 0; - b = data[1]; //First byte, little endian memset (op, '\0', sizeof (RAnalOp)); op->addr = addr; op->type = R_ANAL_OP_TYPE_UNK; @@ -447,7 +445,9 @@ static int sh_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) op->size = 2; - ret = first_nibble_decode[(b>>4) & 0x0F](anal, op, *((ut16 *)data)); + op_MSB = (anal->big_endian)? data[0]:data[1]; + op_LSB = (anal->big_endian)? data[1]:data[0]; + ret = first_nibble_decode[(op_MSB>>4) & 0x0F](anal, op, (ut16)(op_MSB<<16 | op_LSB)); return ret; } diff --git a/libr/asm/arch/include/dis-asm.h b/libr/asm/arch/include/dis-asm.h index bd86cb320e..3f5bf571c2 100644 --- a/libr/asm/arch/include/dis-asm.h +++ b/libr/asm/arch/include/dis-asm.h @@ -280,7 +280,8 @@ extern int print_insn_pdp11 (bfd_vma, disassemble_info *); extern int print_insn_pj (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_sh (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_sh64 (bfd_vma, disassemble_info *); extern int print_insn_sh64x_media (bfd_vma, disassemble_info *); extern int print_insn_sparc (bfd_vma, disassemble_info *); diff --git a/libr/asm/arch/sh/gnu/sh-dis.c b/libr/asm/arch/sh/gnu/sh-dis.c index b8752b64af..77f8cd9632 100644 --- a/libr/asm/arch/sh/gnu/sh-dis.c +++ b/libr/asm/arch/sh/gnu/sh-dis.c @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define LITTLE_BIT 2 +/* disassemble 1 opcode (16bits), take care of endianness if info->flags&LITTLE_BIT*/ static int print_insn_shx (memaddr, info) bfd_vma memaddr; @@ -379,7 +380,7 @@ print_insn_shl (memaddr, info) } int -print_insn_sh (memaddr, info) +print_insn_shb (memaddr, info) bfd_vma memaddr; struct disassemble_info *info; { diff --git a/libr/asm/p/asm_sh.c b/libr/asm/p/asm_sh.c index a5144e2ecb..8e87ec469f 100644 --- a/libr/asm/p/asm_sh.c +++ b/libr/asm/p/asm_sh.c @@ -19,6 +19,7 @@ static int sh_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned in } int print_insn_shl (bfd_vma memaddr, struct disassemble_info *info); +int print_insn_shb (bfd_vma memaddr, struct disassemble_info *info); static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) { return 0; @@ -58,7 +59,7 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { if (len<2) return -1; buf_global = op->buf_asm; Offset = a->pc; - memcpy (bytes, buf, 2); // TODO handle thumb + memcpy (bytes, buf, 2); /* prepare disassembler */ memset (&disasm_obj,'\0', sizeof (struct disassemble_info)); @@ -72,7 +73,10 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { disasm_obj.stream = stdout; op->buf_asm[0] = '\0'; - op->size = print_insn_shl ((bfd_vma)Offset, &disasm_obj); + if (a->big_endian) + op->size = print_insn_shb ((bfd_vma)Offset, &disasm_obj); + else + op->size = print_insn_shl ((bfd_vma)Offset, &disasm_obj); if (op->size == -1) strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);