Signed-off-by: Lluís Vilanova
---
MAINTAINERS |1
Makefile.objs|4 +
configure|3 +
instrument/Makefile.objs |4 +
instrument/cmdline.c | 128 +++
instrument/cmdline.h | 51 ++
instrument/load.c| 166 ++
instrument/load.h| 88
stubs/Makefile.objs |1
stubs/instrument.c | 18 +
10 files changed, 464 insertions(+)
create mode 100644 instrument/Makefile.objs
create mode 100644 instrument/cmdline.c
create mode 100644 instrument/cmdline.h
create mode 100644 instrument/load.c
create mode 100644 instrument/load.h
create mode 100644 stubs/instrument.c
diff --git a/MAINTAINERS b/MAINTAINERS
index fb0eaee06a..6c0b12a69a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1491,6 +1491,7 @@ M: Lluís Vilanova
M: Stefan Hajnoczi
S: Maintained
F: docs/instrument.txt
+F: instrument/
TPM
S: Orphan
diff --git a/Makefile.objs b/Makefile.objs
index 24a4ea08b8..81a9218e14 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -97,6 +97,10 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
util-obj-y += trace/
target-obj-y += trace/
+##
+# instrument
+target-obj-y += instrument/
+
##
# guest agent
diff --git a/configure b/configure
index a21d1bceb9..5175151317 100755
--- a/configure
+++ b/configure
@@ -6025,6 +6025,9 @@ fi
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
if test "$instrument" = "yes"; then
+ LDFLAGS="-rdynamic $LDFLAGS" # limit symbols available to clients
+ QEMU_CFLAGS="-fvisibility=hidden $QEMU_CFLAGS"
+ LIBS="-ldl $LIBS"
echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
fi
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
new file mode 100644
index 00..71994a4c85
--- /dev/null
+++ b/instrument/Makefile.objs
@@ -0,0 +1,4 @@
+# -*- mode: makefile -*-
+
+target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
+target-obj-$(CONFIG_INSTRUMENT) += load.o
diff --git a/instrument/cmdline.c b/instrument/cmdline.c
new file mode 100644
index 00..da7a7cbceb
--- /dev/null
+++ b/instrument/cmdline.c
@@ -0,0 +1,128 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova
+ *
+ * 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
+#include "instrument/cmdline.h"
+#include "instrument/load.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+
+
+QemuOptsList qemu_instr_opts = {
+.name = "instrument",
+.implied_opt_name = "file",
+.merge_lists = true,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head),
+.desc = {
+{
+.name = "file",
+.type = QEMU_OPT_STRING,
+},{
+.name = "arg",
+.type = QEMU_OPT_STRING,
+},
+{ /* end of list */ }
+},
+};
+
+void instr_opt_parse(const char *optarg, char **path,
+ int *argc, const char ***argv)
+{
+const char *arg;
+QemuOptsIter iter;
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("instrument"),
+ optarg, true);
+if (!opts) {
+exit(1);
+} else {
+#if !defined(CONFIG_INSTRUMENT)
+error_report("instrumentation not enabled on this build");
+exit(1);
+#endif
+}
+
+
+arg = qemu_opt_get(opts, "file");
+if (arg != NULL) {
+g_free(*path);
+*path = g_strdup(arg);
+}
+
+qemu_opt_iter_init(&iter, opts, "arg");
+while ((arg = qemu_opt_iter_next(&iter)) != NULL) {
+*argv = realloc(*argv, sizeof(**argv) * (*argc + 1));
+(*argv)[*argc] = g_strdup(arg);
+(*argc)++;
+}
+
+qemu_opts_del(opts);
+}
+
+void instr_init(const char *path, int argc, const char **argv)
+{
+#if defined(CONFIG_INSTRUMENT)
+InstrLoadError err;
+
+if (path == NULL) {
+return;
+}
+
+if (atexit(instr_fini) != 0) {
+fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+abort();
+}
+
+const char *id = "cmdline";
+err = instr_load(path, argc, argv, &id);
+switch (err) {
+case INSTR_LOAD_OK:
+error_report("instrument: loaded library with ID '%s'", id);
+return;
+case INSTR_LOAD_TOO_MANY:
+error_report("instrument: tried to load too many libraries");
+break;
+case INSTR_LOAD_ID_EXISTS:
+g_assert_not_reached();
+break;
+case INSTR_LOAD_ERROR:
+error_report("instrument: library initialization returned non-zero");
+break;
+case INSTR_LOAD_DLERROR:
+error_report("instrument: error loading library: