| @@ -348,26 +348,38 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) · 347 unmodified lines |
| 348 | return export_unknown; | 348 | return export_unknown; |
| 349 | } | 349 | } |
| 350 | | 350 | |
| 351 | static char *sym_extract_namespace(const char **symname) | 351 | static const char *namespace_from_kstrtabns(struct elf_info *info, |
| | 352 | Elf_Sym *kstrtabns) |
| 352 | { | 353 | { |
| 353 | char *namespace = NULL; | 354 | char *value = info->ksymtab_strings + kstrtabns->st_value; |
| 354 | char *ns_separator; | 355 | return value[0] ? value : NULL; |
| | 356 | } |
| | 357 | |
| | 358 | static void sym_update_namespace(const char *symname, const char *namespace) |
| | 359 | { |
| | 360 | struct symbol *s = find_symbol(symname); |
| 355 | | 361 | |
| 356 | ns_separator = strchr(*symname, '.'); | 362 | /* |
| 357 | if (ns_separator) { | 363 | * That symbol should have been created earlier and thus this is |
| 358 | namespace = NOFAIL(strndup(*symname, ns_separator - *symname)); | 364 | * actually an assertion. |
| 359 | *symname = ns_separator + 1; | 365 | */ |
| | 366 | if (!s) { |
| | 367 | merror("Could not update namespace(%s) for symbol %s\n", |
| | 368 | namespace, symname); |
| | 369 | return; |
| 360 | } | 370 | } |
| 361 | | 371 | |
| 362 | return namespace; | 372 | free(s->namespace); |
| | 373 | s->namespace = |
| | 374 | namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL; |
| 363 | } | 375 | } |
| 364 | | 376 | |
| 365 | /** | 377 | /** |
| 366 | * Add an exported symbol - it may have already been added without a | 378 | * Add an exported symbol - it may have already been added without a |
| 367 | * CRC, in this case just update the CRC | 379 | * CRC, in this case just update the CRC |
| 368 | **/ | 380 | **/ |
| 369 | static struct symbol *sym_add_exported(const char *name, const char *namespace, | 381 | static struct symbol *sym_add_exported(const char *name, struct module *mod, |
| 370 | struct module *mod, enum export export) | 382 | enum export export) |
| 371 | { | 383 | { |
| 372 | struct symbol *s = find_symbol(name); | 384 | struct symbol *s = find_symbol(name); |
| 373 | | 385 | |
| @@ -383,8 +395,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, · 9 unmodified lines |
| 383 | s->module = mod; | 395 | s->module = mod; |
| 384 | } | 396 | } |
| 385 | } | 397 | } |
| 386 | free(s->namespace); | | |
| 387 | s->namespace = namespace ? strdup(namespace) : NULL; | | |
| 388 | s->preloaded = 0; | 398 | s->preloaded = 0; |
| 389 | s->vmlinux = is_vmlinux(mod->name); | 399 | s->vmlinux = is_vmlinux(mod->name); |
| 390 | s->kernel = 0; | 400 | s->kernel = 0; |
| @@ -583,6 +593,10 @@ static int parse_elf(struct elf_info *info, const char *filename) · 192 unmodified lines |
| 583 | info->export_unused_gpl_sec = i; | 593 | info->export_unused_gpl_sec = i; |
| 584 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) | 594 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) |
| 585 | info->export_gpl_future_sec = i; | 595 | info->export_gpl_future_sec = i; |
| | 596 | else if (strcmp(secname, "__ksymtab_strings") == 0) |
| | 597 | info->ksymtab_strings = (void *)hdr + |
| | 598 | sechdrs[i].sh_offset - |
| | 599 | sechdrs[i].sh_addr; |
| 586 | | 600 | |
| 587 | if (sechdrs[i].sh_type == SHT_SYMTAB) { | 601 | if (sechdrs[i].sh_type == SHT_SYMTAB) { |
| 588 | unsigned int sh_link_idx; | 602 | unsigned int sh_link_idx; |
| @@ -672,7 +686,6 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 83 unmodified lines |
| 672 | enum export export; | 686 | enum export export; |
| 673 | bool is_crc = false; | 687 | bool is_crc = false; |
| 674 | const char *name; | 688 | const char *name; |
| 675 | char *namespace; | | |
| 676 | | 689 | |
| 677 | if ((!is_vmlinux(mod->name) || mod->is_dot_o) && | 690 | if ((!is_vmlinux(mod->name) || mod->is_dot_o) && |
| 678 | strstarts(symname, "__ksymtab")) | 691 | strstarts(symname, "__ksymtab")) |
| @@ -745,9 +758,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 66 unmodified lines |
| 745 | /* All exported symbols */ | 758 | /* All exported symbols */ |
| 746 | if (strstarts(symname, "__ksymtab_")) { | 759 | if (strstarts(symname, "__ksymtab_")) { |
| 747 | name = symname + strlen("__ksymtab_"); | 760 | name = symname + strlen("__ksymtab_"); |
| 748 | namespace = sym_extract_namespace(&name); | 761 | sym_add_exported(name, mod, export); |
| 749 | sym_add_exported(name, namespace, mod, export); | | |
| 750 | free(namespace); | | |
| 751 | } | 762 | } |
| 752 | if (strcmp(symname, "init_module") == 0) | 763 | if (strcmp(symname, "init_module") == 0) |
| 753 | mod->has_init = 1; | 764 | mod->has_init = 1; |
| @@ -2043,6 +2054,16 @@ static void read_symbols(const char *modname) · 1289 unmodified lines |
| 2043 | handle_moddevtable(mod, &info, sym, symname); | 2054 | handle_moddevtable(mod, &info, sym, symname); |
| 2044 | } | 2055 | } |
| 2045 | | 2056 | |
| | 2057 | /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */ |
| | 2058 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
| | 2059 | symname = remove_dot(info.strtab + sym->st_name); |
| | 2060 | |
| | 2061 | if (strstarts(symname, "__kstrtabns_")) |
| | 2062 | sym_update_namespace(symname + strlen("__kstrtabns_"), |
| | 2063 | namespace_from_kstrtabns(&info, |
| | 2064 | sym)); |
| | 2065 | } |
| | 2066 | |
| 2046 | // check for static EXPORT_SYMBOL_* functions && global vars | 2067 | // check for static EXPORT_SYMBOL_* functions && global vars |
| 2047 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | 2068 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
| 2048 | unsigned char bind = ELF_ST_BIND(sym->st_info); | 2069 | unsigned char bind = ELF_ST_BIND(sym->st_info); |
| @@ -2196,7 +2217,7 @@ static int check_exports(struct module *mod) · 147 unmodified lines |
| 2196 | else | 2217 | else |
| 2197 | basename = mod->name; | 2218 | basename = mod->name; |
| 2198 | | 2219 | |
| 2199 | if (exp->namespace && exp->namespace[0]) { | 2220 | if (exp->namespace) { |
| 2200 | add_namespace(&mod->required_namespaces, | 2221 | add_namespace(&mod->required_namespaces, |
| 2201 | exp->namespace); | 2222 | exp->namespace); |
| 2202 | | 2223 | |
| @@ -2454,12 +2475,12 @@ static void read_dump(const char *fname, unsigned int kernel) · 251 unmodified lines |
| 2454 | mod = new_module(modname); | 2475 | mod = new_module(modname); |
| 2455 | mod->skip = 1; | 2476 | mod->skip = 1; |
| 2456 | } | 2477 | } |
| 2457 | s = sym_add_exported(symname, namespace, mod, | 2478 | s = sym_add_exported(symname, mod, export_no(export)); |
| 2458 | export_no(export)); | | |
| 2459 | s->kernel = kernel; | 2479 | s->kernel = kernel; |
| 2460 | s->preloaded = 1; | 2480 | s->preloaded = 1; |
| 2461 | s->is_static = 0; | 2481 | s->is_static = 0; |
| 2462 | sym_update_crc(symname, mod, crc, export_no(export)); | 2482 | sym_update_crc(symname, mod, crc, export_no(export)); |
| | 2483 | sym_update_namespace(symname, namespace); |
| 2463 | } | 2484 | } |
| 2464 | release_file(file, size); | 2485 | release_file(file, size); |
| 2465 | return; | 2486 | return; |