aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/lib/crt0_64.S
diff options
context:
space:
mode:
authorKunihiko Hayashi2021-06-15 15:33:02 +0900
committerTom Rini2021-06-28 14:47:10 -0400
commit534f0fbd65203871c2b054096422a5d0f3346cb1 (patch)
treec74468b587def18bbddfc217b53fa0de1da1b221 /arch/arm/lib/crt0_64.S
parent2bba78076b03e47967180776a8da74a018186480 (diff)
arm64: Fix relocation of env_addr if POSITION_INDEPENDENT=y
If both POSITION_INDEPENDENT and SYS_RELOC_GD_ENV_ADDR are enabled, wherever original env is placed anywhere, it should be relocated to the right address. Relocation offset gd->reloc_off is calculated with SYS_TEXT_BASE in setup_reloc() and env address gd->env_addr is relocated by the offset in initr_reloc_global_data(). gd->env_addr = (orig env) + gd->reloc_off = (orig env) + (gd->relocaddr - SYS_TEXT_BASE) However, SYS_TEXT_BASE isn't always runtime base address when POSITION_INDEPENDENT is enabled. So the relocated env_addr might point to wrong address. For example, if SYS_TEXT_BASE is zero, gd->env_addr is out of memory location and memory exception will occur. There is a difference between linked address such as SYS_TEXT_BASE and runtime base address. In _main, the difference is calculated as "run-vs-link" offset. The env_addr should also be added to the offset to fix the address. gd->env_addr = (orig env) + ("run-vs-link" offset) + gd->reloc_off = (orig env) + (SYS_TEXT_BASE - _start) + (gd->relocaddr - SYS_TEXT_BASE) = (orig env) + (gd->relocaddr - _start) Cc: Marek Vasut <marex@denx.de> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> Acked-by: Marek Vasut <marex@denx.de> Tested-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'arch/arm/lib/crt0_64.S')
-rw-r--r--arch/arm/lib/crt0_64.S5
1 files changed, 5 insertions, 0 deletions
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 9d2319c0e87..680e674fa33 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -112,6 +112,11 @@ ENTRY(_main)
ldr x9, _TEXT_BASE /* x9 <- Linked value of _start */
sub x9, x9, x0 /* x9 <- Run-vs-link offset */
add lr, lr, x9
+#if defined(CONFIG_SYS_RELOC_GD_ENV_ADDR)
+ ldr x0, [x18, #GD_ENV_ADDR] /* x0 <- gd->env_addr */
+ add x0, x0, x9
+ str x0, [x18, #GD_ENV_ADDR]
+#endif
#endif
/* Add in link-vs-relocation offset */
ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */