1*4882a593Smuzhiyunlibtraceevent(3) 2*4882a593Smuzhiyun================ 3*4882a593Smuzhiyun 4*4882a593SmuzhiyunNAME 5*4882a593Smuzhiyun---- 6*4882a593Smuzhiyuntep_find_function, tep_find_function_address, tep_set_function_resolver, 7*4882a593Smuzhiyuntep_reset_function_resolver, tep_register_function, tep_register_print_string - 8*4882a593Smuzhiyunfunction related tep APIs 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunSYNOPSIS 11*4882a593Smuzhiyun-------- 12*4882a593Smuzhiyun[verse] 13*4882a593Smuzhiyun-- 14*4882a593Smuzhiyun*#include <event-parse.h>* 15*4882a593Smuzhiyun 16*4882a593Smuzhiyuntypedef char pass:[*](*tep_func_resolver_t*)(void pass:[*]_priv_, unsigned long long pass:[*]_addrp_, char pass:[**]_modp_); 17*4882a593Smuzhiyunint *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); 18*4882a593Smuzhiyunvoid *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); 19*4882a593Smuzhiyunconst char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); 20*4882a593Smuzhiyununsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); 21*4882a593Smuzhiyunint *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); 22*4882a593Smuzhiyunint *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); 23*4882a593Smuzhiyun-- 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunDESCRIPTION 26*4882a593Smuzhiyun----------- 27*4882a593SmuzhiyunSome tools may have already a way to resolve the kernel functions. These APIs 28*4882a593Smuzhiyunallow them to keep using it instead of duplicating all the entries inside. 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunThe _tep_func_resolver_t_ type is the prototype of the alternative kernel 31*4882a593Smuzhiyunfunctions resolver. This function receives a pointer to its custom context 32*4882a593Smuzhiyun(set with the _tep_set_function_resolver()_ call ) and the address of a kernel 33*4882a593Smuzhiyunfunction, which has to be resolved. In case of success, it should return 34*4882a593Smuzhiyunthe name of the function and its module (if any) in _modp_. 35*4882a593Smuzhiyun 36*4882a593SmuzhiyunThe _tep_set_function_resolver()_ function registers _func_ as an alternative 37*4882a593Smuzhiyunkernel functions resolver. The _tep_ argument is trace event parser context. 38*4882a593SmuzhiyunThe _priv_ argument is a custom context of the _func_ function. The function 39*4882a593Smuzhiyunresolver is used by the APIs _tep_find_function()_, 40*4882a593Smuzhiyun_tep_find_function_address()_, and _tep_print_func_field()_ to resolve 41*4882a593Smuzhiyuna function address to a function name. 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunThe _tep_reset_function_resolver()_ function resets the kernel functions 44*4882a593Smuzhiyunresolver to the default function. The _tep_ argument is trace event parser 45*4882a593Smuzhiyuncontext. 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun 48*4882a593SmuzhiyunThese APIs can be used to find function name and start address, by given 49*4882a593Smuzhiyunaddress. The given address does not have to be exact, it will select 50*4882a593Smuzhiyunthe function that would contain it. 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunThe _tep_find_function()_ function returns the function name, which contains the 53*4882a593Smuzhiyungiven address _addr_. The _tep_ argument is the trace event parser context. 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunThe _tep_find_function_address()_ function returns the function start address, 56*4882a593Smuzhiyunby given address _addr_. The _addr_ does not have to be exact, it will select 57*4882a593Smuzhiyunthe function that would contain it. The _tep_ argument is the trace event 58*4882a593Smuzhiyunparser context. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunThe _tep_register_function()_ function registers a function name mapped to an 61*4882a593Smuzhiyunaddress and (optional) module. This mapping is used in case the function tracer 62*4882a593Smuzhiyunor events have "%pS" parameter in its format string. It is common to pass in 63*4882a593Smuzhiyunthe kallsyms function names with their corresponding addresses with this 64*4882a593Smuzhiyunfunction. The _tep_ argument is the trace event parser context. The _name_ is 65*4882a593Smuzhiyunthe name of the function, the string is copied internally. The _addr_ is the 66*4882a593Smuzhiyunstart address of the function. The _mod_ is the kernel module the function may 67*4882a593Smuzhiyunbe in (NULL for none). 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunThe _tep_register_print_string()_ function registers a string by the address 70*4882a593Smuzhiyunit was stored in the kernel. Some strings internal to the kernel with static 71*4882a593Smuzhiyunaddress are passed to certain events. The "%s" in the event's format field 72*4882a593Smuzhiyunwhich has an address needs to know what string would be at that address. The 73*4882a593Smuzhiyuntep_register_print_string() supplies the parsing with the mapping between kernel 74*4882a593Smuzhiyunaddresses and those strings. The _tep_ argument is the trace event parser 75*4882a593Smuzhiyuncontext. The _fmt_ is the string to register, it is copied internally. 76*4882a593SmuzhiyunThe _addr_ is the address the string was located at. 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun 79*4882a593SmuzhiyunRETURN VALUE 80*4882a593Smuzhiyun------------ 81*4882a593SmuzhiyunThe _tep_set_function_resolver()_ function returns 0 in case of success, or -1 82*4882a593Smuzhiyunin case of an error. 83*4882a593Smuzhiyun 84*4882a593SmuzhiyunThe _tep_find_function()_ function returns the function name, or NULL in case 85*4882a593Smuzhiyunit cannot be found. 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunThe _tep_find_function_address()_ function returns the function start address, 88*4882a593Smuzhiyunor 0 in case it cannot be found. 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunThe _tep_register_function()_ function returns 0 in case of success. In case of 91*4882a593Smuzhiyunan error -1 is returned, and errno is set to the appropriate error number. 92*4882a593Smuzhiyun 93*4882a593SmuzhiyunThe _tep_register_print_string()_ function returns 0 in case of success. In case 94*4882a593Smuzhiyunof an error -1 is returned, and errno is set to the appropriate error number. 95*4882a593Smuzhiyun 96*4882a593SmuzhiyunEXAMPLE 97*4882a593Smuzhiyun------- 98*4882a593Smuzhiyun[source,c] 99*4882a593Smuzhiyun-- 100*4882a593Smuzhiyun#include <event-parse.h> 101*4882a593Smuzhiyun... 102*4882a593Smuzhiyunstruct tep_handle *tep = tep_alloc(); 103*4882a593Smuzhiyun... 104*4882a593Smuzhiyunchar *my_resolve_kernel_addr(void *context, 105*4882a593Smuzhiyun unsigned long long *addrp, char **modp) 106*4882a593Smuzhiyun{ 107*4882a593Smuzhiyun struct db *function_database = context; 108*4882a593Smuzhiyun struct symbol *sym = sql_lookup(function_database, *addrp); 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun if (!sym) 111*4882a593Smuzhiyun return NULL; 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun *modp = sym->module_name; 114*4882a593Smuzhiyun return sym->name; 115*4882a593Smuzhiyun} 116*4882a593Smuzhiyun 117*4882a593Smuzhiyunvoid show_function( unsigned long long addr) 118*4882a593Smuzhiyun{ 119*4882a593Smuzhiyun unsigned long long fstart; 120*4882a593Smuzhiyun const char *fname; 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun if (tep_set_function_resolver(tep, my_resolve_kernel_addr, 123*4882a593Smuzhiyun function_database) != 0) { 124*4882a593Smuzhiyun /* failed to register my_resolve_kernel_addr */ 125*4882a593Smuzhiyun } 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun /* These APIs use my_resolve_kernel_addr() to resolve the addr */ 128*4882a593Smuzhiyun fname = tep_find_function(tep, addr); 129*4882a593Smuzhiyun fstart = tep_find_function_address(tep, addr); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* 132*4882a593Smuzhiyun addr is in function named fname, starting at fstart address, 133*4882a593Smuzhiyun at offset (addr - fstart) 134*4882a593Smuzhiyun */ 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun tep_reset_function_resolver(tep); 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun} 139*4882a593Smuzhiyun... 140*4882a593Smuzhiyun if (tep_register_function(tep, "kvm_exit", 141*4882a593Smuzhiyun (unsigned long long) 0x12345678, "kvm") != 0) { 142*4882a593Smuzhiyun /* Failed to register kvm_exit address mapping */ 143*4882a593Smuzhiyun } 144*4882a593Smuzhiyun... 145*4882a593Smuzhiyun if (tep_register_print_string(tep, "print string", 146*4882a593Smuzhiyun (unsigned long long) 0x87654321, NULL) != 0) { 147*4882a593Smuzhiyun /* Failed to register "print string" address mapping */ 148*4882a593Smuzhiyun } 149*4882a593Smuzhiyun... 150*4882a593Smuzhiyun-- 151*4882a593Smuzhiyun 152*4882a593SmuzhiyunFILES 153*4882a593Smuzhiyun----- 154*4882a593Smuzhiyun[verse] 155*4882a593Smuzhiyun-- 156*4882a593Smuzhiyun*event-parse.h* 157*4882a593Smuzhiyun Header file to include in order to have access to the library APIs. 158*4882a593Smuzhiyun*-ltraceevent* 159*4882a593Smuzhiyun Linker switch to add when building a program that uses the library. 160*4882a593Smuzhiyun-- 161*4882a593Smuzhiyun 162*4882a593SmuzhiyunSEE ALSO 163*4882a593Smuzhiyun-------- 164*4882a593Smuzhiyun_libtraceevent(3)_, _trace-cmd(1)_ 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunAUTHOR 167*4882a593Smuzhiyun------ 168*4882a593Smuzhiyun[verse] 169*4882a593Smuzhiyun-- 170*4882a593Smuzhiyun*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. 171*4882a593Smuzhiyun*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. 172*4882a593Smuzhiyun-- 173*4882a593SmuzhiyunREPORTING BUGS 174*4882a593Smuzhiyun-------------- 175*4882a593SmuzhiyunReport bugs to <linux-trace-devel@vger.kernel.org> 176*4882a593Smuzhiyun 177*4882a593SmuzhiyunLICENSE 178*4882a593Smuzhiyun------- 179*4882a593Smuzhiyunlibtraceevent is Free Software licensed under the GNU LGPL 2.1 180*4882a593Smuzhiyun 181*4882a593SmuzhiyunRESOURCES 182*4882a593Smuzhiyun--------- 183*4882a593Smuzhiyunhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 184