Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d082773 authored by Matthias Maennich's avatar Matthias Maennich Committed by Jessica Yu
Browse files

modpost: add support for generating namespace dependencies



This patch adds an option to modpost to generate a <module>.ns_deps file
per module, containing the namespace dependencies for that module.

E.g. if the linked module my-module.ko would depend on the symbol
myfunc.MY_NS in the namespace MY_NS, the my-module.ns_deps file created
by modpost would contain the entry MY_NS to express the namespace
dependency of my-module imposed by using the symbol myfunc.

These files can subsequently be used by static analysis tools (like
coccinelle scripts) to address issues with missing namespace imports. A
later patch of this series will introduce such a script 'nsdeps' and a
corresponding make target to automatically add missing
MODULE_IMPORT_NS() definitions to the module's sources. For that it uses
the information provided in the generated .ns_deps files.

Co-developed-by: default avatarMartijn Coenen <maco@android.com>
Signed-off-by: default avatarMartijn Coenen <maco@android.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarMatthias Maennich <maennich@google.com>
Signed-off-by: default avatarJessica Yu <jeyu@kernel.org>
parent 8e2adc6a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
*.lzo
*.mod
*.mod.c
*.ns_deps
*.o
*.o.*
*.order
+1 −1
Original line number Diff line number Diff line
@@ -1669,7 +1669,7 @@ clean: $(clean-dirs)
		-o -name '*.ko.*' \
		-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
		-o -name '*.dwo' -o -name '*.lst' \
		-o -name '*.su' -o -name '*.mod' \
		-o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \
		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
		-o -name '*.lex.c' -o -name '*.tab.[ch]' \
		-o -name '*.asn1.[ch]' \
+49 −5
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ static int sec_mismatch_count = 0;
static int sec_mismatch_fatal = 0;
/* ignore missing files */
static int ignore_missing_files;
/* write namespace dependencies */
static int write_namespace_deps;

enum export {
	export_plain,      export_unused,     export_gpl,
@@ -2176,11 +2178,16 @@ static int check_exports(struct module *mod)
		else
			basename = mod->name;

		if (exp->namespace &&
		if (exp->namespace) {
			add_namespace(&mod->required_namespaces,
				      exp->namespace);

			if (!write_namespace_deps &&
			    !module_imports_namespace(mod, exp->namespace)) {
				warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
				     basename, exp->name, exp->namespace);
			}
		}

		if (!mod->gpl_compatible)
			check_for_gpl_usage(exp->export, basename, exp->name);
@@ -2484,6 +2491,31 @@ static void write_dump(const char *fname)
	free(buf.p);
}

static void write_namespace_deps_files(void)
{
	struct module *mod;
	struct namespace_list *ns;
	struct buffer ns_deps_buf = {};

	for (mod = modules; mod; mod = mod->next) {
		char fname[PATH_MAX];

		if (mod->skip)
			continue;

		ns_deps_buf.pos = 0;

		for (ns = mod->required_namespaces; ns; ns = ns->next)
			buf_printf(&ns_deps_buf, "%s\n", ns->namespace);

		if (ns_deps_buf.pos == 0)
			continue;

		sprintf(fname, "%s.ns_deps", mod->name);
		write_if_changed(&ns_deps_buf, fname);
	}
}

struct ext_sym_list {
	struct ext_sym_list *next;
	const char *file;
@@ -2500,7 +2532,7 @@ int main(int argc, char **argv)
	struct ext_sym_list *extsym_iter;
	struct ext_sym_list *extsym_start = NULL;

	while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) {
	while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) {
		switch (opt) {
		case 'i':
			kernel_read = optarg;
@@ -2541,6 +2573,9 @@ int main(int argc, char **argv)
		case 'E':
			sec_mismatch_fatal = 1;
			break;
		case 'd':
			write_namespace_deps = 1;
			break;
		default:
			exit(1);
		}
@@ -2575,6 +2610,9 @@ int main(int argc, char **argv)

		err |= check_modname_len(mod);
		err |= check_exports(mod);
		if (write_namespace_deps)
			continue;

		add_header(&buf, mod);
		add_intree_flag(&buf, !external_module);
		add_retpoline(&buf);
@@ -2587,6 +2625,12 @@ int main(int argc, char **argv)
		sprintf(fname, "%s.mod.c", mod->name);
		write_if_changed(&buf, fname);
	}

	if (write_namespace_deps) {
		write_namespace_deps_files();
		return 0;
	}

	if (dump_write)
		write_dump(dump_write);
	if (sec_mismatch_count && sec_mismatch_fatal)
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ struct module {
	struct buffer dev_table_buf;
	char	     srcversion[25];
	int is_dot_o;
	// Required namespace dependencies
	struct namespace_list *required_namespaces;
	// Actual imported namespaces
	struct namespace_list *imported_namespaces;
};