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 18da4d0302SSteven Rostedt 19da4d0302SSteven Rostedt #undef TRACE_STRUCT 20da4d0302SSteven Rostedt #define TRACE_STRUCT(args...) args 21da4d0302SSteven Rostedt 2275db37d2SSteven Rostedt extern void __bad_type_size(void); 2375db37d2SSteven Rostedt 24da4d0302SSteven Rostedt #undef TRACE_FIELD 25da4d0302SSteven Rostedt #define TRACE_FIELD(type, item, assign) \ 2675db37d2SSteven Rostedt if (sizeof(type) != sizeof(field.item)) \ 2775db37d2SSteven Rostedt __bad_type_size(); \ 28da4d0302SSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 29da4d0302SSteven Rostedt "offset:%u;\tsize:%u;\n", \ 30da4d0302SSteven Rostedt (unsigned int)offsetof(typeof(field), item), \ 31da4d0302SSteven Rostedt (unsigned int)sizeof(field.item)); \ 32da4d0302SSteven Rostedt if (!ret) \ 33da4d0302SSteven Rostedt return 0; 34da4d0302SSteven Rostedt 35da4d0302SSteven Rostedt 36da4d0302SSteven Rostedt #undef TRACE_FIELD_SPECIAL 37e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 38da4d0302SSteven Rostedt ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \ 39da4d0302SSteven Rostedt "offset:%u;\tsize:%u;\n", \ 40da4d0302SSteven Rostedt (unsigned int)offsetof(typeof(field), item), \ 41da4d0302SSteven Rostedt (unsigned int)sizeof(field.item)); \ 42da4d0302SSteven Rostedt if (!ret) \ 43da4d0302SSteven Rostedt return 0; 44770cb243SSteven Rostedt 45770cb243SSteven Rostedt #undef TRACE_FIELD_ZERO_CHAR 46770cb243SSteven Rostedt #define TRACE_FIELD_ZERO_CHAR(item) \ 47770cb243SSteven Rostedt ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \ 48156b5f17SSteven Rostedt "offset:%u;\tsize:0;\n", \ 49156b5f17SSteven Rostedt (unsigned int)offsetof(typeof(field), item)); \ 50770cb243SSteven Rostedt if (!ret) \ 51770cb243SSteven Rostedt return 0; 52770cb243SSteven Rostedt 53a118e4d1STom Zanussi #undef TRACE_FIELD_SIGN 54a118e4d1STom Zanussi #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 55a118e4d1STom Zanussi TRACE_FIELD(type, item, assign) 56770cb243SSteven Rostedt 572939b046SSteven Rostedt #undef TP_RAW_FMT 582939b046SSteven Rostedt #define TP_RAW_FMT(args...) args 59770cb243SSteven Rostedt 60770cb243SSteven Rostedt #undef TRACE_EVENT_FORMAT 61770cb243SSteven Rostedt #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 62770cb243SSteven Rostedt static int \ 63e8f9f4d7SFrederic Weisbecker ftrace_format_##call(struct ftrace_event_call *unused, \ 64e8f9f4d7SFrederic Weisbecker struct trace_seq *s) \ 65770cb243SSteven Rostedt { \ 66770cb243SSteven Rostedt struct args field; \ 67770cb243SSteven Rostedt int ret; \ 68770cb243SSteven Rostedt \ 69770cb243SSteven Rostedt tstruct; \ 70770cb243SSteven Rostedt \ 71770cb243SSteven Rostedt trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 72770cb243SSteven Rostedt \ 73770cb243SSteven Rostedt return ret; \ 74770cb243SSteven Rostedt } 75770cb243SSteven Rostedt 76e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 77e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 78e45f2e2bSTom Zanussi tpfmt) \ 79e45f2e2bSTom Zanussi static int \ 80e8f9f4d7SFrederic Weisbecker ftrace_format_##call(struct ftrace_event_call *unused, \ 81e8f9f4d7SFrederic Weisbecker struct trace_seq *s) \ 82e45f2e2bSTom Zanussi { \ 83e45f2e2bSTom Zanussi struct args field; \ 84e45f2e2bSTom Zanussi int ret; \ 85e45f2e2bSTom Zanussi \ 86e45f2e2bSTom Zanussi tstruct; \ 87e45f2e2bSTom Zanussi \ 88e45f2e2bSTom Zanussi trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 89e45f2e2bSTom Zanussi \ 90e45f2e2bSTom Zanussi return ret; \ 91e45f2e2bSTom Zanussi } 92e45f2e2bSTom Zanussi 93770cb243SSteven Rostedt #include "trace_event_types.h" 94770cb243SSteven Rostedt 95770cb243SSteven Rostedt #undef TRACE_ZERO_CHAR 96770cb243SSteven Rostedt #define TRACE_ZERO_CHAR(arg) 97770cb243SSteven Rostedt 98770cb243SSteven Rostedt #undef TRACE_FIELD 99770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\ 100770cb243SSteven Rostedt entry->item = assign; 101770cb243SSteven Rostedt 102770cb243SSteven Rostedt #undef TRACE_FIELD 103770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\ 104770cb243SSteven Rostedt entry->item = assign; 105770cb243SSteven Rostedt 106a118e4d1STom Zanussi #undef TRACE_FIELD_SIGN 107a118e4d1STom Zanussi #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 108a118e4d1STom Zanussi TRACE_FIELD(type, item, assign) 109a118e4d1STom Zanussi 1102939b046SSteven Rostedt #undef TP_CMD 1112939b046SSteven Rostedt #define TP_CMD(cmd...) cmd 112770cb243SSteven Rostedt 113770cb243SSteven Rostedt #undef TRACE_ENTRY 114770cb243SSteven Rostedt #define TRACE_ENTRY entry 115770cb243SSteven Rostedt 116770cb243SSteven Rostedt #undef TRACE_FIELD_SPECIAL 117e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 118770cb243SSteven Rostedt cmd; 119770cb243SSteven Rostedt 120770cb243SSteven Rostedt #undef TRACE_EVENT_FORMAT 121770cb243SSteven Rostedt #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 12214be96c9SLi Zefan int ftrace_define_fields_##call(struct ftrace_event_call *event_call); \ 123e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void); \ 124770cb243SSteven Rostedt \ 125e1112b4dSTom Zanussi struct ftrace_event_call __used \ 126770cb243SSteven Rostedt __attribute__((__aligned__(4))) \ 127770cb243SSteven Rostedt __attribute__((section("_ftrace_events"))) event_##call = { \ 128770cb243SSteven Rostedt .name = #call, \ 129770cb243SSteven Rostedt .id = proto, \ 130770cb243SSteven Rostedt .system = __stringify(TRACE_SYSTEM), \ 131e1112b4dSTom Zanussi .raw_init = ftrace_raw_init_event_##call, \ 132770cb243SSteven Rostedt .show_format = ftrace_format_##call, \ 133e1112b4dSTom Zanussi .define_fields = ftrace_define_fields_##call, \ 134e1112b4dSTom Zanussi }; \ 135e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void) \ 136e1112b4dSTom Zanussi { \ 137e1112b4dSTom Zanussi INIT_LIST_HEAD(&event_##call.fields); \ 1380a19e53cSTom Zanussi init_preds(&event_##call); \ 139e1112b4dSTom Zanussi return 0; \ 140e1112b4dSTom Zanussi } \ 141e1112b4dSTom Zanussi 142e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 143e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 144e45f2e2bSTom Zanussi tpfmt) \ 145e45f2e2bSTom Zanussi \ 146e45f2e2bSTom Zanussi struct ftrace_event_call __used \ 147e45f2e2bSTom Zanussi __attribute__((__aligned__(4))) \ 148e45f2e2bSTom Zanussi __attribute__((section("_ftrace_events"))) event_##call = { \ 149e45f2e2bSTom Zanussi .name = #call, \ 150e45f2e2bSTom Zanussi .id = proto, \ 151e45f2e2bSTom Zanussi .system = __stringify(TRACE_SYSTEM), \ 152e45f2e2bSTom Zanussi .show_format = ftrace_format_##call, \ 153e45f2e2bSTom Zanussi }; 154e45f2e2bSTom Zanussi 155e1112b4dSTom Zanussi #include "trace_event_types.h" 156e1112b4dSTom Zanussi 157e1112b4dSTom Zanussi #undef TRACE_FIELD 158e1112b4dSTom Zanussi #define TRACE_FIELD(type, item, assign) \ 159e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type, #item, \ 160e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 16143b51eadSLi Zefan sizeof(field.item), \ 16243b51eadSLi Zefan is_signed_type(type), FILTER_OTHER); \ 163e1112b4dSTom Zanussi if (ret) \ 164e1112b4dSTom Zanussi return ret; 165e1112b4dSTom Zanussi 166e1112b4dSTom Zanussi #undef TRACE_FIELD_SPECIAL 167e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ 168e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 169e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 17043b51eadSLi Zefan sizeof(field.item), 0, FILTER_OTHER); \ 171a118e4d1STom Zanussi if (ret) \ 172a118e4d1STom Zanussi return ret; 173a118e4d1STom Zanussi 174a118e4d1STom Zanussi #undef TRACE_FIELD_SIGN 175a118e4d1STom Zanussi #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 176a118e4d1STom Zanussi ret = trace_define_field(event_call, #type, #item, \ 177a118e4d1STom Zanussi offsetof(typeof(field), item), \ 17843b51eadSLi Zefan sizeof(field.item), is_signed, \ 17943b51eadSLi Zefan FILTER_OTHER); \ 180e1112b4dSTom Zanussi if (ret) \ 181e1112b4dSTom Zanussi return ret; 182e1112b4dSTom Zanussi 183e1112b4dSTom Zanussi #undef TRACE_FIELD_ZERO_CHAR 184e1112b4dSTom Zanussi #define TRACE_FIELD_ZERO_CHAR(item) 185e1112b4dSTom Zanussi 186e1112b4dSTom Zanussi #undef TRACE_EVENT_FORMAT 187e1112b4dSTom Zanussi #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 188e1112b4dSTom Zanussi int \ 18914be96c9SLi Zefan ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ 190e1112b4dSTom Zanussi { \ 191e1112b4dSTom Zanussi struct args field; \ 192e1112b4dSTom Zanussi int ret; \ 193e1112b4dSTom Zanussi \ 194e647d6b3SLi Zefan ret = trace_define_common_fields(event_call); \ 195e647d6b3SLi Zefan if (ret) \ 196e647d6b3SLi Zefan return ret; \ 197e1112b4dSTom Zanussi \ 198e1112b4dSTom Zanussi tstruct; \ 199e1112b4dSTom Zanussi \ 200e1112b4dSTom Zanussi return ret; \ 201770cb243SSteven Rostedt } 202e1112b4dSTom Zanussi 203e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 204e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 205e45f2e2bSTom Zanussi tpfmt) 206e45f2e2bSTom Zanussi 207770cb243SSteven Rostedt #include "trace_event_types.h" 208