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

From: Allen Webb
Date: Fri Dec 16 2022 - 17:17:39 EST


Keep track of the module name when processing match table symbols.

Signed-off-by: Allen Webb <allenwebb@xxxxxxxxxx>
---
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
+ */
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[];
};

--
2.37.3