On Mon, May 9, 2022 at 4:09 AM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote: > > There were more EXPORT_SYMBOL types in the past. The following commits > removed unused ones. > > - f1c3d73e973c ("module: remove EXPORT_SYMBOL_GPL_FUTURE") > - 367948220fce ("module: remove EXPORT_UNUSED_SYMBOL*") > > There are 3 remaining in enum export, but export_unknown does not make > any sense because we never expect such a situation like "we do not know > how it was exported". > > If the symbol name starts with "__ksymtab_", but the section name > does not start with "___ksymtab+" or "___ksymtab_gpl+", it is not an > exported symbol. > > It occurs when a variable starting with "__ksymtab_" is directly defined: > > int __ksymtab_foo; > > Presumably, there is no practical issue for using such a weird variable > name (but there is no good reason for doing so, either). > > Anyway, that is not an exported symbol. Setting export_unknown is not > the right thing to do. Do not call sym_add_exported() in this case. > > With pointless export_unknown removed, the export type finally becomes > boolean (either EXPORT_SYMBOL or EXPORT_SYMBOL_GPL). > > I renamed the field name to is_gpl_only. EXPORT_SYMBOL_GPL sets it true. > Only GPL-compatible modules can use it. > > I removed the orphan comment, "How a symbol is exported", which is > unrelated to sec_mismatch_count. It is about enum export. > See commit bd5cbcedf446 ("kbuild: export-type enhancement to modpost.c") > > Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx> > Reviewed-by: Nicolas Schier <nicolas@xxxxxxxxx> > Tested-by: Nathan Chancellor <nathan@xxxxxxxxxx> > --- Applied to linux-kbuild. > > Changes in v4: > - Rebase again because I dropped > https://patchwork.kernel.org/project/linux-kbuild/patch/20220501084032.1025918-11-masahiroy@xxxxxxxxxx/ > - Remove warning message because I plan to change this hunk again in a later commit > - Remove orphan comment > > Changes in v3: > - New patch > > scripts/mod/modpost.c | 108 ++++++++++++------------------------------ > 1 file changed, 30 insertions(+), 78 deletions(-) > > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c > index d9efbd5b31a6..a78b75f0eeb0 100644 > --- a/scripts/mod/modpost.c > +++ b/scripts/mod/modpost.c > @@ -30,7 +30,7 @@ static bool all_versions; > static bool external_module; > /* Only warn about unresolved symbols */ > static bool warn_unresolved; > -/* How a symbol is exported */ > + > static int sec_mismatch_count; > static bool sec_mismatch_warn_only = true; > /* ignore missing files */ > @@ -47,12 +47,6 @@ static bool error_occurred; > #define MAX_UNRESOLVED_REPORTS 10 > static unsigned int nr_unresolved; > > -enum export { > - export_plain, > - export_gpl, > - export_unknown > -}; > - > /* In kernel, this size is defined in linux/module.h; > * here we use Elf_Addr instead of long for covering cross-compile > */ > @@ -219,7 +213,7 @@ struct symbol { > bool crc_valid; > bool weak; > bool is_static; /* true if symbol is not global */ > - enum export export; /* Type of export */ > + bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */ > char name[]; > }; > > @@ -316,34 +310,6 @@ static void add_namespace(struct list_head *head, const char *namespace) > } > } > > -static const struct { > - const char *str; > - enum export export; > -} export_list[] = { > - { .str = "EXPORT_SYMBOL", .export = export_plain }, > - { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, > - { .str = "(unknown)", .export = export_unknown }, > -}; > - > - > -static const char *export_str(enum export ex) > -{ > - return export_list[ex].str; > -} > - > -static enum export export_no(const char *s) > -{ > - int i; > - > - if (!s) > - return export_unknown; > - for (i = 0; export_list[i].export != export_unknown; i++) { > - if (strcmp(export_list[i].str, s) == 0) > - return export_list[i].export; > - } > - return export_unknown; > -} > - > static void *sym_get_data_by_offset(const struct elf_info *info, > unsigned int secindex, unsigned long offset) > { > @@ -374,18 +340,6 @@ static const char *sec_name(const struct elf_info *info, int secindex) > > #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) > > -static enum export export_from_secname(struct elf_info *elf, unsigned int sec) > -{ > - const char *secname = sec_name(elf, sec); > - > - if (strstarts(secname, "___ksymtab+")) > - return export_plain; > - else if (strstarts(secname, "___ksymtab_gpl+")) > - return export_gpl; > - else > - return export_unknown; > -} > - > static void sym_update_namespace(const char *symname, const char *namespace) > { > struct symbol *s = find_symbol(symname); > @@ -405,7 +359,7 @@ static void sym_update_namespace(const char *symname, const char *namespace) > } > > static struct symbol *sym_add_exported(const char *name, struct module *mod, > - enum export export) > + bool gpl_only) > { > struct symbol *s = find_symbol(name); > > @@ -417,7 +371,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, > > s = alloc_symbol(name); > s->module = mod; > - s->export = export; > + s->is_gpl_only = gpl_only; > list_add_tail(&s->list, &mod->exported_symbols); > hash_add_symbol(s); > > @@ -689,8 +643,6 @@ static void handle_modversion(const struct module *mod, > static void handle_symbol(struct module *mod, struct elf_info *info, > const Elf_Sym *sym, const char *symname) > { > - const char *name; > - > switch (sym->st_shndx) { > case SHN_COMMON: > if (strstarts(symname, "__gnu_lto_")) { > @@ -724,12 +676,15 @@ static void handle_symbol(struct module *mod, struct elf_info *info, > default: > /* All exported symbols */ > if (strstarts(symname, "__ksymtab_")) { > - enum export export; > + const char *name, *secname; > > name = symname + strlen("__ksymtab_"); > - export = export_from_secname(info, > - get_secindex(info, sym)); > - sym_add_exported(name, mod, export); > + secname = sec_name(info, get_secindex(info, sym)); > + > + if (strstarts(secname, "___ksymtab_gpl+")) > + sym_add_exported(name, mod, true); > + else if (strstarts(secname, "___ksymtab+")) > + sym_add_exported(name, mod, false); > } > if (strcmp(symname, "init_module") == 0) > mod->has_init = true; > @@ -2140,20 +2095,6 @@ void buf_write(struct buffer *buf, const char *s, int len) > buf->pos += len; > } > > -static void check_for_gpl_usage(enum export exp, const char *m, const char *s) > -{ > - switch (exp) { > - case export_gpl: > - error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", > - m, s); > - break; > - case export_plain: > - case export_unknown: > - /* ignore */ > - break; > - } > -} > - > static void check_exports(struct module *mod) > { > struct symbol *s, *exp; > @@ -2192,8 +2133,9 @@ static void check_exports(struct module *mod) > add_namespace(&mod->missing_namespaces, exp->namespace); > } > > - if (!mod->is_gpl_compatible) > - check_for_gpl_usage(exp->export, basename, exp->name); > + if (!mod->is_gpl_compatible && exp->is_gpl_only) > + error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", > + basename, exp->name); > } > } > > @@ -2437,6 +2379,7 @@ static void read_dump(const char *fname) > unsigned int crc; > struct module *mod; > struct symbol *s; > + bool gpl_only; > > if (!(symname = strchr(line, '\t'))) > goto fail; > @@ -2454,12 +2397,22 @@ static void read_dump(const char *fname) > crc = strtoul(line, &d, 16); > if (*symname == '\0' || *modname == '\0' || *d != '\0') > goto fail; > + > + if (!strcmp(export, "EXPORT_SYMBOL_GPL")) { > + gpl_only = true; > + } else if (!strcmp(export, "EXPORT_SYMBOL")) { > + gpl_only = false; > + } else { > + error("%s: unknown license %s. skip", symname, export); > + continue; > + } > + > mod = find_module(modname); > if (!mod) { > mod = new_module(modname); > mod->from_dump = true; > } > - s = sym_add_exported(symname, mod, export_no(export)); > + s = sym_add_exported(symname, mod, gpl_only); > s->is_static = false; > sym_set_crc(symname, crc); > sym_update_namespace(symname, namespace); > @@ -2481,9 +2434,9 @@ static void write_dump(const char *fname) > if (mod->from_dump) > continue; > list_for_each_entry(sym, &mod->exported_symbols, list) { > - buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", > + buf_printf(&buf, "0x%08x\t%s\t%s\tEXPORT_SYMBOL%s\t%s\n", > sym->crc, sym->name, mod->name, > - export_str(sym->export), > + sym->is_gpl_only ? "_GPL" : "", > sym->namespace ?: ""); > } > } > @@ -2604,9 +2557,8 @@ int main(int argc, char **argv) > > for (s = symbolhash[n]; s; s = s->next) { > if (s->is_static) > - error("\"%s\" [%s] is a static %s\n", > - s->name, s->module->name, > - export_str(s->export)); > + error("\"%s\" [%s] is a static EXPORT_SYMBOL\n", > + s->name, s->module->name); > } > } > > -- > 2.32.0 > > -- > You received this message because you are subscribed to the Google Groups "Clang Built Linux" group. > To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-linux+unsubscribe@xxxxxxxxxxxxxxxx. > To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20220508190631.2386038-3-masahiroy%40kernel.org. -- Best Regards Masahiro Yamada