diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-07-16 12:25:09 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-07-16 14:44:03 +0200 |
commit | 1cd4bfe5f6a1766893e15199f37a8ec595a3e9a2 (patch) | |
tree | ad31eadcb917f9a4b8b115e45cde51b785bd5921 /arch/arm/include | |
parent | af66ec677c40dfaed68a124d21dd59d5f8c63381 (diff) | |
download | barebox-1cd4bfe5f6a1766893e15199f37a8ec595a3e9a2.tar.gz |
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/arm/include')
-rw-r--r-- | arch/arm/include/asm/barebox-arm.h | 20 |
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); |