]> git.proxmox.com Git - qemu.git/blame - tracetool
QMP: Don't use do_info()
[qemu.git] / tracetool
CommitLineData
94a420b1
SH
1#!/bin/sh
2#
3# Code generator for trace events
4#
5# Copyright IBM, Corp. 2010
6#
7# This work is licensed under the terms of the GNU GPL, version 2. See
8# the COPYING file in the top-level directory.
9
10# Disable pathname expansion, makes processing text with '*' characters simpler
11set -f
12
13usage()
14{
15 cat >&2 <<EOF
7e24e92a 16usage: $0 [--nop | --simple | --ust] [-h | -c]
94a420b1
SH
17Generate tracing code for a file on stdin.
18
19Backends:
26f7227b
SH
20 --nop Tracing disabled
21 --simple Simple built-in backend
7e24e92a 22 --ust LTTng User Space Tracing backend
94a420b1
SH
23
24Output formats:
25 -h Generate .h file
26 -c Generate .c file
27EOF
28 exit 1
29}
30
31# Get the name of a trace event
32get_name()
33{
34 echo ${1%%\(*}
35}
36
37# Get the argument list of a trace event, including types and names
38get_args()
39{
40 local args
41 args=${1#*\(}
2184d75b 42 args=${args%\)*}
94a420b1
SH
43 echo "$args"
44}
45
46# Get the argument name list of a trace event
47get_argnames()
48{
49 local nfields field name
50 nfields=0
51 for field in $(get_args "$1"); do
52 nfields=$((nfields + 1))
53
54 # Drop pointer star
55 field=${field#\*}
56
57 # Only argument names have commas at the end
58 name=${field%,}
59 test "$field" = "$name" && continue
60
61 printf "%s" "$name, "
62 done
63
64 # Last argument name
65 if [ "$nfields" -gt 1 ]
66 then
67 printf "%s" "$name"
68 fi
69}
70
26f7227b
SH
71# Get the number of arguments to a trace event
72get_argc()
73{
74 local name argc
75 argc=0
76 for name in $(get_argnames "$1"); do
77 argc=$((argc + 1))
78 done
79 echo $argc
80}
81
94a420b1
SH
82# Get the format string for a trace event
83get_fmt()
84{
85 local fmt
86 fmt=${1#*\"}
87 fmt=${fmt%\"*}
88 echo "$fmt"
89}
90
1e2cf2bc
SH
91# Get the state of a trace event
92get_state()
93{
94 local str disable state
95 str=$(get_name "$1")
96 disable=${str##disable }
97 if [ "$disable" = "$str" ] ; then
98 state=1
99 else
100 state=0
101 fi
102 echo "$state"
103}
104
94a420b1
SH
105linetoh_begin_nop()
106{
107 return
108}
109
110linetoh_nop()
111{
112 local name args
113 name=$(get_name "$1")
114 args=$(get_args "$1")
115
116 # Define an empty function for the trace event
117 cat <<EOF
118static inline void trace_$name($args)
119{
120}
121EOF
122}
123
124linetoh_end_nop()
125{
126 return
127}
128
129linetoc_begin_nop()
130{
131 return
132}
133
134linetoc_nop()
135{
136 # No need for function definitions in nop backend
137 return
138}
139
140linetoc_end_nop()
141{
142 return
143}
144
26f7227b
SH
145linetoh_begin_simple()
146{
147 cat <<EOF
148#include "simpletrace.h"
149EOF
150
151 simple_event_num=0
152}
153
154cast_args_to_uint64_t()
155{
156 local arg
157 for arg in $(get_argnames "$1"); do
158 printf "%s" "(uint64_t)(uintptr_t)$arg"
159 done
160}
161
162linetoh_simple()
163{
1e2cf2bc 164 local name args argc trace_args state
26f7227b
SH
165 name=$(get_name "$1")
166 args=$(get_args "$1")
167 argc=$(get_argc "$1")
1e2cf2bc
SH
168 state=$(get_state "$1")
169 if [ "$state" = "0" ]; then
170 name=${name##disable }
171 fi
26f7227b
SH
172
173 trace_args="$simple_event_num"
174 if [ "$argc" -gt 0 ]
175 then
176 trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
177 fi
178
179 cat <<EOF
180static inline void trace_$name($args)
181{
182 trace$argc($trace_args);
183}
184EOF
185
186 simple_event_num=$((simple_event_num + 1))
187}
188
189linetoh_end_simple()
190{
22890ab5
PS
191 cat <<EOF
192#define NR_TRACE_EVENTS $simple_event_num
193extern TraceEvent trace_list[NR_TRACE_EVENTS];
194EOF
26f7227b
SH
195}
196
197linetoc_begin_simple()
198{
22890ab5
PS
199 cat <<EOF
200#include "trace.h"
201
202TraceEvent trace_list[] = {
203EOF
204 simple_event_num=0
205
26f7227b
SH
206}
207
208linetoc_simple()
209{
1e2cf2bc 210 local name state
22890ab5 211 name=$(get_name "$1")
1e2cf2bc
SH
212 state=$(get_state "$1")
213 if [ "$state" = "0" ] ; then
214 name=${name##disable }
215 fi
22890ab5 216 cat <<EOF
1e2cf2bc 217{.tp_name = "$name", .state=$state},
22890ab5
PS
218EOF
219 simple_event_num=$((simple_event_num + 1))
26f7227b
SH
220}
221
222linetoc_end_simple()
223{
22890ab5
PS
224 cat <<EOF
225};
226EOF
26f7227b
SH
227}
228
7e24e92a
SH
229# Clean up after UST headers which pollute the namespace
230ust_clean_namespace() {
231 cat <<EOF
232#undef mutex_lock
233#undef mutex_unlock
234#undef inline
235#undef wmb
236EOF
237}
238
239linetoh_begin_ust()
240{
241 echo "#include <ust/tracepoint.h>"
242 ust_clean_namespace
243}
244
245linetoh_ust()
246{
247 local name args argnames
248 name=$(get_name "$1")
249 args=$(get_args "$1")
250 argnames=$(get_argnames "$1")
251
252 cat <<EOF
253DECLARE_TRACE(ust_$name, TPPROTO($args), TPARGS($argnames));
254#define trace_$name trace_ust_$name
255EOF
256}
257
258linetoh_end_ust()
259{
260 return
261}
262
263linetoc_begin_ust()
264{
265 cat <<EOF
266#include <ust/marker.h>
267$(ust_clean_namespace)
268#include "trace.h"
269EOF
270}
271
272linetoc_ust()
273{
274 local name args argnames fmt
275 name=$(get_name "$1")
276 args=$(get_args "$1")
277 argnames=$(get_argnames "$1")
278 fmt=$(get_fmt "$1")
279
280 cat <<EOF
281DEFINE_TRACE(ust_$name);
282
283static void ust_${name}_probe($args)
284{
285 trace_mark(ust, $name, "$fmt", $argnames);
286}
287EOF
288
289 # Collect names for later
290 names="$names $name"
291}
292
293linetoc_end_ust()
294{
295 cat <<EOF
296static void __attribute__((constructor)) trace_init(void)
297{
298EOF
299
300 for name in $names; do
301 cat <<EOF
302 register_trace_ust_$name(ust_${name}_probe);
303EOF
304 done
305
306 echo "}"
307}
308
94a420b1
SH
309# Process stdin by calling begin, line, and end functions for the backend
310convert()
311{
1e2cf2bc 312 local begin process_line end str disable
94a420b1
SH
313 begin="lineto$1_begin_$backend"
314 process_line="lineto$1_$backend"
315 end="lineto$1_end_$backend"
316
317 "$begin"
318
319 while read -r str; do
320 # Skip comments and empty lines
321 str=${str%%#*}
322 test -z "$str" && continue
323
1e2cf2bc
SH
324 # Process the line. The nop backend handles disabled lines.
325 disable=${str%%disable *}
94a420b1 326 echo
1e2cf2bc
SH
327 if test -z "$disable"; then
328 # Pass the disabled state as an arg to lineto$1_simple().
329 # For all other cases, call lineto$1_nop()
330 if [ $backend = "simple" ]; then
331 "$process_line" "$str"
332 else
333 "lineto$1_nop" "${str##disable }"
334 fi
335 else
336 "$process_line" "$str"
337 fi
94a420b1
SH
338 done
339
340 echo
341 "$end"
342}
343
344tracetoh()
345{
346 cat <<EOF
347#ifndef TRACE_H
348#define TRACE_H
349
350/* This file is autogenerated by tracetool, do not edit. */
351
352#include "qemu-common.h"
353EOF
354 convert h
355 echo "#endif /* TRACE_H */"
356}
357
358tracetoc()
359{
360 echo "/* This file is autogenerated by tracetool, do not edit. */"
361 convert c
362}
363
364# Choose backend
365case "$1" in
7e24e92a 366"--nop" | "--simple" | "--ust") backend="${1#--}" ;;
94a420b1
SH
367*) usage ;;
368esac
369shift
370
371case "$1" in
372"-h") tracetoh ;;
373"-c") tracetoc ;;
374"--check-backend") exit 0 ;; # used by ./configure to test for backend
375*) usage ;;
376esac
377
378exit 0