arm64: kernel: switch to PIE code generation for relocatable kernels
We currently use ordinary, position dependent code generation for the
core kernel, which happens to default to the 'small' code model on both
GCC and Clang. This is the code model that relies on ADRP/ADD or
ADRP/LDR pairs for symbol references, which are PC-relative with a range
of -/+ 4 GiB.
This means that the fact that we can link the relocatable KASLR kernel
using the -pie linker flag is somewhat of a coincidence, and not
something which is explicitly supported by the toolchains.
The reason we have not used -fpie for code generation so far (which is
the compiler flag that should be used to generated code that is to be
linked with -pie) is that by default, it generates code based on
assumptions that only hold for shared libraries and PIE executables,
i.e., that gathering all relocatable quantities into a Global Offset
Table (GOT) is desirable because it reduces the CoW footprint, and
because it permits ELF symbol preemption (which lets an executable
override symbols defined in a shared library, in a way that forces the
shared library to update all of its internal references as well)
Fortunately, we can convince the compiler to handle this in a way that
is a bit more suitable for freestanding binaries such as the kernel, by
setting the 'hidden' visibility #pragma, which informs the compiler that
symbol preemption or CoW footprint are of no concern to us.
So let's enable this #pragma and build with -fpie when building a
relocatable kernel. This also means that all constant data items that
carry statically initialized pointer variables are now emitted into the
.data.rel.ro* sections, so move these into .rodata where they belong.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
3 files changed