xref: /openbmc/linux/kernel/trace/trace_export.c (revision 4e5292ea)
1770cb243SSteven Rostedt /*
2770cb243SSteven Rostedt  * trace_export.c - export basic ftrace utilities to user space
3770cb243SSteven Rostedt  *
4770cb243SSteven Rostedt  * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com>
5770cb243SSteven Rostedt  */
6770cb243SSteven Rostedt #include <linux/stringify.h>
7770cb243SSteven Rostedt #include <linux/kallsyms.h>
8770cb243SSteven Rostedt #include <linux/seq_file.h>
9770cb243SSteven Rostedt #include <linux/debugfs.h>
10770cb243SSteven Rostedt #include <linux/uaccess.h>
11770cb243SSteven Rostedt #include <linux/ftrace.h>
12770cb243SSteven Rostedt #include <linux/module.h>
13770cb243SSteven Rostedt #include <linux/init.h>
14770cb243SSteven Rostedt #include <linux/fs.h>
15770cb243SSteven Rostedt 
16770cb243SSteven Rostedt #include "trace_output.h"
17770cb243SSteven Rostedt 
184e5292eaSSteven Rostedt #undef TRACE_SYSTEM
194e5292eaSSteven Rostedt #define TRACE_SYSTEM	ftrace
20da4d0302SSteven Rostedt 
214e5292eaSSteven Rostedt /* not needed for this file */
224e5292eaSSteven Rostedt #undef __field_struct
234e5292eaSSteven Rostedt #define __field_struct(type, item)
24da4d0302SSteven Rostedt 
254e5292eaSSteven Rostedt #undef __field
264e5292eaSSteven Rostedt #define __field(type, item)						\
27da4d0302SSteven Rostedt 	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
284e5292eaSSteven Rostedt 			       "offset:%zu;\tsize:%zu;\n",		\
294e5292eaSSteven Rostedt 			       offsetof(typeof(field), item),		\
304e5292eaSSteven Rostedt 			       sizeof(field.item));			\
31da4d0302SSteven Rostedt 	if (!ret)							\
32da4d0302SSteven Rostedt 		return 0;
33da4d0302SSteven Rostedt 
344e5292eaSSteven Rostedt #undef __field_desc
354e5292eaSSteven Rostedt #define __field_desc(type, container, item)				\
364e5292eaSSteven Rostedt 	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
374e5292eaSSteven Rostedt 			       "offset:%zu;\tsize:%zu;\n",		\
384e5292eaSSteven Rostedt 			       offsetof(typeof(field), container.item),	\
394e5292eaSSteven Rostedt 			       sizeof(field.container.item));		\
40da4d0302SSteven Rostedt 	if (!ret)							\
41da4d0302SSteven Rostedt 		return 0;
42770cb243SSteven Rostedt 
434e5292eaSSteven Rostedt #undef __array
444e5292eaSSteven Rostedt #define __array(type, item, len)					\
454e5292eaSSteven Rostedt 	ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
464e5292eaSSteven Rostedt 			       "offset:%zu;\tsize:%zu;\n",		\
474e5292eaSSteven Rostedt 			       offsetof(typeof(field), item),	\
484e5292eaSSteven Rostedt 			       sizeof(field.item));		\
49770cb243SSteven Rostedt 	if (!ret)							\
50770cb243SSteven Rostedt 		return 0;
51770cb243SSteven Rostedt 
524e5292eaSSteven Rostedt #undef __array_desc
534e5292eaSSteven Rostedt #define __array_desc(type, container, item, len)			\
544e5292eaSSteven Rostedt 	ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
554e5292eaSSteven Rostedt 			       "offset:%zu;\tsize:%zu;\n",		\
564e5292eaSSteven Rostedt 			       offsetof(typeof(field), container.item),	\
574e5292eaSSteven Rostedt 			       sizeof(field.container.item));		\
584e5292eaSSteven Rostedt 	if (!ret)							\
594e5292eaSSteven Rostedt 		return 0;
60770cb243SSteven Rostedt 
614e5292eaSSteven Rostedt #undef __dynamic_array
624e5292eaSSteven Rostedt #define __dynamic_array(type, item)					\
634e5292eaSSteven Rostedt 	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
644e5292eaSSteven Rostedt 			       "offset:%zu;\tsize:0;\n",		\
654e5292eaSSteven Rostedt 			       offsetof(typeof(field), item));		\
664e5292eaSSteven Rostedt 	if (!ret)							\
674e5292eaSSteven Rostedt 		return 0;
68770cb243SSteven Rostedt 
694e5292eaSSteven Rostedt #undef F_printk
704e5292eaSSteven Rostedt #define F_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
714e5292eaSSteven Rostedt 
724e5292eaSSteven Rostedt #undef __entry
734e5292eaSSteven Rostedt #define __entry REC
744e5292eaSSteven Rostedt 
754e5292eaSSteven Rostedt #undef FTRACE_ENTRY
764e5292eaSSteven Rostedt #define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
77770cb243SSteven Rostedt static int								\
784e5292eaSSteven Rostedt ftrace_format_##name(struct ftrace_event_call *unused,			\
79e8f9f4d7SFrederic Weisbecker 		     struct trace_seq *s)				\
80770cb243SSteven Rostedt {									\
814e5292eaSSteven Rostedt 	struct struct_name field __attribute__((unused));		\
824e5292eaSSteven Rostedt 	int ret = 0;							\
83770cb243SSteven Rostedt 									\
84770cb243SSteven Rostedt 	tstruct;							\
85770cb243SSteven Rostedt 									\
864e5292eaSSteven Rostedt 	trace_seq_printf(s, "\nprint fmt: " print);			\
87770cb243SSteven Rostedt 									\
88770cb243SSteven Rostedt 	return ret;							\
89770cb243SSteven Rostedt }
90770cb243SSteven Rostedt 
914e5292eaSSteven Rostedt #undef FTRACE_ENTRY_DUP
924e5292eaSSteven Rostedt #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print)	\
934e5292eaSSteven Rostedt 	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))
944e5292eaSSteven Rostedt 
954e5292eaSSteven Rostedt #include "trace_entries.h"
964e5292eaSSteven Rostedt 
974e5292eaSSteven Rostedt 
984e5292eaSSteven Rostedt #undef __field
994e5292eaSSteven Rostedt #define __field(type, item)						\
1004e5292eaSSteven Rostedt 	ret = trace_define_field(event_call, #type, #item,		\
1014e5292eaSSteven Rostedt 				 offsetof(typeof(field), item),		\
1024e5292eaSSteven Rostedt 				 sizeof(field.item),			\
1034e5292eaSSteven Rostedt 				 is_signed_type(type), FILTER_OTHER);	\
1044e5292eaSSteven Rostedt 	if (ret)							\
1054e5292eaSSteven Rostedt 		return ret;
1064e5292eaSSteven Rostedt 
1074e5292eaSSteven Rostedt #undef __field_desc
1084e5292eaSSteven Rostedt #define __field_desc(type, container, item)	\
1094e5292eaSSteven Rostedt 	ret = trace_define_field(event_call, #type, #item,		\
1104e5292eaSSteven Rostedt 				 offsetof(typeof(field),		\
1114e5292eaSSteven Rostedt 					  container.item),		\
1124e5292eaSSteven Rostedt 				 sizeof(field.container.item),		\
1134e5292eaSSteven Rostedt 				 is_signed_type(type), FILTER_OTHER);	\
1144e5292eaSSteven Rostedt 	if (ret)							\
1154e5292eaSSteven Rostedt 		return ret;
1164e5292eaSSteven Rostedt 
1174e5292eaSSteven Rostedt #undef __array
1184e5292eaSSteven Rostedt #define __array(type, item, len)					\
1194e5292eaSSteven Rostedt 	BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);				\
1204e5292eaSSteven Rostedt 	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
1214e5292eaSSteven Rostedt 				 offsetof(typeof(field), item),		\
1224e5292eaSSteven Rostedt 				 sizeof(field.item), 0, FILTER_OTHER);	\
1234e5292eaSSteven Rostedt 	if (ret)							\
1244e5292eaSSteven Rostedt 		return ret;
1254e5292eaSSteven Rostedt 
1264e5292eaSSteven Rostedt #undef __array_desc
1274e5292eaSSteven Rostedt #define __array_desc(type, container, item, len)			\
1284e5292eaSSteven Rostedt 	BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);				\
1294e5292eaSSteven Rostedt 	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
1304e5292eaSSteven Rostedt 				 offsetof(typeof(field),		\
1314e5292eaSSteven Rostedt 					  container.item),		\
1324e5292eaSSteven Rostedt 				 sizeof(field.container.item), 0,	\
1334e5292eaSSteven Rostedt 				 FILTER_OTHER);				\
1344e5292eaSSteven Rostedt 	if (ret)							\
1354e5292eaSSteven Rostedt 		return ret;
1364e5292eaSSteven Rostedt 
1374e5292eaSSteven Rostedt #undef __dynamic_array
1384e5292eaSSteven Rostedt #define __dynamic_array(type, item)
1394e5292eaSSteven Rostedt 
1404e5292eaSSteven Rostedt #undef FTRACE_ENTRY
1414e5292eaSSteven Rostedt #define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
1424e5292eaSSteven Rostedt int									\
1434e5292eaSSteven Rostedt ftrace_define_fields_##name(struct ftrace_event_call *event_call)	\
144e45f2e2bSTom Zanussi {									\
1454e5292eaSSteven Rostedt 	struct struct_name field;					\
146e45f2e2bSTom Zanussi 	int ret;							\
147e45f2e2bSTom Zanussi 									\
1484e5292eaSSteven Rostedt 	ret = trace_define_common_fields(event_call);			\
1494e5292eaSSteven Rostedt 	if (ret)							\
1504e5292eaSSteven Rostedt 		return ret;						\
151e45f2e2bSTom Zanussi 									\
1524e5292eaSSteven Rostedt 	tstruct;							\
153e45f2e2bSTom Zanussi 									\
154e45f2e2bSTom Zanussi 	return ret;							\
155e45f2e2bSTom Zanussi }
156e45f2e2bSTom Zanussi 
1574e5292eaSSteven Rostedt #include "trace_entries.h"
1584e5292eaSSteven Rostedt 
1594e5292eaSSteven Rostedt 
1604e5292eaSSteven Rostedt #undef __field
1614e5292eaSSteven Rostedt #define __field(type, item)
1624e5292eaSSteven Rostedt 
1634e5292eaSSteven Rostedt #undef __field_desc
1644e5292eaSSteven Rostedt #define __field_desc(type, container, item)
1654e5292eaSSteven Rostedt 
1664e5292eaSSteven Rostedt #undef __array
1674e5292eaSSteven Rostedt #define __array(type, item, len)
1684e5292eaSSteven Rostedt 
1694e5292eaSSteven Rostedt #undef __array_desc
1704e5292eaSSteven Rostedt #define __array_desc(type, container, item, len)
1714e5292eaSSteven Rostedt 
1724e5292eaSSteven Rostedt #undef __dynamic_array
1734e5292eaSSteven Rostedt #define __dynamic_array(type, item)
1744e5292eaSSteven Rostedt 
175770cb243SSteven Rostedt 
176770cb243SSteven Rostedt #undef TRACE_ZERO_CHAR
177770cb243SSteven Rostedt #define TRACE_ZERO_CHAR(arg)
178770cb243SSteven Rostedt 
179770cb243SSteven Rostedt #undef TRACE_FIELD
180770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\
181770cb243SSteven Rostedt 	entry->item = assign;
182770cb243SSteven Rostedt 
183770cb243SSteven Rostedt #undef TRACE_FIELD
184770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\
185770cb243SSteven Rostedt 	entry->item = assign;
186770cb243SSteven Rostedt 
187a118e4d1STom Zanussi #undef TRACE_FIELD_SIGN
188a118e4d1STom Zanussi #define TRACE_FIELD_SIGN(type, item, assign, is_signed)	\
189a118e4d1STom Zanussi 	TRACE_FIELD(type, item, assign)
190a118e4d1STom Zanussi 
1912939b046SSteven Rostedt #undef TP_CMD
1922939b046SSteven Rostedt #define TP_CMD(cmd...)	cmd
193770cb243SSteven Rostedt 
194770cb243SSteven Rostedt #undef TRACE_ENTRY
195770cb243SSteven Rostedt #define TRACE_ENTRY	entry
196770cb243SSteven Rostedt 
197770cb243SSteven Rostedt #undef TRACE_FIELD_SPECIAL
198e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd)	\
199770cb243SSteven Rostedt 	cmd;
200770cb243SSteven Rostedt 
2014e5292eaSSteven Rostedt #undef FTRACE_ENTRY
2024e5292eaSSteven Rostedt #define FTRACE_ENTRY(call, struct_name, type, tstruct, print)		\
203e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void);				\
204770cb243SSteven Rostedt 									\
205e1112b4dSTom Zanussi struct ftrace_event_call __used						\
206770cb243SSteven Rostedt __attribute__((__aligned__(4)))						\
207770cb243SSteven Rostedt __attribute__((section("_ftrace_events"))) event_##call = {		\
208770cb243SSteven Rostedt 	.name			= #call,				\
2094e5292eaSSteven Rostedt 	.id			= type,					\
210770cb243SSteven Rostedt 	.system			= __stringify(TRACE_SYSTEM),		\
211e1112b4dSTom Zanussi 	.raw_init		= ftrace_raw_init_event_##call,		\
212770cb243SSteven Rostedt 	.show_format		= ftrace_format_##call,			\
213e1112b4dSTom Zanussi 	.define_fields		= ftrace_define_fields_##call,		\
214e1112b4dSTom Zanussi };									\
215e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void)				\
216e1112b4dSTom Zanussi {									\
217e1112b4dSTom Zanussi 	INIT_LIST_HEAD(&event_##call.fields);				\
218e1112b4dSTom Zanussi 	return 0;							\
219e1112b4dSTom Zanussi }									\
220e1112b4dSTom Zanussi 
2214e5292eaSSteven Rostedt #include "trace_entries.h"
222