[PATCH 15/16] modprobe, elfops: move most of dump_modversions() to elfops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Andreas Robinson <andr345@xxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux