Signed-off-by: Andreas Robinson <[email protected]>
---
 elfops.c      |    9 +++++++++
 elfops.h      |   14 ++++++++++++++
 elfops_core.c |   25 +++++++++++++++++++++++++
 modprobe.c    |   55 ++-----------------------------------------------------
 4 files changed, 50 insertions(+), 53 deletions(-)

diff --git a/elfops.c b/elfops.c
index 3872bf8..0fb492f 100644
--- a/elfops.c
+++ b/elfops.c
@@ -19,6 +19,15 @@
 static const char *weak_sym = "W";
 static const char *undef_sym = "U";
 
+/* dump_modversions helper */
+static const char *skip_dot(const char *str)
+{
+       /* For our purposes, .foo matches foo.  PPC64 needs this. */
+       if (str && str[0] == '.')
+               return str + 1;
+       return str;
+}
+
 #define ELF32BIT
 #include "elfops_core.c"
 #undef ELF32BIT
diff --git a/elfops.h b/elfops.h
index c33793a..e131da0 100644
--- a/elfops.h
+++ b/elfops.h
@@ -1,6 +1,7 @@
 #ifndef MODINITTOOLS_MODULEOPS_H
 #define MODINITTOOLS_MODULEOPS_H
 #include <stdio.h>
+#include <stdint.h>
 
 /* All the icky stuff to do with manipulating 64 and 32-bit modules
    belongs here. */
@@ -14,6 +15,18 @@ struct kernel_symbol64 {
        char name[64 - 8];
 };
 
+struct modver_info32
+{
+       uint32_t crc;
+       char name[64 - sizeof(uint32_t)];
+};
+
+struct modver_info64
+{
+       uint64_t crc;
+       char name[64 - sizeof(uint64_t)];
+};
+
 struct elf_file
 {
        char *pathname;
@@ -66,6 +79,7 @@ struct module_ops
        char *(*get_aliases)(struct elf_file *module, unsigned long *size);
        char *(*get_modinfo)(struct elf_file *module, unsigned long *size);
        void (*strip_section)(struct elf_file *module, const char *secname);
+       int (*dump_modvers)(struct elf_file *module);
 };
 
 extern struct module_ops mod_ops32, mod_ops64;
diff --git a/elfops_core.c b/elfops_core.c
index 14eef96..39fd4c3 100644
--- a/elfops_core.c
+++ b/elfops_core.c
@@ -318,6 +318,30 @@ static void PERBIT(strip_section)(struct elf_file *module, 
const char *secname)
        }
 }
 
+static int PERBIT(dump_modversions)(struct elf_file *module)
+{
+       unsigned long secsize;
+       struct PERBIT(modver_info) *info;
+       int n = 0;
+
+       info = module->ops->load_section(module, "__versions", &secsize);
+       if (!info)
+               return 0; /* not a kernel module */
+       if (secsize % sizeof(*info) != 0)
+               return -1; /* invalid section size */
+
+       for (n = 0; n < secsize / sizeof(*info); n++) {
+#if defined(ELF32BIT)
+               printf("0x%08lx\t%s\n", (unsigned long)
+#else /* defined(ELF64BIT) */
+               printf("0x%08llx\t%s\n", (unsigned long long)
+#endif
+                       END(info[n].crc, module->conv),
+                       skip_dot(info[n].name));
+       }
+       return n;
+}
+
 struct module_ops PERBIT(mod_ops) = {
        .load_section   = PERBIT(load_section),
        .load_symbols   = PERBIT(load_symbols),
@@ -326,6 +350,7 @@ struct module_ops PERBIT(mod_ops) = {
        .get_aliases    = PERBIT(get_aliases),
        .get_modinfo    = PERBIT(get_modinfo),
        .strip_section  = PERBIT(strip_section),
+       .dump_modvers   = PERBIT(dump_modversions),
 };
 
 #undef PERBIT
diff --git a/modprobe.c b/modprobe.c
index a351a58..c6ef155 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -792,71 +792,20 @@ nonexistent_module:
        goto remove_rest;
 }
 
-struct modver32_info
-{
-       uint32_t crc;
-       char name[64 - sizeof(uint32_t)];
-};
-
-struct modver64_info
-{
-       uint64_t crc;
-       char name[64 - sizeof(uint64_t)];
-};
-
-const char *skip_dot(const char *str)
-{
-       /* For our purposes, .foo matches foo.  PPC64 needs this. */
-       if (str && str[0] == '.')
-               return str + 1;
-       return str;
-}
-
 void dump_modversions(const char *filename, errfn_t error)
 {
        struct elf_file *module;
-       unsigned long secsize;
-       void *info;
-       struct modver32_info *info32;
-       struct modver64_info *info64;
-       int n;
 
        module = grab_elf_file(filename);
        if (!module) {
                error("%s: %s\n", filename, strerror(errno));
                return;
        }
-       info = module->ops->load_section(module, "__versions", &secsize);
-       if (!info)
-               goto done;  /* Does not seem to be a kernel module */
-
-       switch (elf_ident(module->data, module->len, NULL)) {
-       case ELFCLASS32:
-               info32 = info;
-               if (secsize % sizeof(struct modver32_info))
-                       error("Wrong section size in %s\n", filename);
-               for (n = 0; n < secsize / sizeof(struct modver32_info); n++)
-                       printf("0x%08lx\t%s\n", (unsigned long)
-                               info32[n].crc, skip_dot(info32[n].name));
-               break;
-
-       case ELFCLASS64:
-               info64 = info;
-               if (secsize % sizeof(struct modver64_info))
-                       error("Wrong section size in %s\n", filename);
-               for (n = 0; n < secsize / sizeof(struct modver64_info); n++)
-                       printf("0x%08llx\t%s\n", (unsigned long long)
-                               info64[n].crc, skip_dot(info64[n].name));
-               break;
-
-       default:
-               error("%s: ELF class not recognized\n", filename);
-       }
-done:
+       if (module->ops->dump_modvers(module) < 0)
+               error("Wrong section size in '%s'\n", filename);
        release_elf_file(module);
 }
 
-
 /* Does path contain directory(s) subpath? */
 static int type_matches(const char *path, const char *subpath)
 {
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to