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