diff options
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/file2alias.c | 35 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 15 | ||||
| -rw-r--r-- | scripts/mod/modpost.h | 2 | 
3 files changed, 48 insertions, 4 deletions
| diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 00586119a25b..b3333560b95e 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -94,6 +94,7 @@ module_alias_printf(struct module *mod, bool append_wildcard,  		}  	} +	new->builtin_modname = NULL;  	list_add_tail(&new->node, &mod->aliases);  } @@ -1476,8 +1477,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  {  	void *symval;  	char *zeros = NULL; -	const char *type, *name; -	size_t typelen; +	const char *type, *name, *modname; +	size_t typelen, modnamelen;  	static const char *prefix = "__mod_device_table__";  	/* We're looking for a section relative symbol */ @@ -1488,10 +1489,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)  		return; -	/* All our symbols are of form __mod_device_table__<type>__<name>. */ +	/* All our symbols are of form __mod_device_table__kmod_<modname>__<type>__<name>. */  	if (!strstarts(symname, prefix))  		return; -	type = symname + strlen(prefix); + +	modname = strstr(symname, "__kmod_"); +	if (!modname) +		return; +	modname += strlen("__kmod_"); + +	type = strstr(modname, "__"); +	if (!type) +		return; +	modnamelen = type - modname; +	type += strlen("__");  	name = strstr(type, "__");  	if (!name) @@ -1517,5 +1528,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  		}  	} +	if (mod->is_vmlinux) { +		struct module_alias *alias; + +		/* +		 * If this is vmlinux, record the name of the builtin module. +		 * Traverse the linked list in the reverse order, and set the +		 * builtin_modname unless it has already been set in the +		 * previous call. +		 */ +		list_for_each_entry_reverse(alias, &mod->aliases, node) { +			if (alias->builtin_modname) +				break; +			alias->builtin_modname = xstrndup(modname, modnamelen); +		} +	} +  	free(zeros);  } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5ca7c268294e..47c8aa2a6939 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname)  static void write_vmlinux_export_c_file(struct module *mod)  {  	struct buffer buf = { }; +	struct module_alias *alias, *next;  	buf_printf(&buf,  		   "#include <linux/export-internal.h>\n");  	add_exported_symbols(&buf, mod); + +	buf_printf(&buf, +		   "#include <linux/module.h>\n" +		   "#undef __MODULE_INFO_PREFIX\n" +		   "#define __MODULE_INFO_PREFIX\n"); + +	list_for_each_entry_safe(alias, next, &mod->aliases, node) { +		buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n", +			   alias->builtin_modname, alias->str); +		list_del(&alias->node); +		free(alias->builtin_modname); +		free(alias); +	} +  	write_if_changed(&buf, ".vmlinux.export.c");  	free(buf.p);  } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9133e4c3803f..2aecb8f25c87 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len);   * struct module_alias - auto-generated MODULE_ALIAS()   *   * @node: linked to module::aliases + * @modname: name of the builtin module (only for vmlinux)   * @str: a string for MODULE_ALIAS()   */  struct module_alias {  	struct list_head node; +	char *builtin_modname;  	char str[];  }; | 
