diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-22 12:26:52 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-23 10:06:06 +0200 |
commit | 5f04e5e03e941c8cae4f42f670abba847bfbcf9d (patch) | |
tree | c8fa3fe3d61723bb5a0f7e79d9316c6f669736a1 | |
parent | fab26e665163723dab2b44c57644580f95a80500 (diff) | |
download | barebox-5f04e5e03e941c8cae4f42f670abba847bfbcf9d.tar.gz barebox-5f04e5e03e941c8cae4f42f670abba847bfbcf9d.tar.xz |
ARM: aarch64: Fix get_runtime_offset after relocation
get_runtime_offset shall return the offset between the address we are
running at and the address we are linked at. This value obviously
changes when we relocate the binary. cf3b09737b tried to avoid using
R_AARCH64_RELATIVE relocations, but in fact this is exactly what the
function needs to work. Consider barebox starting at 0x10000000
when we are linked at 0x0 then get_runtime_offset() should return
0x10000000 before relocate_to_current_adr(), but afterwards it should
return 0x0.
This patch brings back the previously removed "a" flag. Since gcc5
doesn't put the values of R_AARCH64_RELATIVE fixup'd relocations
into the binary but zeroes instead, we help ourselves by basing
get_runtime_offset on an address which actually is zero. With
CONFIG_RELOCATABLE=y the binary is always linked to 0x0, so _text
is initially zero.
Tested with gcc-5.4.0 (which was "fixed" by cf3b09737b) and gcc-8.2.1.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
-rw-r--r-- | arch/arm/lib64/runtime-offset.S | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/arch/arm/lib64/runtime-offset.S b/arch/arm/lib64/runtime-offset.S index 6624fdfa15..5e5ab9a8d1 100644 --- a/arch/arm/lib64/runtime-offset.S +++ b/arch/arm/lib64/runtime-offset.S @@ -1,31 +1,25 @@ #include <linux/linkage.h> #include <asm/assembler.h> -/* - * The .section directive below intentionally omits "a", since that - * appears to be the simplest way to force assembler to not generate - * R_AARCH64_RELATIVE relocation for - * - * linkadr: - * .quad get_runtime_offset - * - * statement below. While having that relocating was relatively - * harmless with GCC8, builging the code with GCC5 resulted in - * "linkaddr" being initialized to 0 causing complete boot breakdown - */ -.section ".text_bare_init","x" +.section ".text_bare_init","ax" /* * Get the offset between the link address and the address * we are currently running at. */ ENTRY(get_runtime_offset) -1: adr x0, 1b +1: adr x0, _text ldr x1, linkadr subs x0, x0, x1 ret .align 3 linkadr: -.quad get_runtime_offset +/* + * With older gcc versions (gcc5) function pointers will not be filled + * into the binary during compile time and instead rely on relocation + * during runtime. In the binary we'll always have 0x0 here. We deliberately + * use _text here since that is 0x0 and is correct without relocation. + */ +.quad _text ENDPROC(get_runtime_offset) |