]> git.proxmox.com Git - mirror_qemu.git/blob - tracetool
trace: Support for dynamically enabling/disabling trace events
[mirror_qemu.git] / tracetool
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
11 set -f
12
13 usage()
14 {
15 cat >&2 <<EOF
16 usage: $0 [--nop | --simple] [-h | -c]
17 Generate tracing code for a file on stdin.
18
19 Backends:
20 --nop Tracing disabled
21 --simple Simple built-in backend
22
23 Output formats:
24 -h Generate .h file
25 -c Generate .c file
26 EOF
27 exit 1
28 }
29
30 # Get the name of a trace event
31 get_name()
32 {
33 echo ${1%%\(*}
34 }
35
36 # Get the argument list of a trace event, including types and names
37 get_args()
38 {
39 local args
40 args=${1#*\(}
41 args=${args%)*}
42 echo "$args"
43 }
44
45 # Get the argument name list of a trace event
46 get_argnames()
47 {
48 local nfields field name
49 nfields=0
50 for field in $(get_args "$1"); do
51 nfields=$((nfields + 1))
52
53 # Drop pointer star
54 field=${field#\*}
55
56 # Only argument names have commas at the end
57 name=${field%,}
58 test "$field" = "$name" && continue
59
60 printf "%s" "$name, "
61 done
62
63 # Last argument name
64 if [ "$nfields" -gt 1 ]
65 then
66 printf "%s" "$name"
67 fi
68 }
69
70 # Get the number of arguments to a trace event
71 get_argc()
72 {
73 local name argc
74 argc=0
75 for name in $(get_argnames "$1"); do
76 argc=$((argc + 1))
77 done
78 echo $argc
79 }
80
81 # Get the format string for a trace event
82 get_fmt()
83 {
84 local fmt
85 fmt=${1#*\"}
86 fmt=${fmt%\"*}
87 echo "$fmt"
88 }
89
90 linetoh_begin_nop()
91 {
92 return
93 }
94
95 linetoh_nop()
96 {
97 local name args
98 name=$(get_name "$1")
99 args=$(get_args "$1")
100
101 # Define an empty function for the trace event
102 cat <<EOF
103 static inline void trace_$name($args)
104 {
105 }
106 EOF
107 }
108
109 linetoh_end_nop()
110 {
111 return
112 }
113
114 linetoc_begin_nop()
115 {
116 return
117 }
118
119 linetoc_nop()
120 {
121 # No need for function definitions in nop backend
122 return
123 }
124
125 linetoc_end_nop()
126 {
127 return
128 }
129
130 linetoh_begin_simple()
131 {
132 cat <<EOF
133 #include "simpletrace.h"
134 EOF
135
136 simple_event_num=0
137 }
138
139 cast_args_to_uint64_t()
140 {
141 local arg
142 for arg in $(get_argnames "$1"); do
143 printf "%s" "(uint64_t)(uintptr_t)$arg"
144 done
145 }
146
147 linetoh_simple()
148 {
149 local name args argc trace_args
150 name=$(get_name "$1")
151 args=$(get_args "$1")
152 argc=$(get_argc "$1")
153
154 trace_args="$simple_event_num"
155 if [ "$argc" -gt 0 ]
156 then
157 trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
158 fi
159
160 cat <<EOF
161 static inline void trace_$name($args)
162 {
163 trace$argc($trace_args);
164 }
165 EOF
166
167 simple_event_num=$((simple_event_num + 1))
168 }
169
170 linetoh_end_simple()
171 {
172 cat <<EOF
173 #define NR_TRACE_EVENTS $simple_event_num
174 extern TraceEvent trace_list[NR_TRACE_EVENTS];
175 EOF
176 }
177
178 linetoc_begin_simple()
179 {
180 cat <<EOF
181 #include "trace.h"
182
183 TraceEvent trace_list[] = {
184 EOF
185 simple_event_num=0
186
187 }
188
189 linetoc_simple()
190 {
191 local name
192 name=$(get_name "$1")
193 cat <<EOF
194 {.tp_name = "$name", .state=0},
195 EOF
196 simple_event_num=$((simple_event_num + 1))
197 }
198
199 linetoc_end_simple()
200 {
201 cat <<EOF
202 };
203 EOF
204 }
205
206 # Process stdin by calling begin, line, and end functions for the backend
207 convert()
208 {
209 local begin process_line end
210 begin="lineto$1_begin_$backend"
211 process_line="lineto$1_$backend"
212 end="lineto$1_end_$backend"
213
214 "$begin"
215
216 while read -r str; do
217 # Skip comments and empty lines
218 str=${str%%#*}
219 test -z "$str" && continue
220
221 echo
222 "$process_line" "$str"
223 done
224
225 echo
226 "$end"
227 }
228
229 tracetoh()
230 {
231 cat <<EOF
232 #ifndef TRACE_H
233 #define TRACE_H
234
235 /* This file is autogenerated by tracetool, do not edit. */
236
237 #include "qemu-common.h"
238 EOF
239 convert h
240 echo "#endif /* TRACE_H */"
241 }
242
243 tracetoc()
244 {
245 echo "/* This file is autogenerated by tracetool, do not edit. */"
246 convert c
247 }
248
249 # Choose backend
250 case "$1" in
251 "--nop" | "--simple") backend="${1#--}" ;;
252 *) usage ;;
253 esac
254 shift
255
256 case "$1" in
257 "-h") tracetoh ;;
258 "-c") tracetoc ;;
259 "--check-backend") exit 0 ;; # used by ./configure to test for backend
260 *) usage ;;
261 esac
262
263 exit 0