Fix arm thumb disassembler (needs testing)

This commit is contained in:
pancake 2013-01-11 14:21:23 +01:00
parent 3f12cb2cb1
commit ebe2f35630
3 changed files with 20 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2012 - pancake */
/* radare - LGPL - Copyright 2010-2013 - pancake */
#include <stdio.h>
#include <string.h>

View File

@ -2906,7 +2906,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
if (isfloat)
{
unsigned char valbytes[4];
double fvalue;
//double fvalue;
/* Do this a byte at a time so we don't have to
worry about the host's endianness. */
@ -4821,9 +4821,10 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
info->disassembler_options = NULL;
}
if(info->bytes_per_line==2) {
if (info->bytes_per_line==2) {
is_thumb = TRUE;
} else is_thumb = FALSE;
} else is_thumb = FALSE;
/* PR 10288: Control which instructions will be disassembled. */
if (info->private_data == NULL)
{
@ -4989,7 +4990,7 @@ if(info->bytes_per_line==2) {
private_data->last_mapping_sym = last_sym;
private_data->last_type = type;
is_thumb = (private_data->last_type == MAP_THUMB);
//is_thumb = (private_data->last_type == MAP_THUMB);
is_data = (private_data->last_type == MAP_DATA);
/* Look a little bit ahead to see if we should print out
@ -5105,6 +5106,7 @@ if(info->bytes_per_line==2) {
printer = print_insn_thumb16;
info->bytes_per_chunk = 2;
size = 2;
printf ("THUMB MODE \n");
status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
if (!little_code)
@ -5118,7 +5120,7 @@ status = 0;
/* These bit patterns signal a four-byte Thumb
instruction. */
if (1||(given & 0xF800) == 0xF800
if ((given & 0xF800) == 0xF800
|| (given & 0xF800) == 0xF000
|| (given & 0xF800) == 0xE800)
{

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2011 nibble<.ds@gmail.com> */
/* radare - LGPL - Copyright 2009-2013 - pancake, nibble */
#include <stdio.h>
#include <stdarg.h>
@ -53,11 +53,10 @@ static int buf_fprintf(void *stream, const char *format, ...) {
return R_TRUE;
}
static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf, ut64 len) {
static struct disassemble_info disasm_obj;
static int disassemble(RAsm *a, struct r_asm_op_t *op, const ut8 *buf, ut64 len) {
struct disassemble_info disasm_obj;
/* fetching is 4 byte aligned */
if (len<4) return -1;
if (len<(a->bits/8)) return -1;
buf_global = op->buf_asm;
Offset = a->pc;
memcpy (bytes, buf, 4); // TODO handle thumb
@ -67,8 +66,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf,
arm_mode = a->bits;
//disasm_obj.arch = ARM_EXT_V1|ARM_EXT_V4T|ARM_EXT_V5;
/* TODO: set arch */
disasm_obj.arch =0xffffffff;
disasm_obj.mach =0xffffffff;
disasm_obj.arch = 0xffffffff;
disasm_obj.mach = 0xffffffff;
disasm_obj.buffer = bytes;
disasm_obj.read_memory_func = &arm_buffer_read_memory;
@ -82,12 +81,9 @@ static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf,
disasm_obj.bytes_per_line = (a->bits/8);
op->buf_asm[0]='\0';
if (disasm_obj.endian)
op->inst_len = print_insn_little_arm (
(bfd_vma)Offset, &disasm_obj);
else
op->inst_len = print_insn_big_arm (
(bfd_vma)Offset, &disasm_obj);
op->inst_len = disasm_obj.endian?
print_insn_little_arm ((bfd_vma)Offset, &disasm_obj):
print_insn_big_arm ((bfd_vma)Offset, &disasm_obj);
if (op->inst_len == -1)
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
return op->inst_len; //(a->bits/8); //op->inst_len;
@ -95,12 +91,13 @@ static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf,
// XXX: This is wrong, some opcodes are 32bit in thumb mode
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
int opcode = armass_assemble (buf, a->pc, (a->bits==16)?1:0);
int is_thumb = a->bits==16? 1: 0;
int opcode = armass_assemble (buf, a->pc, is_thumb);
if (opcode==-1)
return -1;
if (a->bits==32)
r_mem_copyendian (op->buf, (void *)&opcode, 4, a->big_endian);
else r_mem_copyendian (op->buf, (void *)&opcode, 2, a->big_endian);
else r_mem_copyendian (op->buf, (void *)&opcode, 2, !a->big_endian);
return (a->bits/8);
}