1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5DTrace/SystemTAP backend.
6"""
7
8__author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
9__copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
10__license__    = "GPL version 2 or (at your option) any later version"
11
12__maintainer__ = "Stefan Hajnoczi"
13__email__      = "stefanha@linux.vnet.ibm.com"
14
15
16from tracetool import out
17
18
19PUBLIC = True
20
21
22PROBEPREFIX = None
23
24def _probeprefix():
25    if PROBEPREFIX is None:
26        raise ValueError("you must set PROBEPREFIX")
27    return PROBEPREFIX
28
29
30BINARY = None
31
32def _binary():
33    if BINARY is None:
34        raise ValueError("you must set BINARY")
35    return BINARY
36
37
38def c(events):
39    pass
40
41
42def h(events):
43    out('#include "trace/generated-tracers-dtrace.h"',
44        '')
45
46    for e in events:
47        out('static inline void trace_%(name)s(%(args)s) {',
48            '    QEMU_%(uppername)s(%(argnames)s);',
49            '}',
50            name = e.name,
51            args = e.args,
52            uppername = e.name.upper(),
53            argnames = ", ".join(e.args.names()),
54            )
55
56
57def d(events):
58    out('provider qemu {')
59
60    for e in events:
61        args = str(e.args)
62
63        # DTrace provider syntax expects foo() for empty
64        # params, not foo(void)
65        if args == 'void':
66            args = ''
67
68        # Define prototype for probe arguments
69        out('',
70            'probe %(name)s(%(args)s);',
71            name = e.name,
72            args = args,
73            )
74
75    out('',
76        '};')
77
78
79# Technically 'self' is not used by systemtap yet, but
80# they recommended we keep it in the reserved list anyway
81RESERVED_WORDS = (
82    'break', 'catch', 'continue', 'delete', 'else', 'for',
83    'foreach', 'function', 'global', 'if', 'in', 'limit',
84    'long', 'next', 'probe', 'return', 'self', 'string',
85    'try', 'while'
86    )
87
88def stap(events):
89    for e in events:
90        # Define prototype for probe arguments
91        out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
92            '{',
93            probeprefix = _probeprefix(),
94            name = e.name,
95            binary = _binary(),
96            )
97
98        i = 1
99        if len(e.args) > 0:
100            for name in e.args.names():
101                # Append underscore to reserved keywords
102                if name in RESERVED_WORDS:
103                    name += '_'
104                out('  %s = $arg%d;' % (name, i))
105                i += 1
106
107        out('}')
108
109    out()
110