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 | ||
4e5292ea SR |
18 | #undef TRACE_SYSTEM |
19 | #define TRACE_SYSTEM ftrace | |
da4d0302 | 20 | |
e59a0bff JO |
21 | /* |
22 | * The FTRACE_ENTRY_REG macro allows ftrace entry to define register | |
23 | * function and thus become accesible via perf. | |
24 | */ | |
25 | #undef FTRACE_ENTRY_REG | |
02aa3162 JO |
26 | #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, \ |
27 | filter, regfn) \ | |
28 | FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ | |
29 | filter) | |
e59a0bff | 30 | |
4e5292ea SR |
31 | /* not needed for this file */ |
32 | #undef __field_struct | |
33 | #define __field_struct(type, item) | |
da4d0302 | 34 | |
05ffa2d0 LZ |
35 | #undef __field |
36 | #define __field(type, item) type item; | |
37 | ||
38 | #undef __field_desc | |
39 | #define __field_desc(type, container, item) type item; | |
40 | ||
41 | #undef __array | |
42 | #define __array(type, item, size) type item[size]; | |
43 | ||
44 | #undef __array_desc | |
45 | #define __array_desc(type, container, item, size) type item[size]; | |
46 | ||
47 | #undef __dynamic_array | |
48 | #define __dynamic_array(type, item) type item[]; | |
49 | ||
50 | #undef F_STRUCT | |
51 | #define F_STRUCT(args...) args | |
52 | ||
53 | #undef F_printk | |
54 | #define F_printk(fmt, args...) fmt, args | |
55 | ||
56 | #undef FTRACE_ENTRY | |
02aa3162 JO |
57 | #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ |
58 | struct ____ftrace_##name { \ | |
59 | tstruct \ | |
60 | }; \ | |
61 | static void __always_unused ____ftrace_check_##name(void) \ | |
62 | { \ | |
63 | struct ____ftrace_##name *__entry = NULL; \ | |
64 | \ | |
65 | /* force compile-time check on F_printk() */ \ | |
66 | printk(print); \ | |
05ffa2d0 LZ |
67 | } |
68 | ||
69 | #undef FTRACE_ENTRY_DUP | |
02aa3162 JO |
70 | #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print, filter) \ |
71 | FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ | |
72 | filter) | |
05ffa2d0 LZ |
73 | |
74 | #include "trace_entries.h" | |
75 | ||
4e5292ea SR |
76 | #undef __field |
77 | #define __field(type, item) \ | |
78 | ret = trace_define_field(event_call, #type, #item, \ | |
79 | offsetof(typeof(field), item), \ | |
80 | sizeof(field.item), \ | |
02aa3162 | 81 | is_signed_type(type), filter_type); \ |
4e5292ea SR |
82 | if (ret) \ |
83 | return ret; | |
84 | ||
85 | #undef __field_desc | |
86 | #define __field_desc(type, container, item) \ | |
87 | ret = trace_define_field(event_call, #type, #item, \ | |
88 | offsetof(typeof(field), \ | |
89 | container.item), \ | |
90 | sizeof(field.container.item), \ | |
02aa3162 | 91 | is_signed_type(type), filter_type); \ |
4e5292ea SR |
92 | if (ret) \ |
93 | return ret; | |
94 | ||
95 | #undef __array | |
96 | #define __array(type, item, len) \ | |
04295780 | 97 | do { \ |
87291347 | 98 | char *type_str = #type"["__stringify(len)"]"; \ |
04295780 | 99 | BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ |
87291347 | 100 | ret = trace_define_field(event_call, type_str, #item, \ |
4e5292ea | 101 | offsetof(typeof(field), item), \ |
fb7ae981 | 102 | sizeof(field.item), \ |
02aa3162 | 103 | is_signed_type(type), filter_type); \ |
04295780 SR |
104 | if (ret) \ |
105 | return ret; \ | |
106 | } while (0); | |
4e5292ea SR |
107 | |
108 | #undef __array_desc | |
109 | #define __array_desc(type, container, item, len) \ | |
110 | BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ | |
111 | ret = trace_define_field(event_call, #type "[" #len "]", #item, \ | |
112 | offsetof(typeof(field), \ | |
113 | container.item), \ | |
fb7ae981 | 114 | sizeof(field.container.item), \ |
02aa3162 | 115 | is_signed_type(type), filter_type); \ |
4e5292ea SR |
116 | if (ret) \ |
117 | return ret; | |
118 | ||
119 | #undef __dynamic_array | |
809826a3 LJ |
120 | #define __dynamic_array(type, item) \ |
121 | ret = trace_define_field(event_call, #type, #item, \ | |
122 | offsetof(typeof(field), item), \ | |
02aa3162 | 123 | 0, is_signed_type(type), filter_type);\ |
809826a3 LJ |
124 | if (ret) \ |
125 | return ret; | |
4e5292ea SR |
126 | |
127 | #undef FTRACE_ENTRY | |
02aa3162 | 128 | #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ |
7e4f44b1 | 129 | static int __init \ |
4e5292ea | 130 | ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ |
e45f2e2b | 131 | { \ |
4e5292ea | 132 | struct struct_name field; \ |
e45f2e2b | 133 | int ret; \ |
02aa3162 | 134 | int filter_type = filter; \ |
e45f2e2b | 135 | \ |
4e5292ea | 136 | tstruct; \ |
e45f2e2b TZ |
137 | \ |
138 | return ret; \ | |
139 | } | |
140 | ||
4e5292ea SR |
141 | #include "trace_entries.h" |
142 | ||
509e760c LJ |
143 | #undef __entry |
144 | #define __entry REC | |
145 | ||
4e5292ea SR |
146 | #undef __field |
147 | #define __field(type, item) | |
148 | ||
149 | #undef __field_desc | |
150 | #define __field_desc(type, container, item) | |
151 | ||
152 | #undef __array | |
153 | #define __array(type, item, len) | |
154 | ||
155 | #undef __array_desc | |
156 | #define __array_desc(type, container, item, len) | |
157 | ||
158 | #undef __dynamic_array | |
159 | #define __dynamic_array(type, item) | |
160 | ||
509e760c | 161 | #undef F_printk |
01de982a | 162 | #define F_printk(fmt, args...) __stringify(fmt) ", " __stringify(args) |
509e760c | 163 | |
e59a0bff | 164 | #undef FTRACE_ENTRY_REG |
02aa3162 JO |
165 | #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, filter,\ |
166 | regfn) \ | |
770cb243 | 167 | \ |
523c8113 | 168 | struct ftrace_event_class __refdata event_class_ftrace_##call = { \ |
2e33af02 SR |
169 | .system = __stringify(TRACE_SYSTEM), \ |
170 | .define_fields = ftrace_define_fields_##call, \ | |
ffb9f995 | 171 | .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ |
e59a0bff | 172 | .reg = regfn, \ |
2e33af02 SR |
173 | }; \ |
174 | \ | |
e4a9ea5e | 175 | struct ftrace_event_call __used event_##call = { \ |
2e33af02 | 176 | .class = &event_class_ftrace_##call, \ |
abb43f69 MD |
177 | { \ |
178 | .name = #call, \ | |
179 | }, \ | |
180 | .event.type = etype, \ | |
509e760c | 181 | .print_fmt = print, \ |
f306cc82 | 182 | .flags = TRACE_EVENT_FL_IGNORE_ENABLE | TRACE_EVENT_FL_USE_CALL_FILTER, \ |
e1112b4d | 183 | }; \ |
e4a9ea5e SR |
184 | struct ftrace_event_call __used \ |
185 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; | |
e1112b4d | 186 | |
e59a0bff | 187 | #undef FTRACE_ENTRY |
02aa3162 | 188 | #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print, filter) \ |
e59a0bff | 189 | FTRACE_ENTRY_REG(call, struct_name, etype, \ |
02aa3162 | 190 | PARAMS(tstruct), PARAMS(print), filter, NULL) |
e59a0bff | 191 | |
ced39002 JO |
192 | int ftrace_event_is_function(struct ftrace_event_call *call) |
193 | { | |
194 | return call == &event_function; | |
195 | } | |
196 | ||
4e5292ea | 197 | #include "trace_entries.h" |