diff options
author | fche <fche> | 2007-03-21 01:58:10 +0000 |
---|---|---|
committer | fche <fche> | 2007-03-21 01:58:10 +0000 |
commit | 840489846051292305b56243feba9807ba06039e (patch) | |
tree | dff5fc8d30d0060c8bd734e4ba3d1eb80b207d40 | |
parent | 6fa8d6e2a8378bfaee0e8e1af8cc707b4e14aab3 (diff) | |
download | systemtap-steved-840489846051292305b56243feba9807ba06039e.tar.gz systemtap-steved-840489846051292305b56243feba9807ba06039e.tar.xz systemtap-steved-840489846051292305b56243feba9807ba06039e.zip |
2007-03-20 Frank Ch. Eigler <fche@elastic.org>
PR 4224.
* tapsets.cxx (add_probe_point): Make kernel implicitly relocated
relative to the _stext symbol.
(dwarf_derived_probe ctor, emit_module_decls): Cooperate.
(lookup_symbol_address): New function.
(dwarf_builder::build): Call it thrice.
(in_kprobes_function): Simplify.
* session.h (systemtap_session): Rename cached symbol addresses.
* translate.cxx, elaborate.cxx: Corresponding tweaks.
2007-03-20 Frank Ch. Eigler <fche@elastic.org>
PR 4224.
* sym.c (_stp_module_relocate): Support kernel relocations.
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.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | elaborate.cxx | 4 | ||||
-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 | ||||
-rw-r--r-- | session.h | 11 | ||||
-rw-r--r-- | tapsets.cxx | 113 | ||||
-rw-r--r-- | translate.cxx | 3 |
9 files changed, 124 insertions, 80 deletions
@@ -1,3 +1,15 @@ +2007-03-20 Frank Ch. Eigler <fche@elastic.org> + + PR 4224. + * tapsets.cxx (add_probe_point): Make kernel implicitly relocated + relative to the _stext symbol. + (dwarf_derived_probe ctor, emit_module_decls): Cooperate. + (lookup_symbol_address): New function. + (dwarf_builder::build): Call it thrice. + (in_kprobes_function): Simplify. + * session.h (systemtap_session): Rename cached symbol addresses. + * translate.cxx, elaborate.cxx: Corresponding tweaks. + 2007-03-19 David Smith <dsmith@redhat.com> PR 4146 (partial fix) diff --git a/elaborate.cxx b/elaborate.cxx index ef019016..c2e57856 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -973,9 +973,7 @@ systemtap_session::systemtap_session (): mark_derived_probes(0), hrtimer_derived_probes(0), perfmon_derived_probes(0), - op (0), up (0), - kprobes_text_initialized (false), - kprobes_text_start (0), kprobes_text_end (0) + op (0), up (0) { } 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; @@ -93,7 +93,7 @@ struct systemtap_session bool merge; int buffer_size; unsigned perfmon; - bool symtab; + bool symtab; /* true: emit symbol table at translation time; false: let staprun do it. */ bool prologue_searching; // Cache data @@ -136,10 +136,11 @@ struct systemtap_session translator_output* op; unparser* up; - // kprobes_text data - bool kprobes_text_initialized; - Dwarf_Addr kprobes_text_start; - Dwarf_Addr kprobes_text_end; + // some symbol addresses + // XXX: these belong elsewhere; perhaps the dwflpp instance + Dwarf_Addr sym_kprobes_text_start; + Dwarf_Addr sym_kprobes_text_end; + Dwarf_Addr sym_stext; std::set<std::string> seen_errors; unsigned num_errors () { return seen_errors.size(); } diff --git a/tapsets.cxx b/tapsets.cxx index eb66f2bc..78d47dc7 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2278,55 +2278,11 @@ static int query_kernel_module (Dwfl_Module *, void **, const char *, static bool in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr) { - if (! sess.kprobes_text_initialized) - { - // Only attempt kprobes_text_start/kprobes_text_end - // initialization once - sess.kprobes_text_initialized = true; - - dwflpp *kernel_dw = new dwflpp(sess); - assert(kernel_dw); - kernel_dw->setup(true); - - Dwfl_Module *m = NULL; - kernel_dw->iterate_over_modules(&query_kernel_module, &m); - assert(m); - kernel_dw->focus_on_module(m); - - // Look through the symbol table for "__kprobes_text_{start,end}" - int syments = dwfl_module_getsymtab(kernel_dw->module); - assert(syments); - for (int i = 1; i < syments; ++i) - { - GElf_Sym sym; - const char *name = dwfl_module_getsym(kernel_dw->module, i, - &sym, NULL); - - // Look for a symbol that starts with "__kprobes_text_" - if (name != NULL - && strncmp(name, "__kprobes_text_", 15) == 0) - { - // Match either "__kprobes_text_start" or "__kprobes_text_end" - if (strcmp(name, "__kprobes_text_start") == 0) - sess.kprobes_text_start = sym.st_value; - else if (strcmp(name, "__kprobes_text_end") == 0) - sess.kprobes_text_end = sym.st_value; - - // If we've got both values, quit processing symbols. - if (sess.kprobes_text_start != 0 && sess.kprobes_text_end != 0) - i = syments; - } - } - - if (kernel_dw) - delete kernel_dw; - } - - if (sess.kprobes_text_start != 0 && sess.kprobes_text_end != 0) + if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0) { // If the probe point address is anywhere in the __kprobes // address range, we can't use this probe point. - if (addr >= sess.kprobes_text_start && addr < sess.kprobes_text_end) + if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end) return true; } return false; @@ -2455,6 +2411,13 @@ dwarf_query::add_probe_point(const string& funcname, if (sess.verbose > 1) clog << endl; + if (module == TOK_KERNEL) + { + // PR 4224: adapt to relocatable kernel by subtracting the _stext address here. + reloc_addr = addr - sess.sym_stext; + reloc_section = "_stext"; // a deliberate eyesore + } + if (! bad) { probe = new dwarf_derived_probe(funcname, filename, line, @@ -2938,9 +2901,9 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), if (q->sess.verbose>2) clog << "focused on module '" << q->dw.module_name - << " = [" << hex << q->dw.module_start - << "-" << q->dw.module_end - << ", bias " << q->dw.module_bias << "]" << dec + << " = [0x" << hex << q->dw.module_start + << "-0x" << q->dw.module_end + << ", bias 0x" << q->dw.module_bias << "]" << dec << " file " << debug_filename << " ELF machine " << expect_machine << " (code " << elf_machine << ")" @@ -3495,11 +3458,9 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, maxactive_val (q.maxactive_val) { // Assert relocation invariants - if (module == TOK_KERNEL && section != "") - throw semantic_error ("relocation requested against kernel", q.base_loc->tok); - if (module != TOK_KERNEL && section == "") - throw semantic_error ("missing relocation base against module", q.base_loc->tok); - if (module != TOK_KERNEL && section != "" && dwfl_addr == addr) // addr should be an offset + if (section == "") + throw semantic_error ("missing relocation base against", q.base_loc->tok); + if (section != "" && dwfl_addr == addr) // addr should be an offset throw semantic_error ("inconsistent relocation address", q.base_loc->tok); // Make a target-variable-expanded copy of the probe body @@ -3734,9 +3695,9 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->line() << " .return_p=1,"; if (p->has_maxactive) s.op->line() << " .maxactive_p=1,"; - if (p->module != TOK_KERNEL) // relocation info - s.op->line() << " .module=\"" << p->module << "\", .section=\"" << p->section << "\","; s.op->line() << " .address=0x" << hex << p->addr << dec << "UL,"; + s.op->line() << " .module=\"" << p->module << "\","; + s.op->line() << " .section=\"" << p->section << "\","; if (p->has_maxactive) s.op->line() << " .maxactive_val=" << p->maxactive_val << "UL,"; s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ","; @@ -3827,6 +3788,26 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s) } + +static Dwarf_Addr +lookup_symbol_address (Dwfl_Module *m, const char* wanted) +{ + int syments = dwfl_module_getsymtab(m); + assert(syments); + for (int i = 1; i < syments; ++i) + { + GElf_Sym sym; + const char *name = dwfl_module_getsym(m, i, &sym, NULL); + if (name != NULL && strcmp(name, wanted) == 0) + return sym.st_value; + } + + return 0; +} + + + + void dwarf_builder::build(systemtap_session & sess, probe * base, @@ -3852,6 +3833,26 @@ dwarf_builder::build(systemtap_session & sess, kern_dw->setup(true); } dw = kern_dw; + + + Dwfl_Module* km = 0; + dw->iterate_over_modules(&query_kernel_module, &km); + if (km) + { + sess.sym_kprobes_text_start = lookup_symbol_address (km, "__kprobes_text_start"); + sess.sym_kprobes_text_end = lookup_symbol_address (km, "__kprobes_text_end"); + sess.sym_stext = lookup_symbol_address (km, "_stext"); + + if (sess.verbose > 2) + { + clog << "control symbols:" + // abbreviate the names - they're for our debugging only anyway + << " kts: 0x" << hex << sess.sym_kprobes_text_start + << " kte: 0x" << sess.sym_kprobes_text_end + << " stext: 0x" << sess.sym_stext + << dec << endl; + } + } } else { diff --git a/translate.cxx b/translate.cxx index 89a961e3..d3f9467a 100644 --- a/translate.cxx +++ b/translate.cxx @@ -3986,8 +3986,9 @@ emit_symbol_data (systemtap_session& s) if (s.symtab == false) { + s.op->newline() << "/* filled in by runtime */"; s.op->newline() << "struct stap_symbol *stap_symbols;"; - s.op->newline() << "unsigned stap_num_symbols = 0;\n"; + s.op->newline() << "unsigned stap_num_symbols;\n"; return 0; } |