diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/ChangeLog | 5 | ||||
-rw-r--r-- | runtime/sym.c | 50 | ||||
-rw-r--r-- | runtime/transport/ChangeLog | 5 | ||||
-rw-r--r-- | runtime/transport/symbols.c | 1 |
4 files changed, 46 insertions, 15 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 2b068b5c..4c714b01 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2007-03-20 Frank Ch. Eigler <fche@elastic.org> + + PR 4224. + * sym.c (_stp_module_relocate): Support kernel relocations. + 2007-03-19 Frank Ch. Eigler <fche@elastic.org> * autoconf-hrtimer-rel.c: New file. diff --git a/runtime/sym.c b/runtime/sym.c index a5bc0195..70efd82d 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -34,24 +34,44 @@ static unsigned long _stp_module_relocate (const char *module, const char *secti if (last) { if (!strcmp (module, last->name) && !strcmp (section, last_sec->symbol)) { - STP_UNLOCK_MODULES; - return offset + last_sec->addr; + /* 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; } } /* need to scan all modules */ - for (i = 1; i < _stp_num_modules; i++) { /* XXX: why start at i=1? */ - 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; - } - } - } + 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; + } + } + } STP_UNLOCK_MODULES; last = NULL; return 0; @@ -65,7 +85,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; diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index dcee1d79..90661baf 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,8 @@ +2007-03-20 Frank Ch. Eigler <fche@elastic.org> + + * symbols.c (_stp_do_symbols): Add cautionary blurb for important + setup of _stp_modules[0]->text. + 2007-03-20 Martin Hunt <hunt@redhat.com> * symbols.c (_stp_alloc_module): Fix up error diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 9d5163d0..ee5e967e 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -203,6 +203,7 @@ static int _stp_do_symbols(const char __user *buf, int count) for (i = 0; i < _stp_modules[0]->num_symbols; i++) s[i].symbol += (long)_stp_modules[0]->symbol_data; _stp_symbol_state = 3; + /* NB: this mapping is used by kernel/_stext pseudo-relocations. */ _stp_modules[0]->text = _stp_kallsyms_lookup_name("_stext"); _stp_modules_by_addr[0] = _stp_modules[0]; break; |