Skip to content

Commit f4fdb17

Browse files
committed
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 <[email protected]>
1 parent b7bca42 commit f4fdb17

File tree

3 files changed

+93
-28
lines changed

3 files changed

+93
-28
lines changed

scripts/mod/file2alias.c

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
* of the GNU General Public License, incorporated herein by reference.
1111
*/
1212

13+
#include <stdarg.h>
14+
#include <stdio.h>
15+
16+
#include "list.h"
17+
#include "xalloc.h"
18+
1319
#include "modpost.h"
1420
#include "devicetable-offsets.h"
1521

@@ -31,6 +37,58 @@ typedef Elf64_Addr kernel_ulong_t;
3137
#include <ctype.h>
3238
#include <stdbool.h>
3339

40+
/**
41+
* module_alias_printf - add auto-generated MODULE_ALIAS()
42+
*
43+
* @mod: module
44+
* @append_wildcard: append '*' for future extension if not exist yet
45+
* @fmt: printf(3)-like format
46+
*/
47+
static void __attribute__((format (printf, 3, 4)))
48+
module_alias_printf(struct module *mod, bool append_wildcard,
49+
const char *fmt, ...)
50+
{
51+
struct module_alias *new;
52+
size_t len;
53+
int n;
54+
va_list ap;
55+
56+
/* Determine required size. */
57+
va_start(ap, fmt);
58+
n = vsnprintf(NULL, 0, fmt, ap);
59+
va_end(ap);
60+
61+
if (n < 0) {
62+
error("vsnprintf failed\n");
63+
return;
64+
}
65+
66+
len = n + 1; /* extra byte for '\0' */
67+
68+
if (append_wildcard)
69+
len++; /* extra byte for '*' */
70+
71+
new = xmalloc(sizeof(*new) + len);
72+
73+
/* Now, really print it to the allocated buffer */
74+
va_start(ap, fmt);
75+
n = vsnprintf(new->str, len, fmt, ap);
76+
va_end(ap);
77+
78+
if (n < 0) {
79+
error("vsnprintf failed\n");
80+
free(new);
81+
return;
82+
}
83+
84+
if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) {
85+
new->str[n] = '*';
86+
new->str[n + 1] = '\0';
87+
}
88+
89+
list_add_tail(&new->node, &mod->aliases);
90+
}
91+
3492
typedef uint32_t __u32;
3593
typedef uint16_t __u16;
3694
typedef unsigned char __u8;
@@ -229,9 +287,7 @@ static void do_usb_entry(void *symval,
229287
ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
230288
bInterfaceNumber);
231289

232-
add_wildcard(alias);
233-
buf_printf(&mod->dev_table_buf,
234-
"MODULE_ALIAS(\"%s\");\n", alias);
290+
module_alias_printf(mod, true, "%s", alias);
235291
}
236292

237293
/* Handles increment/decrement of BCD formatted integers */
@@ -375,10 +431,8 @@ static void do_of_entry_multi(void *symval, struct module *mod)
375431
if (isspace(*tmp))
376432
*tmp = '_';
377433

378-
buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
379-
strcat(alias, "C");
380-
add_wildcard(alias);
381-
buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
434+
module_alias_printf(mod, false, "%s", alias);
435+
module_alias_printf(mod, false, "%sC*", alias);
382436
}
383437

384438
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,
608662
char acpi_id[sizeof(*id)];
609663
int j;
610664

611-
buf_printf(&mod->dev_table_buf,
612-
"MODULE_ALIAS(\"pnp:d%s*\");\n", *id);
665+
module_alias_printf(mod, false, "pnp:d%s*", *id);
613666

614667
/* fix broken pnp bus lowercasing */
615668
for (j = 0; j < sizeof(acpi_id); j++)
616669
acpi_id[j] = toupper((*id)[j]);
617-
buf_printf(&mod->dev_table_buf,
618-
"MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
670+
module_alias_printf(mod, false, "acpi*:%s:*", acpi_id);
619671
}
620672
}
621673

@@ -666,14 +718,12 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
666718
char acpi_id[PNP_ID_LEN];
667719
int k;
668720

669-
buf_printf(&mod->dev_table_buf,
670-
"MODULE_ALIAS(\"pnp:d%s*\");\n", id);
721+
module_alias_printf(mod, false, "pnp:d%s*", id);
671722

