Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu>
---
 scripts/tracetool.py                |   31 ++++++++++
 scripts/tracetool/__init__.py       |    8 +++
 scripts/tracetool/backend/dtrace.py |  104 +++++++++++++++++++++++++++++++++++
 scripts/tracetool/format/d.py       |   20 +++++++
 scripts/tracetool/format/stap.py    |   20 +++++++
 5 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 scripts/tracetool/backend/dtrace.py
 create mode 100644 scripts/tracetool/format/d.py
 create mode 100644 scripts/tracetool/format/stap.py

diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 22623ae..2dd9da0 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -44,6 +44,11 @@ Options:
     --help                   This help message.
     --list-backends          Print list of available backends.
     --check-backend          Check if the given backend is valid.
+    --binary <path>          Full path to QEMU binary.
+    --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>).\
 """ % {
             "script" : _SCRIPT,
             "backends" : backend_descr,
@@ -71,6 +76,10 @@ def main(args):
     check_backend = False
     arg_backend = ""
     arg_format = ""
+    binary = None
+    target_type = None
+    target_arch = None
+    probe_prefix = None
     for opt, arg in opts:
         if opt == "--help":
             error_opt()
@@ -87,6 +96,15 @@ def main(args):
         elif opt == "--check-backend":
             check_backend = True
 
+        elif opt == "--binary":
+            binary = arg
+        elif opt == '--target-type':
+            target_type = arg
+        elif opt == '--target-arch':
+            target_arch = arg
+        elif opt == '--probe-prefix':
+            probe_prefix = arg
+
         else:
             error_opt("unhandled option: %s" % opt)
 
@@ -101,6 +119,19 @@ def main(args):
 
     kwargs = {}
 
+    if format == "stap":
+        if binary is None:
+            error_opt("--binary is required for SystemTAP tapset generator")
+        if probe_prefix is None and target_type is None:
+            error_opt("--target-type is required for SystemTAP tapset 
generator")
+        if probe_prefix is None and target_arch is None:
+            error_opt("--target-arch is required for SystemTAP tapset 
generator")
+
+        if probe_prefix is None:
+            probe_prefix = ".".join([ "qemu", target_type, target_arch ])
+    kwargs["binary"] = binary
+    kwargs["probe_prefix"] = probe_prefix
+
     try:
         tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
     except tracetool.TracetoolError as e:
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 345b666..5c87583 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -164,6 +164,9 @@ def try_import(mod_name, attr_name = None, attr_default = 
None):
 
 def generate(fevents, format, backend, **options):
     """Generate the output for the given (format, backend) pair."""
+    binary = options.pop("binary", None)
+    probe_prefix = options.pop("probe_prefix", None)
+
     if len(options) > 0:
         raise ValueError("unknown options: " + ", ".join(options))
 
@@ -185,6 +188,11 @@ def generate(fevents, format, backend, **options):
         raise TracetoolError("backend '%s' not compatible with format '%s'" %
                              (backend, format))
 
+    if backend == "dtrace":
+        import tracetool.backend.dtrace
+        tracetool.backend.dtrace.BINARY = binary
+        tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
+
     events = _read_events(fevents)
 
     if backend == "nop":
diff --git a/scripts/tracetool/backend/dtrace.py 
b/scripts/tracetool/backend/dtrace.py
new file mode 100644
index 0000000..7c2051c
--- /dev/null
+++ b/scripts/tracetool/backend/dtrace.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+DTrace/SystemTAP backend.
+"""
+
+__author__     = "Lluís Vilanova <vilan...@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefa...@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+PUBLIC = True
+
+
+PROBEPREFIX = None
+
+def _probeprefix():
+    if PROBEPREFIX is None:
+        raise ValueError("you must set PROBEPREFIX")
+    return PROBEPREFIX
+
+
+BINARY = None
+
+def _binary():
+    if BINARY is None:
+        raise ValueError("you must set BINARY")
+    return BINARY
+
+
+def c(events):
+    pass
+
+
+def h(events):
+    out('#include "trace-dtrace.h"',
+        '')
+
+    for e in events:
+        out('''static inline void trace_%(name)s(%(args)s) {
+    QEMU_%(uppername)s(%(argnames)s);
+}
+''' %
+            {
+                'name': e.name,
+                'args': e.args,
+                'uppername': e.name.upper(),
+                'argnames': ", ".join(e.args.names()),
+                })
+
+
+def d(events):
+    out('provider qemu {')
+
+    for e in events:
+        args = e.args
+
+        # DTrace provider syntax expects foo() for empty
+        # params, not foo(void)
+        if args == 'void':
+            args = ''
+
+        # Define prototype for probe arguments
+        out('',
+            'probe %(name)s(%(args)s);' %
+            {
+                'name': e.name,
+                'args': args
+                })
+
+    out('',
+        '};')
+
+
+def stap(events):
+    for e in events:
+        # Define prototype for probe arguments
+        out('probe %(probeprefix)s.%(name)s = 
process("%(binary)s").mark("%(name)s")' %
+            {
+                'probeprefix': _probeprefix(),
+                'name': e.name,
+                'binary': _binary(),
+                },
+            '{')
+
+        i = 1
+        if len(e.args) > 0:
+            for name in e.args.names():
+                # 'limit' is a reserved keyword
+                if name == 'limit':
+                    name = '_limit'
+                out('  %s = $arg%d;' % (name.lstrip(), i))
+                i += 1
+
+        out('}')
+
+    out()
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
new file mode 100644
index 0000000..a2d5947
--- /dev/null
+++ b/scripts/tracetool/format/d.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .d file (DTrace only).
+"""
+
+__author__     = "Lluís Vilanova <vilan...@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefa...@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+    out('/* This file is autogenerated by tracetool, do not edit. */')
diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
new file mode 100644
index 0000000..50a4c69
--- /dev/null
+++ b/scripts/tracetool/format/stap.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .stp file (DTrace with SystemTAP only).
+"""
+
+__author__     = "Lluís Vilanova <vilan...@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefa...@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+    out('/* This file is autogenerated by tracetool, do not edit. */')


Reply via email to