]>
sourceware.org Git - systemtap.git/blob - runtime/sym.c
2 * Symbolic Lookup Functions
3 * Copyright (C) 2005, 2006, 2007 Red Hat Inc.
4 * Copyright (C) 2006 Intel Corporation.
6 * This file is part of systemtap, and is free software. You can
7 * redistribute it and/or modify it under the terms of the GNU General
8 * Public License (GPL); either version 2, or (at your option) any
18 * @addtogroup sym Symbolic Functions
19 * Symbolic Lookup Functions
23 static unsigned long _stp_module_relocate (const char *module
, const char *section
, unsigned long offset
) {
24 static struct _stp_module
*last
= NULL
;
25 static struct _stp_symbol
*last_sec
;
30 if (! module
|| _stp_num_modules
== 0) {
36 if (!strcmp (module
, last
->name
) && !strcmp (section
, last_sec
->symbol
)) {
38 return offset
+ last_sec
->addr
;
42 /* need to scan all modules */
43 for (i
= 1; i
< _stp_num_modules
; i
++) { /* XXX: why start at i=1? */
44 last
= _stp_modules
[i
];
45 if (strcmp(module
, last
->name
))
47 for (j
= 0; j
< last
->num_sections
; j
++) {
48 last_sec
= &last
->sections
[j
];
49 if (!strcmp (section
, last_sec
->symbol
)) {
51 return offset
+ last_sec
->addr
;
60 /* Lookup the kernel address for this symbol. Returns 0 if not found. */
61 static unsigned long _stp_kallsyms_lookup_name(const char *name
)
63 struct _stp_symbol
*s
= _stp_modules
[0]->symbols
;
64 unsigned num
= _stp_modules
[0]->num_symbols
;
67 if (strcmp(name
, s
->symbol
) == 0)
74 static const char * _stp_kallsyms_lookup (
76 unsigned long *symbolsize
,
77 unsigned long *offset
,
81 struct _stp_module
*m
;
82 struct _stp_symbol
*s
;
84 unsigned end
, begin
= 0;
86 if (STP_TRYLOCK_MODULES
)
89 end
= _stp_num_modules
;
91 if (_stp_num_modules
>= 2 && addr
> _stp_modules_by_addr
[1]->text
) {
92 /* binary search on index [begin,end) */
94 unsigned mid
= (begin
+ end
) / 2;
95 if (addr
< _stp_modules_by_addr
[mid
]->text
)
99 } while (begin
+ 1 < end
);
100 /* result index in $begin, guaranteed between [0,_stp_num_modules) */
102 m
= _stp_modules_by_addr
[begin
];
104 end
= m
->num_symbols
;
106 /* binary search for symbols within the module */
108 unsigned mid
= (begin
+ end
) / 2;
109 if (addr
< m
->symbols
[mid
].addr
)
113 } while (begin
+ 1 < end
);
114 /* result index in $begin */
116 s
= &m
->symbols
[begin
];
117 if (addr
< s
->addr
) {
121 if (offset
) *offset
= addr
- s
->addr
;
122 if (modname
) *modname
= m
->name
;
124 if ((begin
+ 1) < m
->num_symbols
)
125 *symbolsize
= m
->symbols
[begin
+1].addr
- s
->addr
;
128 // NB: This is only a heuristic. Sometimes there are large
129 // gaps between text areas of modules.
132 strlcpy (namebuf
, s
->symbol
, KSYM_NAME_LEN
+1);
145 /** Print an address symbolically.
146 * @param address The address to lookup.
147 * @note Symbolic lookups should not normally be done within
148 * a probe because it is too time-consuming. Use at module exit time.
151 void _stp_symbol_print (unsigned long address
)
155 unsigned long offset
, size
;
156 char namebuf
[KSYM_NAME_LEN
+1];
158 name
= _stp_kallsyms_lookup(address
, &size
, &offset
, &modname
, namebuf
);
160 _stp_printf ("%p", (void *)address
);
164 _stp_printf (" : %s+%#lx/%#lx [%s]", name
, offset
, size
, modname
);
166 _stp_printf (" : %s+%#lx/%#lx", name
, offset
, size
);
170 void _stp_symbol_snprint (char *str
, size_t len
, unsigned long address
)
174 unsigned long offset
, size
;
175 char namebuf
[KSYM_NAME_LEN
+1];
177 if (len
> KSYM_NAME_LEN
) {
178 name
= _stp_kallsyms_lookup(address
, &size
, &offset
, &modname
, str
);
180 snprintf(str
, len
, "%p", (void *)address
);
182 name
= _stp_kallsyms_lookup(address
, &size
, &offset
, &modname
, namebuf
);
184 strlcpy(str
, namebuf
, len
);
186 snprintf(str
, len
, "%p", (void *)address
);
This page took 0.043139 seconds and 5 git commands to generate.