summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-07-16 12:25:09 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-07-16 14:44:03 +0200
commit1cd4bfe5f6a1766893e15199f37a8ec595a3e9a2 (patch)
treead31eadcb917f9a4b8b115e45cde51b785bd5921 /arch
parentaf66ec677c40dfaed68a124d21dd59d5f8c63381 (diff)
downloadbarebox-1cd4bfe5f6a1766893e15199f37a8ec595a3e9a2.tar.gz
barebox-1cd4bfe5f6a1766893e15199f37a8ec595a3e9a2.tar.xz
ARM: Fix global_variable_offset() for aarch64
Not all toolchains use pc relative addresses for global variables. Apparently the gcc 8.3.0 YOCTO toolchain uses absolute addresses. This means can't simply return 0 for global_variable_offset() but instead have to calculate the offset between the compile addresses for global variables and their runtime address. We do this by getting the address of a global variable pc relative explicitely in assembly and substracting that address from the location the C compiler thinks they are. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/barebox-arm.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index 9840482b23..8b2ecd9ab2 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -31,6 +31,7 @@
#include <linux/types.h>
#include <linux/compiler.h>
#include <asm/barebox-arm-head.h>
+#include <asm/sections.h>
/*
* We have a 4GiB address space split into 1MiB sections, with each
@@ -43,15 +44,22 @@ unsigned long get_runtime_offset(void);
/* global_variable_offset() - Access global variables when not running at link address
*
* Get the offset of global variables when not running at the address we are
- * linked at. ARM uses absolute addresses, so we must add the runtime offset
- * whereas aarch64 uses PC relative addresses, so nothing must be done here.
+ * linked at.
*/
static inline unsigned long global_variable_offset(void)
{
- if (IS_ENABLED(CONFIG_CPU_32))
- return get_runtime_offset();
- else
- return 0;
+#ifdef CONFIG_CPU_V8
+ unsigned long text;
+
+ __asm__ __volatile__(
+ "adr %0, _text\n"
+ : "=r" (text)
+ :
+ : "memory");
+ return text - (unsigned long)_text;
+#else
+ return get_runtime_offset();
+#endif
}
void setup_c(void);