Arjan pointed out that CONFIG_TRIM_UNUSED_SYMBOLS *really* doesn't like the dot in the symbols that GCC uses for the thunks. This seems to work, although my eyes are bleeding just a little bit. Given this, and the hack we already needed for MODVERSIONS, I wonder if a better approach might be to export the thunks using underscores in place of the dots, which is a relatively simple abuse of __EXPORT_SYMBOL(__x86_indirect_thunk_foo,__x86.indirect_thunk.foo,), and then have a hack either when generating or loading modules to do the same replacement. diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index ccb117a4588b..64d7a45ea954 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -8,7 +8,13 @@  #include  #include   -.macro THUNK reg +#ifdef CONFIG_TRIM_UNUSED_KSYMS +#define EXPORT_REG(reg) __is_defined(__KSYM___x86_indirect_thunk_ ## reg) +#else +#define EXPORT_REG(reg) 1 +#endif + +.macro THUNK reg export   .section .text.__x86.indirect_thunk.\reg    ENTRY(__x86.indirect_thunk.\reg) @@ -16,15 +22,33 @@ ENTRY(__x86.indirect_thunk.\reg)   NOSPEC_JMP %\reg   CFI_ENDPROC  ENDPROC(__x86.indirect_thunk.\reg) -EXPORT_SYMBOL(__x86.indirect_thunk.\reg) + +.if \export + EXPORT_SYMBOL_FORCE(__x86.indirect_thunk.\reg) +.endif  .endm   -#ifdef CONFIG_64BIT -.irp reg rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15 - THUNK \reg -.endr +#ifdef __KSYM_DEPS__ +#define GENERATE_THUNK(reg) EXPORT_SYMBOL(__x86.indirect_thunk. ## reg)  #else -.irp reg eax ebx ecx edx esi edi ebp - THUNK \reg -.endr +#define GENERATE_THUNK(reg) THUNK reg EXPORT_REG(reg) +#endif + +GENERATE_THUNK(_ASM_AX) +GENERATE_THUNK(_ASM_BX) +GENERATE_THUNK(_ASM_CX) +GENERATE_THUNK(_ASM_DX) +GENERATE_THUNK(_ASM_SI) +GENERATE_THUNK(_ASM_DI) +GENERATE_THUNK(_ASM_BP) +GENERATE_THUNK(_ASM_SP) +#ifdef CONFIG_64BIT +GENERATE_THUNK(r8) +GENERATE_THUNK(r9) +GENERATE_THUNK(r10) +GENERATE_THUNK(r11) +GENERATE_THUNK(r12) +GENERATE_THUNK(r13) +GENERATE_THUNK(r14) +GENERATE_THUNK(r15)  #endif diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..b13bb65e2530 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -63,33 +63,33 @@ KSYM(__kcrctab_\name):    #if defined(__KSYM_DEPS__)   -#define __EXPORT_SYMBOL(sym, val, sec) === __KSYM_##sym === +#define __EXPORT_SYMBOL(sym, val, sec, force) === __KSYM_##sym ===    #elif defined(CONFIG_TRIM_UNUSED_KSYMS)    #include  #include   -#define __EXPORT_SYMBOL(sym, val, sec) \ - __cond_export_sym(sym, val, sec, __is_defined(__KSYM_##sym)) +#define __EXPORT_SYMBOL(sym, val, sec, force) \ +  __cond_export_sym(sym, val, sec, __or(force, __is_defined(__KSYM_##sym)))  #define __cond_export_sym(sym, val, sec, conf) \   ___cond_export_sym(sym, val, sec, conf)  #define ___cond_export_sym(sym, val, sec, enabled) \   __cond_export_sym_##enabled(sym, val, sec)  #define __cond_export_sym_1(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec  #define __cond_export_sym_0(sym, val, sec) /* nothing */ -  #else -#define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec +#define __EXPORT_SYMBOL(sym, val, sec, force) ___EXPORT_SYMBOL sym, val, sec  #endif    #define EXPORT_SYMBOL(name) \ - __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)),) + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), , 0)  #define EXPORT_SYMBOL_GPL(name)  \ - __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), _gpl) + __EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), _gpl, 0)  #define EXPORT_DATA_SYMBOL(name) \ - __EXPORT_SYMBOL(name, KSYM(name),) + __EXPORT_SYMBOL(name, KSYM(name), , 0)  #define EXPORT_DATA_SYMBOL_GPL(name) \ - __EXPORT_SYMBOL(name, KSYM(name),_gpl) - + __EXPORT_SYMBOL(name, KSYM(name), _gpl, 0) +#define EXPORT_SYMBOL_FORCE(name) \ + __EXPORT_SYMBOL(name, KSYM(name), , 1)  #endif diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh index 513da1a4a2da..991cd136291b 100755 --- a/scripts/adjust_autoksyms.sh +++ b/scripts/adjust_autoksyms.sh @@ -60,7 +60,7 @@ cat > "$new_ksyms_file" << EOT    EOT  [ "$(ls -A "$MODVERDIR")" ] && -sed -ns -e '3{s/ /\n/g;/^$/!p;}' "$MODVERDIR"/*.mod | sort -u | +sed -ns -e '3{s/ /\n/g;/^$/!p;}' "$MODVERDIR"/*.mod | sort -u | tr . _ |  while read sym; do   if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then   sym="${sym#_}"