aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/image.h
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2015-12-26 07:48:02 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2016-02-24 09:57:25 -0500
commit6ad1fe5d9077a1ab40bf74b61994d2e770b00b14 (patch)
tree88cfed6d43d89bb5e21c7e8ea9c32e54baa88fac /arch/arm64/kernel/image.h
parentfd045f6cd98ec4953147b318418bd45e441e52a3 (diff)
arm64: avoid R_AARCH64_ABS64 relocations for Image header fields
Unfortunately, the current way of using the linker to emit build time constants into the Image header will no longer work once we switch to the use of PIE executables. The reason is that such constants are emitted into the binary using R_AARCH64_ABS64 relocations, which are resolved at runtime, not at build time, and the places targeted by those relocations will contain zeroes before that. So refactor the endian swapping linker script constant generation code so that it emits the upper and lower 32-bit words separately. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/image.h')
-rw-r--r--arch/arm64/kernel/image.h32
1 files changed, 19 insertions, 13 deletions
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index c9c62cab25a4..db1bf57948f1 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -26,21 +26,27 @@
26 * There aren't any ELF relocations we can use to endian-swap values known only 26 * There aren't any ELF relocations we can use to endian-swap values known only
27 * at link time (e.g. the subtraction of two symbol addresses), so we must get 27 * at link time (e.g. the subtraction of two symbol addresses), so we must get
28 * the linker to endian-swap certain values before emitting them. 28 * the linker to endian-swap certain values before emitting them.
29 *
30 * Note that, in order for this to work when building the ELF64 PIE executable
31 * (for KASLR), these values should not be referenced via R_AARCH64_ABS64
32 * relocations, since these are fixed up at runtime rather than at build time
33 * when PIE is in effect. So we need to split them up in 32-bit high and low
34 * words.
29 */ 35 */
30#ifdef CONFIG_CPU_BIG_ENDIAN 36#ifdef CONFIG_CPU_BIG_ENDIAN
31#define DATA_LE64(data) \ 37#define DATA_LE32(data) \
32 ((((data) & 0x00000000000000ff) << 56) | \ 38 ((((data) & 0x000000ff) << 24) | \
33 (((data) & 0x000000000000ff00) << 40) | \ 39 (((data) & 0x0000ff00) << 8) | \
34 (((data) & 0x0000000000ff0000) << 24) | \ 40 (((data) & 0x00ff0000) >> 8) | \
35 (((data) & 0x00000000ff000000) << 8) | \ 41 (((data) & 0xff000000) >> 24))
36 (((data) & 0x000000ff00000000) >> 8) | \
37 (((data) & 0x0000ff0000000000) >> 24) | \
38 (((data) & 0x00ff000000000000) >> 40) | \
39 (((data) & 0xff00000000000000) >> 56))
40#else 42#else
41#define DATA_LE64(data) ((data) & 0xffffffffffffffff) 43#define DATA_LE32(data) ((data) & 0xffffffff)
42#endif 44#endif
43 45
46#define DEFINE_IMAGE_LE64(sym, data) \
47 sym##_lo32 = DATA_LE32((data) & 0xffffffff); \
48 sym##_hi32 = DATA_LE32((data) >> 32)
49
44#ifdef CONFIG_CPU_BIG_ENDIAN 50#ifdef CONFIG_CPU_BIG_ENDIAN
45#define __HEAD_FLAG_BE 1 51#define __HEAD_FLAG_BE 1
46#else 52#else
@@ -61,9 +67,9 @@
61 * endian swapped in head.S, all are done here for consistency. 67 * endian swapped in head.S, all are done here for consistency.
62 */ 68 */
63#define HEAD_SYMBOLS \ 69#define HEAD_SYMBOLS \
64 _kernel_size_le = DATA_LE64(_end - _text); \ 70 DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text); \
65 _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \ 71 DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \
66 _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); 72 DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
67 73
68#ifdef CONFIG_EFI 74#ifdef CONFIG_EFI
69 75