1 /* 2 * trace_export.c - export basic ftrace utilities to user space 3 * 4 * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com> 5 */ 6 #include <linux/stringify.h> 7 #include <linux/kallsyms.h> 8 #include <linux/seq_file.h> 9 #include <linux/debugfs.h> 10 #include <linux/uaccess.h> 11 #include <linux/ftrace.h> 12 #include <linux/module.h> 13 #include <linux/init.h> 14 #include <linux/fs.h> 15 16 #include "trace_output.h" 17 18 19 #undef TRACE_STRUCT 20 #define TRACE_STRUCT(args...) args 21 22 extern void __bad_type_size(void); 23 24 #undef TRACE_FIELD 25 #define TRACE_FIELD(type, item, assign) \ 26 if (sizeof(type) != sizeof(field.item)) \ 27 __bad_type_size(); \ 28 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 29 "offset:%u;\tsize:%u;\n", \ 30 (unsigned int)offsetof(typeof(field), item), \ 31 (unsigned int)sizeof(field.item)); \ 32 if (!ret) \ 33 return 0; 34 35 36 #undef TRACE_FIELD_SPECIAL 37 #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 38 ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \ 39 "offset:%u;\tsize:%u;\n", \ 40 (unsigned int)offsetof(typeof(field), item), \ 41 (unsigned int)sizeof(field.item)); \ 42 if (!ret) \ 43 return 0; 44 45 #undef TRACE_FIELD_ZERO_CHAR 46 #define TRACE_FIELD_ZERO_CHAR(item) \ 47 ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \ 48 "offset:%u;\tsize:0;\n", \ 49 (unsigned int)offsetof(typeof(field), item)); \ 50 if (!ret) \ 51 return 0; 52 53 #undef TRACE_FIELD_SIGN 54 #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 55 TRACE_FIELD(type, item, assign) 56 57 #undef TP_RAW_FMT 58 #define TP_RAW_FMT(args...) args 59 60 #undef TRACE_EVENT_FORMAT 61 #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 62 static int \ 63 ftrace_format_##call(struct trace_seq *s) \ 64 { \ 65 struct args field; \ 66 int ret; \ 67 \ 68 tstruct; \ 69 \ 70 trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 71 \ 72 return ret; \ 73 } 74 75 #undef TRACE_EVENT_FORMAT_NOFILTER 76 #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 77 tpfmt) \ 78 static int \ 79 ftrace_format_##call(struct trace_seq *s) \ 80 { \ 81 struct args field; \ 82 int ret; \ 83 \ 84 tstruct; \ 85 \ 86 trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \ 87 \ 88 return ret; \ 89 } 90 91 #include "trace_event_types.h" 92 93 #undef TRACE_ZERO_CHAR 94 #define TRACE_ZERO_CHAR(arg) 95 96 #undef TRACE_FIELD 97 #define TRACE_FIELD(type, item, assign)\ 98 entry->item = assign; 99 100 #undef TRACE_FIELD 101 #define TRACE_FIELD(type, item, assign)\ 102 entry->item = assign; 103 104 #undef TRACE_FIELD_SIGN 105 #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 106 TRACE_FIELD(type, item, assign) 107 108 #undef TP_CMD 109 #define TP_CMD(cmd...) cmd 110 111 #undef TRACE_ENTRY 112 #define TRACE_ENTRY entry 113 114 #undef TRACE_FIELD_SPECIAL 115 #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ 116 cmd; 117 118 #undef TRACE_EVENT_FORMAT 119 #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 120 int ftrace_define_fields_##call(void); \ 121 static int ftrace_raw_init_event_##call(void); \ 122 \ 123 struct ftrace_event_call __used \ 124 __attribute__((__aligned__(4))) \ 125 __attribute__((section("_ftrace_events"))) event_##call = { \ 126 .name = #call, \ 127 .id = proto, \ 128 .system = __stringify(TRACE_SYSTEM), \ 129 .raw_init = ftrace_raw_init_event_##call, \ 130 .show_format = ftrace_format_##call, \ 131 .define_fields = ftrace_define_fields_##call, \ 132 }; \ 133 static int ftrace_raw_init_event_##call(void) \ 134 { \ 135 INIT_LIST_HEAD(&event_##call.fields); \ 136 init_preds(&event_##call); \ 137 return 0; \ 138 } \ 139 140 #undef TRACE_EVENT_FORMAT_NOFILTER 141 #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 142 tpfmt) \ 143 \ 144 struct ftrace_event_call __used \ 145 __attribute__((__aligned__(4))) \ 146 __attribute__((section("_ftrace_events"))) event_##call = { \ 147 .name = #call, \ 148 .id = proto, \ 149 .system = __stringify(TRACE_SYSTEM), \ 150 .show_format = ftrace_format_##call, \ 151 }; 152 153 #include "trace_event_types.h" 154 155 #undef TRACE_FIELD 156 #define TRACE_FIELD(type, item, assign) \ 157 ret = trace_define_field(event_call, #type, #item, \ 158 offsetof(typeof(field), item), \ 159 sizeof(field.item), is_signed_type(type)); \ 160 if (ret) \ 161 return ret; 162 163 #undef TRACE_FIELD_SPECIAL 164 #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ 165 ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 166 offsetof(typeof(field), item), \ 167 sizeof(field.item), 0); \ 168 if (ret) \ 169 return ret; 170 171 #undef TRACE_FIELD_SIGN 172 #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ 173 ret = trace_define_field(event_call, #type, #item, \ 174 offsetof(typeof(field), item), \ 175 sizeof(field.item), is_signed); \ 176 if (ret) \ 177 return ret; 178 179 #undef TRACE_FIELD_ZERO_CHAR 180 #define TRACE_FIELD_ZERO_CHAR(item) 181 182 #undef TRACE_EVENT_FORMAT 183 #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 184 int \ 185 ftrace_define_fields_##call(void) \ 186 { \ 187 struct ftrace_event_call *event_call = &event_##call; \ 188 struct args field; \ 189 int ret; \ 190 \ 191 __common_field(unsigned char, type, 0); \ 192 __common_field(unsigned char, flags, 0); \ 193 __common_field(unsigned char, preempt_count, 0); \ 194 __common_field(int, pid, 1); \ 195 __common_field(int, tgid, 1); \ 196 \ 197 tstruct; \ 198 \ 199 return ret; \ 200 } 201 202 #undef TRACE_EVENT_FORMAT_NOFILTER 203 #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ 204 tpfmt) 205 206 #include "trace_event_types.h" 207