Search
lxdream.org :: lxdream/src/xlat/xlatdasm.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/xlat/xlatdasm.c
changeset 1264:74ad81710528
prev1263:b3de98d19faf
author nkeynes
date Fri May 29 18:47:05 2015 +1000 (6 years ago)
permissions -rw-r--r--
last change Fix test case
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 "xlat/xltcache.h"
    23 #include "xlat/xlatdasm.h"
    24 #include "xlat/disasm/bfd.h"
    25 #include "xlat/disasm/dis-asm.h"
    26 #include "sh4/sh4.h"
    28 #if defined(__i386__)
    29 #define HOST_CPU_NAME "x86"
    30 #define HOST_PRINT print_insn_i386_att
    31 #define HOST_SYNTAX bfd_mach_i386_i386_intel_syntax
    32 #elif defined(__x86_64__) || defined(__amd64__)
    33 #define HOST_CPU_NAME "x86"
    34 #define HOST_PRINT print_insn_i386_att
    35 #define HOST_SYNTAX bfd_mach_x86_64_intel_syntax
    36 #elif defined(__arm__)
    37 #define HOST_CPU_NAME "arm"
    38 #define HOST_PRINT print_insn_little_arm
    39 #define HOST_SYNTAX bfd_mach_arm_unknown
    40 #else
    41 #error Unidentified host platform
    42 #endif
    44 const struct cpu_desc_struct xlat_cpu_desc =
    45     { HOST_CPU_NAME, (disasm_func_t)xlat_disasm_instruction, NULL, mem_has_page,
    46       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 
    47       NULL, 0, NULL, 0, 0,  
    48       &sh4r.pc };
    50 static int xlat_disasm_output( void *data, const char *format, ... );
    51 static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info );
    53 static struct disassemble_info xlat_disasm_info;
    55 static xlat_symbol *xlat_symtab;
    56 static int xlat_num_symbols = 0;
    58 void xlat_dump_block( void *block )
    59 {
    60     xlat_disasm_block( stderr, block );
    61 }
    63 void xlat_disasm_block( FILE *out, void *block )
    64 {
    65     uint32_t buflen = xlat_get_code_size(block);
    66     xlat_disasm_region( out, block, buflen );
    67 }
    69 void xlat_disasm_region(FILE *out, void *start, uint32_t len)
    70 {
    71     uintptr_t start_addr = (uintptr_t)start;
    72     uintptr_t pc;
    73     for( pc = start_addr; pc < start_addr + len;  ) {
    74 	char buf[256];
    75 	char op[256];
    76 	uintptr_t pc2 = xlat_disasm_instruction( pc, buf, sizeof(buf), op );
    77 	fprintf( out, "%08X: %-20s %s\n", (unsigned int)pc, op, buf );
    78 	pc = pc2;
    79     }
    80 }
    82 void xlat_disasm_init( xlat_symbol *symtab, int num_symbols )
    83 {
    84     init_disassemble_info( &xlat_disasm_info, NULL, xlat_disasm_output );
    85     xlat_disasm_info.arch = bfd_arch_i386;
    86     xlat_disasm_info.mach = HOST_SYNTAX;
    87     xlat_disasm_info.endian = BFD_ENDIAN_LITTLE;
    88     xlat_disasm_info.buffer = 0;
    89     xlat_disasm_info.print_address_func = xlat_print_address;
    90     xlat_symtab = symtab;
    91     xlat_num_symbols = num_symbols;
    92 }
    94 static const char *xlat_find_symbol( bfd_vma memaddr, struct disassemble_info *info )
    95 {
    96     int i;
    97     for( i=0; i<xlat_num_symbols; i++ ) {
    98 	if( xlat_symtab[i].ptr == (void *)(uintptr_t)memaddr ) {
    99 	    return xlat_symtab[i].name;
   100 	}
   101     }
   102     return NULL;
   103 }
   105 static void xlat_print_address( bfd_vma memaddr, struct disassemble_info *info )
   106 {
   107     const char *sym = xlat_find_symbol(memaddr, info);
   108     info->fprintf_func( info->stream, "%08X", memaddr );
   109     if( sym != NULL ) {
   110 	info->fprintf_func( info->stream, " <%s>", sym );
   111     }
   112 }
   114 void xlat_print_symbolic_operand( char *buf, int hex, uintptr_t disp )
   115 {
   116     const char *sym = xlat_find_symbol(disp, NULL);
   117     if( sym != NULL ) {
   118         snprintf( buf, 50, "<%s>", sym );
   119     } else if( hex ) {
   120         sprintf( buf, "0x%lx", disp );
   121     } else {
   122         sprintf( buf, "%d", (int)disp );
   123     }
   124 }
   126 uintptr_t xlat_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode )
   127 {
   128     int count, i;
   130     xlat_disasm_info.stream = buf;
   131     buf[0] = 0;
   132     count = HOST_PRINT( pc, &xlat_disasm_info );
   133     if( count != 0 ) {
   134 	unsigned char tmp[count];
   135 	xlat_disasm_info.read_memory_func( pc, tmp, count, &xlat_disasm_info );
   136 	for( i=0; i<count; i++ ) {
   137 	    sprintf( opcode, "%02X ", ((unsigned int)tmp[i])&0xFF );
   138 	    opcode += 3;
   139 	}
   140 	*(opcode-1) = '\0';
   141     }
   142     return pc + count;
   143 }
   145 static int xlat_disasm_output( void *data, const char *format, ... )
   146 {
   147     char *p = (char *)data;
   148     va_list ap;
   149     int n;
   150     p += strlen(p);
   151     va_start( ap, format );
   152     n = vsprintf( p, format, ap );
   153     va_end( ap );
   154     return n;
   155 }
.