filename | src/x86dasm/x86dasm.c |
changeset | 1091:186558374345 |
prev | 1087:d54c499b48c7 |
next | 1092:7c4ffe27e7b5 |
author | nkeynes |
date | Tue Dec 15 08:46:37 2009 +1000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Add side-by-side x86+sh4 disassembly output Print SH4 state information and disassembly of the current block when crashing. Fix delay slot instruction in conditional branch not being marked as a delay-slot instruction in the branch-not-taken path. Rename REG_* defines in cpu.h to avoid conflict with translation defs |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * Wrapper around i386-dis to supply the same behaviour as the other
5 * disassembly functions.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
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.
13 *
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.
18 */
20 #include <stdarg.h>
21 #include <string.h>
22 #include "x86dasm/x86dasm.h"
23 #include "x86dasm/bfd.h"
24 #include "x86dasm/dis-asm.h"
25 #include "sh4/sh4.h"
26 #include "sh4/sh4trans.h"
28 const struct cpu_desc_struct x86_cpu_desc =
29 { "x86", (disasm_func_t)x86_disasm_instruction, NULL, mem_has_page,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,
31 NULL, 0, NULL, 0, 0,
32 &sh4r.pc };
34 static int x86_disasm_output( void *data, const char *format, ... );
35 static void x86_print_address( bfd_vma memaddr, struct disassemble_info *info );
37 static struct disassemble_info x86_disasm_info;
39 static x86_symbol *x86_symtab;
40 static int x86_num_symbols = 0;
42 void xlat_dump_block( void *block )
43 {
44 xlat_disasm_block( stderr, block );
45 }
47 void xlat_disasm_block( FILE *out, void *block )
48 {
49 uint32_t buflen = xlat_get_code_size(block);
50 x86_set_symtab( NULL, 0 );
51 x86_disasm_block( out, block, buflen );
52 }
54 void x86_disasm_block(FILE *out, void *start, uint32_t len)
55 {
56 uintptr_t start_addr = (uintptr_t)start;
57 uintptr_t pc;
58 x86_disasm_init( start, start_addr, len );
59 for( pc = start_addr; pc < start_addr + len; ) {
60 char buf[256];
61 char op[256];
62 uintptr_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op );
63 fprintf( out, "%08X: %-20s %s\n", (unsigned int)pc, op, buf );
64 pc = pc2;
65 }
66 }
68 void x86_disasm_init()
69 {
70 init_disassemble_info( &x86_disasm_info, NULL, x86_disasm_output );
71 x86_disasm_info.arch = bfd_arch_i386;
72 #if SIZEOF_VOID_P == 8
73 x86_disasm_info.mach = bfd_mach_x86_64_intel_syntax;
74 #else
75 x86_disasm_info.mach = bfd_mach_i386_i386_intel_syntax;
76 #endif
77 x86_disasm_info.endian = BFD_ENDIAN_LITTLE;
78 x86_disasm_info.buffer = 0;
79 x86_disasm_info.buffer_vma = 0;
80 x86_disasm_info.buffer_length = -1;
81 x86_disasm_info.print_address_func = x86_print_address;
82 }
84 void x86_set_symtab( x86_symbol *symtab, int num_symbols )
85 {
86 x86_symtab = symtab;
87 x86_num_symbols = num_symbols;
88 }
90 static const char *x86_find_symbol( bfd_vma memaddr, struct disassemble_info *info )
91 {
92 int i;
93 for( i=0; i<x86_num_symbols; i++ ) {
94 if( x86_symtab[i].ptr == (void *)(uintptr_t)memaddr ) {
95 return x86_symtab[i].name;
96 }
97 }
98 return NULL;
99 }
101 static void x86_print_address( bfd_vma memaddr, struct disassemble_info *info )
102 {
103 const char *sym = x86_find_symbol(memaddr, info);
104 info->fprintf_func( info->stream, "%08X", memaddr );
105 if( sym != NULL ) {
106 info->fprintf_func( info->stream, " <%s>", sym );
107 }
108 }
110 void x86_print_symbolic_operand( char *buf, int hex, unsigned int disp )
111 {
112 const char *sym = x86_find_symbol(disp, NULL);
113 if( sym != NULL ) {
114 snprintf( buf, 50, "<%s>", sym );
115 } else if( hex ) {
116 sprintf( buf, "0x%x", disp );
117 } else {
118 sprintf( buf, "%d", (int)disp );
119 }
120 }
122 uintptr_t x86_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode )
123 {
124 int count, i;
126 x86_disasm_info.stream = buf;
127 buf[0] = 0;
128 count = print_insn_i386_att( pc, &x86_disasm_info );
129 if( count != 0 ) {
130 unsigned char tmp[count];
131 x86_disasm_info.read_memory_func( pc, tmp, count, &x86_disasm_info );
132 for( i=0; i<count; i++ ) {
133 sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );
134 opcode += 3;
135 }
136 *(opcode-1) = '\0';
137 }
138 return pc + count;
139 }
141 int x86_disasm_output( void *data, const char *format, ... )
142 {
143 char *p = (char *)data;
144 va_list ap;
145 int n;
146 p += strlen(p);
147 va_start( ap, format );
148 n = vsprintf( p, format, ap );
149 va_end( ap );
150 return n;
151 }
.