aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Robinson <andr345@gmail.com>2009-05-15 15:56:02 +0200
committerAndreas Robinson <andr345@gmail.com>2009-05-15 15:56:02 +0200
commita85e4c165f45767f09536f5baf9fe80ffedcc25a (patch)
treefd7798dd42e2fa0f470646dc6615d3a84355aa2f
parent45ec2644e6970f28fbf2acc789391de3e649f154 (diff)
downloadmodule-init-tools-a85e4c165f45767f09536f5baf9fe80ffedcc25a.tar.gz
modprobe, elfops: move most of dump_modversions() to elfops
Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r--elfops.c9
-rw-r--r--elfops.h14
-rw-r--r--elfops_core.c25
-rw-r--r--modprobe.c55
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)
{