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
85 if (echo "$args" |
grep "[ *]next\($\|[, ]\)" > /dev
/null
2>&1); then
86 echo -e "\n#error 'next' is a bad argument name (clash with systemtap keyword)\n "
90 # Get the argument name list of a trace event
93 local nfields field name sep
96 for field
in $
(get_args
"$1"); do
97 nfields
=$
((nfields
+ 1))
102 # Only argument names have commas at the end
104 test "$field" = "$name" && continue
106 printf "%s%s " $name $sep
110 if [ "$nfields" -gt 1 ]
116 # Get the number of arguments to a trace event
121 for name
in $
(get_argnames
"$1", ","); do
127 # Get the format string including double quotes for a trace event
141 name
=$
(get_name
"$1")
142 args
=$
(get_args
"$1")
144 # Define an empty function for the trace event
146 static inline void trace_$name($args)
164 # No need for function definitions in nop backend
170 # Used when "disabled" events are processed
176 # Used when "disabled" events are processed
185 linetoh_begin_simple
()
188 #include "trace/simple.h"
194 cast_args_to_uint64_t
()
197 for arg
in $
(get_argnames
"$1", ","); do
198 printf "%s" "(uint64_t)(uintptr_t)$arg"
204 local name args argc trace_args
205 name
=$
(get_name
"$1")
206 args
=$
(get_args
"$1")
207 argc
=$
(get_argc
"$1")
209 trace_args
="$simple_event_num"
212 trace_args
="$trace_args, $(cast_args_to_uint64_t "$1")"
216 static inline void trace_$name($args)
218 trace$argc($trace_args);
222 simple_event_num
=$
((simple_event_num
+ 1))
228 #define NR_TRACE_EVENTS $simple_event_num
229 extern TraceEvent trace_list[NR_TRACE_EVENTS];
233 linetoc_begin_simple
()
238 TraceEvent trace_list[] = {
247 name
=$
(get_name
"$1")
249 {.tp_name = "$name", .state=0},
251 simple_event_num
=$
((simple_event_num
+ 1))
262 linetoh_begin_stderr
()
266 #include "trace/stderr.h"
268 extern TraceEvent trace_list[];
276 local name args argnames argc
fmt
277 name
=$
(get_name
"$1")
278 args
=$
(get_args
"$1")
279 argnames
=$
(get_argnames
"$1" ",")
280 argc
=$
(get_argc
"$1")
283 if [ "$argc" -gt 0 ]; then
284 argnames
=", $argnames"
288 static inline void trace_$name($args)
290 if (trace_list[$stderr_event_num].state != 0) {
291 fprintf(stderr, "$name " $fmt "\n" $argnames);
295 stderr_event_num
=$
((stderr_event_num
+ 1))
302 #define NR_TRACE_EVENTS $stderr_event_num
306 linetoc_begin_stderr
()
311 TraceEvent trace_list[] = {
319 name
=$
(get_name
"$1")
321 {.tp_name = "$name", .state=0},
323 stderr_event_num
=$
(($stderr_event_num + 1))
334 # Clean up after UST headers which pollute the namespace
335 ust_clean_namespace
() {
346 echo "#include <ust/tracepoint.h>"
352 local name args argnames
353 name
=$
(get_name
"$1")
354 args
=$
(get_args
"$1")
355 argnames
=$
(get_argnames
"$1", ",")
358 DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
359 #define trace_$name trace_ust_$name
371 #include <ust/marker.h>
372 $(ust_clean_namespace)
379 local name args argnames
fmt
380 name
=$
(get_name
"$1")
381 args
=$
(get_args
"$1")
382 argnames
=$
(get_argnames
"$1", ",")
383 [ -z "$argnames" ] || argnames
=", $argnames"
387 DEFINE_TRACE(ust_$name);
389 static void ust_${name}_probe($args)
391 trace_mark(ust, $name, $fmt$argnames);
395 # Collect names for later
402 static void __attribute__((constructor)) trace_init(void)
406 for name
in $names; do
408 register_trace_ust_$name(ust_${name}_probe);
415 linetoh_begin_dtrace
()
418 #include "trace-dtrace.h"
424 local name args argnames nameupper
425 name
=$
(get_name
"$1")
426 args
=$
(get_args
"$1")
427 argnames
=$
(get_argnames
"$1", ",")
429 nameupper
=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'`
431 # Define an empty function for the trace event
433 static inline void trace_$name($args) {
434 QEMU_${nameupper}($argnames);
444 linetoc_begin_dtrace
()
451 # No need for function definitions in dtrace backend
460 linetod_begin_dtrace
()
470 name
=$
(get_name
"$1")
471 args
=$
(get_args
"$1")
473 # DTrace provider syntax expects foo() for empty
474 # params, not foo(void)
475 if [ "$args" = "void" ]; then
479 # Define prototype for probe arguments
492 linetostap_begin_dtrace
()
499 local i arg name args arglist
500 name
=$
(get_name
"$1")
501 args
=$
(get_args
"$1")
502 arglist
=$
(get_argnames
"$1", "")
504 # Define prototype for probe arguments
506 probe $probeprefix.$name = process("$binary").mark("$name")
513 # postfix reserved words with '_'
530 linetostap_end_dtrace
()
535 # Process stdin by calling begin, line, and end functions for the backend
538 local begin process_line end str name NAME enabled
539 begin
="lineto$1_begin_$backend"
540 process_line
="lineto$1_$backend"
541 end
="lineto$1_end_$backend"
545 while read -r str
; do
546 # Skip comments and empty lines
547 test -z "${str%%#*}" && continue
550 # Process the line. The nop backend handles disabled lines.
551 if has_property
"$str" "disable"; then
552 "lineto$1_nop" "$str"
555 "$process_line" "$str"
558 if [ "$1" = "h" ]; then
559 name
=$
(get_name
"$str")
560 NAME
=$
(echo $name | LC_ALL
=C
tr '[a-z]' '[A-Z]')
561 echo "#define TRACE_${NAME}_ENABLED ${enabled}"
575 /* This file is autogenerated by tracetool, do not edit. */
577 #include "qemu-common.h"
580 echo "#endif /* TRACE_H */"
585 echo "/* This file is autogenerated by tracetool, do not edit. */"
591 if [ $backend != "dtrace" ]; then
592 echo "DTrace probe generator not applicable to $backend backend"
595 echo "/* This file is autogenerated by tracetool, do not edit. */"
601 if [ $backend != "dtrace" ]; then
602 echo "SystemTAP tapset generator not applicable to $backend backend"
605 if [ -z "$binary" ]; then
606 echo "--binary is required for SystemTAP tapset generator"
609 if [ -z "$probeprefix" -a -z "$targettype" ]; then
610 echo "--target-type is required for SystemTAP tapset generator"
613 if [ -z "$probeprefix" -a -z "$targetarch" ]; then
614 echo "--target-arch is required for SystemTAP tapset generator"
617 if [ -z "$probeprefix" ]; then
618 probeprefix
="qemu.$targettype.$targetarch";
620 echo "/* This file is autogenerated by tracetool, do not edit. */"
636 "--nop" |
"--simple" |
"--stderr" |
"--ust" |
"--dtrace") backend
="${1#--}" ;;
638 "--binary") shift ; binary
="$1" ;;
639 "--target-arch") shift ; targetarch
="$1" ;;
640 "--target-type") shift ; targettype
="$1" ;;
641 "--probe-prefix") shift ; probeprefix
="$1" ;;
643 "-h" |
"-c" |
"-d") output
="${1#-}" ;;
644 "--stap") output
="${1#--}" ;;
646 "--check-backend") exit 0 ;; # used by ./configure to test for backend
648 "--list-backends") # used by ./configure to list available backends
649 echo "nop simple stderr ust dtrace"
659 if [ "$backend" = "" -o "$output" = "" ]; then