@@ -282,10 +282,12 @@ dtb_check_done:
/*
* Check to see if we will overwrite ourselves.
+ * r0 = delta
* r4 = final kernel address
* r5 = start of this image
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP
+ * r12 = GOT end, fixed up with delta in r0 if relocating
* We basically want:
* r4 - 16k page directory >= r10 -> OK
* r4 + image length <= r5 -> OK
@@ -297,11 +299,20 @@ dtb_check_done:
cmp r10, r5
bls wont_overwrite
+ /*
+ * Check if the relocate address overlaps the running code in
+ * head.S. In that case we need to relocate past the code
+ * to avoid overwriting some of the running code.
+ */
+ add r12, r12, r0 @ fixup GOT end with delta
+ cmp r10, r12 @ relocating less than GOT end?
+ movlt r10, r12 @ if so, relocate to GOT end
+
/*
* Relocate ourselves past the end of the decompressed kernel.
* r5 = start of this image
* r6 = _edata
- * r10 = end of the decompressed kernel
+ * r10 = end of the decompressed kernel or end of GOT end if larger
* Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap.
*/