From aaf2af3e3b0c159a64609c82811662d7253c3a96 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 25 Mar 2008 11:32:58 -0400 Subject: rebased unwind_branch on top of current master --- translate.cxx | 95 ++++++++++++++++++----------------------------------------- 1 file changed, 29 insertions(+), 66 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 2bfacefc..8b9dee54 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4356,80 +4356,43 @@ c_unparser::visit_hist_op (hist_op*) int emit_symbol_data (systemtap_session& s) { - int rc = 0; - // Instead of processing elf symbol tables, for now we just snatch - // /proc/kallsyms and convert it to our use. We need it sorted by - // address (so we can binary search) , and filtered (to show text - // symbols only), a task that we defer to grep(1) and sort(1). It - // may be useful to cache the symbols.sorted file, perhaps indexed - // by md5sum(/proc/modules), but let's not until this simple method - // proves too costly. LC_ALL=C is already set to avoid the - // excessive penalty of i18n code in some glibc/coreutils versions. - - string sorted_kallsyms = s.tmpdir + "/symbols.sorted"; - string sortcmd = "grep \" [AtT] \" /proc/kallsyms | "; - - 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;\n"; - return 0; - } + // /proc/kallsyms and convert it to our use. - sortcmd += "sort "; -#if __LP64__ - sortcmd += "-k 1,16 "; -#else - sortcmd += "-k 1,8 "; -#endif - sortcmd += "-s -o " + sorted_kallsyms; + unsigned i=0; + ifstream kallsyms("/proc/kallsyms"); + char kallsyms_outbuf [4096]; + ofstream kallsyms_out ((s.tmpdir + "/stap-symbols.h").c_str()); + kallsyms_out.rdbuf()->pubsetbuf (kallsyms_outbuf, + sizeof(kallsyms_outbuf)); - if (s.verbose>1) clog << "Running " << sortcmd << endl; - rc = system(sortcmd.c_str()); - if (rc == 0) + s.op->newline() << "\n\n#include \"stap-symbols.h\""; + kallsyms_out << "struct _stp_symbol _stp_kernel_symbols [] = {"; + string lastaddr, modules_op_addr; + + while (! kallsyms.eof()) { - ifstream kallsyms (sorted_kallsyms.c_str()); - char kallsyms_outbuf [4096]; - ofstream kallsyms_out ((s.tmpdir + "/stap-symbols.h").c_str()); - kallsyms_out.rdbuf()->pubsetbuf (kallsyms_outbuf, - sizeof(kallsyms_outbuf)); - - s.op->newline() << "\n\n#include \"stap-symbols.h\""; + string addr, type, sym; + kallsyms >> addr >> type >> sym >> ws; - unsigned i=0; - kallsyms_out << "struct stap_symbol _stp_stap_symbols [] = {"; - string lastaddr; - while (! kallsyms.eof()) + if (kallsyms.peek() == '[') + break; + + // NB: kallsyms includes some duplicate addresses + if ((type == "t" || type == "T" || type == "A") && lastaddr != addr) { - string addr, type, sym, module; - kallsyms >> addr >> type >> sym; - kallsyms >> ws; - if (kallsyms.peek() == '[') - { - string bracketed; - kallsyms >> bracketed; - module = bracketed.substr (1, bracketed.length()-2); - } - - // NB: kallsyms includes some duplicate addresses - if ((type == "t" || type == "T" || type == "A") && lastaddr != addr) - { - kallsyms_out << " { 0x" << addr << ", " - << "\"" << sym << "\", " - << "\"" << module << "\" }," - << "\n"; - lastaddr = addr; - i ++; - } + kallsyms_out << " { 0x" << addr << ", " << "\"" << sym << "\" },\n"; + lastaddr = addr; + i ++; } - kallsyms_out << "};\n"; - kallsyms_out << "struct stap_symbol *stap_symbols = _stp_stap_symbols;"; - kallsyms_out << "unsigned stap_num_symbols = " << i << ";\n"; + else if (sym == "modules_op") + modules_op_addr = addr; } + kallsyms_out << "};\n"; + kallsyms_out << "unsigned _stp_num_kernel_symbols = " << i << ";\n"; + kallsyms_out << "unsigned long _stp_modules_op = 0x" << modules_op_addr << ";\n"; - return rc; + return (i == 0); } @@ -4515,7 +4478,7 @@ translate_pass (systemtap_session& s) s.op->newline() << "#include "; s.op->newline() << "#include "; s.op->newline() << "#include \"loc2c-runtime.h\" "; - + // XXX: old 2.6 kernel hack s.op->newline() << "#ifndef read_trylock"; s.op->newline() << "#define read_trylock(x) ({ read_lock(x); 1; })"; -- cgit From fa670082537aea7f090bc8dcfab69ac5f62546bc Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Wed, 9 Apr 2008 11:32:50 -0400 Subject: Change stap to get kernel symbols from debuginfo and compile them into the module. --- translate.cxx | 137 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 29 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index baa64741..dc6dd9f8 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4356,45 +4356,124 @@ c_unparser::visit_hist_op (hist_op*) assert(false); } + +static map< Dwarf_Addr, string> addrmap; + +static int +kernel_filter (const char *module, const char *file __attribute__((unused))) +{ + return !strcmp(module,"kernel"); +} + +static int +get_symbols (Dwfl_Module *m, + void **userdata __attribute__ ((unused)), + const char *name __attribute__ ((unused)), + Dwarf_Addr base __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ + 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) { + if (GELF_ST_TYPE (sym.st_info) == STT_FUNC || + strcmp(name, "_etext") == 0 || + strcmp(name, "_stext") == 0 || + strcmp(name, "modules_op") == 0) + addrmap[sym.st_value] = name; + } + } + return DWARF_CB_OK; +} + +int +emit_symbol_data_from_debuginfo(systemtap_session& s, ofstream& kallsyms_out) +{ + static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug"; + static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); + + static char *debuginfo_path = (debuginfo_env_arr ? + debuginfo_env_arr : debuginfo_path_arr); + + static const Dwfl_Callbacks kernel_callbacks = + { + dwfl_linux_kernel_find_elf, + dwfl_standard_find_debuginfo, + dwfl_offline_section_address, + & debuginfo_path + }; + + Dwfl *dwfl = dwfl_begin (&kernel_callbacks); + if (!dwfl) + throw semantic_error ("cannot open dwfl"); + dwfl_report_begin (dwfl); + + int rc = dwfl_linux_kernel_report_offline (dwfl, + s.kernel_release.c_str(), + kernel_filter); + dwfl_report_end (dwfl, NULL, NULL); + if (rc < 0) + return rc; + + dwfl_getmodules (dwfl, &get_symbols, NULL, 0); + dwfl_end(dwfl); + + int i = 0; + map< Dwarf_Addr, string>::iterator pos; + kallsyms_out << "struct _stp_symbol _stp_kernel_symbols [] = {"; + for (pos = addrmap.begin(); pos != addrmap.end(); pos++) { + kallsyms_out << " { 0x" << hex << pos->first << ", " << "\"" << pos->second << "\" },\n"; + i++; + } + + kallsyms_out << "};\n"; + kallsyms_out << "unsigned _stp_num_kernel_symbols = " << dec << i << ";\n"; + return i == 0; +} + int emit_symbol_data (systemtap_session& s) { - // Instead of processing elf symbol tables, for now we just snatch - // /proc/kallsyms and convert it to our use. - unsigned i=0; - ifstream kallsyms("/proc/kallsyms"); char kallsyms_outbuf [4096]; ofstream kallsyms_out ((s.tmpdir + "/stap-symbols.h").c_str()); kallsyms_out.rdbuf()->pubsetbuf (kallsyms_outbuf, - sizeof(kallsyms_outbuf)); - + sizeof(kallsyms_outbuf)); s.op->newline() << "\n\n#include \"stap-symbols.h\""; - kallsyms_out << "struct _stp_symbol _stp_kernel_symbols [] = {"; - string lastaddr, modules_op_addr; - - while (! kallsyms.eof()) - { - string addr, type, sym; - kallsyms >> addr >> type >> sym >> ws; - if (kallsyms.peek() == '[') - break; - - // NB: kallsyms includes some duplicate addresses - if ((type == "t" || type == "T" || type == "A") && lastaddr != addr) - { - kallsyms_out << " { 0x" << addr << ", " << "\"" << sym << "\" },\n"; - lastaddr = addr; - i ++; - } - else if (sym == "modules_op") - modules_op_addr = addr; - } - kallsyms_out << "};\n"; - kallsyms_out << "unsigned _stp_num_kernel_symbols = " << i << ";\n"; - kallsyms_out << "unsigned long _stp_modules_op = 0x" << modules_op_addr << ";\n"; + // FIXME for non-debuginfo use. + if (true) { + return emit_symbol_data_from_debuginfo(s, kallsyms_out); + } else { + // For symbol-table only operation, we don't have debuginfo, + // so parse /proc/kallsyms. + ifstream kallsyms("/proc/kallsyms"); + string lastaddr, modules_op_addr; + + kallsyms_out << "struct _stp_symbol _stp_kernel_symbols [] = {"; + while (! kallsyms.eof()) + { + string addr, type, sym; + kallsyms >> addr >> type >> sym >> ws; + + if (kallsyms.peek() == '[') + break; + + // NB: kallsyms includes some duplicate addresses + if ((type == "t" || type == "T" || type == "A" || sym == "modules_op") && lastaddr != addr) + { + kallsyms_out << " { 0x" << addr << ", " << "\"" << sym << "\" },\n"; + lastaddr = addr; + i ++; + } + } + kallsyms_out << "};\n"; + kallsyms_out << "unsigned _stp_num_kernel_symbols = " << i << ";\n"; + } return (i == 0); } -- cgit From 404bf86f4c825eafe4ad9f34f676c0e37464cfe7 Mon Sep 17 00:00:00 2001 From: Martin Hunt Date: Wed, 9 Apr 2008 15:24:14 -0400 Subject: Include string.h --- translate.cxx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index dc6dd9f8..a72cb1d8 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4359,6 +4359,8 @@ c_unparser::visit_hist_op (hist_op*) static map< Dwarf_Addr, string> addrmap; +#include + static int kernel_filter (const char *module, const char *file __attribute__((unused))) { -- cgit From 342d3f9693ea4eead68ba8ff841132a7adc7776b Mon Sep 17 00:00:00 2001 From: David Smith Date: Fri, 11 Apr 2008 09:52:55 -0500 Subject: 2008-04-11 David Smith * elaborate.h (struct derived_probe_group): Added emit_module_header virtual function. * translate.cxx (c_unparser::emit_common_header): Calls each probe group's emit_module_header function. (translate_pass): Moved inclusion of linux/marker.h to mark_derived_probe_group::emit_module_header(). * tapsets.cxx (struct be_derived_probe_group): Added empty emit_module_header function. (struct timer_derived_probe_group): Ditto. (struct profile_derived_probe_group): Ditto. (struct procfs_derived_probe_group): Ditto. (struct hrtimer_derived_probe_group): Ditto. (struct perfmon_derived_probe_group): Ditto. (dwarf_derived_probe_group::emit_module_header): Moved kprobes kernel check from emit_module_decls() to here. (uprobe_derived_probe_group::emit_module_header): Moved uprobe kernel check from emit_module_decls() to here. (uprobe_derived_probe_group::emit_module_decls): Moved uprobe kernel check to emit_module_header(). (mark_derived_probe_group::emit_module_header): Moved marker kernel check from emit_module_decls and translate_pass() to here. (uprobe_derived_probe_group::emit_module_decls): Moved marker kernel check to emit_module_header(). --- translate.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index c9ec094a..ba848d43 100644 --- a/translate.cxx +++ b/translate.cxx @@ -849,6 +849,11 @@ translator_output::line () void c_unparser::emit_common_header () { + vector g = all_session_groups (*session); + for (unsigned i=0; iemit_module_header (*session); + + o->newline(); o->newline() << "typedef char string_t[MAXSTRINGLEN];"; o->newline(); o->newline() << "#define STAP_SESSION_STARTING 0"; @@ -4526,10 +4531,6 @@ translate_pass (systemtap_session& s) s.op->newline() << "#define read_trylock(x) ({ read_lock(x); 1; })"; s.op->newline() << "#endif"; - s.op->newline() << "#if defined(CONFIG_MARKERS)"; - s.op->newline() << "#include "; - s.op->newline() << "#endif"; - s.up->emit_common_header (); // context etc. for (unsigned i=0; i