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