diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 0f58ceac655d..e4095366fb88 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -428,3 +428,11 @@ extern size_t protected_symbol_exports_count; #define protected_symbol_exports NULL #define protected_symbol_exports_count 0UL #endif + +#ifdef CONFIG_TRIM_UNUSED_KSYMS +extern const char *const permitted_symbol_imports[]; +extern size_t permitted_symbol_imports_count; +#else +#define permitted_symbol_imports NULL +#define permitted_symbol_imports_count 0UL +#endif diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 931e72ab75fb..b1705f3ace45 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -62,6 +62,7 @@ bool target_is_big_endian; bool host_is_big_endian; static unsigned int nr_module_exported_symbols; +static unsigned int nr_white_list_symbols; /* * Cut off the warnings when there are too many. This typically occurs when @@ -1737,18 +1738,29 @@ static void check_exports(struct module *mod) } } -static void handle_white_list_exports(const char *white_list) +struct permitted_symbol { + struct list_head list; + const char *name; +}; + +static void handle_white_list_exports(const char *white_list, + struct list_head *permitted_symbols) { char *buf, *p, *name; - + struct permitted_symbol *ps; buf = read_text_file(white_list); p = buf; while ((name = strsep(&p, "\n"))) { struct symbol *sym = find_symbol(name); - if (sym) + if (sym) { sym->used = true; + ps = xmalloc(sizeof(*ps)); + ps->name = sym->name; + list_add_tail(&ps->list, permitted_symbols); + ++nr_white_list_symbols; + } } free(buf); @@ -2237,6 +2249,31 @@ static void write_protected_exports_c_file(void) free(buf.p); } +static void write_permitted_imports_c_file(struct list_head *permitted_symbols) +{ + struct permitted_symbol *ps, *ps2; + const char *symbols[nr_white_list_symbols]; + unsigned int i = 0; + struct buffer buf = {}; + + list_for_each_entry_safe(ps, ps2, permitted_symbols, list) { + symbols[i++] = ps->name; + list_del(&ps->list); + free(ps); + } + qsort(symbols, nr_white_list_symbols, sizeof(const char *), symbol_cmp); + + buf_printf(&buf, "#include \"../kernel/module/internal.h\"\n\n"); + buf_printf(&buf, "size_t permitted_symbol_imports_count = %d;\n\n", nr_white_list_symbols); + buf_printf(&buf, "const char *const permitted_symbol_imports[] = {\n"); + for (i=0; ifrom_dump)