summaryrefslogtreecommitdiffstats
path: root/tapset/context-symbols.stp
blob: f38c9ec187932739bb129d11758cf87c25d3b4c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// 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.
// <tapsetdescription>
// 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.
// </tapsetdescription>
%{
#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 != '@' && *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, NULL);
		if (m && m->name)
			strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN);
		else
			strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
	} else
		strlcpy (THIS->__retvalue, "<unknown>", 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 "<unknown>".
 * 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, NULL);
	if (m && m->name)
          strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN);
	else
	  strlcpy (THIS->__retvalue, "<unknown>", 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);
%}