672723
/* fix broken pnp bus lowercasing */
673724
for (k = 0; k < sizeof(acpi_id); k++)
674725
acpi_id[k] = toupper(id[k]);
675-
buf_printf(&mod->dev_table_buf,
676-
"MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
726+
module_alias_printf(mod, false, "acpi*:%s:*", acpi_id);
677727
}
678728
}
679729
}
@@ -1534,8 +1584,7 @@ static void do_table(void *symval, unsigned long size,
15341584

15351585
for (i = 0; i < size; i += id_size) {
15361586
if (do_entry(mod->name, symval+i, alias)) {
1537-
buf_printf(&mod->dev_table_buf,
1538-
"MODULE_ALIAS(\"%s\");\n", alias);
1587+
module_alias_printf(mod, false, "%s", alias);
15391588
}
15401589
}
15411590
}
@@ -1660,11 +1709,3 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
16601709
}
16611710
free(zeros);
16621711
}
1663-
1664-
/* Now add out buffered information to the generated C source */
1665-
void add_moddevtable(struct buffer *buf, struct module *mod)
1666-
{
1667-
buf_printf(buf, "\n");
1668-
buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
1669-
free(mod->dev_table_buf.p);
1670-
}

scripts/mod/modpost.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ static struct module *new_module(const char *name, size_t namelen)
176176
INIT_LIST_HEAD(&mod->unresolved_symbols);
177177
INIT_LIST_HEAD(&mod->missing_namespaces);
178178
INIT_LIST_HEAD(&mod->imported_namespaces);
179+
INIT_LIST_HEAD(&mod->aliases);
179180

180181
memcpy(mod->name, name, namelen);
181182
mod->name[namelen] = '\0';
@@ -1966,14 +1967,22 @@ static void write_vmlinux_export_c_file(struct module *mod)
19661967
static void write_mod_c_file(struct module *mod)
19671968
{
19681969
struct buffer buf = { };
1970+
struct module_alias *alias, *next;
19691971
char fname[PATH_MAX];
19701972
int ret;
19711973

19721974
add_header(&buf, mod);
19731975
add_exported_symbols(&buf, mod);
19741976
add_versions(&buf, mod);
19751977
add_depends(&buf, mod);
1976-
add_moddevtable(&buf, mod);
1978+
1979+
buf_printf(&buf, "\n");
1980+
list_for_each_entry_safe(alias, next, &mod->aliases, node) {
1981+
buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str);
1982+
list_del(&alias->node);
1983+
free(alias);
1984+
}
1985+
19771986
add_srcversion(&buf, mod);
19781987

19791988
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);

scripts/mod/modpost.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...);
7979
void
8080
buf_write(struct buffer *buf, const char *s, int len);
8181

82+
/**
83+
* struct module_alias - auto-generated MODULE_ALIAS()
84+
*
85+
* @node: linked to module::aliases
86+
* @str: a string for MODULE_ALIAS()
87+
*/
88+
struct module_alias {
89+
struct list_head node;
90+
char str[];
91+
};
92+
93+
/**
94+
* struct module - represent a module (vmlinux or *.ko)
95+
*
96+
* @aliases: list head for module_aliases
97+
*/
8298
struct module {
8399
struct list_head list;
84100
struct list_head exported_symbols;
@@ -89,12 +105,12 @@ struct module {
89105
bool seen;
90106
bool has_init;
91107
bool has_cleanup;
92-
struct buffer dev_table_buf;
93108
char srcversion[25];
94109
// Missing namespace dependencies
95110
struct list_head missing_namespaces;
96111
// Actual imported namespaces
97112
struct list_head imported_namespaces;
113+
struct list_head aliases;
98114
char name[];
99115
};
100116

@@ -170,7 +186,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr,
170186
/* file2alias.c */
171187
void handle_moddevtable(struct module *mod, struct elf_info *info,
172188
Elf_Sym *sym, const char *symname);
173-
void add_moddevtable(struct buffer *buf, struct module *mod);
174189

175190
/* sumversion.c */
176191
void get_src_version(const char *modname, char sum[], unsigned sumlen);

0 commit comments

Comments
 (0)