@@ -43,3 +43,4 @@ $(obj)/qemu-instr/events.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
# Control code
target-obj-y += control.o
+target-obj-y += cmdline.o
new file mode 100644
@@ -0,0 +1,117 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * 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 <dlfcn.h>
+#include "instrument/cmdline.h"
+#include "instrument/control.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)
+{
+ InstrLoadError err;
+ int64_t handle;
+
+ if (path == NULL) {
+ return;
+ }
+
+ if (atexit(instr_fini) != 0) {
+ fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+ abort();
+ }
+
+ err = instr_load(path, argc, argv, &handle);
+ switch (err) {
+ case INSTR_LOAD_OK:
+ return;
+ case INSTR_LOAD_UNAVAILABLE:
+ error_report("instrument: not available");
+ break;
+ case INSTR_LOAD_ERROR:
+ error_report("instrument: error loading library: %s", dlerror());
+ break;
+ }
+
+ exit(1);
+}
+
+void instr_fini(void)
+{
+ InstrUnloadError err = instr_unload_all();
+
+ switch (err) {
+ case INSTR_UNLOAD_OK:
+ return;
+ case INSTR_UNLOAD_UNAVAILABLE:
+ error_report("instrument: not available");
+ break;
+ case INSTR_UNLOAD_INVALID:
+ /* the user might have already unloaded it */
+ return;
+ case INSTR_UNLOAD_ERROR:
+ error_report("instrument: error unloading library: %s", dlerror());
+ break;
+ }
+
+ exit(1);
+}
new file mode 100644
@@ -0,0 +1,58 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * 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 INSTRUMENT__CMDLINE_H
+#define INSTRUMENT__CMDLINE_H
+
+
+/**
+ * Definition of QEMU options describing instrumentation subsystem
+ * configuration.
+ */
+extern QemuOptsList qemu_instr_opts;
+
+/**
+ * instr_opt_parse:
+ * @optarg: A string argument of --instrument command line argument
+ *
+ * Initialize instrument subsystem.
+ */
+void instr_opt_parse(const char *optarg, char **path,
+ int *argc, const char ***argv);
+
+/**
+ * instr_init:
+ * @path: Path to dynamic trace instrumentation library.
+ * @argc: Number of arguments to the library's #qi_init routine.
+ * @argv: Arguments to the library's #qi_init routine.
+ *
+ * Load and initialize the given instrumentation library.
+ *
+ * Automatically installs #instr_fini as an atexit callback.
+ *
+ * If path is %NULL and we're running with static instrumentation, the library
+ * is not loaded but just initialized.
+ *
+ * Pre-condition: There is no library already loaded.
+ */
+void instr_init(const char *path, int argc, const char **argv);
+
+/**
+ * instr_fini:
+ *
+ * Deinitialize and unload the current instrumentation library.
+ *
+ * If we're running with static instrumentation, the library is not unloaded but
+ * just deinitialized.
+ *
+ * Pre-condition: There is an already loaded library.
+ */
+void instr_fini(void);
+
+#endif /* INSTRUMENT__CMDLINE_H */
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- instrument/Makefile.objs | 1 instrument/cmdline.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++ instrument/cmdline.h | 58 +++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 instrument/cmdline.c create mode 100644 instrument/cmdline.h