From: Frank Ch. Eigler Date: Wed, 14 Sep 2011 21:52:44 +0000 (-0400) Subject: PR6503: get at dynamic module section addresses via horrible hack (tm) X-Git-Tag: release-1.7~153^2~19^2~7 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=2c9caccb8852f29c32f5daa792277bda7d9b27f8;p=systemtap.git PR6503: get at dynamic module section addresses via horrible hack (tm) Since does not declare structs module_sect_attr[s], let's declare it ourselves. We need to get at these, because otherwise there is no way to get at the build-id section address. * runtime/autoconf-module-sect-attrs.c: New (partial) autoconf file. * buildrun.cxx (compile_pass): Build it. * runtime/transport/symbols.c (_stp_module_notifier): Use our own modern (2.6.19+) declaration of these structs to pass all section names/addresses to _stp_kmodule_update_address. --- diff --git a/buildrun.cxx b/buildrun.cxx index 44ae4aba2..043540341 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -266,6 +266,7 @@ compile_pass (systemtap_session& s) output_exportconf(s, o, "path_lookup", "STAPCONF_PATH_LOOKUP"); output_exportconf(s, o, "kern_path_parent", "STAPCONF_KERN_PATH_PARENT"); output_exportconf(s, o, "vfs_path_lookup", "STAPCONF_VFS_PATH_LOOKUP"); + output_autoconf(s, o, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL); // used by tapset/timestamp_monotonic.stp output_exportconf(s, o, "cpu_clock", "STAPCONF_CPU_CLOCK"); diff --git a/runtime/autoconf-module-sect-attrs.c b/runtime/autoconf-module-sect-attrs.c new file mode 100644 index 000000000..f589dca30 --- /dev/null +++ b/runtime/autoconf-module-sect-attrs.c @@ -0,0 +1,7 @@ +#include + +unsigned long foobar(struct module_sect_attrs *moosas) +{ + struct module_sect_attr msa = moosas->attrs[0]; + return msa.address; +} diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 489d2c790..c1360703b 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -71,47 +71,66 @@ static void _stp_do_relocation(const char __user *buf, size_t count) +#if !defined(STAPCONF_MODULE_SECT_ATTRS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) +/* It would be nice if it were (still) in a header we could get to, + like include/linux/module.h, but commit a58730c42 moved them into + kernel/module.c. */ +struct module_sect_attr +{ + struct module_attribute mattr; + char *name; + unsigned long address; +}; + +struct module_sect_attrs +{ + struct attribute_group grp; + unsigned int nsections; + struct module_sect_attr attrs[0]; +}; +#endif + + static int _stp_module_notifier (struct notifier_block * nb, unsigned long val, void *data) { + /* Prior to 2.6.11, struct module contained a module_sections + attribute vector rather than module_sect_attrs. Prior to + 2.6.19, module_sect_attrs lacked a number-of-sections + field. Without CONFIG_KALLSYMS, we don't get any of the + related fields at all in struct module. XXX: autoconf for + that directly? */ + +#if defined(CONFIG_KALLSYMS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) struct module *mod = data; + struct module_sect_attrs *attrs = mod->sect_attrs; + unsigned i; if (val == MODULE_STATE_COMING) { /* A module is arriving. Register all of its section addresses, as though staprun sent us a bunch of STP_RELOCATE messages. Now ... where did the - fishie go? It's in mod->sect_attrs, but the type - declaration is private to kernel/module.c. It's in - the load_info, but we can't get there from here. - It's in sysfs, but one'd have to maneuver through - mod->mkobj etc, or consult userspace; not cool. - - So we cheat. It's under the sofa. */ - -#ifndef STAPCONF_GRSECURITY - _stp_kmodule_update_address(mod->name, ".text", - (unsigned long)mod->module_core); - _stp_kmodule_update_address(mod->name, ".init.text", - (unsigned long)mod->module_init); -#else - _stp_kmodule_update_address(mod->name, ".text", - (unsigned long)mod->module_core_rx); - _stp_kmodule_update_address(mod->name, ".init.text", - (unsigned long)mod->module_init_rx); - /* XXX: also: module_*_rw for .data? */ -#endif - /* _stp_kmodule_update_address(mod->name, - ".note.gnu.build-id", ??); */ + fishie go? */ + for (i=0; insections; i++) + _stp_kmodule_update_address(mod->name, + attrs->attrs[i].name, + attrs->attrs[i].address); } else if (val == MODULE_STATE_LIVE) { /* The init section(s) may have been unloaded. */ - _stp_kmodule_update_address(mod->name, ".init.text", 0); + for (i=0; insections; i++) + if (strstr(attrs->attrs[i].name, "init.") != NULL) + _stp_kmodule_update_address(mod->name, + attrs->attrs[i].name, + 0); } else if (val == MODULE_STATE_GOING) { /* Unregister all sections. */ _stp_kmodule_update_address(mod->name, NULL, 0); } + /* XXX: verify build-id! */ + /* Give the probes a chance to update themselves. */ /* Proper kprobes support for this appears to be relatively recent. Example prerequisite commits: 0deddf436a f24659d9 */ @@ -119,6 +138,8 @@ static int _stp_module_notifier (struct notifier_block * nb, systemtap_module_refresh(); #endif +#endif /* skipped for ancient or kallsyms-free kernels */ + return NOTIFY_DONE; }