diff --git a/linux-user/main.c b/linux-user/main.c index 49108b81d3..d0e0e4fc6a 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1306,8 +1306,9 @@ do { \ fprintf(stderr, fmt , ## __VA_ARGS__); \ cpu_dump_state(env, stderr, fprintf, 0); \ qemu_log(fmt, ## __VA_ARGS__); \ - if (logfile) \ + if (qemu_log_enabled()) { \ log_cpu_state(env, 0); \ + } \ } while (0) static int do_store_exclusive(CPUPPCState *env) diff --git a/linux-user/signal.c b/linux-user/signal.c index b1e139d6fd..43346dcbcc 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -4378,8 +4378,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, sigsegv: unlock_user_struct(frame, frame_addr, 1); - if (logfile) - fprintf (logfile, "segfaulting from setup_frame\n"); + qemu_log("segfaulting from setup_frame\n"); force_sig(TARGET_SIGSEGV); } @@ -4447,8 +4446,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, sigsegv: unlock_user_struct(rt_sf, rt_sf_addr, 1); - if (logfile) - fprintf (logfile, "segfaulting from setup_rt_frame\n"); + qemu_log("segfaulting from setup_rt_frame\n"); force_sig(TARGET_SIGSEGV); } @@ -4489,8 +4487,7 @@ long do_sigreturn(CPUPPCState *env) sigsegv: unlock_user_struct(sr, sr_addr, 1); unlock_user_struct(sc, sc_addr, 1); - if (logfile) - fprintf (logfile, "segfaulting from do_sigreturn\n"); + qemu_log("segfaulting from do_sigreturn\n"); force_sig(TARGET_SIGSEGV); return 0; } @@ -4552,8 +4549,7 @@ long do_rt_sigreturn(CPUPPCState *env) sigsegv: unlock_user_struct(rt_sf, rt_sf_addr, 1); - if (logfile) - fprintf (logfile, "segfaulting from do_rt_sigreturn\n"); + qemu_log("segfaulting from do_rt_sigreturn\n"); force_sig(TARGET_SIGSEGV); return 0; } diff --git a/qemu-log.c b/qemu-log.c index 4d7499fdf5..1dd3de41ad 100644 --- a/qemu-log.c +++ b/qemu-log.c @@ -25,17 +25,39 @@ static const char *logfilename = "qemu.log"; #else static const char *logfilename = "/tmp/qemu.log"; #endif -FILE *logfile; -int loglevel; +FILE *qemu_logfile; +int qemu_loglevel; static int log_append = 0; +void qemu_log(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (qemu_logfile) { + vfprintf(qemu_logfile, fmt, ap); + } + va_end(ap); +} + +void qemu_log_mask(int mask, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if ((qemu_loglevel & mask) && qemu_logfile) { + vfprintf(qemu_logfile, fmt, ap); + } + va_end(ap); +} + /* 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) { + qemu_loglevel = log_flags; + if (qemu_loglevel && !qemu_logfile) { + qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); + if (!qemu_logfile) { perror(logfilename); _exit(1); } @@ -43,30 +65,30 @@ void cpu_set_log(int log_flags) /* 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)); + setvbuf(qemu_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); + setvbuf(qemu_logfile, NULL, _IONBF, 0); #else - setvbuf(logfile, NULL, _IOLBF, 0); + setvbuf(qemu_logfile, NULL, _IOLBF, 0); #endif log_append = 1; } - if (!loglevel && logfile) { - fclose(logfile); - logfile = NULL; + if (!qemu_loglevel && qemu_logfile) { + fclose(qemu_logfile); + qemu_logfile = NULL; } } void cpu_set_log_filename(const char *filename) { logfilename = strdup(filename); - if (logfile) { - fclose(logfile); - logfile = NULL; + if (qemu_logfile) { + fclose(qemu_logfile); + qemu_logfile = NULL; } - cpu_set_log(loglevel); + cpu_set_log(qemu_loglevel); } const CPULogItem cpu_log_items[] = { diff --git a/qemu-log.h b/qemu-log.h index 34600d6af9..d1e0f2d98d 100644 --- a/qemu-log.h +++ b/qemu-log.h @@ -1,9 +1,14 @@ #ifndef QEMU_LOG_H #define QEMU_LOG_H -/* The deprecated global variables: */ -extern FILE *logfile; -extern int loglevel; +#include +#ifdef NEED_CPU_H +#include "disas.h" +#endif + +/* Private global variables, don't use */ +extern FILE *qemu_logfile; +extern int qemu_loglevel; /* * The new API: @@ -14,7 +19,10 @@ extern int loglevel; /* Returns true if qemu_log() will really write somewhere */ -#define qemu_log_enabled() (logfile != NULL) +static inline bool qemu_log_enabled(void) +{ + return qemu_logfile != NULL; +} #define CPU_LOG_TB_OUT_ASM (1 << 0) #define CPU_LOG_TB_IN_ASM (1 << 1) @@ -29,73 +37,97 @@ extern int loglevel; /* Returns true if a bit is set in the current loglevel mask */ -#define qemu_loglevel_mask(b) ((loglevel & (b)) != 0) +static inline bool qemu_loglevel_mask(int mask) +{ + return (qemu_loglevel & mask) != 0; +} /* Logging functions: */ /* main logging function */ -#define qemu_log(...) do { \ - if (logfile) \ - fprintf(logfile, ## __VA_ARGS__); \ - } while (0) +void GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...); /* vfprintf-like logging function */ -#define qemu_log_vprintf(fmt, va) do { \ - if (logfile) \ - vfprintf(logfile, fmt, va); \ - } while (0) +static inline void qemu_log_vprintf(const char *fmt, va_list va) +{ + if (qemu_logfile) { + vfprintf(qemu_logfile, fmt, va); + } +} /* log only if a bit is set on the current loglevel mask */ -#define qemu_log_mask(b, ...) do { \ - if (loglevel & (b)) \ - fprintf(logfile, ## __VA_ARGS__); \ - } while (0) +void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...); /* Special cases: */ #ifdef NEED_CPU_H /* cpu_dump_state() logging functions: */ -#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f)); -#define log_cpu_state_mask(b, env, f) do { \ - if (loglevel & (b)) log_cpu_state((env), (f)); \ - } while (0) +static inline void log_cpu_state(CPUArchState *env1, int flags) +{ + cpu_dump_state(env1, qemu_logfile, fprintf, flags); +} -/* disas() and target_disas() to logfile: */ -#define log_target_disas(start, len, flags) \ - target_disas(logfile, (start), (len), (flags)) -#define log_disas(start, len) \ - disas(logfile, (start), (len)) +static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags) +{ + if (qemu_loglevel & mask) { + log_cpu_state(env1, flags); + } +} +/* disas() and target_disas() to qemu_logfile: */ +static inline void log_target_disas(target_ulong start, target_ulong len, + int flags) +{ + target_disas(qemu_logfile, start, len, flags); +} + +static inline void log_disas(void *code, unsigned long size) +{ + disas(qemu_logfile, code, size); +} + +#if defined(CONFIG_USER_ONLY) /* page_dump() output to the log file: */ -#define log_page_dump() page_dump(logfile) +static inline void log_page_dump(void) +{ + page_dump(qemu_logfile); +} +#endif #endif /* Maintenance: */ /* fflush() the log file */ -#define qemu_log_flush() fflush(logfile) +static inline void qemu_log_flush(void) +{ + fflush(qemu_logfile); +} /* Close the log file */ -#define qemu_log_close() do { \ - fclose(logfile); \ - logfile = NULL; \ - } while (0) +static inline void qemu_log_close(void) +{ + fclose(qemu_logfile); + qemu_logfile = NULL; +} /* Set up a new log file */ -#define qemu_log_set_file(f) do { \ - logfile = (f); \ - } while (0) +static inline void qemu_log_set_file(FILE *f) +{ + qemu_logfile = f; +} /* Set up a new log file, only if none is set */ -#define qemu_log_try_set_file(f) do { \ - if (!logfile) \ - logfile = (f); \ - } while (0) +static inline void qemu_log_try_set_file(FILE *f) +{ + if (!qemu_logfile) { + qemu_logfile = f; + } +} /* define log items */ typedef struct CPULogItem { diff --git a/qemu-tool.c b/qemu-tool.c index 07fc4f201a..318c5fcbca 100644 --- a/qemu-tool.c +++ b/qemu-tool.c @@ -24,8 +24,6 @@ #include -FILE *logfile; - struct QEMUBH { QEMUBHFunc *cb; diff --git a/tcg/tcg.c b/tcg/tcg.c index ab589c7ad2..8386b70abd 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -873,7 +873,7 @@ static const char * const cond_name[] = [TCG_COND_GTU] = "gtu" }; -void tcg_dump_ops(TCGContext *s, FILE *outfile) +void tcg_dump_ops(TCGContext *s) { const uint16_t *opc_ptr; const TCGArg *args; @@ -896,9 +896,10 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) #else pc = args[0]; #endif - if (!first_insn) - fprintf(outfile, "\n"); - fprintf(outfile, " ---- 0x%" PRIx64, pc); + if (!first_insn) { + qemu_log("\n"); + } + qemu_log(" ---- 0x%" PRIx64, pc); first_insn = 0; nb_oargs = def->nb_oargs; nb_iargs = def->nb_iargs; @@ -912,28 +913,28 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) nb_iargs = arg & 0xffff; nb_cargs = def->nb_cargs; - fprintf(outfile, " %s ", def->name); + qemu_log(" %s ", def->name); /* function name */ - fprintf(outfile, "%s", - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1])); + qemu_log("%s", + tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[nb_oargs + nb_iargs - 1])); /* flags */ - fprintf(outfile, ",$0x%" TCG_PRIlx, - args[nb_oargs + nb_iargs]); + qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]); /* nb out args */ - fprintf(outfile, ",$%d", nb_oargs); + qemu_log(",$%d", nb_oargs); for(i = 0; i < nb_oargs; i++) { - fprintf(outfile, ","); - fprintf(outfile, "%s", - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i])); + qemu_log(","); + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[i])); } for(i = 0; i < (nb_iargs - 1); i++) { - fprintf(outfile, ","); + qemu_log(","); if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { - fprintf(outfile, ""); + qemu_log(""); } else { - fprintf(outfile, "%s", - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[nb_oargs + i])); } } } else if (c == INDEX_op_movi_i32 @@ -947,20 +948,21 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) nb_oargs = def->nb_oargs; nb_iargs = def->nb_iargs; nb_cargs = def->nb_cargs; - fprintf(outfile, " %s %s,$", def->name, - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0])); + qemu_log(" %s %s,$", def->name, + tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0])); val = args[1]; th = tcg_find_helper(s, val); if (th) { - fprintf(outfile, "%s", th->name); + qemu_log("%s", th->name); } else { - if (c == INDEX_op_movi_i32) - fprintf(outfile, "0x%x", (uint32_t)val); - else - fprintf(outfile, "0x%" PRIx64 , (uint64_t)val); + if (c == INDEX_op_movi_i32) { + qemu_log("0x%x", (uint32_t)val); + } else { + qemu_log("0x%" PRIx64 , (uint64_t)val); + } } } else { - fprintf(outfile, " %s ", def->name); + qemu_log(" %s ", def->name); if (c == INDEX_op_nopn) { /* variable number of arguments */ nb_cargs = *args; @@ -974,16 +976,18 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) k = 0; for(i = 0; i < nb_oargs; i++) { - if (k != 0) - fprintf(outfile, ","); - fprintf(outfile, "%s", - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); + if (k != 0) { + qemu_log(","); + } + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[k++])); } for(i = 0; i < nb_iargs; i++) { - if (k != 0) - fprintf(outfile, ","); - fprintf(outfile, "%s", - tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); + if (k != 0) { + qemu_log(","); + } + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[k++])); } switch (c) { case INDEX_op_brcond_i32: @@ -998,10 +1002,11 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) #elif TCG_TARGET_REG_BITS == 64 case INDEX_op_setcond_i64: #endif - if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) - fprintf(outfile, ",%s", cond_name[args[k++]]); - else - fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]); + if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) { + qemu_log(",%s", cond_name[args[k++]]); + } else { + qemu_log(",$0x%" TCG_PRIlx, args[k++]); + } i = 1; break; default: @@ -1009,13 +1014,14 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) break; } for(; i < nb_cargs; i++) { - if (k != 0) - fprintf(outfile, ","); + if (k != 0) { + qemu_log(","); + } arg = args[k++]; - fprintf(outfile, "$0x%" TCG_PRIlx, arg); + qemu_log("$0x%" TCG_PRIlx, arg); } } - fprintf(outfile, "\n"); + qemu_log("\n"); args += nb_iargs + nb_oargs + nb_cargs; } } @@ -2048,7 +2054,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { qemu_log("OP:\n"); - tcg_dump_ops(s, logfile); + tcg_dump_ops(s); qemu_log("\n"); } #endif @@ -2069,7 +2075,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { qemu_log("OP after liveness analysis:\n"); - tcg_dump_ops(s, logfile); + tcg_dump_ops(s); qemu_log("\n"); } #endif diff --git a/tcg/tcg.h b/tcg/tcg.h index a83bdddba4..d710694e0a 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -571,7 +571,7 @@ TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, /* only used for debugging purposes */ void tcg_register_helper(void *func, const char *name); const char *tcg_helper_get_name(TCGContext *s, void *func); -void tcg_dump_ops(TCGContext *s, FILE *outfile); +void tcg_dump_ops(TCGContext *s); void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf); TCGv_i32 tcg_const_i32(int32_t val); diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index 453f1875e2..d0a368d99a 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -878,7 +878,7 @@ static void tcg_target_init(TCGContext *s) #if defined(CONFIG_DEBUG_TCG_INTERPRETER) const char *envval = getenv("DEBUG_TCG"); if (envval) { - loglevel = strtol(envval, NULL, 0); + cpu_set_log(strtol(envval, NULL, 0)); } #endif