1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2770cb243SSteven Rostedt /* 3770cb243SSteven Rostedt * trace_export.c - export basic ftrace utilities to user space 4770cb243SSteven Rostedt * 5770cb243SSteven Rostedt * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com> 6770cb243SSteven Rostedt */ 7770cb243SSteven Rostedt #include <linux/stringify.h> 8770cb243SSteven Rostedt #include <linux/kallsyms.h> 9770cb243SSteven Rostedt #include <linux/seq_file.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 15770cb243SSteven Rostedt #include "trace_output.h" 16770cb243SSteven Rostedt 173dd80953SSteven Rostedt (VMware) /* Stub function for events with triggers */ 183dd80953SSteven Rostedt (VMware) static int ftrace_event_register(struct trace_event_call *call, 193dd80953SSteven Rostedt (VMware) enum trace_reg type, void *data) 203dd80953SSteven Rostedt (VMware) { 213dd80953SSteven Rostedt (VMware) return 0; 223dd80953SSteven Rostedt (VMware) } 233dd80953SSteven Rostedt (VMware) 244e5292eaSSteven Rostedt #undef TRACE_SYSTEM 254e5292eaSSteven Rostedt #define TRACE_SYSTEM ftrace 26da4d0302SSteven Rostedt 27e59a0bffSJiri Olsa /* 28e59a0bffSJiri Olsa * The FTRACE_ENTRY_REG macro allows ftrace entry to define register 29e59a0bffSJiri Olsa * function and thus become accesible via perf. 30e59a0bffSJiri Olsa */ 31e59a0bffSJiri Olsa #undef FTRACE_ENTRY_REG 3202aa3162SJiri Olsa #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, \ 3302aa3162SJiri Olsa filter, regfn) \ 3402aa3162SJiri Olsa FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ 3502aa3162SJiri Olsa filter) 36e59a0bffSJiri Olsa 374e5292eaSSteven Rostedt /* not needed for this file */ 384e5292eaSSteven Rostedt #undef __field_struct 394e5292eaSSteven Rostedt #define __field_struct(type, item) 40da4d0302SSteven Rostedt 414e5292eaSSteven Rostedt #undef __field 4205ffa2d0SLi Zefan #define __field(type, item) type item; 4305ffa2d0SLi Zefan 4405ffa2d0SLi Zefan #undef __field_desc 4505ffa2d0SLi Zefan #define __field_desc(type, container, item) type item; 4605ffa2d0SLi Zefan 4705ffa2d0SLi Zefan #undef __array 4805ffa2d0SLi Zefan #define __array(type, item, size) type item[size]; 4905ffa2d0SLi Zefan 5005ffa2d0SLi Zefan #undef __array_desc 5105ffa2d0SLi Zefan #define __array_desc(type, container, item, size) type item[size]; 5205ffa2d0SLi Zefan 5305ffa2d0SLi Zefan #undef __dynamic_array 5405ffa2d0SLi Zefan #define __dynamic_array(type, item) type item[]; 5505ffa2d0SLi Zefan 5605ffa2d0SLi Zefan #undef F_STRUCT 5705ffa2d0SLi Zefan #define F_STRUCT(args...) args 5805ffa2d0SLi Zefan 5905ffa2d0SLi Zefan #undef F_printk 6005ffa2d0SLi Zefan #define F_printk(fmt, args...) fmt, args 6105ffa2d0SLi Zefan 6205ffa2d0SLi Zefan #undef FTRACE_ENTRY 6302aa3162SJiri Olsa #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ 6405ffa2d0SLi Zefan struct ____ftrace_##name { \ 6505ffa2d0SLi Zefan tstruct \ 6605ffa2d0SLi Zefan }; \ 675e9b3972SLi Zefan static void __always_unused ____ftrace_check_##name(void) \ 6805ffa2d0SLi Zefan { \ 6905ffa2d0SLi Zefan struct ____ftrace_##name *__entry = NULL; \ 7005ffa2d0SLi Zefan \ 715e9b3972SLi Zefan /* force compile-time check on F_printk() */ \ 7205ffa2d0SLi Zefan printk(print); \ 7305ffa2d0SLi Zefan } 7405ffa2d0SLi Zefan 7505ffa2d0SLi Zefan #undef FTRACE_ENTRY_DUP 7602aa3162SJiri Olsa #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print, filter) \ 7702aa3162SJiri Olsa FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print), \ 7802aa3162SJiri Olsa filter) 7905ffa2d0SLi Zefan 8005ffa2d0SLi Zefan #include "trace_entries.h" 8105ffa2d0SLi Zefan 824e5292eaSSteven Rostedt #undef __field 834e5292eaSSteven Rostedt #define __field(type, item) \ 844e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type, #item, \ 854e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 864e5292eaSSteven Rostedt sizeof(field.item), \ 8702aa3162SJiri Olsa is_signed_type(type), filter_type); \ 884e5292eaSSteven Rostedt if (ret) \ 894e5292eaSSteven Rostedt return ret; 904e5292eaSSteven Rostedt 914e5292eaSSteven Rostedt #undef __field_desc 924e5292eaSSteven Rostedt #define __field_desc(type, container, item) \ 934e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type, #item, \ 944e5292eaSSteven Rostedt offsetof(typeof(field), \ 954e5292eaSSteven Rostedt container.item), \ 964e5292eaSSteven Rostedt sizeof(field.container.item), \ 9702aa3162SJiri Olsa is_signed_type(type), filter_type); \ 984e5292eaSSteven Rostedt if (ret) \ 994e5292eaSSteven Rostedt return ret; 1004e5292eaSSteven Rostedt 1014e5292eaSSteven Rostedt #undef __array 1024e5292eaSSteven Rostedt #define __array(type, item, len) \ 10304295780SSteven Rostedt do { \ 10487291347SVaibhav Nagarnaik char *type_str = #type"["__stringify(len)"]"; \ 1054e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 10687291347SVaibhav Nagarnaik ret = trace_define_field(event_call, type_str, #item, \ 1074e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 108fb7ae981SLai Jiangshan sizeof(field.item), \ 10902aa3162SJiri Olsa is_signed_type(type), filter_type); \ 1104e5292eaSSteven Rostedt if (ret) \ 11104295780SSteven Rostedt return ret; \ 11204295780SSteven Rostedt } while (0); 1134e5292eaSSteven Rostedt 1144e5292eaSSteven Rostedt #undef __array_desc 1154e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) \ 1164e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 1174e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 1184e5292eaSSteven Rostedt offsetof(typeof(field), \ 1194e5292eaSSteven Rostedt container.item), \ 120fb7ae981SLai Jiangshan sizeof(field.container.item), \ 12102aa3162SJiri Olsa is_signed_type(type), filter_type); \ 1224e5292eaSSteven Rostedt if (ret) \ 1234e5292eaSSteven Rostedt return ret; 1244e5292eaSSteven Rostedt 1254e5292eaSSteven Rostedt #undef __dynamic_array 126809826a3SLai Jiangshan #define __dynamic_array(type, item) \ 127af3dcb53SSteven Rostedt (VMware) ret = trace_define_field(event_call, #type "[]", #item, \ 128809826a3SLai Jiangshan offsetof(typeof(field), item), \ 12902aa3162SJiri Olsa 0, is_signed_type(type), filter_type);\ 130809826a3SLai Jiangshan if (ret) \ 131809826a3SLai Jiangshan return ret; 1324e5292eaSSteven Rostedt 1334e5292eaSSteven Rostedt #undef FTRACE_ENTRY 13402aa3162SJiri Olsa #define FTRACE_ENTRY(name, struct_name, id, tstruct, print, filter) \ 1357e4f44b1SLi Zefan static int __init \ 1362425bcb9SSteven Rostedt (Red Hat) ftrace_define_fields_##name(struct trace_event_call *event_call) \ 137e45f2e2bSTom Zanussi { \ 1384e5292eaSSteven Rostedt struct struct_name field; \ 139e45f2e2bSTom Zanussi int ret; \ 14002aa3162SJiri Olsa int filter_type = filter; \ 141e45f2e2bSTom Zanussi \ 1424e5292eaSSteven Rostedt tstruct; \ 143e45f2e2bSTom Zanussi \ 144e45f2e2bSTom Zanussi return ret; \ 145e45f2e2bSTom Zanussi } 146e45f2e2bSTom Zanussi 1474e5292eaSSteven Rostedt #include "trace_entries.h" 1484e5292eaSSteven Rostedt 149509e760cSLai Jiangshan #undef __entry 150509e760cSLai Jiangshan #define __entry REC 151509e760cSLai Jiangshan 1524e5292eaSSteven Rostedt #undef __field 1534e5292eaSSteven Rostedt #define __field(type, item) 1544e5292eaSSteven Rostedt 1554e5292eaSSteven Rostedt #undef __field_desc 1564e5292eaSSteven Rostedt #define __field_desc(type, container, item) 1574e5292eaSSteven Rostedt 1584e5292eaSSteven Rostedt #undef __array 1594e5292eaSSteven Rostedt #define __array(type, item, len) 1604e5292eaSSteven Rostedt 1614e5292eaSSteven Rostedt #undef __array_desc 1624e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) 1634e5292eaSSteven Rostedt 1644e5292eaSSteven Rostedt #undef __dynamic_array 1654e5292eaSSteven Rostedt #define __dynamic_array(type, item) 1664e5292eaSSteven Rostedt 167509e760cSLai Jiangshan #undef F_printk 16801de982aSWolfgang Mauerer #define F_printk(fmt, args...) __stringify(fmt) ", " __stringify(args) 169509e760cSLai Jiangshan 170e59a0bffSJiri Olsa #undef FTRACE_ENTRY_REG 17102aa3162SJiri Olsa #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, filter,\ 17202aa3162SJiri Olsa regfn) \ 173770cb243SSteven Rostedt \ 1746dff4d7dSBen Dooks static struct trace_event_class __refdata event_class_ftrace_##call = { \ 1752e33af02SSteven Rostedt .system = __stringify(TRACE_SYSTEM), \ 1762e33af02SSteven Rostedt .define_fields = ftrace_define_fields_##call, \ 177ffb9f995SLi Zefan .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ 178e59a0bffSJiri Olsa .reg = regfn, \ 1792e33af02SSteven Rostedt }; \ 1802e33af02SSteven Rostedt \ 1812425bcb9SSteven Rostedt (Red Hat) struct trace_event_call __used event_##call = { \ 1822e33af02SSteven Rostedt .class = &event_class_ftrace_##call, \ 183abb43f69SMathieu Desnoyers { \ 184abb43f69SMathieu Desnoyers .name = #call, \ 185abb43f69SMathieu Desnoyers }, \ 186abb43f69SMathieu Desnoyers .event.type = etype, \ 187509e760cSLai Jiangshan .print_fmt = print, \ 188754cb007SHe Kuang .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \ 189e1112b4dSTom Zanussi }; \ 1906dff4d7dSBen Dooks static struct trace_event_call __used \ 191e4a9ea5eSSteven Rostedt __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; 192e1112b4dSTom Zanussi 193e59a0bffSJiri Olsa #undef FTRACE_ENTRY 19402aa3162SJiri Olsa #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print, filter) \ 195e59a0bffSJiri Olsa FTRACE_ENTRY_REG(call, struct_name, etype, \ 19602aa3162SJiri Olsa PARAMS(tstruct), PARAMS(print), filter, NULL) 197e59a0bffSJiri Olsa 198c6650b2eSYaowei Bai bool ftrace_event_is_function(struct trace_event_call *call) 199ced39002SJiri Olsa { 200ced39002SJiri Olsa return call == &event_function; 201ced39002SJiri Olsa } 202ced39002SJiri Olsa 2034e5292eaSSteven Rostedt #include "trace_entries.h" 204