xref: /openbmc/linux/kernel/trace/trace_export.c (revision ced39002)
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 
18 #undef TRACE_SYSTEM
19 #define TRACE_SYSTEM	ftrace
20 
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
26 #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, regfn) \
27 	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))
28 
29 /* not needed for this file */
30 #undef __field_struct
31 #define __field_struct(type, item)
32 
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
55 #define FTRACE_ENTRY(name, struct_name, id, tstruct, print)	\
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);						\
65 }
66 
67 #undef FTRACE_ENTRY_DUP
68 #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print)	\
69 	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))
70 
71 #include "trace_entries.h"
72 
73 #undef __field
74 #define __field(type, item)						\
75 	ret = trace_define_field(event_call, #type, #item,		\
76 				 offsetof(typeof(field), item),		\
77 				 sizeof(field.item),			\
78 				 is_signed_type(type), FILTER_OTHER);	\
79 	if (ret)							\
80 		return ret;
81 
82 #undef __field_desc
83 #define __field_desc(type, container, item)	\
84 	ret = trace_define_field(event_call, #type, #item,		\
85 				 offsetof(typeof(field),		\
86 					  container.item),		\
87 				 sizeof(field.container.item),		\
88 				 is_signed_type(type), FILTER_OTHER);	\
89 	if (ret)							\
90 		return ret;
91 
92 #undef __array
93 #define __array(type, item, len)					\
94 	do {								\
95 		BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);			\
96 		mutex_lock(&event_storage_mutex);			\
97 		snprintf(event_storage, sizeof(event_storage),		\
98 			 "%s[%d]", #type, len);				\
99 		ret = trace_define_field(event_call, event_storage, #item, \
100 				 offsetof(typeof(field), item),		\
101 				 sizeof(field.item),			\
102 				 is_signed_type(type), FILTER_OTHER);	\
103 		mutex_unlock(&event_storage_mutex);			\
104 		if (ret)						\
105 			return ret;					\
106 	} while (0);
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),		\
114 				 sizeof(field.container.item),		\
115 				 is_signed_type(type), FILTER_OTHER);	\
116 	if (ret)							\
117 		return ret;
118 
119 #undef __dynamic_array
120 #define __dynamic_array(type, item)					\
121 	ret = trace_define_field(event_call, #type, #item,		\
122 				 offsetof(typeof(field), item),		\
123 				 0, is_signed_type(type), FILTER_OTHER);\
124 	if (ret)							\
125 		return ret;
126 
127 #undef FTRACE_ENTRY
128 #define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
129 int									\
130 ftrace_define_fields_##name(struct ftrace_event_call *event_call)	\
131 {									\
132 	struct struct_name field;					\
133 	int ret;							\
134 									\
135 	tstruct;							\
136 									\
137 	return ret;							\
138 }
139 
140 #include "trace_entries.h"
141 
142 #undef __entry
143 #define __entry REC
144 
145 #undef __field
146 #define __field(type, item)
147 
148 #undef __field_desc
149 #define __field_desc(type, container, item)
150 
151 #undef __array
152 #define __array(type, item, len)
153 
154 #undef __array_desc
155 #define __array_desc(type, container, item, len)
156 
157 #undef __dynamic_array
158 #define __dynamic_array(type, item)
159 
160 #undef F_printk
161 #define F_printk(fmt, args...) #fmt ", "  __stringify(args)
162 
163 #undef FTRACE_ENTRY_REG
164 #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, regfn)\
165 									\
166 struct ftrace_event_class event_class_ftrace_##call = {			\
167 	.system			= __stringify(TRACE_SYSTEM),		\
168 	.define_fields		= ftrace_define_fields_##call,		\
169 	.fields			= LIST_HEAD_INIT(event_class_ftrace_##call.fields),\
170 	.reg			= regfn,				\
171 };									\
172 									\
173 struct ftrace_event_call __used event_##call = {			\
174 	.name			= #call,				\
175 	.event.type		= etype,				\
176 	.class			= &event_class_ftrace_##call,		\
177 	.print_fmt		= print,				\
178 };									\
179 struct ftrace_event_call __used						\
180 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call;
181 
182 #undef FTRACE_ENTRY
183 #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print)		\
184 	FTRACE_ENTRY_REG(call, struct_name, etype,			\
185 			 PARAMS(tstruct), PARAMS(print), NULL)
186 
187 int ftrace_event_is_function(struct ftrace_event_call *call)
188 {
189 	return call == &event_function;
190 }
191 
192 #include "trace_entries.h"
193