]> git.proxmox.com Git - qemu.git/blob - qemu-log.c
qemu-log: move logging to qemu-log.c
[qemu.git] / qemu-log.c
1 /*
2 * Logging support
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "qemu-common.h"
21 #include "qemu-log.h"
22
23 #ifdef WIN32
24 static const char *logfilename = "qemu.log";
25 #else
26 static const char *logfilename = "/tmp/qemu.log";
27 #endif
28 FILE *logfile;
29 int loglevel;
30 static int log_append = 0;
31
32 /* enable or disable low levels log */
33 void cpu_set_log(int log_flags)
34 {
35 loglevel = log_flags;
36 if (loglevel && !logfile) {
37 logfile = fopen(logfilename, log_append ? "a" : "w");
38 if (!logfile) {
39 perror(logfilename);
40 _exit(1);
41 }
42 #if !defined(CONFIG_SOFTMMU)
43 /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
44 {
45 static char logfile_buf[4096];
46 setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
47 }
48 #elif defined(_WIN32)
49 /* Win32 doesn't support line-buffering, so use unbuffered output. */
50 setvbuf(logfile, NULL, _IONBF, 0);
51 #else
52 setvbuf(logfile, NULL, _IOLBF, 0);
53 #endif
54 log_append = 1;
55 }
56 if (!loglevel && logfile) {
57 fclose(logfile);
58 logfile = NULL;
59 }
60 }
61
62 void cpu_set_log_filename(const char *filename)
63 {
64 logfilename = strdup(filename);
65 if (logfile) {
66 fclose(logfile);
67 logfile = NULL;
68 }
69 cpu_set_log(loglevel);
70 }
71
72 const CPULogItem cpu_log_items[] = {
73 { CPU_LOG_TB_OUT_ASM, "out_asm",
74 "show generated host assembly code for each compiled TB" },
75 { CPU_LOG_TB_IN_ASM, "in_asm",
76 "show target assembly code for each compiled TB" },
77 { CPU_LOG_TB_OP, "op",
78 "show micro ops for each compiled TB" },
79 { CPU_LOG_TB_OP_OPT, "op_opt",
80 "show micro ops "
81 #ifdef TARGET_I386
82 "before eflags optimization and "
83 #endif
84 "after liveness analysis" },
85 { CPU_LOG_INT, "int",
86 "show interrupts/exceptions in short format" },
87 { CPU_LOG_EXEC, "exec",
88 "show trace before each executed TB (lots of logs)" },
89 { CPU_LOG_TB_CPU, "cpu",
90 "show CPU state before block translation" },
91 #ifdef TARGET_I386
92 { CPU_LOG_PCALL, "pcall",
93 "show protected mode far calls/returns/exceptions" },
94 { CPU_LOG_RESET, "cpu_reset",
95 "show CPU state before CPU resets" },
96 #endif
97 #ifdef DEBUG_IOPORT
98 { CPU_LOG_IOPORT, "ioport",
99 "show all i/o ports accesses" },
100 #endif
101 { 0, NULL, NULL },
102 };
103
104 static int cmp1(const char *s1, int n, const char *s2)
105 {
106 if (strlen(s2) != n) {
107 return 0;
108 }
109 return memcmp(s1, s2, n) == 0;
110 }
111
112 /* takes a comma separated list of log masks. Return 0 if error. */
113 int cpu_str_to_log_mask(const char *str)
114 {
115 const CPULogItem *item;
116 int mask;
117 const char *p, *p1;
118
119 p = str;
120 mask = 0;
121 for (;;) {
122 p1 = strchr(p, ',');
123 if (!p1) {
124 p1 = p + strlen(p);
125 }
126 if (cmp1(p,p1-p,"all")) {
127 for (item = cpu_log_items; item->mask != 0; item++) {
128 mask |= item->mask;
129 }
130 } else {
131 for (item = cpu_log_items; item->mask != 0; item++) {
132 if (cmp1(p, p1 - p, item->name)) {
133 goto found;
134 }
135 }
136 return 0;
137 }
138 found:
139 mask |= item->mask;
140 if (*p1 != ',') {
141 break;
142 }
143 p = p1 + 1;
144 }
145 return mask;
146 }