Search
lxdream.org :: lxdream/src/x86dasm/x86dasm.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/x86dasm/x86dasm.c
changeset 1091:186558374345
prev1087:d54c499b48c7
next1092: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 }
.