filename | src/xlat/xlatdasm.c |
changeset | 1263:b3de98d19faf |
prev | 1094:d2324eb67223 |
next | 1264:74ad81710528 |
author | nkeynes |
date | Tue Mar 06 09:04:34 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Break host disassembly bits out of sh4x86.in, and move the generic disasm bits from x86dasm to xlat. |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/xlat/xlatdasm.c Tue Mar 06 09:04:34 2012 +10001.3 @@ -0,0 +1,155 @@1.4 +/**1.5 + * $Id$1.6 + *1.7 + * Wrapper around i386-dis to supply the same behaviour as the other1.8 + * disassembly functions.1.9 + *1.10 + * Copyright (c) 2005 Nathan Keynes.1.11 + *1.12 + * This program is free software; you can redistribute it and/or modify1.13 + * it under the terms of the GNU General Public License as published by1.14 + * the Free Software Foundation; either version 2 of the License, or1.15 + * (at your option) any later version.1.16 + *1.17 + * This program is distributed in the hope that it will be useful,1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.20 + * GNU General Public License for more details.1.21 + */1.22 +1.23 +#include <stdarg.h>1.24 +#include <string.h>1.25 +#include "xlat/xltcache.h"1.26 +#include "xlat/xlatdasm.h"1.27 +#include "x86dasm/bfd.h"1.28 +#include "x86dasm/dis-asm.h"1.29 +#include "sh4/sh4.h"1.30 +1.31 +#if defined(__i386__)1.32 +#define HOST_CPU_NAME "x86"1.33 +#define HOST_PRINT print_insn_i386_att1.34 +#define HOST_SYNTAX bfd_mach_i386_i386_intel_syntax1.35 +#elif defined(__x86_64__) || defined(__amd64__)1.36 +#define HOST_CPU_NAME "x86"1.37 +#define HOST_PRINT print_insn_i386_att1.38 +#define HOST_SYNTAX bfd_mach_x86_64_intel_syntax1.39 +#elif defined(__arm__)1.40 +#define HOST_CPU_NAME "arm"1.41 +#define HOST_PRINT print_insn_little_arm1.42 +#define HOST_SYNTAX bfd_mach_arm_unknown1.43 +#else1.44 +#error Unidentified host platform1.45 +#endif1.46 +1.47 +const struct cpu_desc_struct xlat_cpu_desc =1.48 + { HOST_CPU_NAME, (disasm_func_t)xlat_disasm_instruction, NULL, mem_has_page,1.49 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,1.50 + NULL, 0, NULL, 0, 0,1.51 + &sh4r.pc };1.52 +1.53 +static int xlat_disasm_output( void *data, const char *format, ... );1.54 +static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info );1.55 +1.56 +static struct disassemble_info xlat_disasm_info;1.57 +1.58 +static xlat_symbol *xlat_symtab;1.59 +static int xlat_num_symbols = 0;1.60 +1.61 +void xlat_dump_block( void *block )1.62 +{1.63 + xlat_disasm_block( stderr, block );1.64 +}1.65 +1.66 +void xlat_disasm_block( FILE *out, void *block )1.67 +{1.68 + uint32_t buflen = xlat_get_code_size(block);1.69 + xlat_disasm_region( out, block, buflen );1.70 +}1.71 +1.72 +void xlat_disasm_region(FILE *out, void *start, uint32_t len)1.73 +{1.74 + uintptr_t start_addr = (uintptr_t)start;1.75 + uintptr_t pc;1.76 + for( pc = start_addr; pc < start_addr + len; ) {1.77 + char buf[256];1.78 + char op[256];1.79 + uintptr_t pc2 = xlat_disasm_instruction( pc, buf, sizeof(buf), op );1.80 + fprintf( out, "%08X: %-20s %s\n", (unsigned int)pc, op, buf );1.81 + pc = pc2;1.82 + }1.83 +}1.84 +1.85 +void xlat_disasm_init( xlat_symbol *symtab, int num_symbols )1.86 +{1.87 + init_disassemble_info( &xlat_disasm_info, NULL, xlat_disasm_output );1.88 + xlat_disasm_info.arch = bfd_arch_i386;1.89 + xlat_disasm_info.mach = HOST_SYNTAX;1.90 + xlat_disasm_info.endian = BFD_ENDIAN_LITTLE;1.91 + xlat_disasm_info.buffer = 0;1.92 + xlat_disasm_info.print_address_func = xlat_print_address;1.93 + xlat_symtab = symtab;1.94 + xlat_num_symbols = num_symbols;1.95 +}1.96 +1.97 +static const char *xlat_find_symbol( bfd_vma memaddr, struct disassemble_info *info )1.98 +{1.99 + int i;1.100 + for( i=0; i<xlat_num_symbols; i++ ) {1.101 + if( xlat_symtab[i].ptr == (void *)(uintptr_t)memaddr ) {1.102 + return xlat_symtab[i].name;1.103 + }1.104 + }1.105 + return NULL;1.106 +}1.107 +1.108 +static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info )1.109 +{1.110 + const char *sym = xlat_find_symbol(memaddr, info);1.111 + info->fprintf_func( info->stream, "%08X", memaddr );1.112 + if( sym != NULL ) {1.113 + info->fprintf_func( info->stream, " <%s>", sym );1.114 + }1.115 +}1.116 +1.117 +void xlat_print_symbolic_operand( char *buf, int hex, uintptr_t disp )1.118 +{1.119 + const char *sym = xlat_find_symbol(disp, NULL);1.120 + if( sym != NULL ) {1.121 + snprintf( buf, 50, "<%s>", sym );1.122 + } else if( hex ) {1.123 + sprintf( buf, "0x%lx", disp );1.124 + } else {1.125 + sprintf( buf, "%d", (int)disp );1.126 + }1.127 +}1.128 +1.129 +uintptr_t xlat_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode )1.130 +{1.131 + int count, i;1.132 +1.133 + xlat_disasm_info.stream = buf;1.134 + buf[0] = 0;1.135 + count = HOST_PRINT( pc, &xlat_disasm_info );1.136 + if( count != 0 ) {1.137 + unsigned char tmp[count];1.138 + xlat_disasm_info.read_memory_func( pc, tmp, count, &xlat_disasm_info );1.139 + for( i=0; i<count; i++ ) {1.140 + sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );1.141 + opcode += 3;1.142 + }1.143 + *(opcode-1) = '\0';1.144 + }1.145 + return pc + count;1.146 +}1.147 +1.148 +static int xlat_disasm_output( void *data, const char *format, ... )1.149 +{1.150 + char *p = (char *)data;1.151 + va_list ap;1.152 + int n;1.153 + p += strlen(p);1.154 + va_start( ap, format );1.155 + n = vsprintf( p, format, ap );1.156 + va_end( ap );1.157 + return n;1.158 +}
.