mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
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 <masahiroy@kernel.org>
This commit is contained in:
parent
b7bca42d10
commit
f4fdb17ca5
@ -10,6 +10,12 @@
|
||||
* of the GNU General Public License, incorporated herein by reference.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#include "modpost.h"
|
||||
#include "devicetable-offsets.h"
|
||||
|
||||
@ -31,6 +37,58 @@ typedef Elf64_Addr kernel_ulong_t;
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user