]>
Commit | Line | Data |
---|---|---|
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 | |
11 | set -f | |
12 | ||
13 | usage() | |
14 | { | |
15 | cat >&2 <<EOF | |
7e24e92a | 16 | usage: $0 [--nop | --simple | --ust] [-h | -c] |
94a420b1 SH |
17 | Generate tracing code for a file on stdin. |
18 | ||
19 | Backends: | |
26f7227b SH |
20 | --nop Tracing disabled |
21 | --simple Simple built-in backend | |
7e24e92a | 22 | --ust LTTng User Space Tracing backend |
94a420b1 SH |
23 | |
24 | Output formats: | |
25 | -h Generate .h file | |
26 | -c Generate .c file | |
27 | EOF | |
28 | exit 1 | |
29 | } | |
30 | ||
31 | # Get the name of a trace event | |
32 | get_name() | |
33 | { | |
34 | echo ${1%%\(*} | |
35 | } | |
36 | ||
37 | # Get the argument list of a trace event, including types and names | |
38 | get_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 | |
47 | get_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 |
72 | get_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 |
83 | get_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 |
92 | get_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 |
105 | linetoh_begin_nop() |
106 | { | |
107 | return | |
108 | } | |
109 | ||
110 | linetoh_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 | |
118 | static inline void trace_$name($args) | |
119 | { | |
120 | } | |
121 | EOF | |
122 | } | |
123 | ||
124 | linetoh_end_nop() | |
125 | { | |
126 | return | |
127 | } | |
128 | ||
129 | linetoc_begin_nop() | |
130 | { | |
131 | return | |
132 | } | |
133 | ||
134 | linetoc_nop() | |
135 | { | |
136 | # No need for function definitions in nop backend | |
137 | return | |
138 | } | |
139 | ||
140 | linetoc_end_nop() | |
141 | { | |
142 | return | |
143 | } | |
144 | ||
26f7227b SH |
145 | linetoh_begin_simple() |
146 | { | |
147 | cat <<EOF | |
148 | #include "simpletrace.h" | |
149 | EOF | |
150 | ||
151 | simple_event_num=0 | |
152 | } | |
153 | ||
154 | cast_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 | ||
162 | linetoh_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 | |
180 | static inline void trace_$name($args) | |
181 | { | |
182 | trace$argc($trace_args); | |
183 | } | |
184 | EOF | |
185 | ||
186 | simple_event_num=$((simple_event_num + 1)) | |
187 | } | |
188 | ||
189 | linetoh_end_simple() | |
190 | { | |
22890ab5 PS |
191 | cat <<EOF |
192 | #define NR_TRACE_EVENTS $simple_event_num | |
193 | extern TraceEvent trace_list[NR_TRACE_EVENTS]; | |
194 | EOF | |
26f7227b SH |
195 | } |
196 | ||
197 | linetoc_begin_simple() | |
198 | { | |
22890ab5 PS |
199 | cat <<EOF |
200 | #include "trace.h" | |
201 | ||
202 | TraceEvent trace_list[] = { | |
203 | EOF | |
204 | simple_event_num=0 | |
205 | ||
26f7227b SH |
206 | } |
207 | ||
208 | linetoc_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 |
218 | EOF |
219 | simple_event_num=$((simple_event_num + 1)) | |
26f7227b SH |
220 | } |
221 | ||
222 | linetoc_end_simple() | |
223 | { | |
22890ab5 PS |
224 | cat <<EOF |
225 | }; | |
226 | EOF | |
26f7227b SH |
227 | } |
228 | ||
7e24e92a SH |
229 | # Clean up after UST headers which pollute the namespace |
230 | ust_clean_namespace() { | |
231 | cat <<EOF | |
232 | #undef mutex_lock | |
233 | #undef mutex_unlock | |
234 | #undef inline | |
235 | #undef wmb | |
236 | EOF | |
237 | } | |
238 | ||
239 | linetoh_begin_ust() | |
240 | { | |
241 | echo "#include <ust/tracepoint.h>" | |
242 | ust_clean_namespace | |
243 | } | |
244 | ||
245 | linetoh_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 | |
253 | DECLARE_TRACE(ust_$name, TPPROTO($args), TPARGS($argnames)); | |
254 | #define trace_$name trace_ust_$name | |
255 | EOF | |
256 | } | |
257 | ||
258 | linetoh_end_ust() | |
259 | { | |
260 | return | |
261 | } | |
262 | ||
263 | linetoc_begin_ust() | |
264 | { | |
265 | cat <<EOF | |
266 | #include <ust/marker.h> | |
267 | $(ust_clean_namespace) | |
268 | #include "trace.h" | |
269 | EOF | |
270 | } | |
271 | ||
272 | linetoc_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 | |
281 | DEFINE_TRACE(ust_$name); | |
282 | ||
283 | static void ust_${name}_probe($args) | |
284 | { | |
285 | trace_mark(ust, $name, "$fmt", $argnames); | |
286 | } | |
287 | EOF | |
288 | ||
289 | # Collect names for later | |
290 | names="$names $name" | |
291 | } | |
292 | ||
293 | linetoc_end_ust() | |
294 | { | |
295 | cat <<EOF | |
296 | static void __attribute__((constructor)) trace_init(void) | |
297 | { | |
298 | EOF | |
299 | ||
300 | for name in $names; do | |
301 | cat <<EOF | |
302 | register_trace_ust_$name(ust_${name}_probe); | |
303 | EOF | |
304 | done | |
305 | ||
306 | echo "}" | |
307 | } | |
308 | ||
94a420b1 SH |
309 | # Process stdin by calling begin, line, and end functions for the backend |
310 | convert() | |
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 | |
5eb5527b | 321 | test -z "${str%%#*}" && continue |
94a420b1 | 322 | |
1e2cf2bc SH |
323 | # Process the line. The nop backend handles disabled lines. |
324 | disable=${str%%disable *} | |
94a420b1 | 325 | echo |
1e2cf2bc SH |
326 | if test -z "$disable"; then |
327 | # Pass the disabled state as an arg to lineto$1_simple(). | |
328 | # For all other cases, call lineto$1_nop() | |
329 | if [ $backend = "simple" ]; then | |
330 | "$process_line" "$str" | |
331 | else | |
332 | "lineto$1_nop" "${str##disable }" | |
333 | fi | |
334 | else | |
335 | "$process_line" "$str" | |
336 | fi | |
94a420b1 SH |
337 | done |
338 | ||
339 | echo | |
340 | "$end" | |
341 | } | |
342 | ||
343 | tracetoh() | |
344 | { | |
345 | cat <<EOF | |
346 | #ifndef TRACE_H | |
347 | #define TRACE_H | |
348 | ||
349 | /* This file is autogenerated by tracetool, do not edit. */ | |
350 | ||
351 | #include "qemu-common.h" | |
352 | EOF | |
353 | convert h | |
354 | echo "#endif /* TRACE_H */" | |
355 | } | |
356 | ||
357 | tracetoc() | |
358 | { | |
359 | echo "/* This file is autogenerated by tracetool, do not edit. */" | |
360 | convert c | |
361 | } | |
362 | ||
363 | # Choose backend | |
364 | case "$1" in | |
7e24e92a | 365 | "--nop" | "--simple" | "--ust") backend="${1#--}" ;; |
94a420b1 SH |
366 | *) usage ;; |
367 | esac | |
368 | shift | |
369 | ||
370 | case "$1" in | |
371 | "-h") tracetoh ;; | |
372 | "-c") tracetoc ;; | |
373 | "--check-backend") exit 0 ;; # used by ./configure to test for backend | |
374 | *) usage ;; | |
375 | esac | |
376 | ||
377 | exit 0 |