Search
lxdream.org :: lxdream/src/xlat/xlatdasm.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/xlat/xlatdasm.c
changeset 1263:b3de98d19faf
prev1094:d2324eb67223
next1264:74ad81710528
author nkeynes
date Tue Mar 06 09:04:34 2012 +1000 (8 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 +0000
1.2 +++ b/src/xlat/xlatdasm.c Tue Mar 06 09:04:34 2012 +1000
1.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 other
1.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 modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.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 of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.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_att
1.34 +#define HOST_SYNTAX bfd_mach_i386_i386_intel_syntax
1.35 +#elif defined(__x86_64__) || defined(__amd64__)
1.36 +#define HOST_CPU_NAME "x86"
1.37 +#define HOST_PRINT print_insn_i386_att
1.38 +#define HOST_SYNTAX bfd_mach_x86_64_intel_syntax
1.39 +#elif defined(__arm__)
1.40 +#define HOST_CPU_NAME "arm"
1.41 +#define HOST_PRINT print_insn_little_arm
1.42 +#define HOST_SYNTAX bfd_mach_arm_unknown
1.43 +#else
1.44 +#error Unidentified host platform
1.45 +#endif
1.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 +}
.