4 * Wrapper around i386-dis to supply the same behaviour as the other
5 * disassembly functions.
7 * Copyright (c) 2005 Nathan Keynes.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
22 #include "xlat/xltcache.h"
23 #include "xlat/xlatdasm.h"
24 #include "xlat/disasm/bfd.h"
25 #include "xlat/disasm/dis-asm.h"
29 #define HOST_CPU_NAME "x86"
30 #define HOST_PRINT print_insn_i386_att
31 #define HOST_SYNTAX bfd_mach_i386_i386_intel_syntax
32 #elif defined(__x86_64__) || defined(__amd64__)
33 #define HOST_CPU_NAME "x86"
34 #define HOST_PRINT print_insn_i386_att
35 #define HOST_SYNTAX bfd_mach_x86_64_intel_syntax
36 #elif defined(__arm__)
37 #define HOST_CPU_NAME "arm"
38 #define HOST_PRINT print_insn_little_arm
39 #define HOST_SYNTAX bfd_mach_arm_unknown
41 #error Unidentified host platform
44 const struct cpu_desc_struct xlat_cpu_desc =
45 { HOST_CPU_NAME, (disasm_func_t)xlat_disasm_instruction, NULL, mem_has_page,
46 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,
50 static int xlat_disasm_output( void *data, const char *format, ... );
51 static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info );
53 static struct disassemble_info xlat_disasm_info;
55 static xlat_symbol *xlat_symtab;
56 static int xlat_num_symbols = 0;
58 void xlat_dump_block( void *block )
60 xlat_disasm_block( stderr, block );
63 void xlat_disasm_block( FILE *out, void *block )
65 uint32_t buflen = xlat_get_code_size(block);
66 xlat_disasm_region( out, block, buflen );
69 void xlat_disasm_region(FILE *out, void *start, uint32_t len)
71 uintptr_t start_addr = (uintptr_t)start;
73 for( pc = start_addr; pc < start_addr + len; ) {
76 uintptr_t pc2 = xlat_disasm_instruction( pc, buf, sizeof(buf), op );
77 fprintf( out, "%08X: %-20s %s\n", (unsigned int)pc, op, buf );
82 void xlat_disasm_init( xlat_symbol *symtab, int num_symbols )
84 init_disassemble_info( &xlat_disasm_info, NULL, xlat_disasm_output );
85 xlat_disasm_info.arch = bfd_arch_i386;
86 xlat_disasm_info.mach = HOST_SYNTAX;
87 xlat_disasm_info.endian = BFD_ENDIAN_LITTLE;
88 xlat_disasm_info.buffer = 0;
89 xlat_disasm_info.print_address_func = xlat_print_address;
91 xlat_num_symbols = num_symbols;
94 static const char *xlat_find_symbol( bfd_vma memaddr, struct disassemble_info *info )
97 for( i=0; i<xlat_num_symbols; i++ ) {
98 if( xlat_symtab[i].ptr == (void *)(uintptr_t)memaddr ) {
99 return xlat_symtab[i].name;
105 static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info )
107 const char *sym = xlat_find_symbol(memaddr, info);
108 info->fprintf_func( info->stream, "%08X", memaddr );
110 info->fprintf_func( info->stream, " <%s>", sym );
114 void xlat_print_symbolic_operand( char *buf, int hex, uintptr_t disp )
116 const char *sym = xlat_find_symbol(disp, NULL);
118 snprintf( buf, 50, "<%s>", sym );
120 sprintf( buf, "0x%lx", disp );
122 sprintf( buf, "%d", (int)disp );
126 uintptr_t xlat_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode )
130 xlat_disasm_info.stream = buf;
132 count = HOST_PRINT( pc, &xlat_disasm_info );
134 unsigned char tmp[count];
135 xlat_disasm_info.read_memory_func( pc, tmp, count, &xlat_disasm_info );
136 for( i=0; i<count; i++ ) {
137 sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );
145 static int xlat_disasm_output( void *data, const char *format, ... )
147 char *p = (char *)data;
151 va_start( ap, format );
152 n = vsprintf( p, format, ap );
.