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 22da4d0302SSteven Rostedt #undef TRACE_FIELD 23da4d0302SSteven Rostedt #define TRACE_FIELD(type, item, assign) \ 24da4d0302SSteven Rostedt ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 25da4d0302SSteven Rostedt "offset:%u;\tsize:%u;\n", \ 26da4d0302SSteven Rostedt (unsigned int)offsetof(typeof(field), item), \ 27da4d0302SSteven Rostedt (unsigned int)sizeof(field.item)); \ 28da4d0302SSteven Rostedt if (!ret) \ 29da4d0302SSteven Rostedt return 0; 30da4d0302SSteven Rostedt 31da4d0302SSteven Rostedt 32da4d0302SSteven Rostedt #undef TRACE_FIELD_SPECIAL 33e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 34da4d0302SSteven Rostedt ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \ 35da4d0302SSteven Rostedt "offset:%u;\tsize:%u;\n", \ 36da4d0302SSteven Rostedt (unsigned int)offsetof(typeof(field), item), \ 37da4d0302SSteven Rostedt (unsigned int)sizeof(field.item)); \ 38da4d0302SSteven Rostedt if (!ret) \ 39da4d0302SSteven Rostedt return 0; 40770cb243SSteven Rostedt 41770cb243SSteven Rostedt #undef TRACE_FIELD_ZERO_CHAR 42770cb243SSteven Rostedt #define TRACE_FIELD_ZERO_CHAR(item) \ 43770cb243SSteven Rostedt ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \ 44156b5f17SSteven Rostedt "offset:%u;\tsize:0;\n", \ 45156b5f17SSteven Rostedt (unsigned int)offsetof(typeof(field), item)); \ 46770cb243SSteven Rostedt if (!ret) \ 47770cb243SSteven Rostedt return 0; 48770cb243SSteven Rostedt 49770cb243SSteven Rostedt 502939b046SSteven Rostedt #undef TP_RAW_FMT 512939b046SSteven Rostedt #define TP_RAW_FMT(args...) args 52770cb243SSteven Rostedt 53770cb243SSteven Rostedt #undef TRACE_EVENT_FORMAT 54770cb243SSteven Rostedt #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 55770cb243SSteven Rostedt static int \ 56770cb243SSteven Rostedt ftrace_format_##call(struct trace_seq *s) \ 57770cb243SSteven Rostedt { \ 58770cb243SSteven Rostedt struct args field; \ 59770cb243SSteven Rostedt int ret; \ 60770cb243SSteven Rostedt \ 61770cb243SSteven Rostedt tstruct; \ 62770cb243SSteven Rostedt \ 63770cb243SSteven Rostedt trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 64770cb243SSteven Rostedt \ 65770cb243SSteven Rostedt return ret; \ 66770cb243SSteven Rostedt } 67770cb243SSteven Rostedt 68e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 69e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 70e45f2e2bSTom Zanussi tpfmt) \ 71e45f2e2bSTom Zanussi static int \ 72e45f2e2bSTom Zanussi ftrace_format_##call(struct trace_seq *s) \ 73e45f2e2bSTom Zanussi { \ 74e45f2e2bSTom Zanussi struct args field; \ 75e45f2e2bSTom Zanussi int ret; \ 76e45f2e2bSTom Zanussi \ 77e45f2e2bSTom Zanussi tstruct; \ 78e45f2e2bSTom Zanussi \ 79e45f2e2bSTom Zanussi trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 80e45f2e2bSTom Zanussi \ 81e45f2e2bSTom Zanussi return ret; \ 82e45f2e2bSTom Zanussi } 83e45f2e2bSTom Zanussi 84770cb243SSteven Rostedt #include "trace_event_types.h" 85770cb243SSteven Rostedt 86770cb243SSteven Rostedt #undef TRACE_ZERO_CHAR 87770cb243SSteven Rostedt #define TRACE_ZERO_CHAR(arg) 88770cb243SSteven Rostedt 89770cb243SSteven Rostedt #undef TRACE_FIELD 90770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\ 91770cb243SSteven Rostedt entry->item = assign; 92770cb243SSteven Rostedt 93770cb243SSteven Rostedt #undef TRACE_FIELD 94770cb243SSteven Rostedt #define TRACE_FIELD(type, item, assign)\ 95770cb243SSteven Rostedt entry->item = assign; 96770cb243SSteven Rostedt 972939b046SSteven Rostedt #undef TP_CMD 982939b046SSteven Rostedt #define TP_CMD(cmd...) cmd 99770cb243SSteven Rostedt 100770cb243SSteven Rostedt #undef TRACE_ENTRY 101770cb243SSteven Rostedt #define TRACE_ENTRY entry 102770cb243SSteven Rostedt 103770cb243SSteven Rostedt #undef TRACE_FIELD_SPECIAL 104e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 105770cb243SSteven Rostedt cmd; 106770cb243SSteven Rostedt 107770cb243SSteven Rostedt #undef TRACE_EVENT_FORMAT 108770cb243SSteven Rostedt #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 109e1112b4dSTom Zanussi int ftrace_define_fields_##call(void); \ 110e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void); \ 111770cb243SSteven Rostedt \ 112e1112b4dSTom Zanussi struct ftrace_event_call __used \ 113770cb243SSteven Rostedt __attribute__((__aligned__(4))) \ 114770cb243SSteven Rostedt __attribute__((section("_ftrace_events"))) event_##call = { \ 115770cb243SSteven Rostedt .name = #call, \ 116770cb243SSteven Rostedt .id = proto, \ 117770cb243SSteven Rostedt .system = __stringify(TRACE_SYSTEM), \ 118e1112b4dSTom Zanussi .raw_init = ftrace_raw_init_event_##call, \ 119770cb243SSteven Rostedt .show_format = ftrace_format_##call, \ 120e1112b4dSTom Zanussi .define_fields = ftrace_define_fields_##call, \ 121e1112b4dSTom Zanussi }; \ 122e1112b4dSTom Zanussi static int ftrace_raw_init_event_##call(void) \ 123e1112b4dSTom Zanussi { \ 124e1112b4dSTom Zanussi INIT_LIST_HEAD(&event_##call.fields); \ 1250a19e53cSTom Zanussi init_preds(&event_##call); \ 126e1112b4dSTom Zanussi return 0; \ 127e1112b4dSTom Zanussi } \ 128e1112b4dSTom Zanussi 129e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 130e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 131e45f2e2bSTom Zanussi tpfmt) \ 132e45f2e2bSTom Zanussi \ 133e45f2e2bSTom Zanussi struct ftrace_event_call __used \ 134e45f2e2bSTom Zanussi __attribute__((__aligned__(4))) \ 135e45f2e2bSTom Zanussi __attribute__((section("_ftrace_events"))) event_##call = { \ 136e45f2e2bSTom Zanussi .name = #call, \ 137e45f2e2bSTom Zanussi .id = proto, \ 138e45f2e2bSTom Zanussi .system = __stringify(TRACE_SYSTEM), \ 139e45f2e2bSTom Zanussi .show_format = ftrace_format_##call, \ 140e45f2e2bSTom Zanussi }; 141e45f2e2bSTom Zanussi 142e1112b4dSTom Zanussi #include "trace_event_types.h" 143e1112b4dSTom Zanussi 144e1112b4dSTom Zanussi #undef TRACE_FIELD 145e1112b4dSTom Zanussi #define TRACE_FIELD(type, item, assign) \ 146e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type, #item, \ 147e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 148e1112b4dSTom Zanussi sizeof(field.item)); \ 149e1112b4dSTom Zanussi if (ret) \ 150e1112b4dSTom Zanussi return ret; 151e1112b4dSTom Zanussi 152e1112b4dSTom Zanussi #undef TRACE_FIELD_SPECIAL 153e1112b4dSTom Zanussi #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ 154e1112b4dSTom Zanussi ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 155e1112b4dSTom Zanussi offsetof(typeof(field), item), \ 156e1112b4dSTom Zanussi sizeof(field.item)); \ 157e1112b4dSTom Zanussi if (ret) \ 158e1112b4dSTom Zanussi return ret; 159e1112b4dSTom Zanussi 160e1112b4dSTom Zanussi #undef TRACE_FIELD_ZERO_CHAR 161e1112b4dSTom Zanussi #define TRACE_FIELD_ZERO_CHAR(item) 162e1112b4dSTom Zanussi 163e1112b4dSTom Zanussi #undef TRACE_EVENT_FORMAT 164e1112b4dSTom Zanussi #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 165e1112b4dSTom Zanussi int \ 166e1112b4dSTom Zanussi ftrace_define_fields_##call(void) \ 167e1112b4dSTom Zanussi { \ 168e1112b4dSTom Zanussi struct ftrace_event_call *event_call = &event_##call; \ 169e1112b4dSTom Zanussi struct args field; \ 170e1112b4dSTom Zanussi int ret; \ 171e1112b4dSTom Zanussi \ 172e1112b4dSTom Zanussi __common_field(unsigned char, type); \ 173e1112b4dSTom Zanussi __common_field(unsigned char, flags); \ 174e1112b4dSTom Zanussi __common_field(unsigned char, preempt_count); \ 175e1112b4dSTom Zanussi __common_field(int, pid); \ 176e1112b4dSTom Zanussi __common_field(int, tgid); \ 177e1112b4dSTom Zanussi \ 178e1112b4dSTom Zanussi tstruct; \ 179e1112b4dSTom Zanussi \ 180e1112b4dSTom Zanussi return ret; \ 181770cb243SSteven Rostedt } 182e1112b4dSTom Zanussi 183e45f2e2bSTom Zanussi #undef TRACE_EVENT_FORMAT_NOFILTER 184e45f2e2bSTom Zanussi #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 185e45f2e2bSTom Zanussi tpfmt) 186e45f2e2bSTom Zanussi 187770cb243SSteven Rostedt #include "trace_event_types.h" 188