filename | src/x86dasm/x86dasm.c |
changeset | 515:5e5bb1dd369e |
prev | 480:d28c2992f5ee |
next | 527:14c9489f647e |
author | nkeynes |
date | Sat Nov 17 01:17:01 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Skip over the "undefined" instructions that actually pass on the SH4 - leaving in until we can determine if they actually do anything, or if they're effectively NOPs |
view | annotate | diff | log | raw |
1 /**
2 * $Id: x86dasm.c,v 1.5 2007-10-31 11:53:35 nkeynes Exp $
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.h"
23 #include "bfd.h"
24 #include "dis-asm.h"
25 #include "sh4/sh4core.h"
27 extern const struct reg_desc_struct sh4_reg_map[];
28 const struct cpu_desc_struct x86_cpu_desc =
29 { "x86", x86_disasm_instruction, NULL, mem_has_page,
30 NULL, NULL, NULL, 1,
31 (char *)&sh4r, sizeof(sh4r), sh4_reg_map,
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;
43 void xlat_disasm_block( FILE *out, void *block )
44 {
45 uint32_t buflen = xlat_get_block_size(block);
46 x86_set_symtab( NULL, 0 );
47 x86_disasm_block( out, block, buflen );
48 }
50 void x86_disasm_block(FILE *out, void *start, uint32_t len)
51 {
52 uint32_t start_addr = (uint32_t)start;
53 uint32_t pc;
54 x86_disasm_init( start, start_addr, len );
55 for( pc = start_addr; pc < start_addr + len; ) {
56 char buf[256];
57 char op[256];
58 uint32_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op );
59 fprintf( out, "%08X: %-20s %s\n", pc, op, buf );
60 pc = pc2;
61 }
62 }
64 void x86_disasm_init(unsigned char *buf, uint32_t vma, int buflen)
65 {
66 init_disassemble_info( &x86_disasm_info, NULL, x86_disasm_output );
67 x86_disasm_info.arch = bfd_arch_i386;
68 x86_disasm_info.mach = bfd_mach_i386_i386_intel_syntax;
69 x86_disasm_info.endian = BFD_ENDIAN_LITTLE;
70 x86_disasm_info.buffer = buf;
71 x86_disasm_info.buffer_vma = vma;
72 x86_disasm_info.buffer_length = buflen;
73 x86_disasm_info.print_address_func = x86_print_address;
74 }
76 void x86_set_symtab( x86_symbol *symtab, int num_symbols )
77 {
78 x86_symtab = symtab;
79 x86_num_symbols = num_symbols;
80 }
82 static const char *x86_find_symbol( bfd_vma memaddr, struct disassemble_info *info )
83 {
84 int i;
85 for( i=0; i<x86_num_symbols; i++ ) {
86 if( x86_symtab[i].ptr == (void *)(uint32_t)memaddr ) {
87 return x86_symtab[i].name;
88 }
89 }
90 return NULL;
91 }
93 static void x86_print_address( bfd_vma memaddr, struct disassemble_info *info )
94 {
95 const char *sym = x86_find_symbol(memaddr, info);
96 info->fprintf_func( info->stream, "%08X", memaddr );
97 if( sym != NULL ) {
98 info->fprintf_func( info->stream, " <%s>", sym );
99 }
100 }
102 uint32_t x86_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
103 {
104 int count, i;
106 x86_disasm_info.stream = buf;
107 buf[0] = 0;
108 count = print_insn_i386_att( pc, &x86_disasm_info );
109 if( count != 0 ) {
110 unsigned char tmp[count];
111 x86_disasm_info.read_memory_func( pc, tmp, count, &x86_disasm_info );
112 for( i=0; i<count; i++ ) {
113 sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );
114 opcode += 3;
115 }
116 *(opcode-1) = '\0';
117 }
118 return pc + count;
119 }
121 int x86_disasm_output( void *data, const char *format, ... )
122 {
123 char *p = (char *)data;
124 va_list ap;
125 int n;
126 p += strlen(p);
127 va_start( ap, format );
128 n = vsprintf( p, format, ap );
129 va_end( ap );
130 return n;
131 }
.