summaryrefslogtreecommitdiff
path: root/util/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/log.c')
-rw-r--r--util/log.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/util/log.c b/util/log.c
index 4e69586a73..671b6174e4 100644
--- a/util/log.c
+++ b/util/log.c
@@ -20,12 +20,16 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/log.h"
+#include "qemu/range.h"
+#include "qemu/error-report.h"
+#include "qemu/cutils.h"
#include "trace/control.h"
static char *logfilename;
FILE *qemu_logfile;
int qemu_loglevel;
static int log_append = 0;
+static GArray *debug_regions;
void qemu_log(const char *fmt, ...)
{
@@ -94,6 +98,89 @@ void qemu_set_log_filename(const char *filename)
qemu_set_log(qemu_loglevel);
}
+/* Returns true if addr is in our debug filter or no filter defined
+ */
+bool qemu_log_in_addr_range(uint64_t addr)
+{
+ if (debug_regions) {
+ int i = 0;
+ for (i = 0; i < debug_regions->len; i++) {
+ struct Range *range = &g_array_index(debug_regions, Range, i);
+ if (addr >= range->begin && addr <= range->end) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+void qemu_set_dfilter_ranges(const char *filter_spec)
+{
+ gchar **ranges = g_strsplit(filter_spec, ",", 0);
+ if (ranges) {
+ gchar **next = ranges;
+ gchar *r = *next++;
+ debug_regions = g_array_sized_new(FALSE, FALSE,
+ sizeof(Range), g_strv_length(ranges));
+ while (r) {
+ char *range_op = strstr(r, "-");
+ char *r2 = range_op ? range_op + 1 : NULL;
+ if (!range_op) {
+ range_op = strstr(r, "+");
+ r2 = range_op ? range_op + 1 : NULL;
+ }
+ if (!range_op) {
+ range_op = strstr(r, "..");
+ r2 = range_op ? range_op + 2 : NULL;
+ }
+ if (range_op) {
+ const char *e = NULL;
+ uint64_t r1val, r2val;
+
+ if ((qemu_strtoull(r, &e, 0, &r1val) == 0) &&
+ (qemu_strtoull(r2, NULL, 0, &r2val) == 0) &&
+ r2val > 0) {
+ struct Range range;
+
+ g_assert(e == range_op);
+
+ switch (*range_op) {
+ case '+':
+ {
+ range.begin = r1val;
+ range.end = r1val + (r2val - 1);
+ break;
+ }
+ case '-':
+ {
+ range.end = r1val;
+ range.begin = r1val - (r2val - 1);
+ break;
+ }
+ case '.':
+ range.begin = r1val;
+ range.end = r2val;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ g_array_append_val(debug_regions, range);
+
+ } else {
+ g_error("Failed to parse range in: %s", r);
+ }
+ } else {
+ g_error("Bad range specifier in: %s", r);
+ }
+ r = *next++;
+ }
+ g_strfreev(ranges);
+ }
+}
+
const QEMULogItem qemu_log_items[] = {
{ CPU_LOG_TB_OUT_ASM, "out_asm",
"show generated host assembly code for each compiled TB" },