qemu-log: cleanup

Don't use global variables directly but via accessor functions. Rename globals.

Convert macros to functions, add GCC format attributes.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Blue Swirl 2012-06-03 16:35:32 +00:00
parent 5726c27fa9
commit eeacee4d86
8 changed files with 166 additions and 111 deletions

View file

@ -1306,8 +1306,9 @@ do { \
fprintf(stderr, fmt , ## __VA_ARGS__); \ fprintf(stderr, fmt , ## __VA_ARGS__); \
cpu_dump_state(env, stderr, fprintf, 0); \ cpu_dump_state(env, stderr, fprintf, 0); \
qemu_log(fmt, ## __VA_ARGS__); \ qemu_log(fmt, ## __VA_ARGS__); \
if (logfile) \ if (qemu_log_enabled()) { \
log_cpu_state(env, 0); \ log_cpu_state(env, 0); \
} \
} while (0) } while (0)
static int do_store_exclusive(CPUPPCState *env) static int do_store_exclusive(CPUPPCState *env)

View file

@ -4378,8 +4378,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigsegv: sigsegv:
unlock_user_struct(frame, frame_addr, 1); unlock_user_struct(frame, frame_addr, 1);
if (logfile) qemu_log("segfaulting from setup_frame\n");
fprintf (logfile, "segfaulting from setup_frame\n");
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
} }
@ -4447,8 +4446,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
sigsegv: sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1); unlock_user_struct(rt_sf, rt_sf_addr, 1);
if (logfile) qemu_log("segfaulting from setup_rt_frame\n");
fprintf (logfile, "segfaulting from setup_rt_frame\n");
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
} }
@ -4489,8 +4487,7 @@ long do_sigreturn(CPUPPCState *env)
sigsegv: sigsegv:
unlock_user_struct(sr, sr_addr, 1); unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1); unlock_user_struct(sc, sc_addr, 1);
if (logfile) qemu_log("segfaulting from do_sigreturn\n");
fprintf (logfile, "segfaulting from do_sigreturn\n");
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
return 0; return 0;
} }
@ -4552,8 +4549,7 @@ long do_rt_sigreturn(CPUPPCState *env)
sigsegv: sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1); unlock_user_struct(rt_sf, rt_sf_addr, 1);
if (logfile) qemu_log("segfaulting from do_rt_sigreturn\n");
fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
return 0; return 0;
} }

View file

