]>
Commit | Line | Data |
---|---|---|
770cb243 SR |
1 | /* |
2 | * trace_export.c - export basic ftrace utilities to user space | |
3 | * | |
4 | * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com> | |
5 | */ | |
6 | #include <linux/stringify.h> | |
7 | #include <linux/kallsyms.h> | |
8 | #include <linux/seq_file.h> | |
9 | #include <linux/debugfs.h> | |
10 | #include <linux/uaccess.h> | |
11 | #include <linux/ftrace.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/init.h> | |
14 | #include <linux/fs.h> | |
15 | ||
16 | #include "trace_output.h" | |
17 | ||
da4d0302 SR |
18 | |
19 | #undef TRACE_STRUCT | |
20 | #define TRACE_STRUCT(args...) args | |
21 | ||
75db37d2 SR |
22 | extern void __bad_type_size(void); |
23 | ||
da4d0302 SR |
24 | #undef TRACE_FIELD |
25 | #define TRACE_FIELD(type, item, assign) \ | |
75db37d2 SR |
26 | if (sizeof(type) != sizeof(field.item)) \ |
27 | __bad_type_size(); \ | |
da4d0302 SR |
28 | ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ |
29 | "offset:%u;\tsize:%u;\n", \ | |
30 | (unsigned int)offsetof(typeof(field), item), \ | |
31 | (unsigned int)sizeof(field.item)); \ | |
32 | if (!ret) \ | |
33 | return 0; | |
34 | ||
35 | ||
36 | #undef TRACE_FIELD_SPECIAL | |
e1112b4d | 37 | #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ |
da4d0302 SR |
38 | ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \ |
39 | "offset:%u;\tsize:%u;\n", \ | |
40 | (unsigned int)offsetof(typeof(field), item), \ | |
41 | (unsigned int)sizeof(field.item)); \ | |
42 | if (!ret) \ | |
43 | return 0; | |
770cb243 SR |
44 | |
45 | #undef TRACE_FIELD_ZERO_CHAR | |
156b5f17 | 46 | #define TRACE_FIELD_ZERO_CHAR(item) \ |
1bbe2a83 | 47 | ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \ |
156b5f17 SR |
48 | "offset:%u;\tsize:0;\n", \ |
49 | (unsigned int)offsetof(typeof(field), item)); \ | |
50 | if (!ret) \ | |
770cb243 SR |
51 | return 0; |
52 | ||
a118e4d1 TZ |
53 | #undef TRACE_FIELD_SIGN |
54 | #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ | |
55 | TRACE_FIELD(type, item, assign) | |
770cb243 | 56 | |
2939b046 SR |
57 | #undef TP_RAW_FMT |
58 | #define TP_RAW_FMT(args...) args | |
770cb243 SR |
59 | |
60 | #undef TRACE_EVENT_FORMAT | |
61 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | |
62 | static int \ | |
e8f9f4d7 FW |
63 | ftrace_format_##call(struct ftrace_event_call *unused, \ |
64 | struct trace_seq *s) \ | |
770cb243 SR |
65 | { \ |
66 | struct args field; \ | |
67 | int ret; \ | |
68 | \ | |
69 | tstruct; \ | |
70 | \ | |
71 | trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ | |
72 | \ | |
73 | return ret; \ | |
74 | } | |
75 | ||
e45f2e2b TZ |
76 | #undef TRACE_EVENT_FORMAT_NOFILTER |
77 | #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ | |
78 | tpfmt) \ | |
79 | static int \ | |
e8f9f4d7 FW |
80 | ftrace_format_##call(struct ftrace_event_call *unused, \ |
81 | struct trace_seq *s) \ | |
e45f2e2b TZ |
82 | { \ |
83 | struct args field; \ | |
84 | int ret; \ | |
85 | \ | |
86 | tstruct; \ | |
87 | \ | |
88 | trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ | |
89 | \ | |
90 | return ret; \ | |
91 | } | |
92 | ||
770cb243 SR |
93 | #include "trace_event_types.h" |
94 | ||
95 | #undef TRACE_ZERO_CHAR | |
96 | #define TRACE_ZERO_CHAR(arg) | |
97 | ||
98 | #undef TRACE_FIELD | |
99 | #define TRACE_FIELD(type, item, assign)\ | |
100 | entry->item = assign; | |
101 | ||
102 | #undef TRACE_FIELD | |
103 | #define TRACE_FIELD(type, item, assign)\ | |
104 | entry->item = assign; | |
105 | ||
a118e4d1 TZ |
106 | #undef TRACE_FIELD_SIGN |
107 | #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ | |
108 | TRACE_FIELD(type, item, assign) | |
109 | ||
2939b046 SR |
110 | #undef TP_CMD |
111 | #define TP_CMD(cmd...) cmd | |
770cb243 SR |
112 | |
113 | #undef TRACE_ENTRY | |
114 | #define TRACE_ENTRY entry | |
115 | ||
116 | #undef TRACE_FIELD_SPECIAL | |
e1112b4d | 117 | #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ |
770cb243 SR |
118 | cmd; |
119 | ||
120 | #undef TRACE_EVENT_FORMAT | |
121 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | |
14be96c9 | 122 | int ftrace_define_fields_##call(struct ftrace_event_call *event_call); \ |
e1112b4d | 123 | static int ftrace_raw_init_event_##call(void); \ |
770cb243 | 124 | \ |
e1112b4d | 125 | struct ftrace_event_call __used \ |
770cb243 SR |
126 | __attribute__((__aligned__(4))) \ |
127 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
ef18012b | 128 | .name = #call, \ |
770cb243 SR |
129 | .id = proto, \ |
130 | .system = __stringify(TRACE_SYSTEM), \ | |
e1112b4d | 131 | .raw_init = ftrace_raw_init_event_##call, \ |
770cb243 | 132 | .show_format = ftrace_format_##call, \ |
e1112b4d TZ |
133 | .define_fields = ftrace_define_fields_##call, \ |
134 | }; \ | |
135 | static int ftrace_raw_init_event_##call(void) \ | |
136 | { \ | |
137 | INIT_LIST_HEAD(&event_##call.fields); \ | |
0a19e53c | 138 | init_preds(&event_##call); \ |
e1112b4d TZ |
139 | return 0; \ |
140 | } \ | |
141 | ||
e45f2e2b TZ |
142 | #undef TRACE_EVENT_FORMAT_NOFILTER |
143 | #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ | |
144 | tpfmt) \ | |
145 | \ | |
146 | struct ftrace_event_call __used \ | |
147 | __attribute__((__aligned__(4))) \ | |
148 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
149 | .name = #call, \ | |
150 | .id = proto, \ | |
151 | .system = __stringify(TRACE_SYSTEM), \ | |
152 | .show_format = ftrace_format_##call, \ | |
153 | }; | |
154 | ||
e1112b4d TZ |
155 | #include "trace_event_types.h" |
156 | ||
157 | #undef TRACE_FIELD | |
158 | #define TRACE_FIELD(type, item, assign) \ | |
159 | ret = trace_define_field(event_call, #type, #item, \ | |
160 | offsetof(typeof(field), item), \ | |
a118e4d1 | 161 | sizeof(field.item), is_signed_type(type)); \ |
e1112b4d TZ |
162 | if (ret) \ |
163 | return ret; | |
164 | ||
165 | #undef TRACE_FIELD_SPECIAL | |
166 | #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ | |
167 | ret = trace_define_field(event_call, #type "[" #len "]", #item, \ | |
168 | offsetof(typeof(field), item), \ | |
a118e4d1 TZ |
169 | sizeof(field.item), 0); \ |
170 | if (ret) \ | |
171 | return ret; | |
172 | ||
173 | #undef TRACE_FIELD_SIGN | |
174 | #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ | |
175 | ret = trace_define_field(event_call, #type, #item, \ | |
176 | offsetof(typeof(field), item), \ | |
177 | sizeof(field.item), is_signed); \ | |
e1112b4d TZ |
178 | if (ret) \ |
179 | return ret; | |
180 | ||
181 | #undef TRACE_FIELD_ZERO_CHAR | |
182 | #define TRACE_FIELD_ZERO_CHAR(item) | |
183 | ||
184 | #undef TRACE_EVENT_FORMAT | |
185 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | |
186 | int \ | |
14be96c9 | 187 | ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ |
e1112b4d | 188 | { \ |
e1112b4d TZ |
189 | struct args field; \ |
190 | int ret; \ | |
191 | \ | |
e647d6b3 LZ |
192 | ret = trace_define_common_fields(event_call); \ |
193 | if (ret) \ | |
194 | return ret; \ | |
e1112b4d TZ |
195 | \ |
196 | tstruct; \ | |
197 | \ | |
198 | return ret; \ | |
770cb243 | 199 | } |
e1112b4d | 200 | |
e45f2e2b TZ |
201 | #undef TRACE_EVENT_FORMAT_NOFILTER |
202 | #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ | |
203 | tpfmt) | |
204 | ||
770cb243 | 205 | #include "trace_event_types.h" |