@@ -148,6 +148,8 @@ include $(SRC_PATH)/Makefile.objs
all-obj-y = $(obj-y)
all-obj-y += $(addprefix ../, $(common-obj-y))
+all-obj-y += $(LIBTRACE_INSTRUMENT)
+
ifdef QEMU_PROGW
# The linker builds a windows executable. Make also a console executable.
$(QEMU_PROGW): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
@@ -215,6 +215,7 @@ trace_events=`dirname $0`/trace-events
trace_backend="nop"
trace_file="trace"
trace_instrument="none"
+trace_instrument_path=""
spice=""
rbd=""
smartcard_nss=""
@@ -634,6 +635,8 @@ for opt do
;;
--with-trace-instrument=*) trace_instrument="$optarg"
;;
+ --with-trace-instrument-path=*) trace_instrument_path="$optarg"
+ ;;
--enable-gprof) gprof="yes"
;;
--enable-gcov) gcov="yes"
@@ -1145,7 +1148,9 @@ echo " Available backends:" $($python "$source_path"/s
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
echo " --with-trace-instrument=TYPE"
-echo " Trace instrumentation type (none; default: $trace_instrument)"
+echo " Trace instrumentation type (none static; default: $trace_instrument)"
+echo " --with-trace-instrument-path=PATH"
+echo " Directory to build user-provided static trace event instrumentation library"
echo " --disable-spice disable spice"
echo " --enable-spice enable spice"
echo " --enable-rbd enable building the rados block device (rbd)"
@@ -3067,13 +3072,32 @@ fi
##########################################
# Check instrumentation type
case "$trace_instrument" in
-none) ;;
+none|static) ;;
*) echo "Error: invalid trace instrumentation type: $trace_instrument"
exit 1
;;
esac
##########################################
+# check for a valid directory for static trace instrumentation
+if test "$trace_instrument" = "static" -a -z "$trace_instrument_path"; then
+ echo "Error: must provide '--with-trace-instrument-path' when using static trace instrumentation"
+ exit 1
+fi
+if test "$trace_instrument" != "static" -a -n "$trace_instrument_path"; then
+ echo "Error: cannot provide '--with-trace-instrument-path' when not using static trace instrumentation"
+ exit 1
+fi
+if test "$trace_instrument" = "static" -a ! -f "$trace_instrument_path/Makefile"; then
+ echo
+ echo "Error: cannot make into '$trace_instrument_path'"
+ echo "Please choose a directory where I can run 'make'"
+ echo
+ exit 1
+fi
+trace_instrument_path=`readlink -f "$trace_instrument_path"`
+
+##########################################
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
# specification is necessary
@@ -3427,6 +3451,9 @@ echo "Trace events $trace_events"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "Trace instrument $trace_instrument"
+if test -n "$trace_instrument_path"; then
+echo "Static instrument $trace_instrument_path"
+fi
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
@@ -3866,6 +3893,13 @@ if test "$trace_instrument" = "none"; then
else
echo "CONFIG_TRACE_INSTRUMENT=y" >> $config_host_mak
fi
+if test "$trace_instrument" = "static"; then
+ echo "#define QI_TYPE_STATIC 1" >> $config_qi
+ echo "CONFIG_TRACE_INSTRUMENT_STATIC=y" >> $config_host_mak
+ echo "TRACE_INSTRUMENT_PATH=\"$trace_instrument_path\"" >> $config_host_mak
+ echo "TRACETOOL_INSTR_STATIC=--instr-static-path \"\$(TRACE_INSTRUMENT_PATH)\"" >> $config_host_mak
+ QEMU_CFLAGS="-I\"$trace_instrument_path\" $QEMU_CFLAGS"
+fi
##########################################
echo "TOOLS=$tools" >> $config_host_mak
@@ -4136,6 +4170,10 @@ if [ "$TARGET_BASE_ARCH" = "" ]; then
fi
symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+if test -n "$trace_instrument_path"; then
+ mkdir -p $target_dir/libtrace-instrument
+ symlink $trace_instrument_path/Makefile $target_dir/libtrace-instrument/Makefile
+fi
upper() {
echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
@@ -8,9 +8,15 @@ $(obj)/generated-tracers.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.m
$(call quiet-command,$(TRACETOOL) \
--format=qemu-h \
--backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $(TRACETOOL_INSTR_STATIC) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+ifdef CONFIG_TRACE_INSTRUMENT_STATIC
+# Rebuild to check for user headers
+.PHONY: $(obj)/generated-tracers.h-timestamp
+endif
+
######################################################################
# User interface
@@ -20,5 +26,26 @@ $(obj)/qemu-instr/events.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.m
$(call quiet-command,$(TRACETOOL) \
--format=api-h \
--backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $(TRACETOOL_INSTR_STATIC) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+
+######################################################################
+# User code (static instrumentation)
+
+ifdef CONFIG_TRACE_INSTRUMENT_STATIC
+LIBTRACE_INSTRUMENT = libtrace-instrument/libtrace-instrument.a
+
+.PHONY: force
+force:
+
+_libinstrument_cflags = $(subst libtrace-instrument,.,$(subst libtrace-instrument/,.,$(1)))
+$(LIBTRACE_INSTRUMENT): QEMU_CFLAGS += -I$(BUILD_DIR)/
+$(LIBTRACE_INSTRUMENT): VPATH = $(TRACE_INSTRUMENT_PATH)
+$(LIBTRACE_INSTRUMENT): $(dir $(LIBTRACE_INSTRUMENT))/Makefile force
+ $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) \
+ QEMU_CFLAGS="$(call _libinstrument_cflags,$(QEMU_CFLAGS))" \
+ TARGET_DIR=$(TARGET_DIR)$(dir $@)/ VPATH=$(VPATH) \
+ SRC_PATH=$(SRC_PATH) V="$(V)" $(notdir $@))
+endif
@@ -48,7 +48,10 @@ Options:
--target-type <type> QEMU emulator target type ('system' or 'user').
--target-arch <arch> QEMU emulator target arch.
--probe-prefix <prefix> Prefix for dtrace probe names
- (default: qemu-<target-type>-<target-arch>).\
+ (default: qemu-<target-type>-<target-arch>).
+ --instr-static--path <path>
+ Path to directory containing static instrumentation
+ library.\
""" % {
"script" : _SCRIPT,
"backends" : backend_descr,
@@ -67,6 +70,7 @@ def main(args):
long_opts = [ "backend=", "format=", "help", "list-backends", "check-backend" ]
long_opts += [ "binary=", "target-type=", "target-arch=", "probe-prefix=" ]
+ long_opts += [ "instr-static-path=" ]
try:
opts, args = getopt.getopt(args[1:], "", long_opts)
@@ -80,6 +84,7 @@ def main(args):
target_type = None
target_arch = None
probe_prefix = None
+ instr_static_path = None
for opt, arg in opts:
if opt == "--help":
error_opt()
@@ -104,6 +109,8 @@ def main(args):
target_arch = arg
elif opt == '--probe-prefix':
probe_prefix = arg
+ elif opt == '--instr-static-path':
+ instr_static_path = arg
else:
error_opt("unhandled option: %s" % opt)
@@ -130,7 +137,8 @@ def main(args):
try:
tracetool.generate(sys.stdin, arg_format, arg_backend,
- binary = binary, probe_prefix = probe_prefix)
+ binary = binary, probe_prefix = probe_prefix,
+ instr_static_path = instr_static_path)
except tracetool.TracetoolError, e:
error_opt(str(e))
@@ -180,6 +180,8 @@ class Event(object):
QEMU_TRACE = "trace_%(name)s"
QEMU_TRACE_BACKEND = "trace_%(name)s_backend"
QI_TRACE_INSTRUMENT = "qi_event_%(name)s"
+ QI_TRACE_NOP = "qi_event_%(name)s_nop"
+ QI_TRACE_BACKEND = "qi_event_%(name)s_trace"
def api(self, fmt = None):
if fmt is None:
@@ -229,7 +231,8 @@ def try_import(mod_name, attr_name = None, attr_default = None):
def generate(fevents, format, backend,
- binary = None, probe_prefix = None):
+ binary = None, probe_prefix = None,
+ instr_static_path = None):
"""Generate the output for the given (format, backend) pair.
Parameters
@@ -244,6 +247,8 @@ def generate(fevents, format, backend,
See tracetool.backend.dtrace.BINARY.
probe_prefix : str or None
See tracetool.backend.dtrace.PROBEPREFIX.
+ instr_static_path : str or None
+ See tracetool.backend.instr_static.PATH.
"""
# fix strange python error (UnboundLocalError tracetool)
import tracetool
@@ -270,6 +275,9 @@ def generate(fevents, format, backend,
tracetool.backend.dtrace.BINARY = binary
tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
+ import tracetool.backend.instr_static
+ tracetool.backend.instr_static.PATH = instr_static_path
+
events = _read_events(fevents)
if backend == "nop":
new file mode 100644
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Static instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+import os
+
+from tracetool import out
+import tracetool.format.qemu_h
+
+
+PATH = None
+
+def _path():
+ if PATH is None:
+ raise ValueError("you must set PATH")
+ return PATH
+
+
+def qemu_h(events):
+ if _path() and os.path.exists(os.sep.join([_path(), "events-pre.h"])):
+ out('#include "events-pre.h"',
+ '',
+ )
+
+ out('#include "instrument/qemu-instr/events.h"',
+ '',
+ )
+ tracetool.format.qemu_h.process_common(events)
+
+ if _path() and os.path.exists(os.sep.join([_path(), "events-post.h"])):
+ out('#include "events-post.h"',
+ '',
+ )
+
+def api_h(events):
+ out('#include "trace/generated-tracers.h"',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('#if defined(QI_EVENT_%(upper_name)s_INLINE)',
+ 'static',
+ '#endif',
+ 'void %(qi)s(%(args)s);',
+ '',
+ 'static inline void %(qi_nop)s(%(args)s)',
+ '{',
+ '}',
+ '',
+ 'static inline void %(qi_backend)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ upper_name = e.name.upper(),
+ )
Compiles a user-provided static library during QEMU compilation. This library must provide the implementation of the 'qi_event_*' routines. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- Makefile.target | 2 + configure | 42 +++++++++++++++- instrument/Makefile.objs | 27 ++++++++++ scripts/tracetool.py | 12 ++++- scripts/tracetool/__init__.py | 10 +++- scripts/tracetool/backend/instr_static.py | 76 +++++++++++++++++++++++++++++ 6 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 scripts/tracetool/backend/instr_static.py