PowerPC disas code
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@107 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									ae48a07313
								
							
						
					
					
						commit
						b9adb4a6bc
					
				
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@ -51,7 +51,7 @@ OBJS+= libqemu.a
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
LIBOBJS+=thunk.o translate-i386.o op-i386.o exec-i386.o
 | 
					LIBOBJS+=thunk.o translate-i386.o op-i386.o exec-i386.o
 | 
				
			||||||
# NOTE: the disassembler code is only needed for debugging
 | 
					# NOTE: the disassembler code is only needed for debugging
 | 
				
			||||||
LIBOBJS+=i386-dis.o dis-buf.o
 | 
					LIBOBJS+=disas.o ppc-dis.o i386-dis.o dis-buf.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: qemu qemu-doc.html
 | 
					all: qemu qemu-doc.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -96,7 +96,7 @@ test speed: qemu
 | 
				
			|||||||
	make -C tests $@
 | 
						make -C tests $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TAGS: 
 | 
					TAGS: 
 | 
				
			||||||
	etags *.[ch] i386/*.[ch]
 | 
						etags *.[ch] tests/*.[ch]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# documentation
 | 
					# documentation
 | 
				
			||||||
qemu-doc.html: qemu-doc.texi
 | 
					qemu-doc.html: qemu-doc.texi
 | 
				
			||||||
@ -109,7 +109,7 @@ Makefile     elf.h       thunk.c\
 | 
				
			|||||||
elfload.c   main.c            signal.c        thunk.h\
 | 
					elfload.c   main.c            signal.c        thunk.h\
 | 
				
			||||||
cpu-i386.h qemu.h op-i386.c opc-i386.h syscall-i386.h  translate-i386.c\
 | 
					cpu-i386.h qemu.h op-i386.c opc-i386.h syscall-i386.h  translate-i386.c\
 | 
				
			||||||
dis-asm.h    gen-i386.h  syscall.c\
 | 
					dis-asm.h    gen-i386.h  syscall.c\
 | 
				
			||||||
dis-buf.c    i386-dis.c  opreg_template.h  syscall_defs.h\
 | 
					dis-buf.c disas.c disas.h ppc-dis.c i386-dis.c  opreg_template.h  syscall_defs.h\
 | 
				
			||||||
ppc.ld s390.ld exec-i386.h exec-i386.c path.c configure \
 | 
					ppc.ld s390.ld exec-i386.h exec-i386.c path.c configure \
 | 
				
			||||||
tests/Makefile\
 | 
					tests/Makefile\
 | 
				
			||||||
tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
 | 
					tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
 | 
				
			||||||
 | 
				
			|||||||
@ -320,6 +320,7 @@ extern int print_insn_w65		PARAMS ((bfd_vma, disassemble_info*));
 | 
				
			|||||||
extern int print_insn_d10v		PARAMS ((bfd_vma, disassemble_info*));
 | 
					extern int print_insn_d10v		PARAMS ((bfd_vma, disassemble_info*));
 | 
				
			||||||
extern int print_insn_v850		PARAMS ((bfd_vma, disassemble_info*));
 | 
					extern int print_insn_v850		PARAMS ((bfd_vma, disassemble_info*));
 | 
				
			||||||
extern int print_insn_tic30		PARAMS ((bfd_vma, disassemble_info*));
 | 
					extern int print_insn_tic30		PARAMS ((bfd_vma, disassemble_info*));
 | 
				
			||||||
 | 
					extern int print_insn_ppc		PARAMS ((bfd_vma, disassemble_info*));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
/* Fetch the disassembler for a given BFD, if that support is available.  */
 | 
					/* Fetch the disassembler for a given BFD, if that support is available.  */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										79
									
								
								disas.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								disas.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					/* General "disassemble this chunk" code.  Used for debugging. */
 | 
				
			||||||
 | 
					#include "dis-asm.h"
 | 
				
			||||||
 | 
					#include "disas.h"
 | 
				
			||||||
 | 
					#include "elf.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Filled in by elfload.c.  Simplistic, but will do for now. */
 | 
				
			||||||
 | 
					unsigned int disas_num_syms;
 | 
				
			||||||
 | 
					void *disas_symtab;
 | 
				
			||||||
 | 
					const char *disas_strtab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Disassemble this for me please... (debugging). */
 | 
				
			||||||
 | 
					void disas(FILE *out, void *code, unsigned long size, enum disas_type type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t *pc;
 | 
				
			||||||
 | 
					    int count;
 | 
				
			||||||
 | 
					    struct disassemble_info disasm_info;
 | 
				
			||||||
 | 
					    int (*print_insn)(bfd_vma pc, disassemble_info *info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    disasm_info.buffer = code;
 | 
				
			||||||
 | 
					    disasm_info.buffer_vma = (unsigned long)code;
 | 
				
			||||||
 | 
					    disasm_info.buffer_length = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type == DISAS_TARGET) {
 | 
				
			||||||
 | 
					#ifdef WORDS_BIGENDIAN
 | 
				
			||||||
 | 
						disasm_info.endian = BFD_ENDIAN_BIG;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						disasm_info.endian = BFD_ENDIAN_LITTLE;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef __i386__
 | 
				
			||||||
 | 
						disasm_info.mach = bfd_mach_i386_i386;
 | 
				
			||||||
 | 
						print_insn = print_insn_i386;
 | 
				
			||||||
 | 
					#elif defined(__powerpc__)
 | 
				
			||||||
 | 
						print_insn = print_insn_ppc;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						fprintf(out, "Asm output not supported on this arch\n");
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
						/* Currently only source supported in x86. */
 | 
				
			||||||
 | 
						disasm_info.endian = BFD_ENDIAN_LITTLE;
 | 
				
			||||||
 | 
						if (type == DISAS_I386_I386)
 | 
				
			||||||
 | 
						    disasm_info.mach = bfd_mach_i386_i386;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    disasm_info.mach = bfd_mach_i386_i8086;
 | 
				
			||||||
 | 
						print_insn = print_insn_i386;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (pc = code; pc < (uint8_t *)code + size; pc += count) {
 | 
				
			||||||
 | 
						fprintf(out, "0x%08lx:  ", (long)pc);
 | 
				
			||||||
 | 
						count = print_insn((long)pc, &disasm_info);
 | 
				
			||||||
 | 
						fprintf(out, "\n");
 | 
				
			||||||
 | 
						if (count < 0)
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Look up symbol for debugging purpose.  Returns "" if unknown. */
 | 
				
			||||||
 | 
					const char *lookup_symbol(void *orig_addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					    /* Hack, because we know this is x86. */
 | 
				
			||||||
 | 
					    Elf32_Sym *sym = disas_symtab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < disas_num_syms; i++) {
 | 
				
			||||||
 | 
						if (sym[i].st_shndx == SHN_UNDEF
 | 
				
			||||||
 | 
						    || sym[i].st_shndx >= SHN_LORESERVE)
 | 
				
			||||||
 | 
						    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
 | 
				
			||||||
 | 
						    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((long)orig_addr >= sym[i].st_value
 | 
				
			||||||
 | 
						    && (long)orig_addr < sym[i].st_value + sym[i].st_size)
 | 
				
			||||||
 | 
						    return disas_strtab + sym[i].st_name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								disas.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								disas.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					#ifndef _QEMU_DISAS_H
 | 
				
			||||||
 | 
					#define _QEMU_DISAS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum disas_type {
 | 
				
			||||||
 | 
					    DISAS_I386_I386,
 | 
				
			||||||
 | 
					    DISAS_I386_I8086,
 | 
				
			||||||
 | 
					    DISAS_TARGET, /* whatever host is. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Disassemble this for me please... (debugging). */
 | 
				
			||||||
 | 
					void disas(FILE *out, void *code, unsigned long size, enum disas_type type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Look up symbol for debugging purpose.  Returns "" if unknown. */
 | 
				
			||||||
 | 
					const char *lookup_symbol(void *orig_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Filled in by elfload.c.  Simplistic, but will do for now. */
 | 
				
			||||||
 | 
					extern unsigned int disas_num_syms;
 | 
				
			||||||
 | 
					extern void *disas_symtab;  /* FIXME: includes are a mess --RR */
 | 
				
			||||||
 | 
					extern const char *disas_strtab;
 | 
				
			||||||
 | 
					#endif /* _QEMU_DISAS_H */
 | 
				
			||||||
@ -25,16 +25,13 @@
 | 
				
			|||||||
#include <signal.h>
 | 
					#include <signal.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "disas.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEBUG_DISAS
 | 
					#define DEBUG_DISAS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IN_OP_I386
 | 
					#define IN_OP_I386
 | 
				
			||||||
#include "cpu-i386.h"
 | 
					#include "cpu-i386.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* dump all code */
 | 
					 | 
				
			||||||
#ifdef DEBUG_DISAS
 | 
					 | 
				
			||||||
#include "dis-asm.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef offsetof
 | 
					#ifndef offsetof
 | 
				
			||||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
 | 
					#define offsetof(type, field) ((size_t) &((type *)0)->field)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -3626,9 +3623,6 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
 | 
				
			|||||||
    uint16_t *gen_opc_end;
 | 
					    uint16_t *gen_opc_end;
 | 
				
			||||||
    int gen_code_size;
 | 
					    int gen_code_size;
 | 
				
			||||||
    long ret;
 | 
					    long ret;
 | 
				
			||||||
#ifdef DEBUG_DISAS
 | 
					 | 
				
			||||||
    struct disassemble_info disasm_info;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* generate intermediate code */
 | 
					    /* generate intermediate code */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3668,35 +3662,12 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    *gen_opc_ptr = INDEX_op_end;
 | 
					    *gen_opc_ptr = INDEX_op_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* optimize flag computations */
 | 
					 | 
				
			||||||
#ifdef DEBUG_DISAS
 | 
					#ifdef DEBUG_DISAS
 | 
				
			||||||
    if (loglevel) {
 | 
					    if (loglevel) {
 | 
				
			||||||
        uint8_t *pc;
 | 
					 | 
				
			||||||
        int count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
 | 
					 | 
				
			||||||
#if 0        
 | 
					 | 
				
			||||||
        disasm_info.flavour = bfd_get_flavour (abfd);
 | 
					 | 
				
			||||||
        disasm_info.arch = bfd_get_arch (abfd);
 | 
					 | 
				
			||||||
        disasm_info.mach = bfd_get_mach (abfd);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        disasm_info.endian = BFD_ENDIAN_LITTLE;
 | 
					 | 
				
			||||||
        if (dc->code32)
 | 
					 | 
				
			||||||
            disasm_info.mach = bfd_mach_i386_i386;
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            disasm_info.mach = bfd_mach_i386_i8086;
 | 
					 | 
				
			||||||
        fprintf(logfile, "----------------\n");
 | 
					        fprintf(logfile, "----------------\n");
 | 
				
			||||||
        fprintf(logfile, "IN:\n");
 | 
					        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
 | 
				
			||||||
        disasm_info.buffer = pc_start;
 | 
						disas(logfile, pc_start, pc_ptr - pc_start,
 | 
				
			||||||
        disasm_info.buffer_vma = (unsigned long)pc_start;
 | 
						      dc->code32 ? DISAS_I386_I386 : DISAS_I386_I8086);
 | 
				
			||||||
        disasm_info.buffer_length = pc_ptr - pc_start;
 | 
					 | 
				
			||||||
        pc = pc_start;
 | 
					 | 
				
			||||||
        while (pc < pc_ptr) {
 | 
					 | 
				
			||||||
            fprintf(logfile, "0x%08lx:  ", (long)pc);
 | 
					 | 
				
			||||||
            count = print_insn_i386((unsigned long)pc, &disasm_info);
 | 
					 | 
				
			||||||
            fprintf(logfile, "\n");
 | 
					 | 
				
			||||||
            pc += count;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        fprintf(logfile, "\n");
 | 
					        fprintf(logfile, "\n");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        fprintf(logfile, "OP:\n");
 | 
					        fprintf(logfile, "OP:\n");
 | 
				
			||||||
@ -3723,33 +3694,8 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG_DISAS
 | 
					#ifdef DEBUG_DISAS
 | 
				
			||||||
    if (loglevel) {
 | 
					    if (loglevel) {
 | 
				
			||||||
        uint8_t *pc;
 | 
					 | 
				
			||||||
        int count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
 | 
					 | 
				
			||||||
#if 0        
 | 
					 | 
				
			||||||
        disasm_info.flavour = bfd_get_flavour (abfd);
 | 
					 | 
				
			||||||
        disasm_info.arch = bfd_get_arch (abfd);
 | 
					 | 
				
			||||||
        disasm_info.mach = bfd_get_mach (abfd);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef WORDS_BIGENDIAN
 | 
					 | 
				
			||||||
        disasm_info.endian = BFD_ENDIAN_BIG;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        disasm_info.endian = BFD_ENDIAN_LITTLE;
 | 
					 | 
				
			||||||
#endif        
 | 
					 | 
				
			||||||
        disasm_info.mach = bfd_mach_i386_i386;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pc = gen_code_buf;
 | 
					 | 
				
			||||||
        disasm_info.buffer = pc;
 | 
					 | 
				
			||||||
        disasm_info.buffer_vma = (unsigned long)pc;
 | 
					 | 
				
			||||||
        disasm_info.buffer_length = *gen_code_size_ptr;
 | 
					 | 
				
			||||||
        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
 | 
					        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
 | 
				
			||||||
        while (pc < gen_code_buf + *gen_code_size_ptr) {
 | 
						disas(logfile, gen_code_buf, *gen_code_size_ptr, DISAS_TARGET);
 | 
				
			||||||
            fprintf(logfile, "0x%08lx:  ", (long)pc);
 | 
					 | 
				
			||||||
            count = print_insn_i386((unsigned long)pc, &disasm_info);
 | 
					 | 
				
			||||||
            fprintf(logfile, "\n");
 | 
					 | 
				
			||||||
            pc += count;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        fprintf(logfile, "\n");
 | 
					        fprintf(logfile, "\n");
 | 
				
			||||||
        fflush(logfile);
 | 
					        fflush(logfile);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user