diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-03-12 15:37:15 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-03-23 07:43:23 +0100 |
commit | 868df08038a91d674a0c50b0c0a2f70dbc445510 (patch) | |
tree | d21cb4ae48c4a4f0e87b453049a36ed0d4ec414d /arch/arm/cpu/setupc_64.S | |
parent | 6b1f910c31f992cb6fe888ba9d436bad3e95c46d (diff) | |
download | barebox-868df08038a91d674a0c50b0c0a2f70dbc445510.tar.gz barebox-868df08038a91d674a0c50b0c0a2f70dbc445510.tar.xz |
ARM: aarch64: Add relocation support
This adds aarch64 support for relocating binaries linked with -pie.
Support is integrated into the already exisiting
relocate_to_current_adr() function which is now used for both arm32
and aarch64.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/cpu/setupc_64.S')
-rw-r--r-- | arch/arm/cpu/setupc_64.S | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S index 3515854784..61e70850d7 100644 --- a/arch/arm/cpu/setupc_64.S +++ b/arch/arm/cpu/setupc_64.S @@ -16,3 +16,63 @@ ENTRY(setup_c) mov x30, x15 ret ENDPROC(setup_c) + +/* + * void relocate_to_adr(unsigned long targetadr) + * + * Copy binary to targetadr, relocate code and continue + * executing at new address. + */ +.section .text.relocate_to_adr +ENTRY(relocate_to_adr) + /* x0: target address */ + + stp x19, x20, [sp, #-16]! + stp x21, x22, [sp, #-16]! + + mov x19, x30 + + mov x21, x0 + + bl get_runtime_offset + mov x5, x0 + + ldr x0, =_text + mov x20, x0 + + add x1, x0, x5 /* x1: from address */ + + cmp x1, x21 /* already at correct address? */ + beq 1f /* yes, skip copy to new address */ + + ldr x2, =__bss_start + + sub x2, x2, x0 /* x2: size */ + mov x0, x21 /* x0: target */ + + /* adjust return address */ + sub x19, x19, x1 /* sub address where we are actually running */ + add x19, x19, x0 /* add address where we are going to run */ + + bl memcpy /* copy binary */ + +#ifdef CONFIG_MMU + bl arm_early_mmu_cache_flush +#endif + mov x0,#0 + ic ivau, x0 /* flush icache */ + + ldr x0,=1f + sub x0, x0, x20 + add x0, x0, x21 + br x0 /* jump to relocated address */ +1: + bl relocate_to_current_adr /* relocate binary */ + + mov x30, x19 + + ldp x21, x22, [sp], #16 + ldp x19, x20, [sp], #16 + ret + +ENDPROC(relocate_to_adr) |