depmod: generate modules.softdep

Signed-off-by: Andreas Robinson <andr345@gmail.com>
diff --git a/depmod.c b/depmod.c
index 1724d94..07f8a99 100644
--- a/depmod.c
+++ b/depmod.c
@@ -948,6 +948,35 @@
 	return 1;
 }
 
+static int output_softdeps(struct module *modules, FILE *out, char *dirname)
+{
+	struct module *i;
+	struct elf_file *file;
+	struct string_table *tbl;
+	int j;
+
+	fprintf(out, "# Soft dependencies extracted from modules themselves.\n");
+	fprintf(out, "# Copy, with a .conf extension, to /etc/modprobe.d to use "
+		"it with modprobe.\n");
+	for (i = modules; i; i = i->next) {
+		char modname[strlen(i->pathname)+1];
+
+		file = i->file;
+		filename2modname(modname, i->pathname);
+
+		/* Grab from new-style .modinfo section. */
+		tbl = file->ops->load_strings(file, ".modinfo", NULL);
+		for (j = 0; tbl && j < tbl->cnt; j++) {
+			const char *p = tbl->str[j];
+			if (strstarts(p, "softdep="))
+				fprintf(out, "softdep %s %s\n",
+					modname, p + strlen("softdep="));
+		}
+		strtbl_free(tbl);
+	}
+	return 1;
+}
+
 struct depfile {
 	char *name;
 	int (*func)(struct module *, FILE *, char *dirname);
@@ -967,6 +996,7 @@
 	{ "modules.seriomap", output_serio_table, 1 },
 	{ "modules.alias", output_aliases, 0 },
 	{ "modules.alias.bin", output_aliases_bin, 0 },
+	{ "modules.softdep", output_softdeps, 0 },
 	{ "modules.symbols", output_symbols, 0 },
 	{ "modules.symbols.bin", output_symbols_bin, 0 },
 	{ "modules.builtin.bin", output_builtin_bin, 0 },