[PATCH] Put stuff in .modinfo

From: Rusty Russell (rusty@rustcorp.com.au)
Date: Fri Apr 18 2003 - 02:15:36 EST


Re-xmit. This means that the MODULE_AUTHOR, MODULE_DESCRIPTION and
MODULE_PARM_DESC put info in .modinfo, so the "modinfo" command does
something useful again.

Also puts vermagic and licence in there, while we're at it.

Linus, please apply.
Rusty.

Name: Restore modinfo section
Author: Rusty Russell
Status: Tested on 2.5.66-bk2
Depends: Module/kallsyms-kai-fix.patch.gz

D: Restores .modinfo section, and uses it to store license and vermagic.

diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .26668-linux-2.5.66-bk2/include/linux/module.h .26668-linux-2.5.66-bk2.updated/include/linux/module.h
--- .26668-linux-2.5.66-bk2/include/linux/module.h 2003-03-27 15:20:11.000000000 +1100
+++ .26668-linux-2.5.66-bk2.updated/include/linux/module.h 2003-03-27 15:20:26.000000000 +1100
@@ -20,10 +20,7 @@
 #include <asm/module.h>
 
 /* Not Yet Implemented */
-#define MODULE_AUTHOR(name)
-#define MODULE_DESCRIPTION(desc)
 #define MODULE_SUPPORTED_DEVICE(name)
-#define MODULE_PARM_DESC(var,desc)
 #define print_modules()
 
 /* v850 toolchain uses a `_' prefix for all user symbols */
@@ -58,12 +55,11 @@ search_extable(const struct exception_ta
                unsigned long value);
 
 #ifdef MODULE
-#define ___module_cat(a,b) a ## b
+#define ___module_cat(a,b) __mod_ ## a ## b
 #define __module_cat(a,b) ___module_cat(a,b)
-/* For userspace: you can also call me... */
-#define MODULE_ALIAS(alias) \
- static const char __module_cat(__alias_,__LINE__)[] \
- __attribute__((section(".modinfo"),unused)) = "alias=" alias
+#define __MODULE_INFO(tag, name, info) \
+static const char __module_cat(name,__LINE__)[] \
+ __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
 
 #define MODULE_GENERIC_TABLE(gtype,name) \
 extern const struct gtype##_id __mod_##gtype##_table \
@@ -71,6 +67,19 @@ extern const struct gtype##_id __mod_##g
 
 #define THIS_MODULE (&__this_module)
 
+#else /* !MODULE */
+
+#define MODULE_GENERIC_TABLE(gtype,name)
+#define __MODULE_INFO(tag, name, info)
+#define THIS_MODULE ((struct module *)0)
+#endif
+
+/* Generic info of form tag = "info" */
+#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
+
+/* For userspace: you can also call me... */
+#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
+
 /*
  * The following license idents are currently accepted as indicating free
  * software modules
@@ -97,17 +108,18 @@ extern const struct gtype##_id __mod_##g
  * 2. So the community can ignore bug reports including proprietary modules
  * 3. So vendors can do likewise based on their own policies
  */
-#define MODULE_LICENSE(license) \
- static const char __module_license[] \
- __attribute__((section(".init.license"), unused)) = license
+#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
 
-#else /* !MODULE */
+/* Author, ideally of form NAME <EMAIL>[, NAME <EMAIL>]*[ and NAME <EMAIL>] */
+#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
+
+/* What your module does. */
+#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
 
