File module-init-tools-dump-modversions.diff of Package module-init-tools

---
 modprobe.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

--- modprobe.c.orig
+++ modprobe.c
@@ -977,6 +977,66 @@ 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)
+{
+	unsigned long size, secsize;
+	void *file = grab_file(filename, &size);
+	struct modver32_info *info32;
+	struct modver64_info *info64;
+	int n;
+
+	if (!file) {
+		error("%s: %s\n", filename, strerror(errno));
+		return;
+	}
+	switch (elf_ident(file, size)) {
+	case ELFCLASS32:
+		info32 = get_section32(file, size, "__versions", &secsize);
+		if (!info32)
+			return;  /* Does not seem to be a kernel module */
+		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 = get_section64(file, size, "__versions", &secsize);
+		if (!info64)
+			return;  /* Does not seem to be a kernel module */
+		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);
+	}
+}
+
 /* Does path contain directory(s) subpath? */
 static int type_matches(const char *path, const char *subpath)
 {
@@ -1388,6 +1448,7 @@ static struct option options[] = { { "ve
 				   { "show-depends", 0, NULL, 'D' },
 				   { "first-time", 0, NULL, 3 },
 				   { "use-blacklist", 0, NULL, 'b' },
+				   { "dump-modversions", 0, NULL, 4 },
 				   { NULL, 0, NULL, 0 } };
 
 #define MODPROBE_DEVFSD_CONF "/etc/modprobe.devfs"
@@ -1425,6 +1486,7 @@ int main(int argc, char *argv[])
 	int ignore_proc = 0;
 	int first_time = 0;
 	int use_blacklist = 0;
+	int dump_modver = 0;
 	unsigned int i, num_modules;
 	char *type = NULL;
 	const char *config = NULL;
@@ -1540,6 +1602,9 @@ int main(int argc, char *argv[])
 		case 3:
 			first_time = 1;
 			break;
+		case 4:
+			dump_modver = 1;
+			break;
 		default:
 			print_usage(argv[0]);
 		}
@@ -1605,6 +1670,11 @@ int main(int argc, char *argv[])
 		LIST_HEAD(list);
 		char *modulearg = argv[optind + i];
 
+		if (dump_modver) {
+			dump_modversions(modulearg, error);
+			continue;
+		}
+
 		/* Convert name we are looking for */
 		underscores(modulearg);
 
openSUSE Build Service is sponsored by