Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

module: use kflagstab instead of *_gpl sections

Read kflagstab section for vmlinux and modules to determine whether
kernel symbols are GPL only.

This patch eliminates the need for fragmenting the ksymtab for infering
the value of GPL-only symbol flag, henceforth stop populating *_gpl
versions of the ksymtab and kcrctab in modpost.

Signed-off-by: Siddharth Nayyar <sidnayyar@google.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>

authored by

Siddharth Nayyar and committed by
Sami Tolvanen
55fcb926 16d0e04f

+46 -40
+11 -10
include/linux/export-internal.h
··· 37 37 * section flag requires it. Use '%progbits' instead of '@progbits' since the 38 38 * former apparently works on all arches according to the binutils source. 39 39 */ 40 - #define __KSYMTAB(name, sym, sec, ns) \ 40 + #define __KSYMTAB(name, sym, ns) \ 41 41 asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1" "\n" \ 42 42 "__kstrtab_" #name ":" "\n" \ 43 43 " .asciz \"" #name "\"" "\n" \ 44 44 "__kstrtabns_" #name ":" "\n" \ 45 45 " .asciz \"" ns "\"" "\n" \ 46 46 " .previous" "\n" \ 47 - " .section \"___ksymtab" sec "+" #name "\", \"a\"" "\n" \ 47 + " .section \"___ksymtab+" #name "\", \"a\"" "\n" \ 48 48 __KSYM_ALIGN "\n" \ 49 49 "__ksymtab_" #name ":" "\n" \ 50 50 __KSYM_REF(sym) "\n" \ ··· 59 59 #define KSYM_FUNC(name) name 60 60 #endif 61 61 62 - #define KSYMTAB_FUNC(name, sec, ns) __KSYMTAB(name, KSYM_FUNC(name), sec, ns) 63 - #define KSYMTAB_DATA(name, sec, ns) __KSYMTAB(name, name, sec, ns) 62 + #define KSYMTAB_FUNC(name, ns) __KSYMTAB(name, KSYM_FUNC(name), ns) 63 + #define KSYMTAB_DATA(name, ns) __KSYMTAB(name, name, ns) 64 64 65 - #define SYMBOL_CRC(sym, crc, sec) \ 66 - asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ 67 - ".balign 4" "\n" \ 68 - "__crc_" #sym ":" "\n" \ 69 - ".long " #crc "\n" \ 70 - ".previous" "\n") 65 + #define SYMBOL_CRC(sym, crc) \ 66 + asm(" .section \"___kcrctab+" #sym "\",\"a\"" "\n" \ 67 + " .balign 4" "\n" \ 68 + "__crc_" #sym ":" "\n" \ 69 + " .long " #crc "\n" \ 70 + " .previous" "\n" \ 71 + ) 71 72 72 73 #define SYMBOL_FLAGS(sym, flags) \ 73 74 asm(" .section \"___kflagstab+" #sym "\",\"a\"" "\n" \
+1
include/linux/module.h
··· 419 419 /* Exported symbols */ 420 420 const struct kernel_symbol *syms; 421 421 const u32 *crcs; 422 + const u8 *flagstab; 422 423 unsigned int num_syms; 423 424 424 425 #ifdef CONFIG_ARCH_USES_CFI_TRAPS
+1
kernel/module/internal.h
··· 57 57 extern const struct kernel_symbol __stop___ksymtab_gpl[]; 58 58 extern const u32 __start___kcrctab[]; 59 59 extern const u32 __start___kcrctab_gpl[]; 60 + extern const u8 __start___kflagstab[]; 60 61 61 62 #define KMOD_PATH_LEN 256 62 63 extern char modprobe_path[];
+29 -26
kernel/module/main.c
··· 11 11 #include <linux/extable.h> 12 12 #include <linux/moduleloader.h> 13 13 #include <linux/module_signature.h> 14 + #include <linux/module_symbol.h> 14 15 #include <linux/trace_events.h> 15 16 #include <linux/init.h> 16 17 #include <linux/kallsyms.h> ··· 88 87 struct symsearch { 89 88 const struct kernel_symbol *start, *stop; 90 89 const u32 *crcs; 91 - enum mod_license license; 90 + const u8 *flagstab; 92 91 }; 93 92 94 93 /* ··· 365 364 struct find_symbol_arg *fsa) 366 365 { 367 366 struct kernel_symbol *sym; 368 - 369 - if (!fsa->gplok && syms->license == GPL_ONLY) 370 - return false; 367 + u8 sym_flags; 371 368 372 369 sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, 373 370 sizeof(struct kernel_symbol), cmp_name); 374 371 if (!sym) 375 372 return false; 376 373 374 + sym_flags = *(syms->flagstab + (sym - syms->start)); 375 + if (!fsa->gplok && (sym_flags & KSYM_FLAG_GPL_ONLY)) 376 + return false; 377 + 377 378 fsa->owner = owner; 378 379 fsa->crc = symversion(syms->crcs, sym - syms->start); 379 380 fsa->sym = sym; 380 - fsa->license = syms->license; 381 + fsa->license = (sym_flags & KSYM_FLAG_GPL_ONLY) ? GPL_ONLY : NOT_GPL_ONLY; 381 382 382 383 return true; 383 384 } ··· 390 387 */ 391 388 bool find_symbol(struct find_symbol_arg *fsa) 392 389 { 393 - static const struct symsearch arr[] = { 394 - { __start___ksymtab, __stop___ksymtab, __start___kcrctab, 395 - NOT_GPL_ONLY }, 396 - { __start___ksymtab_gpl, __stop___ksymtab_gpl, 397 - __start___kcrctab_gpl, 398 - GPL_ONLY }, 390 + const struct symsearch syms = { 391 + .start = __start___ksymtab, 392 + .stop = __stop___ksymtab, 393 + .crcs = __start___kcrctab, 394 + .flagstab = __start___kflagstab, 399 395 }; 400 396 struct module *mod; 401 - unsigned int i; 402 397 403 - for (i = 0; i < ARRAY_SIZE(arr); i++) 404 - if (find_exported_symbol_in_section(&arr[i], NULL, fsa)) 405 - return true; 398 + if (find_exported_symbol_in_section(&syms, NULL, fsa)) 399 + return true; 406 400 407 401 list_for_each_entry_rcu(mod, &modules, list, 408 402 lockdep_is_held(&module_mutex)) { 409 - struct symsearch arr[] = { 410 - { mod->syms, mod->syms + mod->num_syms, mod->crcs, 411 - NOT_GPL_ONLY }, 412 - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, 413 - mod->gpl_crcs, 414 - GPL_ONLY }, 403 + const struct symsearch syms = { 404 + .start = mod->syms, 405 + .stop = mod->syms + mod->num_syms, 406 + .crcs = mod->crcs, 407 + .flagstab = mod->flagstab, 415 408 }; 416 409 417 410 if (mod->state == MODULE_STATE_UNFORMED) 418 411 continue; 419 412 420 - for (i = 0; i < ARRAY_SIZE(arr); i++) 421 - if (find_exported_symbol_in_section(&arr[i], mod, fsa)) 422 - return true; 413 + if (find_exported_symbol_in_section(&syms, mod, fsa)) 414 + return true; 423 415 } 424 416 425 417 pr_debug("Failed to find symbol %s\n", fsa->name); ··· 2679 2681 sizeof(*mod->gpl_syms), 2680 2682 &mod->num_gpl_syms); 2681 2683 mod->gpl_crcs = section_addr(info, "__kcrctab_gpl"); 2684 + mod->flagstab = section_addr(info, "__kflagstab"); 2682 2685 2683 2686 #ifdef CONFIG_CONSTRUCTORS 2684 2687 mod->ctors = section_objs(info, ".ctors", ··· 2883 2884 return ret; 2884 2885 } 2885 2886 2886 - static int check_export_symbol_versions(struct module *mod) 2887 + static int check_export_symbol_sections(struct module *mod) 2887 2888 { 2889 + if (mod->num_syms && !mod->flagstab) { 2890 + pr_err("%s: no flags for exported symbols\n", mod->name); 2891 + return -ENOEXEC; 2892 + } 2888 2893 #ifdef CONFIG_MODVERSIONS 2889 2894 if ((mod->num_syms && !mod->crcs) || 2890 2895 (mod->num_gpl_syms && !mod->gpl_crcs)) { ··· 3504 3501 if (err) 3505 3502 goto free_unload; 3506 3503 3507 - err = check_export_symbol_versions(mod); 3504 + err = check_export_symbol_sections(mod); 3508 3505 if (err) 3509 3506 goto free_unload; 3510 3507
+4 -4
scripts/mod/modpost.c
··· 1876 1876 if (trim_unused_exports && !sym->used) 1877 1877 continue; 1878 1878 1879 - buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n", 1879 + buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n", 1880 1880 sym->is_func ? "FUNC" : "DATA", sym->name, 1881 - sym->is_gpl_only ? "_gpl" : "", sym->namespace); 1881 + sym->namespace); 1882 1882 1883 1883 buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n", 1884 1884 sym->name, get_symbol_flags(sym)); ··· 1899 1899 sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", 1900 1900 sym->name); 1901 1901 1902 - buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", 1903 - sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); 1902 + buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n", 1903 + sym->name, sym->crc); 1904 1904 } 1905 1905 } 1906 1906