Search
lxdream.org :: lxdream/src/x86dasm/x86dasm.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/x86dasm/x86dasm.c
changeset 365:94cab5ad0ed8
prev362:dc40e2064dc4
next376:8c7587af5a5d
author nkeynes
date Tue Sep 04 08:32:10 2007 +0000 (14 years ago)
permissions -rw-r--r--
last change Change sh4x86 test to translate/disasm full basic blocks
Add prelim sym-tab support
file annotate diff log raw
nkeynes@362
     1
/**
nkeynes@365
     2
 * $Id: x86dasm.c,v 1.2 2007-09-04 08:32:10 nkeynes Exp $
nkeynes@362
     3
 *
nkeynes@362
     4
 * Wrapper around i386-dis to supply the same behaviour as the other
nkeynes@362
     5
 * disassembly functions.
nkeynes@362
     6
 *
nkeynes@362
     7
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@362
     8
 *
nkeynes@362
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@362
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@362
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@362
    12
 * (at your option) any later version.
nkeynes@362
    13
 *
nkeynes@362
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@362
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@362
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@362
    17
 * GNU General Public License for more details.
nkeynes@362
    18
 */
nkeynes@362
    19
nkeynes@362
    20
#include <stdarg.h>
nkeynes@362
    21
#include "x86dasm.h"
nkeynes@362
    22
#include "bfd.h"
nkeynes@362
    23
#include "dis-asm.h"
nkeynes@362
    24
#include "sh4/sh4core.h"
nkeynes@362
    25
nkeynes@362
    26
extern const struct reg_desc_struct sh4_reg_map[];
nkeynes@362
    27
const struct cpu_desc_struct x86_cpu_desc = 
nkeynes@362
    28
    { "x86", x86_disasm_instruction, NULL, mem_has_page, 
nkeynes@362
    29
      NULL, NULL, NULL, 1, 
nkeynes@362
    30
      (char *)&sh4r, sizeof(sh4r), sh4_reg_map,
nkeynes@362
    31
      &sh4r.pc };
nkeynes@362
    32
nkeynes@362
    33
static int x86_disasm_output( void *data, const char *format, ... );
nkeynes@362
    34
static int x86_read_memory( bfd_vma memaddr, bfd_byte *buffer, unsigned int length,
nkeynes@362
    35
			    struct disassemble_info *info );
nkeynes@362
    36
static int x86_print_address( bfd_vma memaddr, struct disassemble_info *info );
nkeynes@362
    37
nkeynes@362
    38
static struct disassemble_info x86_disasm_info;
nkeynes@362
    39
nkeynes@365
    40
static x86_symbol *x86_symtab;
nkeynes@365
    41
static int x86_num_symbols = 0;   
nkeynes@365
    42
nkeynes@362
    43
void x86_disasm_init(char *buf, uint32_t vma, int buflen)
nkeynes@362
    44
{
nkeynes@362
    45
    init_disassemble_info( &x86_disasm_info, NULL, x86_disasm_output );
nkeynes@362
    46
    x86_disasm_info.arch = bfd_arch_i386;
nkeynes@362
    47
    x86_disasm_info.mach = bfd_mach_i386_i386_intel_syntax;
nkeynes@362
    48
    x86_disasm_info.endian = BFD_ENDIAN_LITTLE;
nkeynes@362
    49
    x86_disasm_info.buffer = buf;
nkeynes@362
    50
    x86_disasm_info.buffer_vma = vma;
nkeynes@362
    51
    x86_disasm_info.buffer_length = buflen;
nkeynes@365
    52
    x86_disasm_info.print_address_func = x86_print_address;
nkeynes@362
    53
}
nkeynes@362
    54
nkeynes@365
    55
void x86_set_symtab( x86_symbol *symtab, int num_symbols )
nkeynes@365
    56
{
nkeynes@365
    57
    x86_symtab = symtab;
nkeynes@365
    58
    x86_num_symbols = num_symbols;
nkeynes@365
    59
}
nkeynes@365
    60
nkeynes@365
    61
static const char *x86_find_symbol( bfd_vma memaddr, struct disassemble_info *info )
nkeynes@365
    62
{
nkeynes@365
    63
    int i;
nkeynes@365
    64
    for( i=0; i<x86_num_symbols; i++ ) {
nkeynes@365
    65
	if( x86_symtab[i].ptr == (void *)memaddr ) {
nkeynes@365
    66
	    return x86_symtab[i].name;
nkeynes@365
    67
	}
nkeynes@365
    68
    }
nkeynes@365
    69
    return NULL;
nkeynes@365
    70
}
nkeynes@365
    71
nkeynes@365
    72
static int x86_print_address( bfd_vma memaddr, struct disassemble_info *info )
nkeynes@365
    73
{
nkeynes@365
    74
    const char *sym = x86_find_symbol(memaddr, info);
nkeynes@365
    75
    info->fprintf_func( info->stream, "%08X", memaddr );
nkeynes@365
    76
    if( sym != NULL ) {
nkeynes@365
    77
	info->fprintf_func( info->stream, " <%s>", sym );
nkeynes@365
    78
    }
nkeynes@365
    79
    return 0;
nkeynes@365
    80
}
nkeynes@362
    81
nkeynes@362
    82
uint32_t x86_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
nkeynes@362
    83
{
nkeynes@362
    84
    int count, i;
nkeynes@362
    85
nkeynes@362
    86
    x86_disasm_info.stream = buf;
nkeynes@362
    87
    buf[0] = 0;
nkeynes@362
    88
    count = print_insn_i386_att( pc, &x86_disasm_info );
nkeynes@362
    89
    if( count != 0 ) {
nkeynes@362
    90
	char tmp[count];
nkeynes@362
    91
	x86_disasm_info.read_memory_func( pc, tmp, count, &x86_disasm_info );
nkeynes@362
    92
	for( i=0; i<count; i++ ) {
nkeynes@362
    93
	    sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );
nkeynes@362
    94
	    opcode += 3;
nkeynes@362
    95
	}
nkeynes@362
    96
	*(opcode-1) = '\0';
nkeynes@362
    97
    }
nkeynes@362
    98
    return pc + count;
nkeynes@362
    99
}
nkeynes@362
   100
nkeynes@362
   101
int x86_disasm_output( void *data, const char *format, ... )
nkeynes@362
   102
{
nkeynes@362
   103
    char *p = (char *)data;
nkeynes@362
   104
    va_list ap;
nkeynes@362
   105
    int n;
nkeynes@362
   106
    p += strlen(p);
nkeynes@362
   107
    va_start( ap, format );
nkeynes@362
   108
    n = vsprintf( p, format, ap );
nkeynes@362
   109
    va_end( ap );
nkeynes@362
   110
    return n;
nkeynes@362
   111
}
.