1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * trace_export.c - export basic ftrace utilities to user space 4 * 5 * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com> 6 */ 7 #include <linux/stringify.h> 8 #include <linux/kallsyms.h> 9 #include <linux/seq_file.h> 10 #include <linux/uaccess.h> 11 #include <linux/ftrace.h> 12 #include <linux/module.h> 13 #include <linux/init.h> 14 15 #include "trace_output.h" 16 17 /* Stub function for events with triggers */ 18 static int ftrace_event_register(struct trace_event_call *call, 19 enum trace_reg type, void *data) 20 { 21 return 0; 22 } 23 24 #undef TRACE_SYSTEM 25 #define TRACE_SYSTEM ftrace 26 27 /* 28 * The FTRACE_ENTRY_REG macro allows ftrace entry to define register 29 * function and thus become accesible via perf. 30 */ 31 #undef FTRACE_ENTRY_REG 32 #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, \ 33 filter, regfn) \ 34 FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ 35 filter) 36 37 /* not needed for this file */ 38 #undef __field_struct 39 #define __field_struct(type, item) 40 41 #undef __field 42 #define __field(type, item) type item; 43 44 #undef __field_desc 45 #define __field_desc(type, container, item) type item; 46 47 #undef __array 48 #define __array(type, item, size) type item[size]; 49 50 #undef __array_desc 51 #define __array_desc(type, container, item, size) type item[size]; 52 53 #undef __dynamic_array 54 #define __dynamic_array(type, item) type item[]; 55 56 #undef F_STRUCT 57 #define F_STRUCT(args...) args 58 59 #undef F_printk 60 #define F_printk(fmt, args...) fmt, args 61 62 #undef FTRACE_ENTRY 63 #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ 64 struct ____ftrace_##name { \ 65 tstruct \ 66 }; \ 67 static void __always_unused ____ftrace_check_##name(void) \ 68 { \ 69 struct ____ftrace_##name *__entry = NULL; \ 70 \ 71 /* force compile-time check on F_printk() */ \ 72 printk(print); \ 73 } 74 75 #undef FTRACE_ENTRY_DUP 76 #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print, filter) \ 77 FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ 78 filter) 79 80 #include "trace_entries.h" 81 82 #undef __field 83 #define __field(type, item) \ 84 ret = trace_define_field(event_call, #type, #item, \ 85 offsetof(typeof(field), item), \ 86 sizeof(field.item), \ 87 is_signed_type(type), filter_type); \ 88 if (ret) \ 89 return ret; 90 91 #undef __field_desc 92 #define __field_desc(type, container, item) \ 93 ret = trace_define_field(event_call, #type, #item, \ 94 offsetof(typeof(field), \ 95 container.item), \ 96 sizeof(field.container.item), \ 97 is_signed_type(type), filter_type); \ 98 if (ret) \ 99 return ret; 100 101 #undef __array 102 #define __array(type, item, len) \ 103 do { \ 104 char *type_str = #type"["__stringify(len)"]"; \ 105 BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 106 ret = trace_define_field(event_call, type_str, #item, \ 107 offsetof(typeof(field), item), \ 108 sizeof(field.item), \ 109 is_signed_type(type), filter_type); \ 110 if (ret) \ 111 return ret; \ 112 } while (0); 113 114 #undef __array_desc 115 #define __array_desc(type, container, item, len) \ 116 BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 117 ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 118 offsetof(typeof(field), \ 119 container.item), \ 120 sizeof(field.container.item), \ 121 is_signed_type(type), filter_type); \ 122 if (ret) \ 123 return ret; 124 125 #undef __dynamic_array 126 #define __dynamic_array(type, item) \ 127 ret = trace_define_field(event_call, #type "[]", #item, \ 128 offsetof(typeof(field), item), \ 129 0, is_signed_type(type), filter_type);\ 130 if (ret) \ 131 return ret; 132 133 #undef FTRACE_ENTRY 134 #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ 135 static int __init \ 136 ftrace_define_fields_##name(struct trace_event_call *event_call) \ 137 { \ 138 struct struct_name field; \ 139 int ret; \ 140 int filter_type = filter; \ 141 \ 142 tstruct; \ 143 \ 144 return ret; \ 145 } 146 147 #include "trace_entries.h" 148 149 #undef __entry 150 #define __entry REC 151 152 #undef __field 153 #define __field(type, item) 154 155 #undef __field_desc 156 #define __field_desc(type, container, item) 157 158 #undef __array 159 #define __array(type, item, len) 160 161 #undef __array_desc 162 #define __array_desc(type, container, item, len) 163 164 #undef __dynamic_array 165 #define __dynamic_array(type, item) 166 167 #undef F_printk 168 #define F_printk(fmt, args...) __stringify(fmt) ", " __stringify(args) 169 170 #undef FTRACE_ENTRY_REG 171 #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, filter,\ 172 regfn) \ 173 \ 174 static struct trace_event_class __refdata event_class_ftrace_##call = { \ 175 .system = __stringify(TRACE_SYSTEM), \ 176 .define_fields = ftrace_define_fields_##call, \ 177 .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ 178 .reg = regfn, \ 179 }; \ 180 \ 181 struct trace_event_call __used event_##call = { \ 182 .class = &event_class_ftrace_##call, \ 183 { \ 184 .name = #call, \ 185 }, \ 186 .event.type = etype, \ 187 .print_fmt = print, \ 188 .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \ 189 }; \ 190 static struct trace_event_call __used \ 191 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; 192 193 #undef FTRACE_ENTRY 194 #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print, filter) \ 195 FTRACE_ENTRY_REG(call, struct_name, etype, \ 196 PARAMS(tstruct), PARAMS(print), filter, NULL) 197 198 bool ftrace_event_is_function(struct trace_event_call *call) 199 { 200 return call == &event_function; 201 } 202 203 #include "trace_entries.h" 204