diff options
-rw-r--r-- | Makefile.objs | 1 | ||||
-rw-r--r-- | cpu-all.h | 24 | ||||
-rw-r--r-- | exec.c | 122 | ||||
-rw-r--r-- | qemu-log.c | 146 | ||||
-rw-r--r-- | qemu-log.h | 28 |
5 files changed, 170 insertions, 151 deletions
diff --git a/Makefile.objs b/Makefile.objs index 74110dda7e..625c4d5da7 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -1,6 +1,7 @@ ####################################################################### # Target-independent parts used in system and user emulation universal-obj-y = +universal-obj-y += qemu-log.o ####################################################################### # QObject @@ -446,30 +446,6 @@ void cpu_single_step(CPUArchState *env, int enabled); int cpu_is_stopped(CPUArchState *env); void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data); -#define CPU_LOG_TB_OUT_ASM (1 << 0) -#define CPU_LOG_TB_IN_ASM (1 << 1) -#define CPU_LOG_TB_OP (1 << 2) -#define CPU_LOG_TB_OP_OPT (1 << 3) -#define CPU_LOG_INT (1 << 4) -#define CPU_LOG_EXEC (1 << 5) -#define CPU_LOG_PCALL (1 << 6) -#define CPU_LOG_IOPORT (1 << 7) -#define CPU_LOG_TB_CPU (1 << 8) -#define CPU_LOG_RESET (1 << 9) - -/* define log items */ -typedef struct CPULogItem { - int mask; - const char *name; - const char *help; -} CPULogItem; - -extern const CPULogItem cpu_log_items[]; - -void cpu_set_log(int log_flags); -void cpu_set_log_filename(const char *filename); -int cpu_str_to_log_mask(const char *str); - #if !defined(CONFIG_USER_ONLY) /* Return the physical page corresponding to a virtual one. Use it @@ -216,16 +216,6 @@ static void memory_map_init(void); static MemoryRegion io_mem_watch; #endif -/* log support */ -#ifdef WIN32 -static const char *logfilename = "qemu.log"; -#else -static const char *logfilename = "/tmp/qemu.log"; -#endif -FILE *logfile; -int loglevel; -static int log_append = 0; - /* statistics */ static int tb_flush_count; static int tb_phys_invalidate_count; @@ -1673,46 +1663,6 @@ void cpu_single_step(CPUArchState *env, int enabled) #endif } -/* enable or disable low levels log */ -void cpu_set_log(int log_flags) -{ - loglevel = log_flags; - if (loglevel && !logfile) { - logfile = fopen(logfilename, log_append ? "a" : "w"); - if (!logfile) { - perror(logfilename); - _exit(1); - } -#if !defined(CONFIG_SOFTMMU) - /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ - { - static char logfile_buf[4096]; - setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); - } -#elif defined(_WIN32) - /* Win32 doesn't support line-buffering, so use unbuffered output. */ - setvbuf(logfile, NULL, _IONBF, 0); -#else - setvbuf(logfile, NULL, _IOLBF, 0); -#endif - log_append = 1; - } - if (!loglevel && logfile) { - fclose(logfile); - logfile = NULL; - } -} - -void cpu_set_log_filename(const char *filename) -{ - logfilename = strdup(filename); - if (logfile) { - fclose(logfile); - logfile = NULL; - } - cpu_set_log(loglevel); -} - static void cpu_unlink_tb(CPUArchState *env) { /* FIXME: TB unchaining isn't SMP safe. For now just ignore the @@ -1784,78 +1734,6 @@ void cpu_exit(CPUArchState *env) cpu_unlink_tb(env); } -const CPULogItem cpu_log_items[] = { - { CPU_LOG_TB_OUT_ASM, "out_asm", - "show generated host assembly code for each compiled TB" }, - { CPU_LOG_TB_IN_ASM, "in_asm", - "show target assembly code for each compiled TB" }, - { CPU_LOG_TB_OP, "op", - "show micro ops for each compiled TB" }, - { CPU_LOG_TB_OP_OPT, "op_opt", - "show micro ops " -#ifdef TARGET_I386 - "before eflags optimization and " -#endif - "after liveness analysis" }, - { CPU_LOG_INT, "int", - "show interrupts/exceptions in short format" }, - { CPU_LOG_EXEC, "exec", - "show trace before each executed TB (lots of logs)" }, - { CPU_LOG_TB_CPU, "cpu", - "show CPU state before block translation" }, -#ifdef TARGET_I386 - { CPU_LOG_PCALL, "pcall", - "show protected mode far calls/returns/exceptions" }, - { CPU_LOG_RESET, "cpu_reset", - "show CPU state before CPU resets" }, -#endif -#ifdef DEBUG_IOPORT - { CPU_LOG_IOPORT, "ioport", - "show all i/o ports accesses" }, -#endif - { 0, NULL, NULL }, -}; - -static int cmp1(const char *s1, int n, const char *s2) -{ - if (strlen(s2) != n) - return 0; - return memcmp(s1, s2, n) == 0; -} - -/* takes a comma separated list of log masks. Return 0 if error. */ -int cpu_str_to_log_mask(const char *str) -{ - const CPULogItem *item; - int mask; - const char *p, *p1; - - p = str; - mask = 0; - for(;;) { - p1 = strchr(p, ','); - if (!p1) - p1 = p + strlen(p); - if(cmp1(p,p1-p,"all")) { - for(item = cpu_log_items; item->mask != 0; item++) { - mask |= item->mask; - } - } else { - for(item = cpu_log_items; item->mask != 0; item++) { - if (cmp1(p, p1 - p, item->name)) - goto found; - } - return 0; - } - found: - mask |= item->mask; - if (*p1 != ',') - break; - p = p1 + 1; - } - return mask; -} - void cpu_abort(CPUArchState *env, const char *fmt, ...) { va_list ap; diff --git a/qemu-log.c b/qemu-log.c new file mode 100644 index 0000000000..4d7499fdf5 --- /dev/null +++ b/qemu-log.c @@ -0,0 +1,146 @@ +/* + * Logging support + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "qemu-common.h" +#include "qemu-log.h" + +#ifdef WIN32 +static const char *logfilename = "qemu.log"; +#else +static const char *logfilename = "/tmp/qemu.log"; +#endif +FILE *logfile; +int loglevel; +static int log_append = 0; + +/* enable or disable low levels log */ +void cpu_set_log(int log_flags) +{ + loglevel = log_flags; + if (loglevel && !logfile) { + logfile = fopen(logfilename, log_append ? "a" : "w"); + if (!logfile) { + perror(logfilename); + _exit(1); + } +#if !defined(CONFIG_SOFTMMU) + /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ + { + static char logfile_buf[4096]; + setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); + } +#elif defined(_WIN32) + /* Win32 doesn't support line-buffering, so use unbuffered output. */ + setvbuf(logfile, NULL, _IONBF, 0); +#else + setvbuf(logfile, NULL, _IOLBF, 0); +#endif + log_append = 1; + } + if (!loglevel && logfile) { + fclose(logfile); + logfile = NULL; + } +} + +void cpu_set_log_filename(const char *filename) +{ + logfilename = strdup(filename); + if (logfile) { + fclose(logfile); + logfile = NULL; + } + cpu_set_log(loglevel); +} + +const CPULogItem cpu_log_items[] = { + { CPU_LOG_TB_OUT_ASM, "out_asm", + "show generated host assembly code for each compiled TB" }, + { CPU_LOG_TB_IN_ASM, "in_asm", + "show target assembly code for each compiled TB" }, + { CPU_LOG_TB_OP, "op", + "show micro ops for each compiled TB" }, + { CPU_LOG_TB_OP_OPT, "op_opt", + "show micro ops " +#ifdef TARGET_I386 + "before eflags optimization and " +#endif + "after liveness analysis" }, + { CPU_LOG_INT, "int", + "show interrupts/exceptions in short format" }, + { CPU_LOG_EXEC, "exec", + "show trace before each executed TB (lots of logs)" }, + { CPU_LOG_TB_CPU, "cpu", + "show CPU state before block translation" }, +#ifdef TARGET_I386 + { CPU_LOG_PCALL, "pcall", + "show protected mode far calls/returns/exceptions" }, + { CPU_LOG_RESET, "cpu_reset", + "show CPU state before CPU resets" }, +#endif +#ifdef DEBUG_IOPORT + { CPU_LOG_IOPORT, "ioport", + "show all i/o ports accesses" }, +#endif + { 0, NULL, NULL }, +}; + +static int cmp1(const char *s1, int n, const char *s2) +{ + if (strlen(s2) != n) { + return 0; + } + return memcmp(s1, s2, n) == 0; +} + +/* takes a comma separated list of log masks. Return 0 if error. */ +int cpu_str_to_log_mask(const char *str) +{ + const CPULogItem *item; + int mask; + const char *p, *p1; + + p = str; + mask = 0; + for (;;) { + p1 = strchr(p, ','); + if (!p1) { + p1 = p + strlen(p); + } + if (cmp1(p,p1-p,"all")) { + for (item = cpu_log_items; item->mask != 0; item++) { + mask |= item->mask; + } + } else { + for (item = cpu_log_items; item->mask != 0; item++) { + if (cmp1(p, p1 - p, item->name)) { + goto found; + } + } + return 0; + } + found: + mask |= item->mask; + if (*p1 != ',') { + break; + } + p = p1 + 1; + } + return mask; +} diff --git a/qemu-log.h b/qemu-log.h index a9b3ca4e0b..34600d6af9 100644 --- a/qemu-log.h +++ b/qemu-log.h @@ -5,7 +5,6 @@ extern FILE *logfile; extern int loglevel; - /* * The new API: * @@ -17,11 +16,21 @@ extern int loglevel; */ #define qemu_log_enabled() (logfile != NULL) +#define CPU_LOG_TB_OUT_ASM (1 << 0) +#define CPU_LOG_TB_IN_ASM (1 << 1) +#define CPU_LOG_TB_OP (1 << 2) +#define CPU_LOG_TB_OP_OPT (1 << 3) +#define CPU_LOG_INT (1 << 4) +#define CPU_LOG_EXEC (1 << 5) +#define CPU_LOG_PCALL (1 << 6) +#define CPU_LOG_IOPORT (1 << 7) +#define CPU_LOG_TB_CPU (1 << 8) +#define CPU_LOG_RESET (1 << 9) + /* Returns true if a bit is set in the current loglevel mask */ #define qemu_loglevel_mask(b) ((loglevel & (b)) != 0) - /* Logging functions: */ /* main logging function @@ -46,8 +55,6 @@ extern int loglevel; } while (0) - - /* Special cases: */ #ifdef NEED_CPU_H @@ -68,7 +75,6 @@ extern int loglevel; #endif - /* Maintenance: */ /* fflush() the log file */ @@ -91,5 +97,17 @@ extern int loglevel; logfile = (f); \ } while (0) +/* define log items */ +typedef struct CPULogItem { + int mask; + const char *name; + const char *help; +} CPULogItem; + +extern const CPULogItem cpu_log_items[]; + +void cpu_set_log(int log_flags); +void cpu_set_log_filename(const char *filename); +int cpu_str_to_log_mask(const char *str); #endif |