aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/lib
diff options
context:
space:
mode:
authorAndre Przywara2022-07-12 12:00:23 +0100
committerTom Rini2022-07-26 17:53:43 -0400
commit81e712a91729950fbd8fb38a6f729cb9847b0adb (patch)
tree67de40c2967cd1deeb99a396a6ea371448ad76a9 /arch/arm/lib
parent86feeab3dc71977afb70f595e42060ce324086d0 (diff)
ARM: relocate: Fix Thumb code by using proper label type
The generic ARM relocate_code function was using its own function entry point as a relocation base, and it was obtaining that address by using the "adr" instruction on that entry point label. However that label is not just an ordinary label, instead we explicitly mark it as a function start address. Normally that doesn't change much (other than for debugging), but when assembled in Thumb mode, newer versions of the GNU assembler prepare everything for this address being used as the argument to a "bx" call, so make sure bit 0 is set in there to mark this function as Thumb code. Of course this doesn't end up very well when we use this address for the ensuing memcpy operation. To avoid this problem, and to solve it in a robust way, add an extra label, which is not marked as a function entry, and use that for the adr instruction. This lets all assemblers generate the right immediate offset in the "adr" instruction. This fixes in particular ARMv7-M ports when using GNU binutils v2.37 or newer (commit d3e52e120b68 seems to trigger the change in behaviour). Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reported-by: Jesse Taube <mr.bossman075@gmail.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/relocate.S3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
index 14b7f61c1a4..5102bfabde4 100644
--- a/arch/arm/lib/relocate.S
+++ b/arch/arm/lib/relocate.S
@@ -78,7 +78,8 @@ ENDPROC(relocate_vectors)
*/
ENTRY(relocate_code)
- adr r3, relocate_code
+relocate_base:
+ adr r3, relocate_base
ldr r1, _image_copy_start_ofs
add r1, r3 /* r1 <- Run &__image_copy_start */
subs r4, r0, r1 /* r4 <- Run to copy offset */