summaryrefslogtreecommitdiff
path: root/lib/asm-offsets.c
diff options
context:
space:
mode:
authorKunihiko Hayashi <hayashi.kunihiko@socionext.com>2021-06-15 09:33:02 +0300
committerTom Rini <trini@konsulko.com>2021-06-28 21:47:10 +0300
commit534f0fbd65203871c2b054096422a5d0f3346cb1 (patch)
treec74468b587def18bbddfc217b53fa0de1da1b221 /lib/asm-offsets.c
parent2bba78076b03e47967180776a8da74a018186480 (diff)
downloadu-boot-534f0fbd65203871c2b054096422a5d0f3346cb1.tar.xz
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 'lib/asm-offsets.c')
-rw-r--r--lib/asm-offsets.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index ee592cfda1..c691066332 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -41,5 +41,7 @@ int main(void)
DEFINE(GD_NEW_GD, offsetof(struct global_data, new_gd));
+ DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
+
return 0;
}