// context-symbols tapset // Copyright (C) 2005-2008 Red Hat Inc. // Copyright (C) 2006 Intel Corporation. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. // // Context functions provide additional information about where an event occurred. These functions can //provide information such as a backtrace to where the event occurred and the current register values for the //processor. // %{ #ifndef STP_NEED_SYMBOL_DATA #define STP_NEED_SYMBOL_DATA 1 #endif %} /** * sfunction print_stack - Print out stack from string. * @stk: String with list of hexadecimal addresses. * * Perform a symbolic lookup of the addresses in the given string, * which is assumed to be the result of a prior call to * backtrace(). * * Print one line per address, including the address, the * name of the function containing the address, and an estimate of * its position within that function. Return nothing. */ function print_stack(stk:string) %{ char *ptr = THIS->stk; char *tok = strsep(&ptr, " "); while (tok && *tok) { _stp_print_char(' '); _stp_symbol_print (simple_strtol(tok, NULL, 16)); _stp_print_char('\n'); tok = strsep(&ptr, " "); } %} /** * sfunction probefunc - Return the probe point's function name, if known. */ function probefunc:string () %{ /* pure */ char *ptr, *start; start = strstr(CONTEXT->probe_point, "function(\""); ptr = start + 10; if (!start) { start = strstr(CONTEXT->probe_point, "inline(\""); ptr = start + 8; } if (start) { int len = MAXSTRINGLEN; char *dst = THIS->__retvalue; while (*ptr != '@' && --len > 0 && *ptr) *dst++ = *ptr++; *dst = 0; } else if (CONTEXT->regs && #if defined (__ia64__) ((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)KERNEL_START)) { #else ((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)PAGE_OFFSET)) { #endif _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs), current, 0); if (THIS->__retvalue[0] == '.') /* powerpc symbol has a dot*/ strlcpy(THIS->__retvalue,THIS->__retvalue + 1,MAXSTRINGLEN); } else { THIS->__retvalue[0] = '\0'; } %} /** * sfunction probemod - Return the probe point's module name, if known. */ function probemod:string () %{ /* pure */ char *ptr, *start; start = strstr(CONTEXT->probe_point, "module(\""); ptr = start + 8; if (start) { int len = MAXSTRINGLEN; char *dst = THIS->__retvalue; while (*ptr != '"' && --len && *ptr) *dst++ = *ptr++; *dst = 0; } else if (CONTEXT->regs) { struct _stp_module *m; m = _stp_mod_sec_lookup (REG_IP(CONTEXT->regs), current, NULL); if (m && m->name) strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN); else strlcpy (THIS->__retvalue, "", MAXSTRINGLEN); } else strlcpy (THIS->__retvalue, "", MAXSTRINGLEN); %} /** * sfunction modname - Return the kernel module name loaded at the address. * @addr: The address. * * Description: Returns the module name associated with the given * address if known. If not known it will return the string "". * If the address was not in a kernel module, but in the kernel itself, * then the string "kernel" will be returned. */ function modname:string (addr: long) %{ /* pure */ struct _stp_module *m; m = _stp_mod_sec_lookup (THIS->addr, current, NULL); if (m && m->name) strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN); else strlcpy (THIS->__retvalue, "", MAXSTRINGLEN); %} /** * sfunction symname - Return the symbol associated with the given address. * @addr: The address to translate. * * Description: Returns the (function) symbol name associated with the * given address if known. If not known it will return the hex string * representation of addr. */ function symname:string (addr: long) %{ /* pure */ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr, NULL, 0); %} /** * sfunction symdata - Return the symbol and module offset for the address. * @addr: The address to translate. * * Description: Returns the (function) symbol name associated with the * given address if known, plus the module name (between brackets) and * the offset inside the module, plus the size of the symbol function. * If any element is not known it will be omitted and if the symbol name * is unknown it will return the hex string for the given address. */ function symdata:string (addr: long) %{ /* pure */ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr, NULL, 1); %}