diff options
author | Kunihiko Hayashi <hayashi.kunihiko@socionext.com> | 2021-06-15 15:33:02 +0900 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-06-28 11:21:57 -0400 |
commit | 51d69a7bdde35a49cc133b6fc25c8421634e9a35 (patch) | |
tree | 636a9adf59f77ee2efee50922dd3305012cc5282 | |
parent | f2fd4dad1f87743a82f34cda53cdac2083f34d2a (diff) | |
download | u-boot-WIP/env-test.zip u-boot-WIP/env-test.tar.gz u-boot-WIP/env-test.tar.bz2 |
arm64: Fix relocation of env_addr if POSITION_INDEPENDENT=yWIP/env-test
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>
-rw-r--r-- | arch/arm/lib/crt0_64.S | 5 | ||||
-rw-r--r-- | lib/asm-offsets.c | 2 |
2 files changed, 7 insertions, 0 deletions
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 9d2319c..680e674 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 */ diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index ee592cf..c691066 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; } |