Commit adcc2591 authored by Nicolas Pitre's avatar Nicolas Pitre
Browse files

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
Loading
Loading
Loading
Loading
+17 −10
Original line number Original line Diff line number Diff line
@@ -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
/*
/*
 * 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
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
#endif
#endif


		.ltorg
		.ltorg
reloc_code_end:


		.align
		.align
		.section ".stack", "aw", %nobits
		.section ".stack", "aw", %nobits