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 2605ffa2d0SLi Zefan #define __field(type, item) type item; 2775db37d2SSteven Rostedt 2805ffa2d0SLi Zefan #undef __field_desc 2905ffa2d0SLi Zefan #define __field_desc(type, container, item) type item; 30da4d0302SSteven Rostedt 3105ffa2d0SLi Zefan #undef __array 3205ffa2d0SLi Zefan #define __array(type, item, size) type item[size]; 33da4d0302SSteven Rostedt 3405ffa2d0SLi Zefan #undef __array_desc 3505ffa2d0SLi Zefan #define __array_desc(type, container, item, size) type item[size]; 36770cb243SSteven Rostedt 3705ffa2d0SLi Zefan #undef __dynamic_array 3805ffa2d0SLi Zefan #define __dynamic_array(type, item) type item[]; 39770cb243SSteven Rostedt 4005ffa2d0SLi Zefan #undef F_STRUCT 4105ffa2d0SLi Zefan #define F_STRUCT(args...) args 42770cb243SSteven Rostedt 4305ffa2d0SLi Zefan #undef F_printk 4405ffa2d0SLi Zefan #define F_printk(fmt, args...) fmt, args 45770cb243SSteven Rostedt 4605ffa2d0SLi Zefan #undef FTRACE_ENTRY 4705ffa2d0SLi Zefan #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ 4805ffa2d0SLi Zefan struct ____ftrace_##name { \ 4905ffa2d0SLi Zefan tstruct \ 50e1112b4dSTom Zanussi }; \ 5105ffa2d0SLi Zefan static void __used ____ftrace_check_##name(void) \ 5205ffa2d0SLi Zefan { \ 5305ffa2d0SLi Zefan struct ____ftrace_##name *__entry = NULL; \ 54e45f2e2bSTom Zanussi \ 5505ffa2d0SLi Zefan /* force cmpile-time check on F_printk() */ \ 5605ffa2d0SLi Zefan printk(print); \ 5705ffa2d0SLi Zefan } 58e45f2e2bSTom Zanussi 5905ffa2d0SLi Zefan #undef FTRACE_ENTRY_DUP 6005ffa2d0SLi Zefan #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print) \ 6105ffa2d0SLi Zefan FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print)) 62e1112b4dSTom Zanussi 6305ffa2d0SLi Zefan #include "trace_entries.h" 6405ffa2d0SLi Zefan 6505ffa2d0SLi Zefan 6605ffa2d0SLi Zefan #undef __field 674e5292eaSSteven Rostedt #define __field(type, item) \ 68770cb243SSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 694e5292eaSSteven Rostedt "offset:%zu;\tsize:%zu;\n", \ 704e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 714e5292eaSSteven Rostedt sizeof(field.item)); \ 72770cb243SSteven Rostedt if (!ret) \ 73770cb243SSteven Rostedt return 0; 74770cb243SSteven Rostedt 754e5292eaSSteven Rostedt #undef __field_desc 764e5292eaSSteven Rostedt #define __field_desc(type, container, item) \ 774e5292eaSSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 784e5292eaSSteven Rostedt "offset:%zu;\tsize:%zu;\n", \ 794e5292eaSSteven Rostedt offsetof(typeof(field), container.item), \ 804e5292eaSSteven Rostedt sizeof(field.container.item)); \ 81770cb243SSteven Rostedt if (!ret) \ 82770cb243SSteven Rostedt return 0; 83770cb243SSteven Rostedt 844e5292eaSSteven Rostedt #undef __array 854e5292eaSSteven Rostedt #define __array(type, item, len) \ 864e5292eaSSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ 874e5292eaSSteven Rostedt "offset:%zu;\tsize:%zu;\n", \ 884e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 894e5292eaSSteven Rostedt sizeof(field.item)); \ 90770cb243SSteven Rostedt if (!ret) \ 91770cb243SSteven Rostedt return 0; 92770cb243SSteven Rostedt 934e5292eaSSteven Rostedt #undef __array_desc 944e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) \ 954e5292eaSSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ 964e5292eaSSteven Rostedt "offset:%zu;\tsize:%zu;\n", \ 974e5292eaSSteven Rostedt offsetof(typeof(field), container.item), \ 984e5292eaSSteven Rostedt sizeof(field.container.item)); \ 994e5292eaSSteven Rostedt if (!ret) \ 1004e5292eaSSteven Rostedt return 0; 101770cb243SSteven Rostedt 1024e5292eaSSteven Rostedt #undef __dynamic_array 1034e5292eaSSteven Rostedt #define __dynamic_array(type, item) \ 1044e5292eaSSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 1054e5292eaSSteven Rostedt "offset:%zu;\tsize:0;\n", \ 1064e5292eaSSteven Rostedt offsetof(typeof(field), item)); \ 1074e5292eaSSteven Rostedt if (!ret) \ 1084e5292eaSSteven Rostedt return 0; 109770cb243SSteven Rostedt 1104e5292eaSSteven Rostedt #undef F_printk 1114e5292eaSSteven Rostedt #define F_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) 1124e5292eaSSteven Rostedt 1134e5292eaSSteven Rostedt #undef __entry 1144e5292eaSSteven Rostedt #define __entry REC 1154e5292eaSSteven Rostedt 1164e5292eaSSteven Rostedt #undef FTRACE_ENTRY 1174e5292eaSSteven Rostedt #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ 118770cb243SSteven Rostedt static int \ 1194e5292eaSSteven Rostedt ftrace_format_##name(struct ftrace_event_call *unused, \ 120770cb243SSteven Rostedt struct trace_seq *s) \ 121770cb243SSteven Rostedt { \ 1224e5292eaSSteven Rostedt struct struct_name field __attribute__((unused)); \ 1234e5292eaSSteven Rostedt int ret = 0; \ 124770cb243SSteven Rostedt \ 125770cb243SSteven Rostedt tstruct; \ 126770cb243SSteven Rostedt \ 1274e5292eaSSteven Rostedt trace_seq_printf(s, "\nprint fmt: " print); \ 128770cb243SSteven Rostedt \ 129770cb243SSteven Rostedt return ret; \ 130770cb243SSteven Rostedt } 131770cb243SSteven Rostedt 1324e5292eaSSteven Rostedt #include "trace_entries.h" 1334e5292eaSSteven Rostedt 1344e5292eaSSteven Rostedt #undef __field 1354e5292eaSSteven Rostedt #define __field(type, item) \ 136e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type, #item, \ 137e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 13843b51eadSLi Zefan sizeof(field.item), \ 13943b51eadSLi Zefan is_signed_type(type), FILTER_OTHER); \ 140e1112b4dSTom Zanussi if (ret) \ 141e1112b4dSTom Zanussi return ret; 142e1112b4dSTom Zanussi 1434e5292eaSSteven Rostedt #undef __field_desc 1444e5292eaSSteven Rostedt #define __field_desc(type, container, item) \ 1454e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type, #item, \ 1464e5292eaSSteven Rostedt offsetof(typeof(field), \ 1474e5292eaSSteven Rostedt container.item), \ 1484e5292eaSSteven Rostedt sizeof(field.container.item), \ 1494e5292eaSSteven Rostedt is_signed_type(type), FILTER_OTHER); \ 1504e5292eaSSteven Rostedt if (ret) \ 1514e5292eaSSteven Rostedt return ret; 1524e5292eaSSteven Rostedt 1534e5292eaSSteven Rostedt #undef __array 1544e5292eaSSteven Rostedt #define __array(type, item, len) \ 1554e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 156e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 157e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 15843b51eadSLi Zefan sizeof(field.item), 0, FILTER_OTHER); \ 159a118e4d1STom Zanussi if (ret) \ 160a118e4d1STom Zanussi return ret; 161a118e4d1STom Zanussi 1624e5292eaSSteven Rostedt #undef __array_desc 1634e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) \ 1644e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 1654e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 1664e5292eaSSteven Rostedt offsetof(typeof(field), \ 1674e5292eaSSteven Rostedt container.item), \ 1684e5292eaSSteven Rostedt sizeof(field.container.item), 0, \ 16943b51eadSLi Zefan FILTER_OTHER); \ 170e1112b4dSTom Zanussi if (ret) \ 171e1112b4dSTom Zanussi return ret; 172e1112b4dSTom Zanussi 1734e5292eaSSteven Rostedt #undef __dynamic_array 1744e5292eaSSteven Rostedt #define __dynamic_array(type, item) 175e1112b4dSTom Zanussi 1764e5292eaSSteven Rostedt #undef FTRACE_ENTRY 1774e5292eaSSteven Rostedt #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ 178e1112b4dSTom Zanussi int \ 1794e5292eaSSteven Rostedt ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ 180e1112b4dSTom Zanussi { \ 1814e5292eaSSteven Rostedt struct struct_name field; \ 182e1112b4dSTom Zanussi int ret; \ 183e1112b4dSTom Zanussi \ 184e647d6b3SLi Zefan ret = trace_define_common_fields(event_call); \ 185e647d6b3SLi Zefan if (ret) \ 186e647d6b3SLi Zefan return ret; \ 187e1112b4dSTom Zanussi \ 188e1112b4dSTom Zanussi tstruct; \ 189e1112b4dSTom Zanussi \ 190e1112b4dSTom Zanussi return ret; \ 191770cb243SSteven Rostedt } 192e1112b4dSTom Zanussi 1934e5292eaSSteven Rostedt #include "trace_entries.h" 194e45f2e2bSTom Zanussi 195d7a4b414SFrederic Weisbecker static int ftrace_raw_init_event(struct ftrace_event_call *call) 196d7a4b414SFrederic Weisbecker { 197d7a4b414SFrederic Weisbecker INIT_LIST_HEAD(&call->fields); 198d7a4b414SFrederic Weisbecker return 0; 199d7a4b414SFrederic Weisbecker } 2004e5292eaSSteven Rostedt 2014e5292eaSSteven Rostedt #undef __field 2024e5292eaSSteven Rostedt #define __field(type, item) 2034e5292eaSSteven Rostedt 2044e5292eaSSteven Rostedt #undef __field_desc 2054e5292eaSSteven Rostedt #define __field_desc(type, container, item) 2064e5292eaSSteven Rostedt 2074e5292eaSSteven Rostedt #undef __array 2084e5292eaSSteven Rostedt #define __array(type, item, len) 2094e5292eaSSteven Rostedt 2104e5292eaSSteven Rostedt #undef __array_desc 2114e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) 2124e5292eaSSteven Rostedt 2134e5292eaSSteven Rostedt #undef __dynamic_array 2144e5292eaSSteven Rostedt #define __dynamic_array(type, item) 2154e5292eaSSteven Rostedt 2164e5292eaSSteven Rostedt #undef FTRACE_ENTRY 2174e5292eaSSteven Rostedt #define FTRACE_ENTRY(call, struct_name, type, tstruct, print) \ 218770cb243SSteven Rostedt \ 219770cb243SSteven Rostedt struct ftrace_event_call __used \ 220770cb243SSteven Rostedt __attribute__((__aligned__(4))) \ 221770cb243SSteven Rostedt __attribute__((section("_ftrace_events"))) event_##call = { \ 222770cb243SSteven Rostedt .name = #call, \ 2234e5292eaSSteven Rostedt .id = type, \ 224770cb243SSteven Rostedt .system = __stringify(TRACE_SYSTEM), \ 225d7a4b414SFrederic Weisbecker .raw_init = ftrace_raw_init_event, \ 226770cb243SSteven Rostedt .show_format = ftrace_format_##call, \ 227770cb243SSteven Rostedt .define_fields = ftrace_define_fields_##call, \ 228770cb243SSteven Rostedt }; \ 229770cb243SSteven Rostedt 2304e5292eaSSteven Rostedt #include "trace_entries.h" 231