diff mbox series

[v7,2/5] modpost: Track module name for built-in modules

Message ID 20221216221703.294683-3-allenwebb@google.com (mailing list archive)
State New, archived
Headers show
Series [v7,1/5] module.h: MODULE_DEVICE_TABLE for built-in modules | expand

Commit Message

Allen Webb Dec. 16, 2022, 10:17 p.m. UTC
Keep track of the module name when processing match table symbols.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 scripts/mod/file2alias.c | 37 +++++++++++++++++++++++++++++++++----
 scripts/mod/modpost.h    |  1 +
 2 files changed, 34 insertions(+), 4 deletions(-)

Comments

Christophe Leroy Dec. 17, 2022, 10:08 a.m. UTC | #1
Le 16/12/2022 à 23:17, Allen Webb a écrit :
> Keep track of the module name when processing match table symbols.
> 
> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>   scripts/mod/file2alias.c | 37 +++++++++++++++++++++++++++++++++----
>   scripts/mod/modpost.h    |  1 +
>   2 files changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 80d973144fded..458e41ae0f5f1 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -28,6 +28,7 @@ typedef Elf64_Addr	kernel_ulong_t;
>   #include <stdint.h>
>   #endif
>   
> +#include <assert.h>
>   #include <ctype.h>
>   #include <stdbool.h>
>   
> @@ -1540,9 +1541,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>   			Elf_Sym *sym, const char *symname)
>   {
>   	void *symval;
> -	char *zeros = NULL;
> -	const char *name, *identifier;
> -	unsigned int namelen;
> +	char *zeros = NULL, *modname_str = NULL;
> +	const char *name, *identifier, *modname;
> +	unsigned int namelen, modnamelen;
>   
>   	/* We're looking for a section relative symbol */
>   	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
> @@ -1552,7 +1553,11 @@ 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_<name>__<identifier>_device_table. */
> +	/* All our symbols are either of form
> +	 *   __mod_<name>__<identifier>_device_table
> +	 * or
> +	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
> +	 */

Comments style is wrong. Multiline comments outside net/ start with an 
empty /* line.

>   	if (strncmp(symname, "__mod_", strlen("__mod_")))
>   		return;
>   	name = symname + strlen("__mod_");
> @@ -1564,8 +1569,29 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>   	identifier = strstr(name, "__");
>   	if (!identifier)
>   		return;
> +	modnamelen = namelen;
>   	namelen = identifier - name;
>   
> +	/* In the vmlinuz.o case we want to handle __kmod_ so aliases from
> +	 * builtin modules are attributed correctly.
> +	 */
> +	modname = strstr(identifier + 2, "__kmod_");
> +	if (modname) {
> +		modname += strlen("__kmod_");
> +		modnamelen -= (modname - name) + strlen("_device_table");
> +		modname_str = malloc(modnamelen + 1);
> +		/* We don't want to continue if the allocation fails. */
> +		assert(modname_str);
> +		memcpy(modname_str, modname, modnamelen);
> +		modname_str[modnamelen] = '\0';
> +	}
> +
> +	if (modname_str)
> +		modname = modname_str;
> +	else
> +		modname = mod->name;
> +	mod->builtin_name = modname;
> +
>   	/* Handle all-NULL symbols allocated into .bss */
>   	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
>   		zeros = calloc(1, sym->st_size);
> @@ -1597,6 +1623,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>   		}
>   	}
>   	free(zeros);
> +	mod->builtin_name = NULL;
> +	if (modname_str)
> +		free(modname_str);
>   }
>   
>   /* Now add out buffered information to the generated C source */
> diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> index 1178f40a73f3d..34fe5fc0b02cb 100644
> --- a/scripts/mod/modpost.h
> +++ b/scripts/mod/modpost.h
> @@ -128,6 +128,7 @@ struct module {
>   	struct list_head missing_namespaces;
>   	// Actual imported namespaces
>   	struct list_head imported_namespaces;
> +	const char *builtin_name;
>   	char name[];
>   };
>
diff mbox series

Patch

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 80d973144fded..458e41ae0f5f1 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -28,6 +28,7 @@  typedef Elf64_Addr	kernel_ulong_t;
 #include <stdint.h>
 #endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <stdbool.h>
 
@@ -1540,9 +1541,9 @@  void handle_moddevtable(struct module *mod, struct elf_info *info,
 			Elf_Sym *sym, const char *symname)
 {
 	void *symval;
-	char *zeros = NULL;
-	const char *name, *identifier;
-	unsigned int namelen;
+	char *zeros = NULL, *modname_str = NULL;
+	const char *name, *identifier, *modname;
+	unsigned int namelen, modnamelen;
 
 	/* We're looking for a section relative symbol */
 	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
@@ -1552,7 +1553,11 @@  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_<name>__<identifier>_device_table. */
+	/* All our symbols are either of form
+	 *   __mod_<name>__<identifier>_device_table
+	 * or
+	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
+	 */
 	if (strncmp(symname, "__mod_", strlen("__mod_")))
 		return;
 	name = symname + strlen("__mod_");
@@ -1564,8 +1569,29 @@  void handle_moddevtable(struct module *mod, struct elf_info *info,
 	identifier = strstr(name, "__");
 	if (!identifier)
 		return;
+	modnamelen = namelen;
 	namelen = identifier - name;
 
+	/* In the vmlinuz.o case we want to handle __kmod_ so aliases from
+	 * builtin modules are attributed correctly.
+	 */
+	modname = strstr(identifier + 2, "__kmod_");
+	if (modname) {
+		modname += strlen("__kmod_");
+		modnamelen -= (modname - name) + strlen("_device_table");
+		modname_str = malloc(modnamelen + 1);
+		/* We don't want to continue if the allocation fails. */
+		assert(modname_str);
+		memcpy(modname_str, modname, modnamelen);
+		modname_str[modnamelen] = '\0';
+	}
+
+	if (modname_str)
+		modname = modname_str;
+	else
+		modname = mod->name;
+	mod->builtin_name = modname;
+
 	/* Handle all-NULL symbols allocated into .bss */
 	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
 		zeros = calloc(1, sym->st_size);
@@ -1597,6 +1623,9 @@  void handle_moddevtable(struct module *mod, struct elf_info *info,
 		}
 	}
 	free(zeros);
+	mod->builtin_name = NULL;
+	if (modname_str)
+		free(modname_str);
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 1178f40a73f3d..34fe5fc0b02cb 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -128,6 +128,7 @@  struct module {
 	struct list_head missing_namespaces;
 	// Actual imported namespaces
 	struct list_head imported_namespaces;
+	const char *builtin_name;
 	char name[];
 };