Revert "Add support for generating a systemtap tapset static probes"
[qemu.git] / tracetool
blob5b6636ac27cbbe6c71467a10bdad095199bb6bb9
1 #!/bin/sh
3 # Code generator for trace events
5 # Copyright IBM, Corp. 2010
7 # This work is licensed under the terms of the GNU GPL, version 2. See
8 # the COPYING file in the top-level directory.
10 # Disable pathname expansion, makes processing text with '*' characters simpler
11 set -f
13 usage()
15 cat >&2 <<EOF
16 usage: $0 [--nop | --simple | --ust] [-h | -c]
17 Generate tracing code for a file on stdin.
19 Backends:
20 --nop Tracing disabled
21 --simple Simple built-in backend
22 --ust LTTng User Space Tracing backend
23 --dtrace DTrace/SystemTAP backend
25 Output formats:
26 -h Generate .h file
27 -c Generate .c file
28 -d Generate .d file (DTrace only)
29 EOF
30 exit 1
33 # Get the name of a trace event
34 get_name()
36 echo ${1%%\(*}
39 # Get the argument list of a trace event, including types and names
40 get_args()
42 local args
43 args=${1#*\(}
44 args=${args%\)*}
45 echo "$args"
48 # Get the argument name list of a trace event
49 get_argnames()
51 local nfields field name sep
52 nfields=0
53 sep="$2"
54 for field in $(get_args "$1"); do
55 nfields=$((nfields + 1))
57 # Drop pointer star
58 field=${field#\*}
60 # Only argument names have commas at the end
61 name=${field%,}
62 test "$field" = "$name" && continue
64 printf "%s%s " $name $sep
65 done
67 # Last argument name
68 if [ "$nfields" -gt 1 ]
69 then
70 printf "%s" "$name"
74 # Get the number of arguments to a trace event
75 get_argc()
77 local name argc
78 argc=0
79 for name in $(get_argnames "$1", ","); do
80 argc=$((argc + 1))
81 done
82 echo $argc
85 # Get the format string for a trace event
86 get_fmt()
88 local fmt
89 fmt=${1#*\"}
90 fmt=${fmt%\"*}
91 echo "$fmt"
94 # Get the state of a trace event
95 get_state()
97 local str disable state
98 str=$(get_name "$1")
99 disable=${str##disable }
100 if [ "$disable" = "$str" ] ; then
101 state=1
102 else
103 state=0
105 echo "$state"
108 linetoh_begin_nop()
110 return
113 linetoh_nop()
115 local name args
116 name=$(get_name "$1")
117 args=$(get_args "$1")
119 # Define an empty function for the trace event
120 cat <<EOF
121 static inline void trace_$name($args)
127 linetoh_end_nop()
129 return
132 linetoc_begin_nop()
134 return
137 linetoc_nop()
139 # No need for function definitions in nop backend
140 return
143 linetoc_end_nop()
145 return
148 linetoh_begin_simple()
150 cat <<EOF
151 #include "simpletrace.h"
154 simple_event_num=0
157 cast_args_to_uint64_t()
159 local arg
160 for arg in $(get_argnames "$1", ","); do
161 printf "%s" "(uint64_t)(uintptr_t)$arg"
162 done
165 linetoh_simple()
167 local name args argc trace_args state
168 name=$(get_name "$1")
169 args=$(get_args "$1")
170 argc=$(get_argc "$1")
171 state=$(get_state "$1")
172 if [ "$state" = "0" ]; then
173 name=${name##disable }
176 trace_args="$simple_event_num"
177 if [ "$argc" -gt 0 ]
178 then
179 trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
182 cat <<EOF
183 static inline void trace_$name($args)
185 trace$argc($trace_args);
189 simple_event_num=$((simple_event_num + 1))
192 linetoh_end_simple()
194 cat <<EOF
195 #define NR_TRACE_EVENTS $simple_event_num
196 extern TraceEvent trace_list[NR_TRACE_EVENTS];
200 linetoc_begin_simple()
202 cat <<EOF
203 #include "trace.h"
205 TraceEvent trace_list[] = {
207 simple_event_num=0
211 linetoc_simple()
213 local name state
214 name=$(get_name "$1")
215 state=$(get_state "$1")
216 if [ "$state" = "0" ] ; then
217 name=${name##disable }
219 cat <<EOF
220 {.tp_name = "$name", .state=$state},
222 simple_event_num=$((simple_event_num + 1))
225 linetoc_end_simple()
227 cat <<EOF
232 # Clean up after UST headers which pollute the namespace
233 ust_clean_namespace() {
234 cat <<EOF
235 #undef mutex_lock
236 #undef mutex_unlock
237 #undef inline
238 #undef wmb
242 linetoh_begin_ust()
244 echo "#include <ust/tracepoint.h>"
245 ust_clean_namespace
248 linetoh_ust()
250 local name args argnames
251 name=$(get_name "$1")
252 args=$(get_args "$1")
253 argnames=$(get_argnames "$1", ",")
255 cat <<EOF
256 DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
257 #define trace_$name trace_ust_$name
261 linetoh_end_ust()
263 return
266 linetoc_begin_ust()
268 cat <<EOF
269 #include <ust/marker.h>
270 $(ust_clean_namespace)
271 #include "trace.h"
275 linetoc_ust()
277 local name args argnames fmt
278 name=$(get_name "$1")
279 args=$(get_args "$1")
280 argnames=$(get_argnames "$1", ",")
281 fmt=$(get_fmt "$1")
283 cat <<EOF
284 DEFINE_TRACE(ust_$name);
286 static void ust_${name}_probe($args)
288 trace_mark(ust, $name, "$fmt", $argnames);
292 # Collect names for later
293 names="$names $name"
296 linetoc_end_ust()
298 cat <<EOF
299 static void __attribute__((constructor)) trace_init(void)
303 for name in $names; do
304 cat <<EOF
305 register_trace_ust_$name(ust_${name}_probe);
307 done
309 echo "}"
312 linetoh_begin_dtrace()
314 cat <<EOF
315 #include "trace-dtrace.h"
319 linetoh_dtrace()
321 local name args argnames state nameupper
322 name=$(get_name "$1")
323 args=$(get_args "$1")
324 argnames=$(get_argnames "$1", ",")
325 state=$(get_state "$1")
326 if [ "$state" = "0" ] ; then
327 name=${name##disable }
330 nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
332 # Define an empty function for the trace event
333 cat <<EOF
334 static inline void trace_$name($args) {
335 if (QEMU_${nameupper}_ENABLED()) {
336 QEMU_${nameupper}($argnames);
342 linetoh_end_dtrace()
344 return
347 linetoc_begin_dtrace()
349 return
352 linetoc_dtrace()
354 # No need for function definitions in dtrace backend
355 return
358 linetoc_end_dtrace()
360 return
363 linetod_begin_dtrace()
365 cat <<EOF
366 provider qemu {
370 linetod_dtrace()
372 local name args state
373 name=$(get_name "$1")
374 args=$(get_args "$1")
375 state=$(get_state "$1")
376 if [ "$state" = "0" ] ; then
377 name=${name##disable }
380 # Define prototype for probe arguments
381 cat <<EOF
382 probe $name($args);
386 linetod_end_dtrace()
388 cat <<EOF
393 # Process stdin by calling begin, line, and end functions for the backend
394 convert()
396 local begin process_line end str disable
397 begin="lineto$1_begin_$backend"
398 process_line="lineto$1_$backend"
399 end="lineto$1_end_$backend"
401 "$begin"
403 while read -r str; do
404 # Skip comments and empty lines
405 test -z "${str%%#*}" && continue
407 # Process the line. The nop backend handles disabled lines.
408 disable=${str%%disable *}
409 echo
410 if test -z "$disable"; then
411 # Pass the disabled state as an arg for the simple
412 # or DTrace backends which handle it dynamically.
413 # For all other backends, call lineto$1_nop()
414 if [ $backend = "simple" -o "$backend" = "dtrace" ]; then
415 "$process_line" "$str"
416 else
417 "lineto$1_nop" "${str##disable }"
419 else
420 "$process_line" "$str"
422 done
424 echo
425 "$end"
428 tracetoh()
430 cat <<EOF
431 #ifndef TRACE_H
432 #define TRACE_H
434 /* This file is autogenerated by tracetool, do not edit. */
436 #include "qemu-common.h"
438 convert h
439 echo "#endif /* TRACE_H */"
442 tracetoc()
444 echo "/* This file is autogenerated by tracetool, do not edit. */"
445 convert c
448 tracetod()
450 if [ $backend != "dtrace" ]; then
451 echo "DTrace probe generator not applicable to $backend backend"
452 exit 1
454 echo "/* This file is autogenerated by tracetool, do not edit. */"
455 convert d
458 # Choose backend
459 case "$1" in
460 "--nop" | "--simple" | "--ust" | "--dtrace") backend="${1#--}" ;;
461 *) usage ;;
462 esac
463 shift
465 case "$1" in
466 "-h") tracetoh ;;
467 "-c") tracetoc ;;
468 "-d") tracetod ;;
469 "--check-backend") exit 0 ;; # used by ./configure to test for backend
470 *) usage ;;
471 esac
473 exit 0