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:
parent
5726c27fa9
commit
eeacee4d86
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
54
qemu-log.c
54
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[] = {
|
||||
|
110
qemu-log.h
110
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 <stdarg.h>
|
||||
#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 {
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
FILE *logfile;
|
||||
|
||||
struct QEMUBH
|
||||
{
|
||||
QEMUBHFunc *cb;
|
||||
|
92
tcg/tcg.c
92
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, "<dummy>");
|
||||
qemu_log("<dummy>");
|
||||
} 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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user