mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-07-25 04:34:23 +00:00
better debug support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@18 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
0ecfa9930c
commit
586314f2aa
38
Makefile
38
Makefile
|
@ -34,13 +34,10 @@ DEFINES+=-D_GNU_SOURCE
|
||||||
DEFINES+=-DCONFIG_PREFIX=\"/usr/local\"
|
DEFINES+=-DCONFIG_PREFIX=\"/usr/local\"
|
||||||
LDSCRIPT=$(ARCH).ld
|
LDSCRIPT=$(ARCH).ld
|
||||||
LIBS+=-ldl -lm
|
LIBS+=-ldl -lm
|
||||||
|
VERSION=0.1
|
||||||
|
|
||||||
#DEFINES+= -DGEMU -DDOSEMU -DNO_TRACE_MSGS
|
OBJS= elfload.o main.o thunk.o syscall.o
|
||||||
#OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
|
|
||||||
# i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
|
|
||||||
# i386/dis8086.o i386/emu-ldt.o
|
|
||||||
OBJS+=translate-i386.o op-i386.o
|
OBJS+=translate-i386.o op-i386.o
|
||||||
OBJS+= elfload.o main.o thunk.o syscall.o
|
|
||||||
# NOTE: the disassembler code is only needed for debugging
|
# NOTE: the disassembler code is only needed for debugging
|
||||||
OBJS+=i386-dis.o dis-buf.o
|
OBJS+=i386-dis.o dis-buf.o
|
||||||
SRCS = $(OBJS:.o=.c)
|
SRCS = $(OBJS:.o=.c)
|
||||||
|
@ -53,15 +50,6 @@ gemu: $(OBJS)
|
||||||
depend: $(SRCS)
|
depend: $(SRCS)
|
||||||
$(CC) -MM $(CFLAGS) $^ 1>.depend
|
$(CC) -MM $(CFLAGS) $^ 1>.depend
|
||||||
|
|
||||||
# old i386 emulator
|
|
||||||
i386/interp_32_32.o: i386/interp_32_32.c i386/interp_gen.h
|
|
||||||
|
|
||||||
i386/interp_gen.h: i386/gencode
|
|
||||||
./i386/gencode > $@
|
|
||||||
|
|
||||||
i386/gencode: i386/gencode.c
|
|
||||||
$(CC) -O2 -Wall -g $< -o $@
|
|
||||||
|
|
||||||
# new i386 emulator
|
# new i386 emulator
|
||||||
dyngen: dyngen.c
|
dyngen: dyngen.c
|
||||||
$(HOST_CC) -O2 -Wall -g $< -o $@
|
$(HOST_CC) -O2 -Wall -g $< -o $@
|
||||||
|
@ -78,7 +66,7 @@ op-i386.o: op-i386.c opreg_template.h ops_template.h
|
||||||
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *~ i386/*.o i386/*~ gemu TAGS
|
rm -f *.o *~ gemu dyngen TAGS
|
||||||
|
|
||||||
# various test targets
|
# various test targets
|
||||||
test speed: gemu
|
test speed: gemu
|
||||||
|
@ -87,6 +75,26 @@ test speed: gemu
|
||||||
TAGS:
|
TAGS:
|
||||||
etags *.[ch] i386/*.[ch]
|
etags *.[ch] i386/*.[ch]
|
||||||
|
|
||||||
|
FILES= \
|
||||||
|
COPYING.LIB dyngen.c ioctls.h ops_template.h syscall_types.h\
|
||||||
|
Makefile elf.h linux_bin.h segment.h thunk.c\
|
||||||
|
TODO elfload.c main.c signal.c thunk.h\
|
||||||
|
cpu-i386.h gemu.h op-i386.c syscall-i386.h translate-i386.c\
|
||||||
|
dis-asm.h gen-i386.h op-i386.h syscall.c\
|
||||||
|
dis-buf.c i386-dis.c opreg_template.h syscall_defs.h\
|
||||||
|
i386.ld ppc.ld\
|
||||||
|
tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
|
||||||
|
tests/test2.c tests/hello.c tests/sha1.c tests/test1.c
|
||||||
|
|
||||||
|
FILE=gemu-$(VERSION)
|
||||||
|
|
||||||
|
tar:
|
||||||
|
rm -rf /tmp/$(FILE)
|
||||||
|
mkdir -p /tmp/$(FILE)
|
||||||
|
cp -P $(FILES) /tmp/$(FILE)
|
||||||
|
( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) )
|
||||||
|
rm -rf /tmp/$(FILE)
|
||||||
|
|
||||||
ifneq ($(wildcard .depend),)
|
ifneq ($(wildcard .depend),)
|
||||||
include .depend
|
include .depend
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -27,6 +27,11 @@
|
||||||
|
|
||||||
#include "cpu-i386.h"
|
#include "cpu-i386.h"
|
||||||
|
|
||||||
|
#define DEBUG_LOGFILE "/tmp/gemu.log"
|
||||||
|
|
||||||
|
FILE *logfile = NULL;
|
||||||
|
int loglevel;
|
||||||
|
|
||||||
unsigned long x86_stack_size;
|
unsigned long x86_stack_size;
|
||||||
unsigned long stktop;
|
unsigned long stktop;
|
||||||
|
|
||||||
|
@ -83,7 +88,7 @@ int cpu_x86_inl(int addr)
|
||||||
void usage(void)
|
void usage(void)
|
||||||
{
|
{
|
||||||
printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
|
printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
|
||||||
"usage: gemu program [arguments...]\n"
|
"usage: gemu [-d] program [arguments...]\n"
|
||||||
"Linux x86 emulator\n"
|
"Linux x86 emulator\n"
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -95,11 +100,27 @@ int main(int argc, char **argv)
|
||||||
struct target_pt_regs regs1, *regs = ®s1;
|
struct target_pt_regs regs1, *regs = ®s1;
|
||||||
struct image_info info1, *info = &info1;
|
struct image_info info1, *info = &info1;
|
||||||
CPUX86State *env;
|
CPUX86State *env;
|
||||||
|
int optind;
|
||||||
|
|
||||||
if (argc <= 1)
|
if (argc <= 1)
|
||||||
usage();
|
usage();
|
||||||
|
loglevel = 0;
|
||||||
filename = argv[1];
|
optind = 1;
|
||||||
|
if (argv[optind] && !strcmp(argv[optind], "-d")) {
|
||||||
|
loglevel = 1;
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
filename = argv[optind];
|
||||||
|
|
||||||
|
/* init debug */
|
||||||
|
if (loglevel) {
|
||||||
|
logfile = fopen(DEBUG_LOGFILE, "w");
|
||||||
|
if (!logfile) {
|
||||||
|
perror(DEBUG_LOGFILE);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
setvbuf(logfile, NULL, _IOLBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Zero out regs */
|
/* Zero out regs */
|
||||||
memset(regs, 0, sizeof(struct target_pt_regs));
|
memset(regs, 0, sizeof(struct target_pt_regs));
|
||||||
|
|
44
op-i386.c
44
op-i386.c
|
@ -1,3 +1,5 @@
|
||||||
|
#define DEBUG_EXEC
|
||||||
|
|
||||||
typedef unsigned char uint8_t;
|
typedef unsigned char uint8_t;
|
||||||
typedef unsigned short uint16_t;
|
typedef unsigned short uint16_t;
|
||||||
typedef unsigned int uint32_t;
|
typedef unsigned int uint32_t;
|
||||||
|
@ -10,6 +12,11 @@ typedef signed long long int64_t;
|
||||||
|
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
|
|
||||||
|
typedef struct FILE FILE;
|
||||||
|
extern FILE *logfile;
|
||||||
|
extern int loglevel;
|
||||||
|
extern int fprintf(FILE *, const char *, ...);
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
register int T0 asm("esi");
|
register int T0 asm("esi");
|
||||||
register int T1 asm("ebx");
|
register int T1 asm("ebx");
|
||||||
|
@ -1636,6 +1643,32 @@ void OPPROTO op_fcos(void)
|
||||||
/* main execution loop */
|
/* main execution loop */
|
||||||
uint8_t code_gen_buffer[65536];
|
uint8_t code_gen_buffer[65536];
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXEC
|
||||||
|
static const char *cc_op_str[] = {
|
||||||
|
"DYNAMIC",
|
||||||
|
"EFLAGS",
|
||||||
|
"MUL",
|
||||||
|
"ADDB",
|
||||||
|
"ADDW",
|
||||||
|
"ADDL",
|
||||||
|
"SUBB",
|
||||||
|
"SUBW",
|
||||||
|
"SUBL",
|
||||||
|
"LOGICB",
|
||||||
|
"LOGICW",
|
||||||
|
"LOGICL",
|
||||||
|
"INCB",
|
||||||
|
"INCW",
|
||||||
|
"INCL",
|
||||||
|
"DECB",
|
||||||
|
"DECW",
|
||||||
|
"DECL",
|
||||||
|
"SHLB",
|
||||||
|
"SHLW",
|
||||||
|
"SHLL",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
int cpu_x86_exec(CPUX86State *env1)
|
int cpu_x86_exec(CPUX86State *env1)
|
||||||
{
|
{
|
||||||
int saved_T0, saved_T1, saved_A0;
|
int saved_T0, saved_T1, saved_A0;
|
||||||
|
@ -1653,6 +1686,17 @@ int cpu_x86_exec(CPUX86State *env1)
|
||||||
/* prepare setjmp context for exception handling */
|
/* prepare setjmp context for exception handling */
|
||||||
if (setjmp(env->jmp_env) == 0) {
|
if (setjmp(env->jmp_env) == 0) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
#ifdef DEBUG_EXEC
|
||||||
|
if (loglevel) {
|
||||||
|
fprintf(logfile,
|
||||||
|
"EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
|
||||||
|
"ESI=%08x ESI=%08X EBP=%08x ESP=%08x\n"
|
||||||
|
"CCS=%08x CCD=%08x CCOP=%s\n",
|
||||||
|
env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],
|
||||||
|
env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],
|
||||||
|
env->cc_src, env->cc_dst, cc_op_str[env->cc_op]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc);
|
cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc);
|
||||||
/* execute the generated code */
|
/* execute the generated code */
|
||||||
gen_func = (void *)code_gen_buffer;
|
gen_func = (void *)code_gen_buffer;
|
||||||
|
|
|
@ -5,23 +5,21 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* dump all code */
|
|
||||||
#define DEBUG_DISAS
|
#define DEBUG_DISAS
|
||||||
#define DEBUG_LOGFILE "/tmp/gemu.log"
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISAS
|
|
||||||
#include "dis-asm.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
static uint8_t *gen_code_ptr;
|
static uint8_t *gen_code_ptr;
|
||||||
int __op_param1, __op_param2, __op_param3;
|
int __op_param1, __op_param2, __op_param3;
|
||||||
|
|
||||||
#ifdef DEBUG_DISAS
|
extern FILE *logfile;
|
||||||
static FILE *logfile = NULL;
|
extern int loglevel;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* supress that */
|
/* supress that */
|
||||||
static void error(const char *fmt, ...)
|
static void error(const char *fmt, ...)
|
||||||
|
@ -716,9 +714,6 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
|
||||||
int reg1, reg2, opreg;
|
int reg1, reg2, opreg;
|
||||||
int mod, rm, code;
|
int mod, rm, code;
|
||||||
|
|
||||||
#ifdef DEBUG_DISAS
|
|
||||||
fprintf(logfile, "modrm=0x%x\n", modrm);
|
|
||||||
#endif
|
|
||||||
mod = (modrm >> 6) & 3;
|
mod = (modrm >> 6) & 3;
|
||||||
rm = modrm & 7;
|
rm = modrm & 7;
|
||||||
|
|
||||||
|
@ -731,9 +726,6 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
|
||||||
if (base == 4) {
|
if (base == 4) {
|
||||||
havesib = 1;
|
havesib = 1;
|
||||||
code = ldub(s->pc++);
|
code = ldub(s->pc++);
|
||||||
#ifdef DEBUG_DISAS
|
|
||||||
fprintf(logfile, "sib=0x%x\n", code);
|
|
||||||
#endif
|
|
||||||
scale = (code >> 6) & 3;
|
scale = (code >> 6) & 3;
|
||||||
index = (code >> 3) & 7;
|
index = (code >> 3) & 7;
|
||||||
base = code & 7;
|
base = code & 7;
|
||||||
|
@ -988,11 +980,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
|
||||||
// cur_pc = s->pc; /* for insn generation */
|
// cur_pc = s->pc; /* for insn generation */
|
||||||
next_byte:
|
next_byte:
|
||||||
b = ldub(s->pc);
|
b = ldub(s->pc);
|
||||||
#ifdef DEBUG_DISAS
|
|
||||||
fprintf(logfile, "ib=0x%02x\n", b);
|
|
||||||
#endif
|
|
||||||
if (b < 0)
|
|
||||||
return -1;
|
|
||||||
s->pc++;
|
s->pc++;
|
||||||
/* check prefixes */
|
/* check prefixes */
|
||||||
switch (b) {
|
switch (b) {
|
||||||
|
@ -2247,33 +2234,26 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
|
||||||
gen_start();
|
gen_start();
|
||||||
|
|
||||||
#ifdef DEBUG_DISAS
|
#ifdef DEBUG_DISAS
|
||||||
if (!logfile) {
|
if (loglevel) {
|
||||||
logfile = fopen(DEBUG_LOGFILE, "w");
|
INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
|
||||||
if (!logfile) {
|
disasm_info.buffer = pc_start;
|
||||||
perror(DEBUG_LOGFILE);
|
disasm_info.buffer_vma = (unsigned long)pc_start;
|
||||||
exit(1);
|
disasm_info.buffer_length = 15;
|
||||||
}
|
|
||||||
setvbuf(logfile, NULL, _IOLBF, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
|
|
||||||
disasm_info.buffer = pc_start;
|
|
||||||
disasm_info.buffer_vma = (unsigned long)pc_start;
|
|
||||||
disasm_info.buffer_length = 15;
|
|
||||||
#if 0
|
#if 0
|
||||||
disasm_info.flavour = bfd_get_flavour (abfd);
|
disasm_info.flavour = bfd_get_flavour (abfd);
|
||||||
disasm_info.arch = bfd_get_arch (abfd);
|
disasm_info.arch = bfd_get_arch (abfd);
|
||||||
disasm_info.mach = bfd_get_mach (abfd);
|
disasm_info.mach = bfd_get_mach (abfd);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
disasm_info.endian = BFD_ENDIAN_BIG;
|
disasm_info.endian = BFD_ENDIAN_BIG;
|
||||||
#else
|
#else
|
||||||
disasm_info.endian = BFD_ENDIAN_LITTLE;
|
disasm_info.endian = BFD_ENDIAN_LITTLE;
|
||||||
#endif
|
#endif
|
||||||
fprintf(logfile, "IN:\n");
|
fprintf(logfile, "IN:\n");
|
||||||
fprintf(logfile, "0x%08lx: ", (long)pc_start);
|
fprintf(logfile, "0x%08lx: ", (long)pc_start);
|
||||||
print_insn_i386((unsigned long)pc_start, &disasm_info);
|
print_insn_i386((unsigned long)pc_start, &disasm_info);
|
||||||
fprintf(logfile, "\n\n");
|
fprintf(logfile, "\n\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
is_jmp = 0;
|
is_jmp = 0;
|
||||||
ret = disas_insn(dc, pc_start, &is_jmp);
|
ret = disas_insn(dc, pc_start, &is_jmp);
|
||||||
|
@ -2290,7 +2270,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
|
||||||
*gen_code_size_ptr = gen_code_ptr - gen_code_buf;
|
*gen_code_size_ptr = gen_code_ptr - gen_code_buf;
|
||||||
|
|
||||||
#ifdef DEBUG_DISAS
|
#ifdef DEBUG_DISAS
|
||||||
{
|
if (loglevel) {
|
||||||
uint8_t *pc;
|
uint8_t *pc;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue