From f4fdb17ca5a5285d4a0ed81b25d5a3d7b9b3ebf3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:41 +0900 Subject: [PATCH 01/16] modpost: introduce module_alias_printf() helper The generic ->do_entry() handler is currently limited to returning a single alias string. However, this is not flexible enough for several subsystems, which currently require their own implementations: - do_usb_table() - do_of_table() - do_pnp_device_entry() - do_pnp_card_entries() This commit introduces a helper function so that these special cases can add multiple MODULE_ALIAS() and then migrate to the generic framework. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 91 +++++++++++++++++++++++++++++----------- scripts/mod/modpost.c | 11 ++++- scripts/mod/modpost.h | 19 ++++++++- 3 files changed, 93 insertions(+), 28 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 34678ed40fdb..d6c8d5e08821 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -10,6 +10,12 @@ * of the GNU General Public License, incorporated herein by reference. */ +#include +#include + +#include "list.h" +#include "xalloc.h" + #include "modpost.h" #include "devicetable-offsets.h" @@ -31,6 +37,58 @@ typedef Elf64_Addr kernel_ulong_t; #include #include +/** + * module_alias_printf - add auto-generated MODULE_ALIAS() + * + * @mod: module + * @append_wildcard: append '*' for future extension if not exist yet + * @fmt: printf(3)-like format + */ +static void __attribute__((format (printf, 3, 4))) +module_alias_printf(struct module *mod, bool append_wildcard, + const char *fmt, ...) +{ + struct module_alias *new; + size_t len; + int n; + va_list ap; + + /* Determine required size. */ + va_start(ap, fmt); + n = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + return; + } + + len = n + 1; /* extra byte for '\0' */ + + if (append_wildcard) + len++; /* extra byte for '*' */ + + new = xmalloc(sizeof(*new) + len); + + /* Now, really print it to the allocated buffer */ + va_start(ap, fmt); + n = vsnprintf(new->str, len, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + free(new); + return; + } + + if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) { + new->str[n] = '*'; + new->str[n + 1] = '\0'; + } + + list_add_tail(&new->node, &mod->aliases); +} + typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -229,9 +287,7 @@ static void do_usb_entry(void *symval, ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, bInterfaceNumber); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, true, "%s", alias); } /* Handles increment/decrement of BCD formatted integers */ @@ -375,10 +431,8 @@ static void do_of_entry_multi(void *symval, struct module *mod) if (isspace(*tmp)) *tmp = '_'; - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); - strcat(alias, "C"); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, false, "%s", alias); + module_alias_printf(mod, false, "%sC*", alias); } static void do_of_table(void *symval, unsigned long size, @@ -608,14 +662,12 @@ static void do_pnp_device_entry(void *symval, unsigned long size, char acpi_id[sizeof(*id)]; int j; - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); + module_alias_printf(mod, false, "pnp:d%s*", *id); /* fix broken pnp bus lowercasing */ for (j = 0; j < sizeof(acpi_id); j++) acpi_id[j] = toupper((*id)[j]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } @@ -666,14 +718,12 @@ static void do_pnp_card_entries(void *symval, unsigned long size, char acpi_id[PNP_ID_LEN]; int k; - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", id); + module_alias_printf(mod, false, "pnp:d%s*", id); /* fix broken pnp bus lowercasing */ for (k = 0; k < sizeof(acpi_id); k++) acpi_id[k] = toupper(id[k]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } } @@ -1534,8 +1584,7 @@ static void do_table(void *symval, unsigned long size, for (i = 0; i < size; i += id_size) { if (do_entry(mod->name, symval+i, alias)) { - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, false, "%s", alias); } } } @@ -1660,11 +1709,3 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, } free(zeros); } - -/* Now add out buffered information to the generated C source */ -void add_moddevtable(struct buffer *buf, struct module *mod) -{ - buf_printf(buf, "\n"); - buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos); - free(mod->dev_table_buf.p); -} diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 107393a8c48a..1948d69ce2b9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -176,6 +176,7 @@ static struct module *new_module(const char *name, size_t namelen) INIT_LIST_HEAD(&mod->unresolved_symbols); INIT_LIST_HEAD(&mod->missing_namespaces); INIT_LIST_HEAD(&mod->imported_namespaces); + INIT_LIST_HEAD(&mod->aliases); memcpy(mod->name, name, namelen); mod->name[namelen] = '\0'; @@ -1966,6 +1967,7 @@ static void write_vmlinux_export_c_file(struct module *mod) static void write_mod_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; char fname[PATH_MAX]; int ret; @@ -1973,7 +1975,14 @@ static void write_mod_c_file(struct module *mod) add_exported_symbols(&buf, mod); add_versions(&buf, mod); add_depends(&buf, mod); - add_moddevtable(&buf, mod); + + buf_printf(&buf, "\n"); + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str); + list_del(&alias->node); + free(alias); + } + add_srcversion(&buf, mod); ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index ada3a36cc4bc..52efe0026b34 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -79,6 +79,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...); void buf_write(struct buffer *buf, const char *s, int len); +/** + * struct module_alias - auto-generated MODULE_ALIAS() + * + * @node: linked to module::aliases + * @str: a string for MODULE_ALIAS() + */ +struct module_alias { + struct list_head node; + char str[]; +}; + +/** + * struct module - represent a module (vmlinux or *.ko) + * + * @aliases: list head for module_aliases + */ struct module { struct list_head list; struct list_head exported_symbols; @@ -89,12 +105,12 @@ struct module { bool seen; bool has_init; bool has_cleanup; - struct buffer dev_table_buf; char srcversion[25]; // Missing namespace dependencies struct list_head missing_namespaces; // Actual imported namespaces struct list_head imported_namespaces; + struct list_head aliases; char name[]; }; @@ -170,7 +186,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, /* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); -void add_moddevtable(struct buffer *buf, struct module *mod); /* sumversion.c */ void get_src_version(const char *modname, char sum[], unsigned sumlen); -- 2.51.0 From d92b7a3b528bb4b69fa8b6f99c63fe8ad7927cec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:42 +0900 Subject: [PATCH 02/16] modpost: deduplicate MODULE_ALIAS() for all drivers MODULE_DEVICE_TABLE(pnp_card, ...) may have duplicated IDs. For instance, snd_ad1816a_pnpids[] in sound/isa/ad1816a/ad1816a.c includes multiple occurrences of the "ADS7180" string within its .devs fields. Currently, do_pnp_card_entries() handles deduplication on its own, but this logic should be moved to a common helper function, as drivers in other subsystems might also have similar duplication issues. For example, drivers/media/i2c/s5c73m3/s5c73m3.mod.c contains duplicated MODULE_ALIAS() entries because both s5c73m3-core.c and s5c73m3-spi.c define the same compatible string. This commit eliminates redundant MODULE_ALIAS() entries across all drivers. [Before] $ grep MODULE_ALIAS drivers/media/i2c/s5c73m3/s5c73m3.mod.c MODULE_ALIAS("i2c:S5C73M3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); [After] $ grep MODULE_ALIAS drivers/media/i2c/s5c73m3/s5c73m3.mod.c MODULE_ALIAS("i2c:S5C73M3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3"); MODULE_ALIAS("of:N*T*Csamsung,s5c73m3C*"); Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 48 +++++++++++++--------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d6c8d5e08821..71dd5272013b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -48,7 +48,7 @@ static void __attribute__((format (printf, 3, 4))) module_alias_printf(struct module *mod, bool append_wildcard, const char *fmt, ...) { - struct module_alias *new; + struct module_alias *new, *als; size_t len; int n; va_list ap; @@ -86,6 +86,14 @@ module_alias_printf(struct module *mod, bool append_wildcard, new->str[n + 1] = '\0'; } + /* avoid duplication */ + list_for_each_entry(als, &mod->aliases, node) { + if (!strcmp(als->str, new->str)) { + free(new); + return; + } + } + list_add_tail(&new->node, &mod->aliases); } @@ -687,44 +695,18 @@ static void do_pnp_card_entries(void *symval, unsigned long size, for (j = 0; j < PNP_MAX_DEVICES; j++) { const char *id = (char *)(*devs)[j].id; - int i2, j2; - int dup = 0; + char acpi_id[PNP_ID_LEN]; if (!id[0]) break; - /* find duplicate, already added value */ - for (i2 = 0; i2 < i && !dup; i2++) { - DEF_FIELD_ADDR_VAR(symval + i2 * id_size, - pnp_card_device_id, - devs, devs_dup); - - for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { - const char *id2 = - (char *)(*devs_dup)[j2].id; - - if (!id2[0]) - break; - - if (!strcmp(id, id2)) { - dup = 1; - break; - } - } - } - /* add an individual alias for every device entry */ - if (!dup) { - char acpi_id[PNP_ID_LEN]; - int k; + module_alias_printf(mod, false, "pnp:d%s*", id); - module_alias_printf(mod, false, "pnp:d%s*", id); - - /* fix broken pnp bus lowercasing */ - for (k = 0; k < sizeof(acpi_id); k++) - acpi_id[k] = toupper(id[k]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* fix broken pnp bus lowercasing */ + for (int k = 0; k < sizeof(acpi_id); k++) + acpi_id[k] = toupper(id[k]); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } } -- 2.51.0 From c4d1a9f9d11b5d7c5cf4fab33f86f7d7a978801e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:43 +0900 Subject: [PATCH 03/16] modpost: remove DEF_FIELD_ADDR_VAR() macro With the former cleanups in do_pnp_card_entries(), this macro is no longer used by anyone. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 71dd5272013b..cd8be749260c 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -138,19 +138,12 @@ struct devtable { #define DEF_FIELD(m, devid, f) \ typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) -/* Define a variable v that holds the address of field f of struct devid - * based at address m. Due to the way typeof works, for a field of type - * T[N] the variable has type T(*)[N], _not_ T*. - */ -#define DEF_FIELD_ADDR_VAR(m, devid, f, v) \ - typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f) - /* Define a variable f that holds the address of field f of struct devid * based at address m. Due to the way typeof works, for a field of type * T[N] the variable has type T(*)[N], _not_ T*. */ #define DEF_FIELD_ADDR(m, devid, f) \ - DEF_FIELD_ADDR_VAR(m, devid, f, f) + typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) #define ADD(str, sep, cond, field) \ do { \ -- 2.51.0 From c7c24d60151c022bd8e357f5395a327d354a676a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:44 +0900 Subject: [PATCH 04/16] modpost: pass (struct module *) to do_*_entry() functions Replace the first argument with a pointer to struct module. 'filename' can be replaced with mod->name. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 118 +++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cd8be749260c..b23ef324b155 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -126,7 +126,7 @@ typedef struct { struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; - int (*do_entry)(const char *filename, void *symval, char *alias); + int (*do_entry)(struct module *mod, void *symval, char *alias); }; /* Size of alias provided to do_entry functions */ @@ -452,7 +452,7 @@ static void do_of_table(void *symval, unsigned long size, } /* Looks like: hid:bNvNpN */ -static int do_hid_entry(const char *filename, +static int do_hid_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, hid_device_id, bus); @@ -470,7 +470,7 @@ static int do_hid_entry(const char *filename, } /* Looks like: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(const char *filename, +static int do_ieee1394_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ieee1394_device_id, match_flags); @@ -494,7 +494,7 @@ static int do_ieee1394_entry(const char *filename, } /* Looks like: pci:vNdNsvNsdNbcNscNiN or _pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(const char *filename, +static int do_pci_entry(struct module *mod, void *symval, char *alias) { /* Class field can be divided into these three. */ @@ -538,7 +538,7 @@ static int do_pci_entry(const char *filename, || (subclass_mask != 0 && subclass_mask != 0xFF) || (interface_mask != 0 && interface_mask != 0xFF)) { warn("Can't handle masks in %s:%04X\n", - filename, class_mask); + mod->name, class_mask); return 0; } @@ -550,7 +550,7 @@ static int do_pci_entry(const char *filename, } /* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(const char *filename, +static int do_ccw_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ccw_device_id, match_flags); @@ -573,7 +573,7 @@ static int do_ccw_entry(const char *filename, } /* looks like: "ap:tN" */ -static int do_ap_entry(const char *filename, +static int do_ap_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ap_device_id, dev_type); @@ -583,7 +583,7 @@ static int do_ap_entry(const char *filename, } /* looks like: "css:tN" */ -static int do_css_entry(const char *filename, +static int do_css_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, css_device_id, type); @@ -593,7 +593,7 @@ static int do_css_entry(const char *filename, } /* Looks like: "serio:tyNprNidNexN" */ -static int do_serio_entry(const char *filename, +static int do_serio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, serio_device_id, type); @@ -618,7 +618,7 @@ static int do_serio_entry(const char *filename, * or _CLS. Also, bb, ss, and pp can be substituted with ?? * as don't care byte. */ -static int do_acpi_entry(const char *filename, +static int do_acpi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, acpi_device_id, id); @@ -705,7 +705,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, } /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ -static int do_pcmcia_entry(const char *filename, +static int do_pcmcia_entry(struct module *mod, void *symval, char *alias) { unsigned int i; @@ -741,7 +741,7 @@ static int do_pcmcia_entry(const char *filename, return 1; } -static int do_vio_entry(const char *filename, void *symval, +static int do_vio_entry(struct module *mod, void *symval, char *alias) { char *tmp; @@ -773,7 +773,7 @@ static void do_input(char *alias, } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ -static int do_input_entry(const char *filename, void *symval, +static int do_input_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, input_device_id, flags); @@ -830,7 +830,7 @@ static int do_input_entry(const char *filename, void *symval, return 1; } -static int do_eisa_entry(const char *filename, void *symval, +static int do_eisa_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); @@ -839,7 +839,7 @@ static int do_eisa_entry(const char *filename, void *symval, } /* Looks like: parisc:tNhvNrevNsvN */ -static int do_parisc_entry(const char *filename, void *symval, +static int do_parisc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, parisc_device_id, hw_type); @@ -858,7 +858,7 @@ static int do_parisc_entry(const char *filename, void *symval, } /* Looks like: sdio:cNvNdN. */ -static int do_sdio_entry(const char *filename, +static int do_sdio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, sdio_device_id, class); @@ -874,7 +874,7 @@ static int do_sdio_entry(const char *filename, } /* Looks like: ssb:vNidNrevN. */ -static int do_ssb_entry(const char *filename, +static int do_ssb_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ssb_device_id, vendor); @@ -890,7 +890,7 @@ static int do_ssb_entry(const char *filename, } /* Looks like: bcma:mNidNrevNclN. */ -static int do_bcma_entry(const char *filename, +static int do_bcma_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, bcma_device_id, manuf); @@ -908,7 +908,7 @@ static int do_bcma_entry(const char *filename, } /* Looks like: virtio:dNvN */ -static int do_virtio_entry(const char *filename, void *symval, +static int do_virtio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, virtio_device_id, device); @@ -928,7 +928,7 @@ static int do_virtio_entry(const char *filename, void *symval, * in the name. */ -static int do_vmbus_entry(const char *filename, void *symval, +static int do_vmbus_entry(struct module *mod, void *symval, char *alias) { int i; @@ -945,7 +945,7 @@ static int do_vmbus_entry(const char *filename, void *symval, } /* Looks like: rpmsg:S */ -static int do_rpmsg_entry(const char *filename, void *symval, +static int do_rpmsg_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, rpmsg_device_id, name); @@ -955,7 +955,7 @@ static int do_rpmsg_entry(const char *filename, void *symval, } /* Looks like: i2c:S */ -static int do_i2c_entry(const char *filename, void *symval, +static int do_i2c_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, i2c_device_id, name); @@ -964,7 +964,7 @@ static int do_i2c_entry(const char *filename, void *symval, return 1; } -static int do_i3c_entry(const char *filename, void *symval, +static int do_i3c_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, i3c_device_id, match_flags); @@ -982,7 +982,7 @@ static int do_i3c_entry(const char *filename, void *symval, return 1; } -static int do_slim_entry(const char *filename, void *symval, char *alias) +static int do_slim_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, slim_device_id, manf_id); DEF_FIELD(symval, slim_device_id, prod_code); @@ -993,7 +993,7 @@ static int do_slim_entry(const char *filename, void *symval, char *alias) } /* Looks like: spi:S */ -static int do_spi_entry(const char *filename, void *symval, +static int do_spi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, spi_device_id, name); @@ -1034,7 +1034,7 @@ static void dmi_ascii_filter(char *d, const char *s) } -static int do_dmi_entry(const char *filename, void *symval, +static int do_dmi_entry(struct module *mod, void *symval, char *alias) { int i, j; @@ -1058,7 +1058,7 @@ static int do_dmi_entry(const char *filename, void *symval, return 1; } -static int do_platform_entry(const char *filename, +static int do_platform_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, platform_device_id, name); @@ -1066,7 +1066,7 @@ static int do_platform_entry(const char *filename, return 1; } -static int do_mdio_entry(const char *filename, +static int do_mdio_entry(struct module *mod, void *symval, char *alias) { int i; @@ -1091,7 +1091,7 @@ static int do_mdio_entry(const char *filename, } /* Looks like: zorro:iN. */ -static int do_zorro_entry(const char *filename, void *symval, +static int do_zorro_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, zorro_device_id, id); @@ -1101,7 +1101,7 @@ static int do_zorro_entry(const char *filename, void *symval, } /* looks like: "pnp:dD" */ -static int do_isapnp_entry(const char *filename, +static int do_isapnp_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, isapnp_device_id, vendor); @@ -1116,7 +1116,7 @@ static int do_isapnp_entry(const char *filename, } /* Looks like: "ipack:fNvNdN". */ -static int do_ipack_entry(const char *filename, +static int do_ipack_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ipack_device_id, format); @@ -1178,7 +1178,7 @@ static void append_nibble_mask(char **outp, * N is exactly 8 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_amba_entry(const char *filename, +static int do_amba_entry(struct module *mod, void *symval, char *alias) { unsigned int digit; @@ -1188,7 +1188,7 @@ static int do_amba_entry(const char *filename, if ((id & mask) != id) fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", - filename, id, mask); + mod->name, id, mask); p += sprintf(alias, "amba:d"); for (digit = 0; digit < 8; digit++) @@ -1205,7 +1205,7 @@ static int do_amba_entry(const char *filename, * N is exactly 2 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_mips_cdmm_entry(const char *filename, +static int do_mips_cdmm_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, mips_cdmm_device_id, type); @@ -1220,7 +1220,7 @@ static int do_mips_cdmm_entry(const char *filename, * complicated. */ -static int do_x86cpu_entry(const char *filename, void *symval, +static int do_x86cpu_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, x86_cpu_id, feature); @@ -1239,7 +1239,7 @@ static int do_x86cpu_entry(const char *filename, void *symval, } /* LOOKS like cpu:type:*:feature:*FEAT* */ -static int do_cpu_entry(const char *filename, void *symval, char *alias) +static int do_cpu_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, cpu_feature, feature); @@ -1248,7 +1248,7 @@ static int do_cpu_entry(const char *filename, void *symval, char *alias) } /* Looks like: mei:S:uuid:N:* */ -static int do_mei_entry(const char *filename, void *symval, +static int do_mei_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mei_cl_device_id, name); @@ -1266,7 +1266,7 @@ static int do_mei_entry(const char *filename, void *symval, } /* Looks like: rapidio:vNdNavNadN */ -static int do_rio_entry(const char *filename, +static int do_rio_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, rio_device_id, did); @@ -1285,7 +1285,7 @@ static int do_rio_entry(const char *filename, } /* Looks like: ulpi:vNpN */ -static int do_ulpi_entry(const char *filename, void *symval, +static int do_ulpi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ulpi_device_id, vendor); @@ -1297,7 +1297,7 @@ static int do_ulpi_entry(const char *filename, void *symval, } /* Looks like: hdaudio:vNrNaN */ -static int do_hda_entry(const char *filename, void *symval, char *alias) +static int do_hda_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, hda_device_id, vendor_id); DEF_FIELD(symval, hda_device_id, rev_id); @@ -1313,7 +1313,7 @@ static int do_hda_entry(const char *filename, void *symval, char *alias) } /* Looks like: sdw:mNpNvNcN */ -static int do_sdw_entry(const char *filename, void *symval, char *alias) +static int do_sdw_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); @@ -1331,7 +1331,7 @@ static int do_sdw_entry(const char *filename, void *symval, char *alias) } /* Looks like: fsl-mc:vNdN */ -static int do_fsl_mc_entry(const char *filename, void *symval, +static int do_fsl_mc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, fsl_mc_device_id, vendor); @@ -1342,7 +1342,7 @@ static int do_fsl_mc_entry(const char *filename, void *symval, } /* Looks like: tbsvc:kSpNvNrN */ -static int do_tbsvc_entry(const char *filename, void *symval, char *alias) +static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, tb_service_id, match_flags); DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); @@ -1366,7 +1366,7 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias) } /* Looks like: typec:idNmN */ -static int do_typec_entry(const char *filename, void *symval, char *alias) +static int do_typec_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, typec_device_id, svid); DEF_FIELD(symval, typec_device_id, mode); @@ -1378,7 +1378,7 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) } /* Looks like: tee:uuid */ -static int do_tee_entry(const char *filename, void *symval, char *alias) +static int do_tee_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); @@ -1393,28 +1393,28 @@ static int do_tee_entry(const char *filename, void *symval, char *alias) } /* Looks like: wmi:guid */ -static int do_wmi_entry(const char *filename, void *symval, char *alias) +static int do_wmi_entry(struct module *mod, void *symval, char *alias) { int len; DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); if (strlen(*guid_string) != UUID_STRING_LEN) { warn("Invalid WMI device id 'wmi:%s' in '%s'\n", - *guid_string, filename); + *guid_string, mod->name); return 0; } len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); if (len < 0 || len >= ALIAS_SIZE) { warn("Could not generate all MODULE_ALIAS's in '%s'\n", - filename); + mod->name); return 0; } return 1; } /* Looks like: mhi:S */ -static int do_mhi_entry(const char *filename, void *symval, char *alias) +static int do_mhi_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); @@ -1422,7 +1422,7 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) } /* Looks like: mhi_ep:S */ -static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +static int do_mhi_ep_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); @@ -1431,7 +1431,7 @@ static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) } /* Looks like: ishtp:{guid} */ -static int do_ishtp_entry(const char *filename, void *symval, char *alias) +static int do_ishtp_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, ishtp_device_id, guid); @@ -1442,7 +1442,7 @@ static int do_ishtp_entry(const char *filename, void *symval, char *alias) return 1; } -static int do_auxiliary_entry(const char *filename, void *symval, char *alias) +static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); @@ -1455,7 +1455,7 @@ static int do_auxiliary_entry(const char *filename, void *symval, char *alias) * * N is exactly 2 digits, where each is an upper-case hex digit. */ -static int do_ssam_entry(const char *filename, void *symval, char *alias) +static int do_ssam_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, ssam_device_id, match_flags); DEF_FIELD(symval, ssam_device_id, domain); @@ -1473,7 +1473,7 @@ static int do_ssam_entry(const char *filename, void *symval, char *alias) } /* Looks like: dfl:tNfN */ -static int do_dfl_entry(const char *filename, void *symval, char *alias) +static int do_dfl_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); @@ -1485,7 +1485,7 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias) } /* Looks like: cdx:vNdN */ -static int do_cdx_entry(const char *filename, void *symval, +static int do_cdx_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, cdx_device_id, vendor); @@ -1518,7 +1518,7 @@ static int do_cdx_entry(const char *filename, void *symval, return 1; } -static int do_vchiq_entry(const char *filename, void *symval, char *alias) +static int do_vchiq_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD_ADDR(symval, vchiq_device_id, name); sprintf(alias, "vchiq:%s", *name); @@ -1527,7 +1527,7 @@ static int do_vchiq_entry(const char *filename, void *symval, char *alias) } /* Looks like: coreboot:tN */ -static int do_coreboot_entry(const char *filename, void *symval, char *alias) +static int do_coreboot_entry(struct module *mod, void *symval, char *alias) { DEF_FIELD(symval, coreboot_device_id, tag); sprintf(alias, "coreboot:t%08X", tag); @@ -1547,7 +1547,7 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) static void do_table(void *symval, unsigned long size, unsigned long id_size, const char *device_id, - int (*do_entry)(const char *filename, void *symval, char *alias), + int (*do_entry)(struct module *mod, void *symval, char *alias), struct module *mod) { unsigned int i; @@ -1558,7 +1558,7 @@ static void do_table(void *symval, unsigned long size, size -= id_size; for (i = 0; i < size; i += id_size) { - if (do_entry(mod->name, symval+i, alias)) { + if (do_entry(mod, symval+i, alias)) { module_alias_printf(mod, false, "%s", alias); } } -- 2.51.0 From 6d3b3dd26fd71dde0b41478755a59ca30aaeb664 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:45 +0900 Subject: [PATCH 05/16] modpost: call module_alias_printf() from all do_*_entry() functions The do_*_entry() functions cannot check the length of the given buffer. Use module_alias_printf() helper consistently for these functions. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 438 ++++++++++++++++----------------------- 1 file changed, 181 insertions(+), 257 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index b23ef324b155..5ef87a6d33f8 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -126,12 +126,9 @@ typedef struct { struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; - int (*do_entry)(struct module *mod, void *symval, char *alias); + void (*do_entry)(struct module *mod, void *symval); }; -/* Size of alias provided to do_entry functions */ -#define ALIAS_SIZE 500 - /* Define a variable f that holds the value of field f of struct devid * based at address m. */ @@ -158,15 +155,6 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/* End in a wildcard, for future extension */ -static inline void add_wildcard(char *str) -{ - int len = strlen(str); - - if (str[len - 1] != '*') - strcat(str + len, "*"); -} - static inline void add_uuid(char *str, uuid_le uuid) { int len = strlen(str); @@ -452,34 +440,34 @@ static void do_of_table(void *symval, unsigned long size, } /* Looks like: hid:bNvNpN */ -static int do_hid_entry(struct module *mod, - void *symval, char *alias) +static void do_hid_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hid_device_id, bus); DEF_FIELD(symval, hid_device_id, group); DEF_FIELD(symval, hid_device_id, vendor); DEF_FIELD(symval, hid_device_id, product); - sprintf(alias, "hid:"); ADD(alias, "b", bus != HID_BUS_ANY, bus); ADD(alias, "g", group != HID_GROUP_ANY, group); ADD(alias, "v", vendor != HID_ANY_ID, vendor); ADD(alias, "p", product != HID_ANY_ID, product); - return 1; + module_alias_printf(mod, false, "hid:%s", alias); } /* Looks like: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(struct module *mod, - void *symval, char *alias) +static void do_ieee1394_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ieee1394_device_id, match_flags); DEF_FIELD(symval, ieee1394_device_id, vendor_id); DEF_FIELD(symval, ieee1394_device_id, model_id); DEF_FIELD(symval, ieee1394_device_id, specifier_id); DEF_FIELD(symval, ieee1394_device_id, version); - strcpy(alias, "ieee1394:"); ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID, vendor_id); ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID, @@ -489,14 +477,13 @@ static int do_ieee1394_entry(struct module *mod, ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION, version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "ieee1394:%s", alias); } /* Looks like: pci:vNdNsvNsdNbcNscNiN or _pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(struct module *mod, - void *symval, char *alias) +static void do_pci_entry(struct module *mod, void *symval) { + char alias[256]; /* Class field can be divided into these three. */ unsigned char baseclass, subclass, interface, baseclass_mask, subclass_mask, interface_mask; @@ -519,7 +506,6 @@ static int do_pci_entry(struct module *mod, default: warn("Unknown PCI driver_override alias %08X\n", override_only); - return 0; } ADD(alias, "v", vendor != PCI_ANY_ID, vendor); @@ -539,27 +525,27 @@ static int do_pci_entry(struct module *mod, || (interface_mask != 0 && interface_mask != 0xFF)) { warn("Can't handle masks in %s:%04X\n", mod->name, class_mask); - return 0; + return; } ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); ADD(alias, "sc", subclass_mask == 0xFF, subclass); ADD(alias, "i", interface_mask == 0xFF, interface); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "%s", alias); } /* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(struct module *mod, - void *symval, char *alias) +static void do_ccw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ccw_device_id, match_flags); DEF_FIELD(symval, ccw_device_id, cu_type); DEF_FIELD(symval, ccw_device_id, cu_model); DEF_FIELD(symval, ccw_device_id, dev_type); DEF_FIELD(symval, ccw_device_id, dev_model); - strcpy(alias, "ccw:"); ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, cu_type); ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, @@ -568,47 +554,42 @@ static int do_ccw_entry(struct module *mod, dev_type); ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, dev_model); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ccw:%s", alias); } /* looks like: "ap:tN" */ -static int do_ap_entry(struct module *mod, - void *symval, char *alias) +static void do_ap_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ap_device_id, dev_type); - sprintf(alias, "ap:t%02X*", dev_type); - return 1; + module_alias_printf(mod, false, "ap:t%02X*", dev_type); } /* looks like: "css:tN" */ -static int do_css_entry(struct module *mod, - void *symval, char *alias) +static void do_css_entry(struct module *mod, void *symval) { DEF_FIELD(symval, css_device_id, type); - sprintf(alias, "css:t%01X", type); - return 1; + module_alias_printf(mod, false, "css:t%01X", type); } /* Looks like: "serio:tyNprNidNexN" */ -static int do_serio_entry(struct module *mod, - void *symval, char *alias) +static void do_serio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, serio_device_id, type); DEF_FIELD(symval, serio_device_id, proto); DEF_FIELD(symval, serio_device_id, id); DEF_FIELD(symval, serio_device_id, extra); - strcpy(alias, "serio:"); ADD(alias, "ty", type != SERIO_ANY, type); ADD(alias, "pr", proto != SERIO_ANY, proto); ADD(alias, "id", id != SERIO_ANY, id); ADD(alias, "ex", extra != SERIO_ANY, extra); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "serio:%s", alias); } /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or @@ -618,21 +599,19 @@ static int do_serio_entry(struct module *mod, * or _CLS. Also, bb, ss, and pp can be substituted with ?? * as don't care byte. */ -static int do_acpi_entry(struct module *mod, - void *symval, char *alias) +static void do_acpi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, acpi_device_id, id); DEF_FIELD(symval, acpi_device_id, cls); DEF_FIELD(symval, acpi_device_id, cls_msk); if ((*id)[0]) - sprintf(alias, "acpi*:%s:*", *id); + module_alias_printf(mod, false, "acpi*:%s:*", *id); else { + char alias[256]; int i, byte_shift, cnt = 0; unsigned int msk; - sprintf(&alias[cnt], "acpi*:"); - cnt = 6; for (i = 1; i <= 3; i++) { byte_shift = 8 * (3-i); msk = (cls_msk >> byte_shift) & 0xFF; @@ -643,9 +622,8 @@ static int do_acpi_entry(struct module *mod, sprintf(&alias[cnt], "??"); cnt += 2; } - sprintf(&alias[cnt], ":*"); + module_alias_printf(mod, false, "acpi*:%s:*", alias); } - return 1; } /* looks like: "pnp:dD" */ @@ -705,9 +683,9 @@ static void do_pnp_card_entries(void *symval, unsigned long size, } /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ -static int do_pcmcia_entry(struct module *mod, - void *symval, char *alias) +static void do_pcmcia_entry(struct module *mod, void *symval) { + char alias[256] = {}; unsigned int i; DEF_FIELD(symval, pcmcia_device_id, match_flags); DEF_FIELD(symval, pcmcia_device_id, manf_id); @@ -721,7 +699,6 @@ static int do_pcmcia_entry(struct module *mod, (*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]); } - strcpy(alias, "pcmcia:"); ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID, manf_id); ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID, @@ -737,13 +714,12 @@ static int do_pcmcia_entry(struct module *mod, ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]); ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "pcmcia:%s", alias); } -static int do_vio_entry(struct module *mod, void *symval, - char *alias) +static void do_vio_entry(struct module *mod, void *symval) { + char alias[256]; char *tmp; DEF_FIELD_ADDR(symval, vio_device_id, type); DEF_FIELD_ADDR(symval, vio_device_id, compat); @@ -756,8 +732,7 @@ static int do_vio_entry(struct module *mod, void *symval, if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "%s", alias); } static void do_input(char *alias, @@ -773,9 +748,10 @@ static void do_input(char *alias, } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ -static int do_input_entry(struct module *mod, void *symval, - char *alias) +static void do_input_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, input_device_id, flags); DEF_FIELD(symval, input_device_id, bustype); DEF_FIELD(symval, input_device_id, vendor); @@ -791,8 +767,6 @@ static int do_input_entry(struct module *mod, void *symval, DEF_FIELD_ADDR(symval, input_device_id, ffbit); DEF_FIELD_ADDR(symval, input_device_id, swbit); - sprintf(alias, "input:"); - ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype); ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor); ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product); @@ -827,99 +801,96 @@ static int do_input_entry(struct module *mod, void *symval, sprintf(alias + strlen(alias), "w*"); if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); - return 1; + + module_alias_printf(mod, false, "input:%s", alias); } -static int do_eisa_entry(struct module *mod, void *symval, - char *alias) +static void do_eisa_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); - sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); - return 1; + module_alias_printf(mod, false, EISA_DEVICE_MODALIAS_FMT "*", *sig); } /* Looks like: parisc:tNhvNrevNsvN */ -static int do_parisc_entry(struct module *mod, void *symval, - char *alias) +static void do_parisc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, parisc_device_id, hw_type); DEF_FIELD(symval, parisc_device_id, hversion); DEF_FIELD(symval, parisc_device_id, hversion_rev); DEF_FIELD(symval, parisc_device_id, sversion); - strcpy(alias, "parisc:"); ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type); ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion); ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev); ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "parisc:%s", alias); } /* Looks like: sdio:cNvNdN. */ -static int do_sdio_entry(struct module *mod, - void *symval, char *alias) +static void do_sdio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdio_device_id, class); DEF_FIELD(symval, sdio_device_id, vendor); DEF_FIELD(symval, sdio_device_id, device); - strcpy(alias, "sdio:"); ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class); ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor); ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "sdio:%s", alias); } /* Looks like: ssb:vNidNrevN. */ -static int do_ssb_entry(struct module *mod, - void *symval, char *alias) +static void do_ssb_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssb_device_id, vendor); DEF_FIELD(symval, ssb_device_id, coreid); DEF_FIELD(symval, ssb_device_id, revision); - strcpy(alias, "ssb:"); ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor); ADD(alias, "id", coreid != SSB_ANY_ID, coreid); ADD(alias, "rev", revision != SSB_ANY_REV, revision); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ssb:%s", alias); } /* Looks like: bcma:mNidNrevNclN. */ -static int do_bcma_entry(struct module *mod, - void *symval, char *alias) +static void do_bcma_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, bcma_device_id, manuf); DEF_FIELD(symval, bcma_device_id, id); DEF_FIELD(symval, bcma_device_id, rev); DEF_FIELD(symval, bcma_device_id, class); - strcpy(alias, "bcma:"); ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf); ADD(alias, "id", id != BCMA_ANY_ID, id); ADD(alias, "rev", rev != BCMA_ANY_REV, rev); ADD(alias, "cl", class != BCMA_ANY_CLASS, class); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "bcma:%s", alias); } /* Looks like: virtio:dNvN */ -static int do_virtio_entry(struct module *mod, void *symval, - char *alias) +static void do_virtio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, virtio_device_id, device); DEF_FIELD(symval, virtio_device_id, vendor); - strcpy(alias, "virtio:"); ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device); ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "virtio:%s", alias); } /* @@ -928,8 +899,7 @@ static int do_virtio_entry(struct module *mod, void *symval, * in the name. */ -static int do_vmbus_entry(struct module *mod, void *symval, - char *alias) +static void do_vmbus_entry(struct module *mod, void *symval) { int i; DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid); @@ -938,68 +908,57 @@ static int do_vmbus_entry(struct module *mod, void *symval, for (i = 0; i < (sizeof(*guid) * 2); i += 2) sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); - strcpy(alias, "vmbus:"); - strcat(alias, guid_name); - - return 1; + module_alias_printf(mod, false, "vmbus:%s", guid_name); } /* Looks like: rpmsg:S */ -static int do_rpmsg_entry(struct module *mod, void *symval, - char *alias) +static void do_rpmsg_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, rpmsg_device_id, name); - sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); - return 1; + module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); } /* Looks like: i2c:S */ -static int do_i2c_entry(struct module *mod, void *symval, - char *alias) +static void do_i2c_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, i2c_device_id, name); - sprintf(alias, I2C_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, I2C_MODULE_PREFIX "%s", *name); } -static int do_i3c_entry(struct module *mod, void *symval, - char *alias) +static void do_i3c_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, i3c_device_id, match_flags); DEF_FIELD(symval, i3c_device_id, dcr); DEF_FIELD(symval, i3c_device_id, manuf_id); DEF_FIELD(symval, i3c_device_id, part_id); DEF_FIELD(symval, i3c_device_id, extra_info); - strcpy(alias, "i3c:"); ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr); ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id); ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id); ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info); - return 1; + module_alias_printf(mod, false, "i3c:%s", alias); } -static int do_slim_entry(struct module *mod, void *symval, char *alias) +static void do_slim_entry(struct module *mod, void *symval) { DEF_FIELD(symval, slim_device_id, manf_id); DEF_FIELD(symval, slim_device_id, prod_code); - sprintf(alias, "slim:%x:%x:*", manf_id, prod_code); - - return 1; + module_alias_printf(mod, false, "slim:%x:%x:*", manf_id, prod_code); } /* Looks like: spi:S */ -static int do_spi_entry(struct module *mod, void *symval, - char *alias) +static void do_spi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, spi_device_id, name); - sprintf(alias, SPI_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, SPI_MODULE_PREFIX "%s", *name); } static const struct dmifield { @@ -1034,12 +993,11 @@ static void dmi_ascii_filter(char *d, const char *s) } -static int do_dmi_entry(struct module *mod, void *symval, - char *alias) +static void do_dmi_entry(struct module *mod, void *symval) { + char alias[256] = {}; int i, j; DEF_FIELD_ADDR(symval, dmi_system_id, matches); - sprintf(alias, "dmi*"); for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { for (j = 0; j < 4; j++) { @@ -1054,80 +1012,75 @@ static int do_dmi_entry(struct module *mod, void *symval, } } - strcat(alias, ":"); - return 1; + module_alias_printf(mod, false, "dmi*%s:", alias); } -static int do_platform_entry(struct module *mod, - void *symval, char *alias) +static void do_platform_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, platform_device_id, name); - sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); - return 1; + + module_alias_printf(mod, false, PLATFORM_MODULE_PREFIX "%s", *name); } -static int do_mdio_entry(struct module *mod, - void *symval, char *alias) +static void do_mdio_entry(struct module *mod, void *symval) { + char id[33]; int i; DEF_FIELD(symval, mdio_device_id, phy_id); DEF_FIELD(symval, mdio_device_id, phy_id_mask); - alias += sprintf(alias, MDIO_MODULE_PREFIX); - for (i = 0; i < 32; i++) { if (!((phy_id_mask >> (31-i)) & 1)) - *(alias++) = '?'; + id[i] = '?'; else if ((phy_id >> (31-i)) & 1) - *(alias++) = '1'; + id[i] = '1'; else - *(alias++) = '0'; + id[i] = '0'; } /* Terminate the string */ - *alias = 0; + id[32] = '\0'; - return 1; + module_alias_printf(mod, false, MDIO_MODULE_PREFIX "%s", id); } /* Looks like: zorro:iN. */ -static int do_zorro_entry(struct module *mod, void *symval, - char *alias) +static void do_zorro_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, zorro_device_id, id); - strcpy(alias, "zorro:"); + ADD(alias, "i", id != ZORRO_WILDCARD, id); - return 1; + + module_alias_printf(mod, false, "zorro:%s", alias); } /* looks like: "pnp:dD" */ -static int do_isapnp_entry(struct module *mod, - void *symval, char *alias) +static void do_isapnp_entry(struct module *mod, void *symval) { DEF_FIELD(symval, isapnp_device_id, vendor); DEF_FIELD(symval, isapnp_device_id, function); - sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", + module_alias_printf(mod, false, "pnp:d%c%c%c%x%x%x%x*", 'A' + ((vendor >> 2) & 0x3f) - 1, 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 'A' + ((vendor >> 8) & 0x1f) - 1, (function >> 4) & 0x0f, function & 0x0f, (function >> 12) & 0x0f, (function >> 8) & 0x0f); - return 1; } /* Looks like: "ipack:fNvNdN". */ -static int do_ipack_entry(struct module *mod, - void *symval, char *alias) +static void do_ipack_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, ipack_device_id, format); DEF_FIELD(symval, ipack_device_id, vendor); DEF_FIELD(symval, ipack_device_id, device); - strcpy(alias, "ipack:"); + ADD(alias, "f", format != IPACK_ANY_FORMAT, format); ADD(alias, "v", vendor != IPACK_ANY_ID, vendor); ADD(alias, "d", device != IPACK_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ipack:%s", alias); } /* @@ -1178,9 +1131,9 @@ static void append_nibble_mask(char **outp, * N is exactly 8 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_amba_entry(struct module *mod, - void *symval, char *alias) +static void do_amba_entry(struct module *mod, void *symval) { + char alias[256]; unsigned int digit; char *p = alias; DEF_FIELD(symval, amba_id, id); @@ -1190,13 +1143,12 @@ static int do_amba_entry(struct module *mod, fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", mod->name, id, mask); - p += sprintf(alias, "amba:d"); for (digit = 0; digit < 8; digit++) append_nibble_mask(&p, (id >> (4 * (7 - digit))) & 0xf, (mask >> (4 * (7 - digit))) & 0xf); - return 1; + module_alias_printf(mod, false, "amba:d%s", alias); } /* @@ -1205,13 +1157,11 @@ static int do_amba_entry(struct module *mod, * N is exactly 2 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_mips_cdmm_entry(struct module *mod, - void *symval, char *alias) +static void do_mips_cdmm_entry(struct module *mod, void *symval) { DEF_FIELD(symval, mips_cdmm_device_id, type); - sprintf(alias, "mipscdmm:t%02X*", type); - return 1; + module_alias_printf(mod, false, "mipscdmm:t%02X*", type); } /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* @@ -1220,137 +1170,130 @@ static int do_mips_cdmm_entry(struct module *mod, * complicated. */ -static int do_x86cpu_entry(struct module *mod, void *symval, - char *alias) +static void do_x86cpu_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, x86_cpu_id, feature); DEF_FIELD(symval, x86_cpu_id, family); DEF_FIELD(symval, x86_cpu_id, model); DEF_FIELD(symval, x86_cpu_id, vendor); - strcpy(alias, "cpu:type:x86,"); ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); ADD(alias, "fam", family != X86_FAMILY_ANY, family); ADD(alias, "mod", model != X86_MODEL_ANY, model); strcat(alias, ":feature:*"); if (feature != X86_FEATURE_ANY) sprintf(alias + strlen(alias), "%04X*", feature); - return 1; + + module_alias_printf(mod, false, "cpu:type:x86,%s", alias); } /* LOOKS like cpu:type:*:feature:*FEAT* */ -static int do_cpu_entry(struct module *mod, void *symval, char *alias) +static void do_cpu_entry(struct module *mod, void *symval) { DEF_FIELD(symval, cpu_feature, feature); - sprintf(alias, "cpu:type:*:feature:*%04X*", feature); - return 1; + module_alias_printf(mod, false, "cpu:type:*:feature:*%04X*", feature); } /* Looks like: mei:S:uuid:N:* */ -static int do_mei_entry(struct module *mod, void *symval, - char *alias) +static void do_mei_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD_ADDR(symval, mei_cl_device_id, name); DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid); DEF_FIELD(symval, mei_cl_device_id, version); - sprintf(alias, MEI_CL_MODULE_PREFIX); - sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*"); add_uuid(alias, *uuid); ADD(alias, ":", version != MEI_CL_VERSION_ANY, version); - strcat(alias, ":*"); - - return 1; + module_alias_printf(mod, false, MEI_CL_MODULE_PREFIX "%s:%s:*", + (*name)[0] ? *name : "*", alias); } /* Looks like: rapidio:vNdNavNadN */ -static int do_rio_entry(struct module *mod, - void *symval, char *alias) +static void do_rio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, rio_device_id, did); DEF_FIELD(symval, rio_device_id, vid); DEF_FIELD(symval, rio_device_id, asm_did); DEF_FIELD(symval, rio_device_id, asm_vid); - strcpy(alias, "rapidio:"); ADD(alias, "v", vid != RIO_ANY_ID, vid); ADD(alias, "d", did != RIO_ANY_ID, did); ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid); ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "rapidio:%s", alias); } /* Looks like: ulpi:vNpN */ -static int do_ulpi_entry(struct module *mod, void *symval, - char *alias) +static void do_ulpi_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ulpi_device_id, vendor); DEF_FIELD(symval, ulpi_device_id, product); - sprintf(alias, "ulpi:v%04xp%04x", vendor, product); - - return 1; + module_alias_printf(mod, false, "ulpi:v%04xp%04x", vendor, product); } /* Looks like: hdaudio:vNrNaN */ -static int do_hda_entry(struct module *mod, void *symval, char *alias) +static void do_hda_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hda_device_id, vendor_id); DEF_FIELD(symval, hda_device_id, rev_id); DEF_FIELD(symval, hda_device_id, api_version); - strcpy(alias, "hdaudio:"); ADD(alias, "v", vendor_id != 0, vendor_id); ADD(alias, "r", rev_id != 0, rev_id); ADD(alias, "a", api_version != 0, api_version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "hdaudio:%s", alias); } /* Looks like: sdw:mNpNvNcN */ -static int do_sdw_entry(struct module *mod, void *symval, char *alias) +static void do_sdw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); DEF_FIELD(symval, sdw_device_id, sdw_version); DEF_FIELD(symval, sdw_device_id, class_id); - strcpy(alias, "sdw:"); ADD(alias, "m", mfg_id != 0, mfg_id); ADD(alias, "p", part_id != 0, part_id); ADD(alias, "v", sdw_version != 0, sdw_version); ADD(alias, "c", class_id != 0, class_id); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "sdw:%s", alias); } /* Looks like: fsl-mc:vNdN */ -static int do_fsl_mc_entry(struct module *mod, void *symval, - char *alias) +static void do_fsl_mc_entry(struct module *mod, void *symval) { DEF_FIELD(symval, fsl_mc_device_id, vendor); DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type); - sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); - return 1; + module_alias_printf(mod, false, "fsl-mc:v%08Xd%s", vendor, *obj_type); } /* Looks like: tbsvc:kSpNvNrN */ -static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) +static void do_tbsvc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, tb_service_id, match_flags); DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); DEF_FIELD(symval, tb_service_id, protocol_id); DEF_FIELD(symval, tb_service_id, protocol_version); DEF_FIELD(symval, tb_service_id, protocol_revision); - strcpy(alias, "tbsvc:"); if (match_flags & TBSVC_MATCH_PROTOCOL_KEY) sprintf(alias + strlen(alias), "k%s", *protocol_key); else @@ -1361,93 +1304,80 @@ static int do_tbsvc_entry(struct module *mod, void *symval, char *alias) ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION, protocol_revision); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "tbsvc:%s", alias); } /* Looks like: typec:idNmN */ -static int do_typec_entry(struct module *mod, void *symval, char *alias) +static void do_typec_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, typec_device_id, svid); DEF_FIELD(symval, typec_device_id, mode); - sprintf(alias, "typec:id%04X", svid); ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); - return 1; + module_alias_printf(mod, false, "typec:id%04X%s", svid, alias); } /* Looks like: tee:uuid */ -static int do_tee_entry(struct module *mod, void *symval, char *alias) +static void do_tee_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); - sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + module_alias_printf(mod, true, + "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]); - - add_wildcard(alias); - return 1; } /* Looks like: wmi:guid */ -static int do_wmi_entry(struct module *mod, void *symval, char *alias) +static void do_wmi_entry(struct module *mod, void *symval) { - int len; DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); if (strlen(*guid_string) != UUID_STRING_LEN) { warn("Invalid WMI device id 'wmi:%s' in '%s'\n", *guid_string, mod->name); - return 0; + return; } - len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); - if (len < 0 || len >= ALIAS_SIZE) { - warn("Could not generate all MODULE_ALIAS's in '%s'\n", - mod->name); - return 0; - } - return 1; + module_alias_printf(mod, false, WMI_MODULE_PREFIX "%s", *guid_string); } /* Looks like: mhi:S */ -static int do_mhi_entry(struct module *mod, void *symval, char *alias) +static void do_mhi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: mhi_ep:S */ -static int do_mhi_ep_entry(struct module *mod, void *symval, char *alias) +static void do_mhi_ep_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_EP_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: ishtp:{guid} */ -static int do_ishtp_entry(struct module *mod, void *symval, char *alias) +static void do_ishtp_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD_ADDR(symval, ishtp_device_id, guid); - strcpy(alias, ISHTP_MODULE_PREFIX "{"); add_guid(alias, *guid); - strcat(alias, "}"); - return 1; + module_alias_printf(mod, false, ISHTP_MODULE_PREFIX "{%s}", alias); } -static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) +static void do_auxiliary_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); - sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name); } /* @@ -1455,8 +1385,10 @@ static int do_auxiliary_entry(struct module *mod, void *symval, char *alias) * * N is exactly 2 digits, where each is an upper-case hex digit. */ -static int do_ssam_entry(struct module *mod, void *symval, char *alias) +static void do_ssam_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssam_device_id, match_flags); DEF_FIELD(symval, ssam_device_id, domain); DEF_FIELD(symval, ssam_device_id, category); @@ -1464,30 +1396,28 @@ static int do_ssam_entry(struct module *mod, void *symval, char *alias) DEF_FIELD(symval, ssam_device_id, instance); DEF_FIELD(symval, ssam_device_id, function); - sprintf(alias, "ssam:d%02Xc%02X", domain, category); ADD(alias, "t", match_flags & SSAM_MATCH_TARGET, target); ADD(alias, "i", match_flags & SSAM_MATCH_INSTANCE, instance); ADD(alias, "f", match_flags & SSAM_MATCH_FUNCTION, function); - return 1; + module_alias_printf(mod, false, "ssam:d%02Xc%02X%s", + domain, category, alias); } /* Looks like: dfl:tNfN */ -static int do_dfl_entry(struct module *mod, void *symval, char *alias) +static void do_dfl_entry(struct module *mod, void *symval) { DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); - sprintf(alias, "dfl:t%04Xf%04X", type, feature_id); - - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "dfl:t%04Xf%04X", type, feature_id); } /* Looks like: cdx:vNdN */ -static int do_cdx_entry(struct module *mod, void *symval, - char *alias) +static void do_cdx_entry(struct module *mod, void *symval) { + char alias[256]; + DEF_FIELD(symval, cdx_device_id, vendor); DEF_FIELD(symval, cdx_device_id, device); DEF_FIELD(symval, cdx_device_id, subvendor); @@ -1506,7 +1436,7 @@ static int do_cdx_entry(struct module *mod, void *symval, default: warn("Unknown CDX driver_override alias %08X\n", override_only); - return 0; + return; } ADD(alias, "v", vendor != CDX_ANY_ID, vendor); @@ -1515,24 +1445,22 @@ static int do_cdx_entry(struct module *mod, void *symval, ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice); ADD(alias, "c", class_mask == 0xFFFFFF, class); - return 1; + module_alias_printf(mod, false, "%s", alias); } -static int do_vchiq_entry(struct module *mod, void *symval, char *alias) +static void do_vchiq_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, vchiq_device_id, name); - sprintf(alias, "vchiq:%s", *name); - return 1; + module_alias_printf(mod, false, "vchiq:%s", *name); } /* Looks like: coreboot:tN */ -static int do_coreboot_entry(struct module *mod, void *symval, char *alias) +static void do_coreboot_entry(struct module *mod, void *symval) { DEF_FIELD(symval, coreboot_device_id, tag); - sprintf(alias, "coreboot:t%08X", tag); - return 1; + module_alias_printf(mod, false, "coreboot:t%08X", tag); } /* Does namelen bytes of name exactly match the symbol? */ @@ -1547,21 +1475,17 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) static void do_table(void *symval, unsigned long size, unsigned long id_size, const char *device_id, - int (*do_entry)(struct module *mod, void *symval, char *alias), + void (*do_entry)(struct module *mod, void *symval), struct module *mod) { unsigned int i; - char alias[ALIAS_SIZE]; device_id_check(mod->name, device_id, size, id_size, symval); /* Leave last one: it's the terminator. */ size -= id_size; - for (i = 0; i < size; i += id_size) { - if (do_entry(mod, symval+i, alias)) { - module_alias_printf(mod, false, "%s", alias); - } - } + for (i = 0; i < size; i += id_size) + do_entry(mod, symval + i); } static const struct devtable devtable[] = { -- 2.51.0 From a5d8d417e62ab3823a06e1bc08634d737d810e59 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:46 +0900 Subject: [PATCH 06/16] modpost: convert do_pnp_card_entries() to a generic handler do_pnp_card_entries() no longer needs to iterate over the pnp_card_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5ef87a6d33f8..00bb3f8f0647 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -651,34 +651,24 @@ static void do_pnp_device_entry(void *symval, unsigned long size, } /* looks like: "pnp:dD" for every device of the card */ -static void do_pnp_card_entries(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_card_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_card_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); - - for (i = 0; i < count; i++) { - unsigned int j; - DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); + DEF_FIELD_ADDR(symval, pnp_card_device_id, devs); - for (j = 0; j < PNP_MAX_DEVICES; j++) { - const char *id = (char *)(*devs)[j].id; - char acpi_id[PNP_ID_LEN]; + for (unsigned int i = 0; i < PNP_MAX_DEVICES; i++) { + const char *id = (char *)(*devs)[i].id; + char acpi_id[PNP_ID_LEN]; - if (!id[0]) - break; + if (!id[0]) + break; - /* add an individual alias for every device entry */ - module_alias_printf(mod, false, "pnp:d%s*", id); + /* fix broken pnp bus lowercasing */ + for (unsigned int j = 0; j < sizeof(acpi_id); j++) + acpi_id[j] = toupper(id[j]); - /* fix broken pnp bus lowercasing */ - for (int k = 0; k < sizeof(acpi_id); k++) - acpi_id[k] = toupper(id[k]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* add an individual alias for every device entry */ + module_alias_printf(mod, false, "pnp:d%s*", id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } @@ -1541,6 +1531,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; /* Create MODULE_ALIAS() statements. @@ -1591,8 +1582,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_of_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp_card")) - do_pnp_card_entries(symval, sym->st_size, mod); else { int i; -- 2.51.0 From 600dbaf1e2f0c0b70b2d3e7513a161b884e7718f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:47 +0900 Subject: [PATCH 07/16] modpost: convert do_pnp_device_entry() to a generic handler do_pnp_device_entry() no longer needs to iterate over the pnp_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 00bb3f8f0647..cacfa0de634b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -627,27 +627,16 @@ static void do_acpi_entry(struct module *mod, void *symval) } /* looks like: "pnp:dD" */ -static void do_pnp_device_entry(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_device_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); - - for (i = 0; i < count; i++) { - DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); - char acpi_id[sizeof(*id)]; - int j; - - module_alias_printf(mod, false, "pnp:d%s*", *id); + DEF_FIELD_ADDR(symval, pnp_device_id, id); + char acpi_id[sizeof(*id)]; - /* fix broken pnp bus lowercasing */ - for (j = 0; j < sizeof(acpi_id); j++) - acpi_id[j] = toupper((*id)[j]); - module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); - } + /* fix broken pnp bus lowercasing */ + for (unsigned int i = 0; i < sizeof(acpi_id); i++) + acpi_id[i] = toupper((*id)[i]); + module_alias_printf(mod, false, "pnp:d%s*", *id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } /* looks like: "pnp:dD" for every device of the card */ @@ -1531,6 +1520,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1580,8 +1570,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_usb_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "of")) do_of_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp")) - do_pnp_device_entry(symval, sym->st_size, mod); else { int i; -- 2.51.0 From c58854c8e0b50c2f30c729b82b92b3fd8cc8f2c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:48 +0900 Subject: [PATCH 08/16] modpost: convert do_of_table() to a generic handler do_of_table() no longer needs to iterate over the of_device_id array. Convert it to a generic ->do_entry() handler. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cacfa0de634b..7f079a3857b2 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -398,7 +398,7 @@ static void do_usb_table(void *symval, unsigned long size, do_usb_entry_multi(symval + i, mod); } -static void do_of_entry_multi(void *symval, struct module *mod) +static void do_of_entry(struct module *mod, void *symval) { char alias[500]; int len; @@ -424,21 +424,6 @@ static void do_of_entry_multi(void *symval, struct module *mod) module_alias_printf(mod, false, "%sC*", alias); } -static void do_of_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_of_device_id; - - device_id_check(mod->name, "of", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_of_entry_multi(symval + i, mod); -} - /* Looks like: hid:bNvNpN */ static void do_hid_entry(struct module *mod, void *symval) { @@ -1520,6 +1505,7 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"of", SIZE_of_device_id, do_of_entry}, {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1568,8 +1554,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, /* First handle the "special" cases */ if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "of")) - do_of_table(symval, sym->st_size, mod); else { int i; -- 2.51.0 From abd20428c3f2f8b97a2a0414343faf0ff246a018 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:49 +0900 Subject: [PATCH 09/16] modpost: convert do_usb_table() to a generic handler do_usb_table() no longer needs to iterate over the usb_device_id array. Convert it to a generic ->do_entry() handler. This is the last special case. Clean up handle_moddevtable(). Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 7f079a3857b2..7f1bbb46dc65 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -122,7 +122,6 @@ typedef struct { * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" -/* This array collects all instances that use the generic do_table */ struct devtable { const char *device_id; /* name of table, __mod___*_device_table. */ unsigned long id_size; @@ -318,7 +317,7 @@ static unsigned int incbcd(unsigned int *bcd, return init; } -static void do_usb_entry_multi(void *symval, struct module *mod) +static void do_usb_entry_multi(struct module *mod, void *symval) { unsigned int devlo, devhi; unsigned char chi, clo, max; @@ -383,21 +382,6 @@ static void do_usb_entry_multi(void *symval, struct module *mod) } } -static void do_usb_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_usb_device_id; - - device_id_check(mod->name, "usb", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_usb_entry_multi(symval + i, mod); -} - static void do_of_entry(struct module *mod, void *symval) { char alias[500]; @@ -1506,6 +1490,7 @@ static const struct devtable devtable[] = { {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, {"of", SIZE_of_device_id, do_of_entry}, + {"usb", SIZE_usb_device_id, do_usb_entry_multi}, {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; @@ -1551,21 +1536,15 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, symval = sym_get_data(info, sym); } - /* First handle the "special" cases */ - if (sym_is(name, namelen, "usb")) - do_usb_table(symval, sym->st_size, mod); - else { - int i; - - for (i = 0; i < ARRAY_SIZE(devtable); i++) { - const struct devtable *p = &devtable[i]; + for (int i = 0; i < ARRAY_SIZE(devtable); i++) { + const struct devtable *p = &devtable[i]; - if (sym_is(name, namelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, - p->device_id, p->do_entry, mod); - break; - } + if (sym_is(name, namelen, p->device_id)) { + do_table(symval, sym->st_size, p->id_size, + p->device_id, p->do_entry, mod); + break; } } + free(zeros); } -- 2.51.0 From 9d98038d438d8515473a75a29bc524e9a4a5882a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:50 +0900 Subject: [PATCH 10/16] modpost: move strstarts() to modpost.h This macro is useful in file2alias.c as well. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 2 +- scripts/mod/modpost.c | 2 -- scripts/mod/modpost.h | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 7f1bbb46dc65..541e6a3f95bc 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1515,7 +1515,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, return; /* All our symbols are of form __mod____device_table. */ - if (strncmp(symname, "__mod_", strlen("__mod_"))) + if (!strstarts(symname, "__mod_")) return; name = symname + strlen("__mod_"); namelen = strlen(name); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1948d69ce2b9..3bbd5efcf3f3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -341,8 +341,6 @@ static const char *sec_name(const struct elf_info *info, unsigned int secindex) return sech_name(info, &info->sechdrs[secindex]); } -#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) - static struct symbol *sym_add_exported(const char *name, struct module *mod, bool gpl_only, const char *namespace) { diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 52efe0026b34..49848fcbe2a1 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -67,6 +67,8 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) + struct buffer { char *p; int pos; -- 2.51.0 From 9a8ace8bb2efa0ca43a77866fa9c835294b1e045 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:51 +0900 Subject: [PATCH 11/16] modpost: rename variables in handle_moddevtable() This commit renames the variables in handle_moddevtable() as follows: name -> type namelen -> typelen identifier -> name These changes align with the definition in include/linux/module.h: extern typeof(name) __mod_##type##__##name##_device_table Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 541e6a3f95bc..038b2ab79e11 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1503,8 +1503,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; - const char *name, *identifier; - unsigned int namelen; + const char *type, *name; + size_t typelen; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) @@ -1514,19 +1514,19 @@ 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. */ + /* All our symbols are of form __mod____device_table. */ if (!strstarts(symname, "__mod_")) return; - name = symname + strlen("__mod_"); - namelen = strlen(name); - if (namelen < strlen("_device_table")) + type = symname + strlen("__mod_"); + typelen = strlen(type); + if (typelen < strlen("_device_table")) return; - if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) + if (strcmp(type + typelen - strlen("_device_table"), "_device_table")) return; - identifier = strstr(name, "__"); - if (!identifier) + name = strstr(type, "__"); + if (!name) return; - namelen = identifier - name; + typelen = name - type; /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { @@ -1539,7 +1539,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, for (int i = 0; i < ARRAY_SIZE(devtable); i++) { const struct devtable *p = &devtable[i]; - if (sym_is(name, namelen, p->device_id)) { + if (sym_is(type, typelen, p->device_id)) { do_table(symval, sym->st_size, p->id_size, p->device_id, p->do_entry, mod); break; -- 2.51.0 From 054a9cd395a79f4a5595f2cd24542e9bca8723c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:52 +0900 Subject: [PATCH 12/16] modpost: rename alias symbol for MODULE_DEVICE_TABLE() This commit renames the alias symbol, __mod____device_table to __mod_device_table____. This change simplifies the code slightly, as there is no longer a need to check both the prefix and suffix. Signed-off-by: Masahiro Yamada --- include/linux/module.h | 2 +- scripts/mod/file2alias.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 88ecc5e9f523..3dd79a3d0cbf 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -247,7 +247,7 @@ extern void cleanup_module(void); #ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ -extern typeof(name) __mod_##type##__##name##_device_table \ +extern typeof(name) __mod_device_table__##type##__##name \ __attribute__ ((unused, alias(__stringify(name)))) #else /* !MODULE */ #define MODULE_DEVICE_TABLE(type, name) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 038b2ab79e11..fc4bbeea1268 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -123,7 +123,7 @@ typedef struct { #include "../../include/linux/mod_devicetable.h" struct devtable { - const char *device_id; /* name of table, __mod___*_device_table. */ + const char *device_id; unsigned long id_size; void (*do_entry)(struct module *mod, void *symval); }; @@ -190,7 +190,7 @@ static void device_id_check(const char *modname, const char *device_id, int i; if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_%s___device_table=%lu.\n" + fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_device_table__%s__=%lu.\n" "Fix definition of struct %s_device_id in mod_devicetable.h\n", modname, device_id, id_size, device_id, size, device_id); } @@ -1505,6 +1505,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, char *zeros = NULL; const char *type, *name; size_t typelen; + static const char *prefix = "__mod_device_table__"; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) @@ -1514,15 +1515,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____device_table. */ - if (!strstarts(symname, "__mod_")) - return; - type = symname + strlen("__mod_"); - typelen = strlen(type); - if (typelen < strlen("_device_table")) - return; - if (strcmp(type + typelen - strlen("_device_table"), "_device_table")) + /* All our symbols are of form __mod_device_table____. */ + if (!strstarts(symname, prefix)) return; + type = symname + strlen(prefix); + name = strstr(type, "__"); if (!name) return; -- 2.51.0 From 2b1bd507542a6ec1506a847da8e81fc764a4e707 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Nov 2024 08:56:53 +0900 Subject: [PATCH 13/16] modpost: improve error messages in device_id_check() The first error message in device_id_check() is obscure and can be misleading because the cause of the error is unlikely to be found in the struct definition in mod_devicetable.h. This type of error occurs when an array is passed to an incorrect type of MODULE_DEVICE_TABLE(). [Example 1] static const struct acpi_device_id foo_ids[] = { { "FOO" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, foo_ids); Currently, modpost outputs a meaningless suggestion: ERROR: modpost: ...: sizeof(struct of_device_id)=200 is not a modulo of the size of section __mod_device_table__of__=64. Fix definition of struct of_device_id in mod_devicetable.h The root cause here is that MODULE_DEVICE_TABLE(of, ...) is used instead of the correct MODULE_DEVICE_TABLE(acpi, ...). This commit provides a more intuitive error message: ERROR: modpost: ...: type mismatch between foo_ids[] and MODULE_DEVICE_TABLE(of, ...) The second error message, related to a missing terminator, is too verbose. [Example 2] static const struct acpi_device_id foo_ids[] = { { "FOO" }, }; MODULE_DEVICE_TABLE(acpi, foo_ids); The current error message is overly long, and does not pinpoint the incorrect array: ...: struct acpi_device_id is 32 bytes. The last of 1 is: 0x46 0x4f 0x4f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ERROR: modpost: ...: struct acpi_device_id is not terminated with a NULL entry! This commit changes it to a more concise error message, sufficient to identify the incorrect array: ERROR: modpost: ...: foo_ids[] is not terminated with a NULL entry Lastly, this commit squashes device_id_check() into do_table() and changes fatal() into error(), allowing modpost to continue processing other modules. Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 55 +++++++++++++--------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index fc4bbeea1268..5b5745f00eb3 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -176,40 +176,6 @@ static inline void add_guid(char *str, guid_t guid) guid.b[12], guid.b[13], guid.b[14], guid.b[15]); } -/** - * Check that sizeof(device_id type) are consistent with size of section - * in .o file. If in-consistent then userspace and kernel does not agree - * on actual size which is a bug. - * Also verify that the final entry in the table is all zeros. - * Ignore both checks if build host differ from target host and size differs. - **/ -static void device_id_check(const char *modname, const char *device_id, - unsigned long size, unsigned long id_size, - void *symval) -{ - int i; - - if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_device_table__%s__=%lu.\n" - "Fix definition of struct %s_device_id in mod_devicetable.h\n", - modname, device_id, id_size, device_id, size, device_id); - } - /* Verify last one is a terminator */ - for (i = 0; i < id_size; i++ ) { - if (*(uint8_t*)(symval+size-id_size+i)) { - fprintf(stderr, - "%s: struct %s_device_id is %lu bytes. The last of %lu is:\n", - modname, device_id, id_size, size / id_size); - for (i = 0; i < id_size; i++ ) - fprintf(stderr,"0x%02x ", - *(uint8_t*)(symval+size-id_size+i) ); - fprintf(stderr,"\n"); - fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n", - modname, device_id); - } - } -} - /* USB is special because the bcdDevice can be matched against a numeric range */ /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ static void do_usb_entry(void *symval, @@ -1420,7 +1386,7 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) return memcmp(name, symbol, namelen) == 0; } -static void do_table(void *symval, unsigned long size, +static void do_table(const char *name, void *symval, unsigned long size, unsigned long id_size, const char *device_id, void (*do_entry)(struct module *mod, void *symval), @@ -1428,7 +1394,21 @@ static void do_table(void *symval, unsigned long size, { unsigned int i; - device_id_check(mod->name, device_id, size, id_size, symval); + if (size % id_size || size < id_size) { + error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n", + mod->name, name, device_id); + return; + } + + /* Verify the last entry is a terminator */ + for (i = size - id_size; i < size; i++) { + if (*(uint8_t *)(symval + i)) { + error("%s: %s[] is not terminated with a NULL entry\n", + mod->name, name); + return; + } + } + /* Leave last one: it's the terminator. */ size -= id_size; @@ -1524,6 +1504,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!name) return; typelen = name - type; + name += strlen("__"); /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { @@ -1537,7 +1518,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, const struct devtable *p = &devtable[i]; if (sym_is(type, typelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, + do_table(name, symval, sym->st_size, p->id_size, p->device_id, p->do_entry, mod); break; } -- 2.51.0 From 091aa11a2983cdc608f3978d365f5479e78917d8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 Nov 2024 08:22:55 +0900 Subject: [PATCH 14/16] genksyms: reduce indentation in export_symbol() Modify this function to return earlier when find_symbol() returns NULL, reducing the level of improve readability. No functional changes are intended. Signed-off-by: Masahiro Yamada --- scripts/genksyms/genksyms.c | 73 +++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index f3901c55df23..07f9b8cfb233 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -632,54 +632,55 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) void export_symbol(const char *name) { struct symbol *sym; + unsigned long crc; + int has_changed = 0; sym = find_symbol(name, SYM_NORMAL, 0); - if (!sym) + if (!sym) { error_with_pos("export undefined symbol %s", name); - else { - unsigned long crc; - int has_changed = 0; + return; + } - if (flag_dump_defs) - fprintf(debugfile, "Export %s == <", name); + if (flag_dump_defs) + fprintf(debugfile, "Export %s == <", name); - expansion_trail = (struct symbol *)-1L; + expansion_trail = (struct symbol *)-1L; - sym->expansion_trail = expansion_trail; - expansion_trail = sym; - crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; + sym->expansion_trail = expansion_trail; + expansion_trail = sym; + crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; - sym = expansion_trail; - while (sym != (struct symbol *)-1L) { - struct symbol *n = sym->expansion_trail; + sym = expansion_trail; + while (sym != (struct symbol *)-1L) { + struct symbol *n = sym->expansion_trail; - if (sym->status != STATUS_UNCHANGED) { - if (!has_changed) { - print_location(); - fprintf(stderr, "%s: %s: modversion " - "changed because of changes " - "in ", flag_preserve ? "error" : - "warning", name); - } else - fprintf(stderr, ", "); - print_type_name(sym->type, sym->name); - if (sym->status == STATUS_DEFINED) - fprintf(stderr, " (became defined)"); - has_changed = 1; - if (flag_preserve) - errors++; + if (sym->status != STATUS_UNCHANGED) { + if (!has_changed) { + print_location(); + fprintf(stderr, + "%s: %s: modversion changed because of changes in ", + flag_preserve ? "error" : "warning", + name); + } else { + fprintf(stderr, ", "); } - sym->expansion_trail = 0; - sym = n; + print_type_name(sym->type, sym->name); + if (sym->status == STATUS_DEFINED) + fprintf(stderr, " (became defined)"); + has_changed = 1; + if (flag_preserve) + errors++; } - if (has_changed) - fprintf(stderr, "\n"); + sym->expansion_trail = 0; + sym = n; + } + if (has_changed) + fprintf(stderr, "\n"); - if (flag_dump_defs) - fputs(">\n", debugfile); + if (flag_dump_defs) + fputs(">\n", debugfile); - printf("#SYMVER %s 0x%08lx\n", name, crc); - } + printf("#SYMVER %s 0x%08lx\n", name, crc); } /*----------------------------------------------------------------------*/ -- 2.51.0 From 6b1fabce7313dcd4d95e541dd400ba5748b09b94 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Nov 2024 17:26:45 +0900 Subject: [PATCH 15/16] kbuild: deb-pkg: add python3:native to build dependency Python3 is necessary for running some scripts such as drivers/gpu/drm/msm/registers/gen_header.py Both scripts/package/kernel.spec and scripts/package/PKGBUILD already list Python as the build dependency. Do likewise for scripts/package/mkdebian. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/package/mkdebian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index fc3b7fa709fc..4ffcc70f8e31 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -202,7 +202,7 @@ Build-Depends-Arch: bc, bison, cpio, flex, gcc-${host_gnu} , kmod, libelf-dev:native, libssl-dev:native, libssl-dev , - rsync + python3:native, rsync Homepage: https://www.kernel.org/ Package: $packagename-$version -- 2.51.0 From 5eaea85187bf2132d1af916010fa9e26bb63f97f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 23 Nov 2024 17:36:08 +0900 Subject: [PATCH 16/16] modpost: replace tdb_hash() with hash_str() Use a helper available in scripts/include/hash.h. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3bbd5efcf3f3..0584cbcdbd2d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -210,19 +211,6 @@ struct symbol { static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10); -/* This is based on the hash algorithm from gdbm, via tdb */ -static inline unsigned int tdb_hash(const char *name) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) - value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - /** * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module @@ -240,7 +228,7 @@ static struct symbol *alloc_symbol(const char *name) /* For the hash of exported symbols */ static void hash_add_symbol(struct symbol *sym) { - hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name)); + hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name)); } static void sym_add_unresolved(const char *name, struct module *mod, bool weak) @@ -261,7 +249,7 @@ static struct symbol *sym_find_with_module(const char *name, struct module *mod) if (name[0] == '.') name++; - hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) { + hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) { if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) return s; } -- 2.51.0