-#define MODULE_ALIAS(alias)
-#define MODULE_GENERIC_TABLE(gtype,name)
-#define THIS_MODULE ((struct module *)0)
-#define MODULE_LICENSE(license)
-#endif
+/* One for each parameter, describing how to use it. Some files do
+ multiple of these per line, so can't just use MODULE_INFO. */
+#define MODULE_PARM_DESC(_parm, desc) \
+ __MODULE_INFO(parm, _parm, #_parm ":" desc)
 
 #define MODULE_DEVICE_TABLE(type,name) \
   MODULE_GENERIC_TABLE(type##_device,name)
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .26668-linux-2.5.66-bk2/kernel/module.c .26668-linux-2.5.66-bk2.updated/kernel/module.c
--- .26668-linux-2.5.66-bk2/kernel/module.c 2003-03-27 15:20:11.000000000 +1100
+++ .26668-linux-2.5.66-bk2.updated/kernel/module.c 2003-03-27 15:20:12.000000000 +1100
@@ -914,12 +914,12 @@ EXPORT_SYMBOL_GPL(__symbol_get);
 /* Change all symbols so that sh_value encodes the pointer directly. */
 static int simplify_symbols(Elf_Shdr *sechdrs,
                             unsigned int symindex,
- unsigned int strindex,
+ const char *strtab,
                             unsigned int versindex,
                             struct module *mod)
 {
         Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
- const char *strtab = (char *)sechdrs[strindex].sh_addr;
+
         unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
         int ret = 0;
 
@@ -1038,13 +1038,9 @@ static inline int license_is_gpl_compati
                 || strcmp(license, "Dual MPL/GPL") == 0);
 }
 
-static void set_license(struct module *mod, Elf_Shdr *sechdrs, int licenseidx)
+static void set_license(struct module *mod, const char *license)
 {
- char *license;
-
- if (licenseidx)
- license = (char *)sechdrs[licenseidx].sh_addr;
- else
+ if (!license)
                 license = "unspecified";
 
         mod->license_gplok = license_is_gpl_compatible(license);
@@ -1055,6 +1051,40 @@ static void set_license(struct module *m
         }
 }
 
+/* Parse tag=value strings from .modinfo section */
+static char *next_string(char *string, unsigned long *secsize)
+{
+ /* Skip non-zero chars */
+ while (string[0]) {
+ string++;
+ if ((*secsize)-- <= 1)
+ return NULL;
+ }
+
+ /* Skip any zero padding. */
+ while (!string[0]) {
+ string++;
+ if ((*secsize)-- <= 1)
+ return NULL;
+ }
+ return string;
+}
+
+static char *get_modinfo(Elf_Shdr *sechdrs,
+ unsigned int info,
+ const char *tag)
+{
+ char *p;
+ unsigned int taglen = strlen(tag);
+ unsigned long size = sechdrs[info].sh_size;
+
+ for (p = (char *)sechdrs[info].sh_addr; p; p = next_string(p, &size)) {
+ if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
+ return p + taglen + 1;
+ }
+ return NULL;
+}
+
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
 static struct module *load_module(void *umod,
@@ -1063,9 +1093,9 @@ static struct module *load_module(void *
 {
         Elf_Ehdr *hdr;
         Elf_Shdr *sechdrs;
- char *secstrings, *args;
- unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
- modindex, obsparmindex, licenseindex, gplindex, vmagindex,
+ char *secstrings, *args, *modmagic, *strtab = NULL;
+ unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
+ exportindex, modindex, obsparmindex, infoindex, gplindex,
                 crcindex, gplcrcindex, versindex;
         long arglen;
         struct module *mod;
@@ -1099,6 +1129,7 @@ static struct module *load_module(void *
         /* Convenience variables */
         sechdrs = (void *)hdr + hdr->e_shoff;
         secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ sechdrs[0].sh_addr = 0;
 
         /* And these should exist, but gcc whinges if we don't init them */
         symindex = strindex = 0;
@@ -1112,6 +1143,7 @@ static struct module *load_module(void *
                 if (sechdrs[i].sh_type == SHT_SYMTAB) {
                         symindex = i;
                         strindex = sechdrs[i].sh_link;
+ strtab = (char *)hdr + sechdrs[strindex].sh_offset;
                 }
 #ifndef CONFIG_MODULE_UNLOAD
                 /* Don't load .exit sections */
@@ -1120,12 +1152,6 @@ static struct module *load_module(void *
 #endif
         }
 
-#ifdef CONFIG_KALLSYMS
- /* Keep symbol and string tables for decoding later. */
- sechdrs[symindex].sh_flags |= SHF_ALLOC;
- sechdrs[strindex].sh_flags |= SHF_ALLOC;
-#endif
-
         modindex = find_sec(hdr, sechdrs, secstrings,
                             ".gnu.linkonce.this_module");
         if (!modindex) {
@@ -1143,9 +1169,16 @@ static struct module *load_module(void *
         setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
         exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
         obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
- licenseindex = find_sec(hdr, sechdrs, secstrings, ".init.license");
- vmagindex = find_sec(hdr, sechdrs, secstrings, "__vermagic");
         versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
+ infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
+
+ /* Don't keep modinfo section */
+ sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
+#ifdef CONFIG_KALLSYMS
+ /* Keep symbol and string tables for decoding later. */
+ sechdrs[symindex].sh_flags |= SHF_ALLOC;
+ sechdrs[strindex].sh_flags |= SHF_ALLOC;
+#endif
 
         /* Check module struct version now, before we try to use module. */
         if (!check_modstruct_version(sechdrs, versindex, mod)) {
@@ -1153,14 +1186,15 @@ static struct module *load_module(void *
                 goto free_hdr;
         }
 
+ modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
         /* This is allowed: modprobe --force will invalidate it. */
- if (!vmagindex) {
+ if (!modmagic) {
                 tainted |= TAINT_FORCED_MODULE;
                 printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
                        mod->name);
- } else if (!same_magic((char *)sechdrs[vmagindex].sh_addr, vermagic)) {
+ } else if (!same_magic(modmagic, vermagic)) {
                 printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
- mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic);
+ mod->name, modmagic, vermagic);
                 err = -ENOEXEC;
                 goto free_hdr;
         }
@@ -1240,11 +1274,11 @@ static struct module *load_module(void *
         /* Now we've moved module, initialize linked lists, etc. */
         module_unload_init(mod);
 
- /* Set up license info based on contents of section */
- set_license(mod, sechdrs, licenseindex);
+ /* Set up license info based on the info section */
+ set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
         /* Fix up syms, so that st_value is a pointer to location. */
- err = simplify_symbols(sechdrs, symindex, strindex, versindex, mod);
+ err = simplify_symbols(sechdrs, symindex, strtab, versindex, mod);
         if (err < 0)
                 goto cleanup;
 
@@ -1274,8 +1308,7 @@ static struct module *load_module(void *
         for (i = 1; i < hdr->e_shnum; i++) {
                 const char *strtab = (char *)sechdrs[strindex].sh_addr;
                 if (sechdrs[i].sh_type == SHT_REL)
- err = apply_relocate(sechdrs, strtab, symindex, i,
- mod);
+ err = apply_relocate(sechdrs, strtab, symindex, i,mod);
                 else if (sechdrs[i].sh_type == SHT_RELA)
                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
                                                  mod);
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .26668-linux-2.5.66-bk2/scripts/modpost.c .26668-linux-2.5.66-bk2.updated/scripts/modpost.c
--- .26668-linux-2.5.66-bk2/scripts/modpost.c 2003-03-18 12:21:42.000000000 +1100
+++ .26668-linux-2.5.66-bk2.updated/scripts/modpost.c 2003-03-27 15:20:12.000000000 +1100
@@ -398,9 +398,7 @@ add_header(struct buffer *b)
         buf_printf(b, "#include <linux/vermagic.h>\n");
         buf_printf(b, "#include <linux/compiler.h>\n");
         buf_printf(b, "\n");
- buf_printf(b, "const char vermagic[]\n");
- buf_printf(b, "__attribute__((section(\"__vermagic\"))) =\n");
- buf_printf(b, "VERMAGIC_STRING;\n");
+ buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
 }
 
 /* Record CRCs for unresolved symbols */

--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Apr 23 2003 - 22:00:23 EST