@ -25,17 +25,39 @@ static const char *logfilename = "qemu.log";
#else #else
static const char *logfilename = "/tmp/qemu.log"; static const char *logfilename = "/tmp/qemu.log";
#endif #endif
FILE *logfile; FILE *qemu_logfile;
int loglevel; int qemu_loglevel;
static int log_append = 0; 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 */ /* enable or disable low levels log */
void cpu_set_log(int log_flags) void cpu_set_log(int log_flags)
{ {
loglevel = log_flags; qemu_loglevel = log_flags;
if (loglevel && !logfile) { if (qemu_loglevel && !qemu_logfile) {
logfile = fopen(logfilename, log_append ? "a" : "w"); qemu_logfile = fopen(logfilename, log_append ? "a" : "w");
if (!logfile) { if (!qemu_logfile) {
perror(logfilename); perror(logfilename);
_exit(1); _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" */ /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
{ {
static char logfile_buf[4096]; 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) #elif defined(_WIN32)
/* Win32 doesn't support line-buffering, so use unbuffered output. */ /* Win32 doesn't support line-buffering, so use unbuffered output. */
setvbuf(logfile, NULL, _IONBF, 0); setvbuf(qemu_logfile, NULL, _IONBF, 0);
#else #else
setvbuf(logfile, NULL, _IOLBF, 0); setvbuf(qemu_logfile, NULL, _IOLBF, 0);
#endif #endif
log_append = 1; log_append = 1;
} }
if (!loglevel && logfile) { if (!qemu_loglevel && qemu_logfile) {
fclose(logfile); fclose(qemu_logfile);
logfile = NULL; qemu_logfile = NULL;
} }
} }
void cpu_set_log_filename(const char *filename) void cpu_set_log_filename(const char *filename)
{ {
logfilename = strdup(filename); logfilename = strdup(filename);
if (logfile) { if (qemu_logfile) {
fclose(logfile); fclose(qemu_logfile);
logfile = NULL; qemu_logfile = NULL;
} }
cpu_set_log(loglevel); cpu_set_log(qemu_loglevel);
} }
const CPULogItem cpu_log_items[] = { const CPULogItem cpu_log_items[] = {

View file

@ -1,9 +1,14 @@
#ifndef QEMU_LOG_H #ifndef QEMU_LOG_H
#define QEMU_LOG_H #define QEMU_LOG_H
/* The deprecated global variables: */ #include <stdarg.h>
extern FILE *logfile; #ifdef NEED_CPU_H
extern int loglevel; #include "disas.h"
#endif
/* Private global variables, don't use */
extern FILE *qemu_logfile;
extern int qemu_loglevel;
/* /*
* The new API: * The new API:
@ -14,7 +19,10 @@ extern int loglevel;
/* Returns true if qemu_log() will really write somewhere /* 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_OUT_ASM (1 << 0)
#define CPU_LOG_TB_IN_ASM (1 << 1) #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 /* 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: */ /* Logging functions: */
/* main logging function /* main logging function
*/ */
#define qemu_log(...) do { \ void GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
if (logfile) \
fprintf(logfile, ## __VA_ARGS__); \
} while (0)
/* vfprintf-like logging function /* vfprintf-like logging function
*/ */
#define qemu_log_vprintf(fmt, va) do { \ static inline void qemu_log_vprintf(const char *fmt, va_list va)
if (logfile) \ {
vfprintf(logfile, fmt, va); \ if (qemu_logfile) {
} while (0) vfprintf(qemu_logfile, fmt, va);
}
}
/* log only if a bit is set on the current loglevel mask /* log only if a bit is set on the current loglevel mask
*/ */
#define qemu_log_mask(b, ...) do { \ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
if (loglevel & (b)) \
fprintf(logfile, ## __VA_ARGS__); \
} while (0)
/* Special cases: */ /* Special cases: */
#ifdef NEED_CPU_H #ifdef NEED_CPU_H
/* cpu_dump_state() logging functions: */ /* cpu_dump_state() logging functions: */
#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f)); static inline void log_cpu_state(CPUArchState *env1, int flags)
#define log_cpu_state_mask(b, env, f) do { \ {
if (loglevel & (b)) log_cpu_state((env), (f)); \ cpu_dump_state(env1, qemu_logfile, fprintf, flags);
} while (0) }
/* disas() and target_disas() to logfile: */ static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags)
#define log_target_disas(start, len, flags) \ {
target_disas(logfile, (start), (len), (flags)) if (qemu_loglevel & mask) {
#define log_disas(start, len) \ log_cpu_state(env1, flags);
disas(logfile, (start), (len)) }
}
/* 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: */ /* 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 #endif
/* Maintenance: */ /* Maintenance: */
/* fflush() the log file */ /* fflush() the log file */
#define qemu_log_flush() fflush(logfile) static inline void qemu_log_flush(void)
{
fflush(qemu_logfile);
}
/* Close the log file */ /* Close the log file */
#define qemu_log_close() do { \ static inline void qemu_log_close(void)
fclose(logfile); \ {
logfile = NULL; \ fclose(qemu_logfile);
} while (0) qemu_logfile = NULL;
}
/* Set up a new log file */ /* Set up a new log file */
#define qemu_log_set_file(f) do { \ static inline void qemu_log_set_file(FILE *f)
logfile = (f); \ {
} while (0) qemu_logfile = f;
}
/* Set up a new log file, only if none is set */ /* Set up a new log file, only if none is set */
#define qemu_log_try_set_file(f) do { \ static inline void qemu_log_try_set_file(FILE *f)
if (!logfile) \ {
logfile = (f); \ if (!qemu_logfile) {
} while (0) qemu_logfile = f;
}
}
/* define log items */ /* define log items */
typedef struct CPULogItem { typedef struct CPULogItem {

View file

@ -24,8 +24,6 @@
#include <sys/time.h> #include <sys/time.h>
FILE *logfile;
struct QEMUBH struct QEMUBH
{ {
QEMUBHFunc *cb; QEMUBHFunc *cb;

View file

@ -873,7 +873,7 @@ static const char * const cond_name[] =
[TCG_COND_GTU] = "gtu" [TCG_COND_GTU] = "gtu"
}; };
void tcg_dump_ops(TCGContext *s, FILE *outfile) void tcg_dump_ops(TCGContext *s)
{ {
const uint16_t *opc_ptr; const uint16_t *opc_ptr;
const TCGArg *args; const TCGArg *args;
@ -896,9 +896,10 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
#else #else
pc = args[0]; pc = args[0];
#endif #endif
if (!first_insn) if (!first_insn) {
fprintf(outfile, "\n"); qemu_log("\n");
fprintf(outfile, " ---- 0x%" PRIx64, pc); }
qemu_log(" ---- 0x%" PRIx64, pc);
first_insn = 0; first_insn = 0;
nb_oargs = def->nb_oargs; nb_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs; nb_iargs = def->nb_iargs;
@ -912,28 +913,28 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
nb_iargs = arg & 0xffff; nb_iargs = arg & 0xffff;
nb_cargs = def->nb_cargs; nb_cargs = def->nb_cargs;
fprintf(outfile, " %s ", def->name); qemu_log(" %s ", def->name);
/* function name */ /* function name */
fprintf(outfile, "%s", qemu_log("%s",
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1])); tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[nb_oargs + nb_iargs - 1]));
/* flags */ /* flags */
fprintf(outfile, ",$0x%" TCG_PRIlx, qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
args[nb_oargs + nb_iargs]);
/* nb out args */ /* nb out args */
fprintf(outfile, ",$%d", nb_oargs); qemu_log(",$%d", nb_oargs);
for(i = 0; i < nb_oargs; i++) { for(i = 0; i < nb_oargs; i++) {
fprintf(outfile, ","); qemu_log(",");
fprintf(outfile, "%s", qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i])); args[i]));
} }
for(i = 0; i < (nb_iargs - 1); i++) { for(i = 0; i < (nb_iargs - 1); i++) {
fprintf(outfile, ","); qemu_log(",");
if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
fprintf(outfile, "<dummy>"); qemu_log("<dummy>");
} else { } else {
fprintf(outfile, "%s", qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); args[nb_oargs + i]));
} }
} }
} else if (c == INDEX_op_movi_i32 } 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_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs; nb_iargs = def->nb_iargs;
nb_cargs = def->nb_cargs; nb_cargs = def->nb_cargs;
fprintf(outfile, " %s %s,$", def->name, qemu_log(" %s %s,$", def->name,
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0])); tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
val = args[1]; val = args[1];
th = tcg_find_helper(s, val); th = tcg_find_helper(s, val);
if (th) { if (th) {
fprintf(outfile, "%s", th->name); qemu_log("%s", th->name);
} else { } else {
if (c == INDEX_op_movi_i32) if (c == INDEX_op_movi_i32) {
fprintf(outfile, "0x%x", (uint32_t)val); qemu_log("0x%x", (uint32_t)val);
else } else {
fprintf(outfile, "0x%" PRIx64 , (uint64_t)val); qemu_log("0x%" PRIx64 , (uint64_t)val);
}
} }
} else { } else {
fprintf(outfile, " %s ", def->name); qemu_log(" %s ", def->name);
if (c == INDEX_op_nopn) { if (c == INDEX_op_nopn) {
/* variable number of arguments */ /* variable number of arguments */
nb_cargs = *args; nb_cargs = *args;
@ -974,16 +976,18 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
k = 0; k = 0;
for(i = 0; i < nb_oargs; i++) { for(i = 0; i < nb_oargs; i++) {
if (k != 0) if (k != 0) {
fprintf(outfile, ","); qemu_log(",");
fprintf(outfile, "%s", }
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[k++]));
} }
for(i = 0; i < nb_iargs; i++) { for(i = 0; i < nb_iargs; i++) {
if (k != 0) if (k != 0) {
fprintf(outfile, ","); qemu_log(",");
fprintf(outfile, "%s", }
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[k++]));
} }
switch (c) { switch (c) {
case INDEX_op_brcond_i32: case INDEX_op_brcond_i32:
@ -998,10 +1002,11 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
#elif TCG_TARGET_REG_BITS == 64 #elif TCG_TARGET_REG_BITS == 64
case INDEX_op_setcond_i64: case INDEX_op_setcond_i64:
#endif #endif
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
fprintf(outfile, ",%s", cond_name[args[k++]]); qemu_log(",%s", cond_name[args[k++]]);
else } else {
fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]); qemu_log(",$0x%" TCG_PRIlx, args[k++]);
}
i = 1; i = 1;
break; break;
default: default:
@ -1009,13 +1014,14 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
break; break;
} }
for(; i < nb_cargs; i++) { for(; i < nb_cargs; i++) {
if (k != 0) if (k != 0) {
fprintf(outfile, ","); qemu_log(",");
}
arg = args[k++]; 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; 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 #ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
qemu_log("OP:\n"); qemu_log("OP:\n");
tcg_dump_ops(s, logfile); tcg_dump_ops(s);
qemu_log("\n"); qemu_log("\n");
} }
#endif #endif
@ -2069,7 +2075,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
#ifdef DEBUG_DISAS #ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
qemu_log("OP after liveness analysis:\n"); qemu_log("OP after liveness analysis:\n");
tcg_dump_ops(s, logfile); tcg_dump_ops(s);
qemu_log("\n"); qemu_log("\n");
} }
#endif #endif

View file

@ -571,7 +571,7 @@ TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args,
/* only used for debugging purposes */ /* only used for debugging purposes */
void tcg_register_helper(void *func, const char *name); void tcg_register_helper(void *func, const char *name);
const char *tcg_helper_get_name(TCGContext *s, void *func); 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); void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
TCGv_i32 tcg_const_i32(int32_t val); TCGv_i32 tcg_const_i32(int32_t val);

View file

@ -878,7 +878,7 @@ static void tcg_target_init(TCGContext *s)
#if defined(CONFIG_DEBUG_TCG_INTERPRETER) #if defined(CONFIG_DEBUG_TCG_INTERPRETER)
const char *envval = getenv("DEBUG_TCG"); const char *envval = getenv("DEBUG_TCG");
if (envval) { if (envval) {
loglevel = strtol(envval, NULL, 0); cpu_set_log(strtol(envval, NULL, 0));
} }
#endif #endif