summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/ChangeLog8
-rw-r--r--runtime/sym.c100
-rw-r--r--runtime/sym.h1
-rw-r--r--runtime/transport/ChangeLog5
-rw-r--r--runtime/transport/symbols.c5
5 files changed, 65 insertions, 54 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index c8941e85..96471c74 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,5 +1,13 @@
2007-03-21 Martin Hunt <hunt@redhat.com>
+ * sym.h: Declare _stp_module_relocate.
+ * sym.c (_stp_module_relocate): Add comments, reformat, add
+ a way for "last" cached values to be cleared when modules
+ are removed.
+ (_stp_symbol_print): Simplify and remove static buffer.
+ (_stp_symbol_snprint): Ditto.
+
+2007-03-21 Martin Hunt <hunt@redhat.com>
* map.c (_stp_map_init): Fix signed vs unsigned comparison warning.
2007-03-20 Frank Ch. Eigler <fche@elastic.org>
diff --git a/runtime/sym.c b/runtime/sym.c
index 70efd82d..a461157e 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -20,58 +20,60 @@
* @{
*/
-static unsigned long _stp_module_relocate (const char *module, const char *section, unsigned long offset) {
+unsigned long _stp_module_relocate (const char *module, const char *section, unsigned long offset) {
static struct _stp_module *last = NULL;
static struct _stp_symbol *last_sec;
unsigned long flags;
int i,j;
- dbug("_stp_relocate_module: %s, %s, %lx\n", module, section, offset);
+
+ /* if module is -1, we invalidate last. _stp_del_module calls this when modules are deleted. */
+ if ((long)module == -1) {
+ last = NULL;
+ return 0;
+ }
+
+ dbug("_stp_relocate_module: %s, %s, %lx\n", module, section, offset);
+
STP_LOCK_MODULES;
if (! module || _stp_num_modules == 0) {
STP_UNLOCK_MODULES;
return offset;
}
+ /* Most likely our relocation is in the same section of the same module as the last. */
if (last) {
if (!strcmp (module, last->name) && !strcmp (section, last_sec->symbol)) {
- /* XXX: But is this enough protection? What if the module `last' is
- unloaded sometime between the last relocate call and this one? Do
- the last/last_sec pointers become invalid to traverse like that? */
- STP_UNLOCK_MODULES;
- return offset + last_sec->addr;
+ offset += last_sec->addr;
+ STP_UNLOCK_MODULES;
+ return offset;
}
}
- /* need to scan all modules */
- if (! strcmp (module, "kernel"))
- {
- STP_UNLOCK_MODULES;
-
- /* See also transport/symbols.c (_stp_do_symbols). */
- if (strcmp (section, "_stext"))
- return 0;
- else
- return offset + _stp_modules[0]->text;
-
- /* NB: we could also use _stp_kallsyms_lookup_name (section); */
- /* If _stp_kallsyms_lookup_name also returned the symbol,
- we could set last & last_sym and take some advantage of
- caching. But OTOH the advantage would be tiny in comparison
- to the hard-coded calculation above. */
- }
- else /* relocatable module */
- for (i = 1; i < _stp_num_modules; i++) { /* skip over [0]=kernel */
- last = _stp_modules[i];
- if (strcmp(module, last->name))
- continue;
- for (j = 0; j < (int)last->num_sections; j++) {
- last_sec = &last->sections[j];
- if (!strcmp (section, last_sec->symbol)) {
- STP_UNLOCK_MODULES;
- return offset + last_sec->addr;
- }
- }
- }
+ /* not cached. need to scan all modules */
+ if (! strcmp (module, "kernel")) {
+ STP_UNLOCK_MODULES;
+
+ /* See also transport/symbols.c (_stp_do_symbols). */
+ if (strcmp (section, "_stext"))
+ return 0;
+ else
+ return offset + _stp_modules[0]->text;
+ } else {
+ /* relocatable module */
+ for (i = 1; i < _stp_num_modules; i++) { /* skip over [0]=kernel */
+ last = _stp_modules[i];
+ if (strcmp(module, last->name))
+ continue;
+ for (j = 0; j < (int)last->num_sections; j++) {
+ last_sec = &last->sections[j];
+ if (!strcmp (section, last_sec->symbol)) {
+ offset += last_sec->addr;
+ STP_UNLOCK_MODULES;
+ return offset;
+ }
+ }
+ }
+ }
STP_UNLOCK_MODULES;
last = NULL;
return 0;
@@ -85,7 +87,7 @@ static unsigned long _stp_kallsyms_lookup_name(const char *name)
while (num--) {
if (strcmp(name, s->symbol) == 0)
- return s->addr;
+ return s->addr;
s++;
}
return 0;
@@ -173,9 +175,8 @@ void _stp_symbol_print (unsigned long address)
char *modname;
const char *name;
unsigned long offset, size;
- char namebuf[KSYM_NAME_LEN+1];
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
_stp_printf ("%p", (void *)address);
@@ -192,19 +193,12 @@ void _stp_symbol_snprint (char *str, size_t len, unsigned long address)
char *modname;
const char *name;
unsigned long offset, size;
- char namebuf[KSYM_NAME_LEN+1];
-
- if (len > KSYM_NAME_LEN) {
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, str);
- if (!name)
- snprintf(str, len, "%p", (void *)address);
- } else {
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);
- if (name)
- strlcpy(str, namebuf, len);
- else
- snprintf(str, len, "%p", (void *)address);
- }
+
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ if (name)
+ strlcpy(str, name, len);
+ else
+ snprintf(str, len, "%p", (void *)address);
}
/** @} */
diff --git a/runtime/sym.h b/runtime/sym.h
index 82a0cfcd..d164e23f 100644
--- a/runtime/sym.h
+++ b/runtime/sym.h
@@ -61,4 +61,5 @@ struct _stp_module *_stp_modules_by_addr[STP_MAX_MODULES];
/* the number of modules in the arrays */
int _stp_num_modules = 0;
+unsigned long _stp_module_relocate (const char *module, const char *section, unsigned long offset);
#endif /* _STAP_SYMBOLS_H_ */
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 90661baf..f752ccd4 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,8 @@
+2007-03-21 Martin Hunt <hunt@redhat.com>
+
+ * symbols.c (_stp_del_module): Add a call to _stp_module_relocate
+ to clear its cache.
+
2007-03-20 Frank Ch. Eigler <fche@elastic.org>
* symbols.c (_stp_do_symbols): Add cautionary blurb for important
diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index ee5e967e..9780b0b1 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -1,7 +1,7 @@
/* -*- linux-c -*-
* symbols.c - stp symbol and module functions
*
- * Copyright (C) Red Hat Inc, 2006
+ * Copyright (C) Red Hat Inc, 2006, 2007
*
* 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
@@ -110,6 +110,9 @@ static void _stp_del_module(struct _stp_module *mod)
// kbug("deleting %s\n", mod->name);
+ /* signal relocation code to clear its cache */
+ _stp_module_relocate((char *)-1, NULL, 0);
+
/* remove module from the arrays */
for (num = 0; num < _stp_num_modules; num++) {
if (_stp_modules[num] == mod)