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
16 usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c]
17 Generate tracing code for a file on stdin.
20 --nop Tracing disabled
21 --simple Simple built-in backend
22 --stderr Stderr built-in backend
23 --ust LTTng User Space Tracing backend
24 --dtrace DTrace/SystemTAP backend
29 -d Generate .d file (DTrace only)
30 --stap Generate .stp file (DTrace with SystemTAP only)
33 --binary [path] Full path to QEMU binary
34 --target-arch [arch] QEMU emulator target arch
35 --target-type [type] QEMU emulator target type ('system' or 'user')
36 --probe-prefix [prefix] Prefix for dtrace probe names
37 (default: qemu-\$targettype-\$targetarch)
43 # Print a line without interpreting backslash escapes
45 # The built-in echo command may interpret backslash escapes without an option
46 # to disable this behavior.
52 # Get the name of a trace event
60 # Get the given property of a trace event
61 # 1: trace-events line
63 # -> return 0 if property is present, or 1 otherwise
69 for prop in $props; do
70 if [ "$prop" = "$2" ]; then
77 # Get the argument list of a trace event, including types and names
86 # Get the argument name list of a trace event
89 local nfields field name sep
92 for field in $(get_args "$1"); do
93 nfields=$((nfields + 1))
98 # Only argument names have commas at the end
100 test "$field" = "$name" && continue
102 printf "%s%s " $name $sep
106 if [ "$nfields" -gt 1 ]
112 # Get the number of arguments to a trace event
117 for name in $(get_argnames "$1", ","); do
123 # Get the format string including double quotes for a trace event
137 name=$(get_name "$1")
138 args=$(get_args "$1")
140 # Define an empty function for the trace event
142 static inline void trace_$name($args)
160 # No need for function definitions in nop backend
169 linetoh_begin_simple()
172 #include "trace/simple.h"
178 cast_args_to_uint64_t()
181 for arg in $(get_argnames "$1", ","); do
182 printf "%s" "(uint64_t)(uintptr_t)$arg"
188 local name args argc trace_args
189 name=$(get_name "$1")
190 args=$(get_args "$1")
191 argc=$(get_argc "$1")
193 trace_args="$simple_event_num"
196 trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
200 static inline void trace_$name($args)
202 trace$argc($trace_args);
206 simple_event_num=$((simple_event_num + 1))
212 #define NR_TRACE_EVENTS $simple_event_num
213 extern TraceEvent trace_list[NR_TRACE_EVENTS];
217 linetoc_begin_simple()
222 TraceEvent trace_list[] = {
231 name=$(get_name "$1")
233 {.tp_name = "$name", .state=0},
235 simple_event_num=$((simple_event_num + 1))
246 linetoh_begin_stderr()
250 #include "trace/stderr.h"
252 extern TraceEvent trace_list[];
260 local name args argnames argc fmt
261 name=$(get_name "$1")
262 args=$(get_args "$1")
263 argnames=$(get_argnames "$1" ",")
264 argc=$(get_argc "$1")
267 if [ "$argc" -gt 0 ]; then
268 argnames=", $argnames"
272 static inline void trace_$name($args)
274 if (trace_list[$stderr_event_num].state != 0) {
275 fprintf(stderr, "$name " $fmt "\n" $argnames);
279 stderr_event_num=$((stderr_event_num + 1))
286 #define NR_TRACE_EVENTS $stderr_event_num
290 linetoc_begin_stderr()
295 TraceEvent trace_list[] = {
303 name=$(get_name "$1")
305 {.tp_name = "$name", .state=0},
307 stderr_event_num=$(($stderr_event_num + 1))
318 # Clean up after UST headers which pollute the namespace
319 ust_clean_namespace() {
330 echo "#include <ust/tracepoint.h>"
336 local name args argnames
337 name=$(get_name "$1")
338 args=$(get_args "$1")
339 argnames=$(get_argnames "$1", ",")
342 DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
343 #define trace_$name trace_ust_$name
355 #include <ust/marker.h>
356 $(ust_clean_namespace)
363 local name args argnames fmt
364 name=$(get_name "$1")
365 args=$(get_args "$1")
366 argnames=$(get_argnames "$1", ",")
367 [ -z "$argnames" ] || argnames=", $argnames"
371 DEFINE_TRACE(ust_$name);
373 static void ust_${name}_probe($args)
375 trace_mark(ust, $name, $fmt$argnames);
379 # Collect names for later
386 static void __attribute__((constructor)) trace_init(void)
390 for name in $names; do
392 register_trace_ust_$name(ust_${name}_probe);
399 linetoh_begin_dtrace()
402 #include "trace-dtrace.h"
408 local name args argnames nameupper
409 name=$(get_name "$1")
410 args=$(get_args "$1")
411 argnames=$(get_argnames "$1", ",")
413 nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
415 # Define an empty function for the trace event
417 static inline void trace_$name($args) {
418 if (QEMU_${nameupper}_ENABLED()) {
419 QEMU_${nameupper}($argnames);
430 linetoc_begin_dtrace()
437 # No need for function definitions in dtrace backend
446 linetod_begin_dtrace()
456 name=$(get_name "$1")
457 args=$(get_args "$1")
459 # DTrace provider syntax expects foo() for empty
460 # params, not foo(void)
461 if [ "$args" = "void" ]; then
465 # Define prototype for probe arguments
478 linetostap_begin_dtrace()
485 local i arg name args arglist
486 name=$(get_name "$1")
487 args=$(get_args "$1")
488 arglist=$(get_argnames "$1", "")
490 # Define prototype for probe arguments
492 probe $probeprefix.$name = process("$binary").mark("$name")
499 # 'limit' is a reserved keyword
500 if [ "$arg" = "limit" ]; then
514 linetostap_end_dtrace()
519 # Process stdin by calling begin, line, and end functions for the backend
522 local begin process_line end str disable
523 begin="lineto$1_begin_$backend"
524 process_line="lineto$1_$backend"
525 end="lineto$1_end_$backend"
529 while read -r str; do
530 # Skip comments and empty lines
531 test -z "${str%%#*}" && continue
534 # Process the line. The nop backend handles disabled lines.
535 if has_property "$str" "disable"; then
536 "lineto$1_nop" "$str"
538 "$process_line" "$str"
552 /* This file is autogenerated by tracetool, do not edit. */
554 #include "qemu-common.h"
557 echo "#endif /* TRACE_H */"
562 echo "/* This file is autogenerated by tracetool, do not edit. */"
568 if [ $backend != "dtrace" ]; then
569 echo "DTrace probe generator not applicable to $backend backend"
572 echo "/* This file is autogenerated by tracetool, do not edit. */"
578 if [ $backend != "dtrace" ]; then
579 echo "SystemTAP tapset generator not applicable to $backend backend"
582 if [ -z "$binary" ]; then
583 echo "--binary is required for SystemTAP tapset generator"
586 if [ -z "$probeprefix" -a -z "$targettype" ]; then
587 echo "--target-type is required for SystemTAP tapset generator"
590 if [ -z "$probeprefix" -a -z "$targetarch" ]; then
591 echo "--target-arch is required for SystemTAP tapset generator"
594 if [ -z "$probeprefix" ]; then
595 probeprefix="qemu.$targettype.$targetarch";
597 echo "/* This file is autogenerated by tracetool, do not edit. */"
613 "--nop" | "--simple" | "--stderr" | "--ust" | "--dtrace") backend="${1#--}" ;;
615 "--binary") shift ; binary="$1" ;;
616 "--target-arch") shift ; targetarch="$1" ;;
617 "--target-type") shift ; targettype="$1" ;;
618 "--probe-prefix") shift ; probeprefix="$1" ;;
620 "-h" | "-c" | "-d") output="${1#-}" ;;
621 "--stap") output="${1#--}" ;;
623 "--check-backend") exit 0 ;; # used by ./configure to test for backend
625 "--list-backends") # used by ./configure to list available backends
626 echo "nop simple stderr ust dtrace"
636 if [ "$backend" = "" -o "$output" = "" ]; then