diff options
-rw-r--r-- | runtime/ChangeLog | 8 | ||||
-rw-r--r-- | runtime/sym.c | 100 | ||||
-rw-r--r-- | runtime/sym.h | 1 | ||||
-rw-r--r-- | runtime/transport/ChangeLog | 5 | ||||
-rw-r--r-- | runtime/transport/symbols.c | 5 |
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) |