]> Git Repo - qemu.git/blob - tracetool
trace: Support for dynamically enabling/disabling trace events
[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
This page took 0.037358 seconds and 4 git commands to generate.