From 2b7ad332cd36c3ca79b5d44e3dea3e871aa8282a Mon Sep 17 00:00:00 2001 From: pkujhd Date: Wed, 8 Mar 2023 13:57:58 +0800 Subject: [PATCH] arm64 replace call code use X17 register instead of X9 --- asm_bytes.go | 13 +++++++++---- relocate.go | 8 ++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/asm_bytes.go b/asm_bytes.go index 9d0eac36..90be4a5c 100644 --- a/asm_bytes.go +++ b/asm_bytes.go @@ -8,10 +8,15 @@ const ( // arm/arm64 var ( - armcode = []byte{0x04, 0xF0, 0x1F, 0xE5} //LDR PC, [PC, #-4] - arm64code = []byte{ - 0x49, 0x00, 0x00, 0x58, // LDR X9 [PC+8] - 0x20, 0x01, 0x1F, 0xD6} // BR X9 + armReplaceCallCode = []byte{0x04, 0xF0, 0x1F, 0xE5} //LDR PC, [PC, #-4] + // X16 and X17 are the IP0 and IP1 intra-procedure-call corruptible registers - + // since Go only uses them for the stack prologue and epilogue calculations, + // and we should already be clear of that by the time we hit a R_CALLARM64, + // so we should be able to safely use them for far jumps + armReplace64CALLCode = []byte{ + 0x51, 0x00, 0x00, 0x58, // LDR X17 [PC+8] - read 64 bit address from PC+8 into X17 + 0x20, 0x02, 0x1f, 0xd6, // BR X17 - jump to address in X17 + } arm64Bcode = []byte{0x00, 0x00, 0x00, 0x14} // B [PC+0x0] arm64LDRcode = []byte{0x00, 0x00, 0x40, 0xF9} // LDR XX [XX] ) diff --git a/relocate.go b/relocate.go index fe83a9eb..715566d4 100644 --- a/relocate.go +++ b/relocate.go @@ -164,11 +164,11 @@ func (linker *Linker) relocteCALLARM(addr uintptr, loc obj.Reloc, segment *segme } putUint24(segment.codeByte[loc.Offset:], off) if loc.Type == reloctype.R_CALLARM64 { - copy(segment.codeByte[segment.codeOff:], arm64code) - segment.codeOff += len(arm64code) + copy(segment.codeByte[segment.codeOff:], armReplace64CALLCode) + segment.codeOff += len(armReplace64CALLCode) } else { - copy(segment.codeByte[segment.codeOff:], armcode) - segment.codeOff += len(armcode) + copy(segment.codeByte[segment.codeOff:], armReplaceCallCode) + segment.codeOff += len(armReplaceCallCode) } putAddressAddOffset(byteorder, segment.codeByte, &segment.codeOff, uint64(int(addr)+add)) } else {