summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-08-22 12:26:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-08-23 10:06:06 +0200
commit5f04e5e03e941c8cae4f42f670abba847bfbcf9d (patch)
treec8fa3fe3d61723bb5a0f7e79d9316c6f669736a1
parentfab26e665163723dab2b44c57644580f95a80500 (diff)
downloadbarebox-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.S24
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)