nkeynes@362: /** nkeynes@586: * $Id$ nkeynes@362: * nkeynes@362: * Wrapper around i386-dis to supply the same behaviour as the other nkeynes@362: * disassembly functions. nkeynes@362: * nkeynes@362: * Copyright (c) 2005 Nathan Keynes. nkeynes@362: * nkeynes@362: * This program is free software; you can redistribute it and/or modify nkeynes@362: * it under the terms of the GNU General Public License as published by nkeynes@362: * the Free Software Foundation; either version 2 of the License, or nkeynes@362: * (at your option) any later version. nkeynes@362: * nkeynes@362: * This program is distributed in the hope that it will be useful, nkeynes@362: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@362: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@362: * GNU General Public License for more details. nkeynes@362: */ nkeynes@362: nkeynes@362: #include nkeynes@480: #include nkeynes@755: #include "x86dasm/x86dasm.h" nkeynes@755: #include "x86dasm/bfd.h" nkeynes@755: #include "x86dasm/dis-asm.h" nkeynes@586: #include "sh4/sh4.h" nkeynes@527: #include "sh4/sh4trans.h" nkeynes@362: nkeynes@362: extern const struct reg_desc_struct sh4_reg_map[]; nkeynes@362: const struct cpu_desc_struct x86_cpu_desc = nkeynes@755: { "x86", (disasm_func_t)x86_disasm_instruction, NULL, mem_has_page, nkeynes@362: NULL, NULL, NULL, 1, nkeynes@362: (char *)&sh4r, sizeof(sh4r), sh4_reg_map, nkeynes@362: &sh4r.pc }; nkeynes@362: nkeynes@362: static int x86_disasm_output( void *data, const char *format, ... ); nkeynes@429: static void x86_print_address( bfd_vma memaddr, struct disassemble_info *info ); nkeynes@362: nkeynes@362: static struct disassemble_info x86_disasm_info; nkeynes@362: nkeynes@365: static x86_symbol *x86_symtab; nkeynes@365: static int x86_num_symbols = 0; nkeynes@365: nkeynes@515: nkeynes@515: void xlat_disasm_block( FILE *out, void *block ) nkeynes@515: { nkeynes@586: uint32_t buflen = xlat_get_code_size(block); nkeynes@515: x86_set_symtab( NULL, 0 ); nkeynes@515: x86_disasm_block( out, block, buflen ); nkeynes@515: } nkeynes@515: nkeynes@376: void x86_disasm_block(FILE *out, void *start, uint32_t len) nkeynes@376: { nkeynes@527: uintptr_t start_addr = (uintptr_t)start; nkeynes@376: uint32_t pc; nkeynes@376: x86_disasm_init( start, start_addr, len ); nkeynes@376: for( pc = start_addr; pc < start_addr + len; ) { nkeynes@376: char buf[256]; nkeynes@376: char op[256]; nkeynes@376: uint32_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op ); nkeynes@376: fprintf( out, "%08X: %-20s %s\n", pc, op, buf ); nkeynes@376: pc = pc2; nkeynes@376: } nkeynes@376: } nkeynes@376: nkeynes@527: void x86_disasm_init(unsigned char *buf, uintptr_t vma, int buflen) nkeynes@362: { nkeynes@362: init_disassemble_info( &x86_disasm_info, NULL, x86_disasm_output ); nkeynes@362: x86_disasm_info.arch = bfd_arch_i386; nkeynes@527: #if SH4_TRANSLATOR == TARGET_X86_64 nkeynes@527: x86_disasm_info.mach = bfd_mach_x86_64_intel_syntax; nkeynes@527: #else nkeynes@362: x86_disasm_info.mach = bfd_mach_i386_i386_intel_syntax; nkeynes@527: #endif nkeynes@362: x86_disasm_info.endian = BFD_ENDIAN_LITTLE; nkeynes@362: x86_disasm_info.buffer = buf; nkeynes@362: x86_disasm_info.buffer_vma = vma; nkeynes@362: x86_disasm_info.buffer_length = buflen; nkeynes@365: x86_disasm_info.print_address_func = x86_print_address; nkeynes@362: } nkeynes@362: nkeynes@365: void x86_set_symtab( x86_symbol *symtab, int num_symbols ) nkeynes@365: { nkeynes@365: x86_symtab = symtab; nkeynes@365: x86_num_symbols = num_symbols; nkeynes@365: } nkeynes@365: nkeynes@365: static const char *x86_find_symbol( bfd_vma memaddr, struct disassemble_info *info ) nkeynes@365: { nkeynes@365: int i; nkeynes@365: for( i=0; ifprintf_func( info->stream, "%08X", memaddr ); nkeynes@365: if( sym != NULL ) { nkeynes@365: info->fprintf_func( info->stream, " <%s>", sym ); nkeynes@365: } nkeynes@365: } nkeynes@362: nkeynes@527: uint32_t x86_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode ) nkeynes@362: { nkeynes@362: int count, i; nkeynes@362: nkeynes@362: x86_disasm_info.stream = buf; nkeynes@362: buf[0] = 0; nkeynes@362: count = print_insn_i386_att( pc, &x86_disasm_info ); nkeynes@362: if( count != 0 ) { nkeynes@429: unsigned char tmp[count]; nkeynes@362: x86_disasm_info.read_memory_func( pc, tmp, count, &x86_disasm_info ); nkeynes@362: for( i=0; i