Commit adcc2591 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Nicolas Pitre

ARM: zImage: make sure not to relocate on top of the relocation code

If the zImage load address is slightly below the relocation address,
there is a risk for the copied data to overwrite the copy loop or
cache flush code that the relocation process requires.  Always
bump the relocation address by the size of that code to avoid this
issue.

Noticed by Tony Lindgren <tony@atomide.com>.

While at it, let's start the copy from the restart symbol which makes
the above code size computation possible by the assembler directly
(same sections), given that we don't need to preserve the code before
that point anyway. And therefore we don't need to carry the _start
pointer in r5 anymore.
Signed-off-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
Tested-by: default avatarTony Lindgren <tony@atomide.com>
parent 7c2527f0
...@@ -187,15 +187,14 @@ not_angel: ...@@ -187,15 +187,14 @@ not_angel:
bl cache_on bl cache_on
restart: adr r0, LC0 restart: adr r0, LC0
ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} ldmia r0, {r1, r2, r3, r6, r9, r11, r12}
ldr sp, [r0, #32] ldr sp, [r0, #28]
/* /*
* We might be running at a different address. We need * We might be running at a different address. We need
* to fix up various pointers. * to fix up various pointers.
*/ */
sub r0, r0, r1 @ calculate the delta offset sub r0, r0, r1 @ calculate the delta offset
add r5, r5, r0 @ _start
add r6, r6, r0 @ _edata add r6, r6, r0 @ _edata
#ifndef CONFIG_ZBOOT_ROM #ifndef CONFIG_ZBOOT_ROM
...@@ -214,31 +213,39 @@ restart: adr r0, LC0 ...@@ -214,31 +213,39 @@ restart: adr r0, LC0
/* /*
* Check to see if we will overwrite ourselves. * Check to see if we will overwrite ourselves.
* r4 = final kernel address * r4 = final kernel address
* r5 = start of this image
* r9 = size of decompressed image * r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP * r10 = end of this image, including bss/stack/malloc space if non XIP
* We basically want: * We basically want:
* r4 >= r10 -> OK * r4 >= r10 -> OK
* r4 + image length <= r5 -> OK * r4 + image length <= current position (pc) -> OK
*/ */
cmp r4, r10 cmp r4, r10
bhs wont_overwrite bhs wont_overwrite
add r10, r4, r9 add r10, r4, r9
cmp r10, r5 ARM( cmp r10, pc )
THUMB( mov lr, pc )
THUMB( cmp r10, lr )
bls wont_overwrite bls wont_overwrite
/* /*
* Relocate ourselves past the end of the decompressed kernel. * Relocate ourselves past the end of the decompressed kernel.
* r5 = start of this image
* r6 = _edata * r6 = _edata
* r10 = end of the decompressed kernel * r10 = end of the decompressed kernel
* Because we always copy ahead, we need to do it from the end and go * Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap. * backward in case the source and destination overlap.
*/ */
/* Round up to next 256-byte boundary. */ /*
add r10, r10, #256 * Bump to the next 256-byte boundary with the size of
* the relocation code added. This avoids overwriting
* ourself when the offset is small.
*/
add r10, r10, #((reloc_code_end - restart + 256) & ~255)
bic r10, r10, #255 bic r10, r10, #255
/* Get start of code we want to copy and align it down. */
adr r5, restart
bic r5, r5, #31
sub r9, r6, r5 @ size to copy sub r9, r6, r5 @ size to copy
add r9, r9, #31 @ rounded up to a multiple add r9, r9, #31 @ rounded up to a multiple
bic r9, r9, #31 @ ... of 32 bytes bic r9, r9, #31 @ ... of 32 bytes
...@@ -346,7 +353,6 @@ not_relocated: mov r0, #0 ...@@ -346,7 +353,6 @@ not_relocated: mov r0, #0
LC0: .word LC0 @ r1 LC0: .word LC0 @ r1
.word __bss_start @ r2 .word __bss_start @ r2
.word _end @ r3 .word _end @ r3
.word _start @ r5
.word _edata @ r6 .word _edata @ r6
.word _image_size @ r9 .word _image_size @ r9
.word _got_start @ r11 .word _got_start @ r11
...@@ -1075,6 +1081,7 @@ memdump: mov r12, r0 ...@@ -1075,6 +1081,7 @@ memdump: mov r12, r0
#endif #endif
.ltorg .ltorg
reloc_code_end:
.align .align
.section ".stack", "aw", %nobits .section ".stack", "aw", %nobits
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment