aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
authorSean Anderson <seanga2@gmail.com>2019-12-17 21:35:32 -0500
committerAndes <uboot@andestech.com>2020-02-10 14:50:53 +0800
commitd9f1cee286c8d039e290f624baeeb133b8d47a21 (patch)
treef277013476e390b4cdf12c0bd8967c70265a3283 /arch/riscv
parente1dff2d69e5a21a61c3eb28e5d230a6d48749b6c (diff)
downloadu-boot-d9f1cee286c8d039e290f624baeeb133b8d47a21.zip
u-boot-d9f1cee286c8d039e290f624baeeb133b8d47a21.tar.gz
u-boot-d9f1cee286c8d039e290f624baeeb133b8d47a21.tar.bz2
riscv: Fix breakage caused by linker relaxation
Due to the two-instruction sequence needed to access arbitrary memory locations, the RISC-V linker aggressively optimises memory accesses and jumps at link-time. This is called "linker relaxation," and is discussed in this SiFive article <https://www.sifive.com/blog/all-aboard-part-3-linker-relaxation-in-riscv-toolchain>. One of the optimizations in place is to assume that the __global_pointer symbol is placed in the gp register. To quote the article: "...The magic __global_pointer$ symbol is defined to point 0x800 bytes past the start of the .sdata section. The 0x800 magic number allows signed 12-bit offsets from __global_pointer$ to address symbols at the start of the .sdata section. The linker assumes that if this symbol is defined, then the gp register contains that value, which it can then use to relax accesses to global symbols within that 12-bit range. The compiler treats the gp register as a constant so it doesn't need to be saved or restored, which means it is generally only written by _start, the ELF entry point." However, U-Boot instead keeps the global data pointer in gp. This causes memory accesses and jumps optimized to use the gp pointer to fail. To fix this problem, we undefine the __global_pointer symbol. Signed-off-by: Sean Anderson <seanga2@gmail.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Rick Chen <rick@andestech.com>
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/cpu/u-boot.lds1
1 files changed, 0 insertions, 1 deletions
diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds
index 838a844..c00d17c 100644
--- a/arch/riscv/cpu/u-boot.lds
+++ b/arch/riscv/cpu/u-boot.lds
@@ -32,7 +32,6 @@ SECTIONS
. = ALIGN(4);
.data : {
- __global_pointer$ = . + 0x800;
*(.data*)
}
. = ALIGN(4);