mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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 changed files with 3340 additions and 63 deletions
6
Makefile
6
Makefile
|
@ -51,7 +51,7 @@ OBJS+= libqemu.a
|
|||
|
||||
LIBOBJS+=thunk.o translate-i386.o op-i386.o exec-i386.o
|
||||
# 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
|
||||
|
||||
|
@ -96,7 +96,7 @@ test speed: qemu
|
|||
make -C tests $@
|
||||
|
||||
TAGS:
|
||||
etags *.[ch] i386/*.[ch]
|
||||
etags *.[ch] tests/*.[ch]
|
||||
|
||||
# documentation
|
||||
qemu-doc.html: qemu-doc.texi
|
||||
|
@ -109,7 +109,7 @@ Makefile elf.h thunk.c\
|
|||
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\
|
||||
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 \
|
||||
tests/Makefile\
|
||||
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_v850 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
|
||||
/* 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 <assert.h>
|
||||
|
||||
#include "disas.h"
|
||||
|
||||
#define DEBUG_DISAS
|
||||
|
||||
#define IN_OP_I386
|
||||
#include "cpu-i386.h"
|
||||
|
||||
/* dump all code */
|
||||
#ifdef DEBUG_DISAS
|
||||
#include "dis-asm.h"
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
||||
#endif
|
||||
|
@ -3626,9 +3623,6 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
|
|||
uint16_t *gen_opc_end;
|
||||
int gen_code_size;
|
||||
long ret;
|
||||
#ifdef DEBUG_DISAS
|
||||
struct disassemble_info disasm_info;
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
|
||||
/* optimize flag computations */
|
||||
#ifdef DEBUG_DISAS
|
||||
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, "IN:\n");
|
||||
disasm_info.buffer = pc_start;
|
||||
disasm_info.buffer_vma = (unsigned long)pc_start;
|
||||
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, "IN: %s\n", lookup_symbol(pc_start));
|
||||
disas(logfile, pc_start, pc_ptr - pc_start,
|
||||
dc->code32 ? DISAS_I386_I386 : DISAS_I386_I8086);
|
||||
fprintf(logfile, "\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
|
||||
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);
|
||||
while (pc < gen_code_buf + *gen_code_size_ptr) {
|
||||
fprintf(logfile, "0x%08lx: ", (long)pc);
|
||||
count = print_insn_i386((unsigned long)pc, &disasm_info);
|
||||
fprintf(logfile, "\n");
|
||||
pc += count;
|
||||
}
|
||||
disas(logfile, gen_code_buf, *gen_code_size_ptr, DISAS_TARGET);
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue