]> sourceware.org Git - systemtap.git/commitdiff
PR6503: get at dynamic module section addresses via horrible hack (tm)
authorFrank Ch. Eigler <fche@redhat.com>
Wed, 14 Sep 2011 21:52:44 +0000 (17:52 -0400)
committerFrank Ch. Eigler <fche@redhat.com>
Wed, 14 Sep 2011 22:17:58 +0000 (18:17 -0400)
Since <linux/module.h> 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.

buildrun.cxx
runtime/autoconf-module-sect-attrs.c [new file with mode: 0644]
runtime/transport/symbols.c

index 44ae4aba2a39b7938ef5e8d5cabbc40eb2eebc8b..04354034180eacba331ad8cabd4206e3517c0490 100644 (file)
@@ -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 (file)
index 0000000..f589dca
--- /dev/null
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+unsigned long foobar(struct module_sect_attrs *moosas)
+{
+  struct module_sect_attr msa = moosas->attrs[0];
+  return msa.address;
+}
index 489d2c7909c6eb6c72ef44f1b9e44af420fb78bb..c1360703b69f51e2c5e2cc74cfcaf819801444d3 100644 (file)
@@ -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; i<attrs->nsections; 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; i<attrs->nsections; 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;
 }
 
This page took 0.034795 seconds and 5 git commands to generate.