qemu-log: move logging to qemu-log.c

Move logging functions from exec.c to qemu-log.c,
compile it only once.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Blue Swirl 2012-06-03 15:03:23 +00:00
parent 7798a8828a
commit 5726c27fa9
5 changed files with 170 additions and 151 deletions

View File

@ -1,6 +1,7 @@
#######################################################################
# Target-independent parts used in system and user emulation
universal-obj-y =
universal-obj-y += qemu-log.o
#######################################################################
# QObject

View File

@ -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

122
exec.c
View File

@ -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;

146
qemu-log.c Normal file
View File

@ -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;
}

View File

@ -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