From 586314f2aa62990dead8144e780c4c8c498eece6 Mon Sep 17 00:00:00 2001 From: bellard Date: Mon, 3 Mar 2003 15:02:29 +0000 Subject: [PATCH] better debug support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@18 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile | 38 ++++++++++++++++----------- linux-user/main.c | 27 ++++++++++++++++--- op-i386.c | 44 +++++++++++++++++++++++++++++++ translate-i386.c | 66 +++++++++++++++++------------------------------ 4 files changed, 114 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index b007f40dde..066f30cbe5 100644 --- a/Makefile +++ b/Makefile @@ -34,13 +34,10 @@ DEFINES+=-D_GNU_SOURCE DEFINES+=-DCONFIG_PREFIX=\"/usr/local\" LDSCRIPT=$(ARCH).ld LIBS+=-ldl -lm +VERSION=0.1 -#DEFINES+= -DGEMU -DDOSEMU -DNO_TRACE_MSGS -#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= elfload.o main.o thunk.o syscall.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 OBJS+=i386-dis.o dis-buf.o SRCS = $(OBJS:.o=.c) @@ -53,15 +50,6 @@ gemu: $(OBJS) depend: $(SRCS) $(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 dyngen: dyngen.c $(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 $@ $< clean: - rm -f *.o *~ i386/*.o i386/*~ gemu TAGS + rm -f *.o *~ gemu dyngen TAGS # various test targets test speed: gemu @@ -87,6 +75,26 @@ test speed: gemu TAGS: 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),) include .depend endif diff --git a/linux-user/main.c b/linux-user/main.c index 68858daf4c..cdd118f369 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -27,6 +27,11 @@ #include "cpu-i386.h" +#define DEBUG_LOGFILE "/tmp/gemu.log" + +FILE *logfile = NULL; +int loglevel; + unsigned long x86_stack_size; unsigned long stktop; @@ -83,7 +88,7 @@ int cpu_x86_inl(int addr) void usage(void) { 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" ); exit(1); @@ -95,11 +100,27 @@ int main(int argc, char **argv) struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; CPUX86State *env; + int optind; if (argc <= 1) usage(); - - filename = argv[1]; + loglevel = 0; + 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 */ memset(regs, 0, sizeof(struct target_pt_regs)); diff --git a/op-i386.c b/op-i386.c index 451318af72..849e508e20 100644 --- a/op-i386.c +++ b/op-i386.c @@ -1,3 +1,5 @@ +#define DEBUG_EXEC + typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; @@ -10,6 +12,11 @@ typedef signed long long int64_t; #define NULL 0 +typedef struct FILE FILE; +extern FILE *logfile; +extern int loglevel; +extern int fprintf(FILE *, const char *, ...); + #ifdef __i386__ register int T0 asm("esi"); register int T1 asm("ebx"); @@ -1636,6 +1643,32 @@ void OPPROTO op_fcos(void) /* main execution loop */ 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 saved_T0, saved_T1, saved_A0; @@ -1653,6 +1686,17 @@ int cpu_x86_exec(CPUX86State *env1) /* prepare setjmp context for exception handling */ if (setjmp(env->jmp_env) == 0) { 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); /* execute the generated code */ gen_func = (void *)code_gen_buffer; diff --git a/translate-i386.c b/translate-i386.c index eb621c3e72..20a8039048 100644 --- a/translate-i386.c +++ b/translate-i386.c @@ -5,23 +5,21 @@ #include #include -/* dump all code */ #define DEBUG_DISAS -#define DEBUG_LOGFILE "/tmp/gemu.log" - -#ifdef DEBUG_DISAS -#include "dis-asm.h" -#endif #define IN_OP_I386 #include "cpu-i386.h" +/* dump all code */ +#ifdef DEBUG_DISAS +#include "dis-asm.h" +#endif + static uint8_t *gen_code_ptr; int __op_param1, __op_param2, __op_param3; -#ifdef DEBUG_DISAS -static FILE *logfile = NULL; -#endif +extern FILE *logfile; +extern int loglevel; /* supress that */ 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 mod, rm, code; -#ifdef DEBUG_DISAS - fprintf(logfile, "modrm=0x%x\n", modrm); -#endif mod = (modrm >> 6) & 3; rm = modrm & 7; @@ -731,9 +726,6 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ if (base == 4) { havesib = 1; code = ldub(s->pc++); -#ifdef DEBUG_DISAS - fprintf(logfile, "sib=0x%x\n", code); -#endif scale = (code >> 6) & 3; index = (code >> 3) & 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 */ next_byte: b = ldub(s->pc); -#ifdef DEBUG_DISAS - fprintf(logfile, "ib=0x%02x\n", b); -#endif - if (b < 0) - return -1; s->pc++; /* check prefixes */ switch (b) { @@ -2247,33 +2234,26 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, gen_start(); #ifdef DEBUG_DISAS - if (!logfile) { - logfile = fopen(DEBUG_LOGFILE, "w"); - if (!logfile) { - perror(DEBUG_LOGFILE); - exit(1); - } - 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 (loglevel) { + 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 - disasm_info.flavour = bfd_get_flavour (abfd); - disasm_info.arch = bfd_get_arch (abfd); - disasm_info.mach = bfd_get_mach (abfd); + 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; + disasm_info.endian = BFD_ENDIAN_BIG; #else - disasm_info.endian = BFD_ENDIAN_LITTLE; + disasm_info.endian = BFD_ENDIAN_LITTLE; #endif - fprintf(logfile, "IN:\n"); - fprintf(logfile, "0x%08lx: ", (long)pc_start); - print_insn_i386((unsigned long)pc_start, &disasm_info); - fprintf(logfile, "\n\n"); + fprintf(logfile, "IN:\n"); + fprintf(logfile, "0x%08lx: ", (long)pc_start); + print_insn_i386((unsigned long)pc_start, &disasm_info); + fprintf(logfile, "\n\n"); + } #endif is_jmp = 0; 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; #ifdef DEBUG_DISAS - { + if (loglevel) { uint8_t *pc; int count;