![Ard Biesheuvel](/assets/img/avatar_default.png)
An ordinary arm64 defconfig build has ~64 KB worth of __ksymtab entries, each consisting of two 64-bit fields containing absolute references, to the symbol itself and to a char array containing its name, respectively. When we build the same configuration with KASLR enabled, we end up with an additional ~192 KB of relocations in the .init section, i.e., one 24 byte entry for each absolute reference, which all need to be processed at boot time. Given how the struct kernel_symbol that describes each entry is completely local to module.c (except for the references emitted by EXPORT_SYMBOL() itself), we can easily modify it to contain two 32-bit relative references instead. This reduces the size of the __ksymtab section by 50% for all 64-bit architectures, and gets rid of the runtime relocations entirely for architectures implementing KASLR, either via standard PIE linking (arm64) or using custom host tools (x86). Note that the binary search involving __ksymtab contents relies on each section being sorted by symbol name. This is implemented based on the input section names, not the names in the ksymtab entries, so this patch does not interfere with that. Given that the use of place-relative relocations requires support both in the toolchain and in the module loader, we cannot enable this feature for all architectures. So make it dependent on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Link: http://lkml.kernel.org/r/20180704083651.24360-4-ard.biesheuvel@linaro.org Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Jessica Yu <jeyu@kernel.org> Acked-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Will Deacon <will.deacon@arm.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: James Morris <james.morris@microsoft.com> Cc: James Morris <jmorris@namei.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: Nicolas Pitre <nico@linaro.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Russell King <linux@armlinux.org.uk> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Garnier <thgarnie@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
94 lines
2.1 KiB
C
94 lines
2.1 KiB
C
#ifndef __ASM_GENERIC_EXPORT_H
|
|
#define __ASM_GENERIC_EXPORT_H
|
|
|
|
#ifndef KSYM_FUNC
|
|
#define KSYM_FUNC(x) x
|
|
#endif
|
|
#ifdef CONFIG_64BIT
|
|
#ifndef KSYM_ALIGN
|
|
#define KSYM_ALIGN 8
|
|
#endif
|
|
#else
|
|
#ifndef KSYM_ALIGN
|
|
#define KSYM_ALIGN 4
|
|
#endif
|
|
#endif
|
|
#ifndef KCRC_ALIGN
|
|
#define KCRC_ALIGN 4
|
|
#endif
|
|
|
|
.macro __put, val, name
|
|
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
|
.long \val - ., \name - .
|
|
#elif defined(CONFIG_64BIT)
|
|
.quad \val, \name
|
|
#else
|
|
.long \val, \name
|
|
#endif
|
|
.endm
|
|
|
|
/*
|
|
* note on .section use: @progbits vs %progbits nastiness doesn't matter,
|
|
* since we immediately emit into those sections anyway.
|
|
*/
|
|
.macro ___EXPORT_SYMBOL name,val,sec
|
|
#ifdef CONFIG_MODULES
|
|
.globl __ksymtab_\name
|
|
.section ___ksymtab\sec+\name,"a"
|
|
.balign KSYM_ALIGN
|
|
__ksymtab_\name:
|
|
__put \val, __kstrtab_\name
|
|
.previous
|
|
.section __ksymtab_strings,"a"
|
|
__kstrtab_\name:
|
|
.asciz "\name"
|
|
.previous
|
|
#ifdef CONFIG_MODVERSIONS
|
|
.section ___kcrctab\sec+\name,"a"
|
|
.balign KCRC_ALIGN
|
|
__kcrctab_\name:
|
|
#if defined(CONFIG_MODULE_REL_CRCS)
|
|
.long __crc_\name - .
|
|
#else
|
|
.long __crc_\name
|
|
#endif
|
|
.weak __crc_\name
|
|
.previous
|
|
#endif
|
|
#endif
|
|
.endm
|
|
#undef __put
|
|
|
|
#if defined(__KSYM_DEPS__)
|
|
|
|
#define __EXPORT_SYMBOL(sym, val, sec) === __KSYM_##sym ===
|
|
|
|
#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
|
|
|
|
#include <linux/kconfig.h>
|
|
#include <generated/autoksyms.h>
|
|
|
|
#define __EXPORT_SYMBOL(sym, val, sec) \
|
|
__cond_export_sym(sym, val, sec, __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
|
|
#endif
|
|
|
|
#define EXPORT_SYMBOL(name) \
|
|
__EXPORT_SYMBOL(name, KSYM_FUNC(name),)
|
|
#define EXPORT_SYMBOL_GPL(name) \
|
|
__EXPORT_SYMBOL(name, KSYM_FUNC(name), _gpl)
|
|
#define EXPORT_DATA_SYMBOL(name) \
|
|
__EXPORT_SYMBOL(name, name,)
|
|
#define EXPORT_DATA_SYMBOL_GPL(name) \
|
|
__EXPORT_SYMBOL(name, name,_gpl)
|
|
|
|
#endif
|