@@ -134,3 +134,4 @@ trace-dtrace-root.h
trace-dtrace-root.dtrace
trace-ust-all.h
trace-ust-all.c
+!/instrument/*
@@ -602,6 +602,9 @@ endif
ifdef CONFIG_INSTRUMENT
$(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
$(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h "$(DESTDIR)$(includedir)/qemu-instr/"
+ $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/trace.h "$(DESTDIR)$(includedir)/qemu-instr/"
+ $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h "$(DESTDIR)$(includedir)/qemu-instr/"
+ $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.inc.h "$(DESTDIR)$(includedir)/qemu-instr/"
endif
install-datadir:
@@ -4,3 +4,4 @@ target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
target-obj-$(CONFIG_INSTRUMENT) += load.o
target-obj-$(CONFIG_INSTRUMENT) += qmp.o
target-obj-$(CONFIG_INSTRUMENT) += control.o
+target-obj-$(CONFIG_INSTRUMENT) += trace.o
@@ -25,4 +25,10 @@
return; \
}
+#define ERROR_IF_RET(cond, ret, msg, args...) \
+ if (unlikely(cond)) { \
+ _ERROR(msg, ##args); \
+ return ret; \
+ } \
+
#endif /* INSTRUMENT_ERROR_H */
new file mode 100644
@@ -0,0 +1,51 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__TYPES_H
+#define QI__TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * SECTION: types
+ * @section_id: qi-types
+ * @title: Common types
+ */
+
+/**
+ * QITraceEvent:
+ *
+ * Opaque structure defining a tracing event.
+ */
+typedef struct QITraceEvent QITraceEvent;
+
+/**
+ * QITraceEventIter:
+ *
+ * Opaque structure defining a tracing event iterator.
+ */
+typedef struct QITraceEventIter QITraceEventIter;
+
+/**
+ * QICPU:
+ *
+ * Opaque guest CPU pointer.
+ */
+typedef struct QICPU_d *QICPU;
+
+
+#include <qemu-instr/types.inc.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__TYPES_H */
new file mode 100644
@@ -0,0 +1,15 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <stdlib.h>
+
+
+struct QITraceEventIter {
+ char buffer[(sizeof(size_t) * 2) + sizeof(char *)];
+};
new file mode 100644
@@ -0,0 +1,125 @@
+/*
+ * API for QEMU's tracing events.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "instrument/error.h"
+#include "qemu/compiler.h"
+#include "qemu-instr/trace.h"
+#include "trace/control.h"
+
+
+SYM_PUBLIC
+QITraceEvent *qi_trace_event_name(const char *name)
+{
+ ERROR_IF_RET(!name, NULL, "must provide a name");
+ return (QITraceEvent *)trace_event_name(name);
+}
+
+SYM_PUBLIC
+void qi_trace_event_iter_init(QITraceEventIter *iter, const char *pattern)
+{
+ TraceEventIter *iter_ = (TraceEventIter *)iter;
+ ERROR_IF(!iter_, "must provide an iterator");
+ trace_event_iter_init(iter_, pattern);
+}
+
+SYM_PUBLIC
+QITraceEvent *qi_trace_event_iter_next(QITraceEventIter *iter)
+{
+ TraceEventIter *iter_ = (TraceEventIter *)iter;
+ ERROR_IF_RET(!iter_, NULL, "must provide an iterator");
+ return (QITraceEvent *)trace_event_iter_next(iter_);
+}
+
+
+SYM_PUBLIC
+bool qi_trace_event_is_vcpu(QITraceEvent *ev)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_is_vcpu(ev_);
+}
+
+SYM_PUBLIC
+const char *qi_trace_event_get_name(QITraceEvent *ev)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_name(ev_);
+}
+
+
+SYM_PUBLIC
+bool qi_trace_event_get_state(QITraceEvent *ev)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_state_static(ev_) &&
+ trace_event_get_state_dynamic(ev_);
+}
+
+SYM_PUBLIC
+bool qi_trace_event_get_vcpu_state(QICPU *vcpu, QITraceEvent *ev)
+{
+ CPUState *vcpu_ = (CPUState *)vcpu;
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!vcpu_, false, "must provide a vCPU");
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_state_static(ev_) &&
+ trace_event_get_vcpu_state_dynamic(vcpu_, ev_);
+}
+
+SYM_PUBLIC
+bool qi_trace_event_get_state_static(QITraceEvent *ev)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_state_static(ev_);
+}
+
+SYM_PUBLIC
+bool qi_trace_event_get_state_dynamic(QITraceEvent *ev)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_state_dynamic(ev_);
+}
+
+SYM_PUBLIC
+bool qi_trace_event_get_vcpu_state_dynamic(QICPU *vcpu, QITraceEvent *ev)
+{
+ CPUState *vcpu_ = (CPUState *)vcpu;
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF_RET(!vcpu_, false, "must provide a vCPU");
+ ERROR_IF_RET(!ev_, false, "must provide an event");
+ return trace_event_get_vcpu_state_dynamic(vcpu_, ev_);
+}
+
+SYM_PUBLIC
+void qi_trace_event_set_state_dynamic(QITraceEvent *ev, bool state)
+{
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF(!ev_, "must provide an event");
+ ERROR_IF(!trace_event_get_state_static(ev_),
+ "event must be statically enabled");
+ trace_event_set_state_dynamic(ev_, state);
+}
+
+SYM_PUBLIC
+void qi_trace_event_set_vcpu_state_dynamic(QICPU *vcpu,
+ QITraceEvent *ev, bool state)
+{
+ CPUState *vcpu_ = (CPUState *)vcpu;
+ TraceEvent *ev_ = (TraceEvent *)ev;
+ ERROR_IF(!vcpu_, "must provide a vCPU");
+ ERROR_IF(!ev_, "must provide an event");
+ ERROR_IF(!trace_event_get_state_static(ev_),
+ "event must be statically enabled");
+ trace_event_set_vcpu_state_dynamic(vcpu_, ev_, state);
+}
@@ -13,6 +13,7 @@
#include "qemu-common.h"
#include "event-internal.h"
+/* NOTE: Keep in sync with size of QITraceEventIter */
typedef struct TraceEventIter {
size_t event;
size_t group;
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- .gitignore | 1 Makefile | 3 + instrument/Makefile.objs | 1 instrument/error.h | 6 ++ instrument/qemu-instr/types.h | 51 +++++++++++++++ instrument/qemu-instr/types.inc.h | 15 ++++ instrument/trace.c | 125 +++++++++++++++++++++++++++++++++++++ trace/control.h | 1 8 files changed, 203 insertions(+) create mode 100644 instrument/qemu-instr/types.h create mode 100644 instrument/qemu-instr/types.inc.h create mode 100644 instrument/trace.c