1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:38:00 -07:00

cmd/link: use R12 as trampoline scratch register on ARM

The external linker uses R12. Do the same. We previously use R11,
the temp register in Go ABI. This does not really matter if the
caller is Go code, because all registers are clobbered at call.
But it the caller is C code, it may assume R11 live across a call.
Using R11 may clobber live value. On the callee side, R12 is not
an argument register in both Go and C calling convention.

Change-Id: I958c5dad52aa51bb282a7ad420f5423863e69c14
Reviewed-on: https://go-review.googlesource.com/c/go/+/314454
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-27 17:05:36 -04:00
parent 4a7effa418
commit 11052d77a3

View File

@ -443,8 +443,8 @@ func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *l
tramp.SetSize(12) // 3 instructions
P := make([]byte, tramp.Size())
t := ldr.SymValue(target) + offset
o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe12fff10 | 11) // JMP (R11)
o1 := uint32(0xe5900000 | 12<<12 | 15<<16) // MOVW (R15), R12 // R15 is actual pc + 8
o2 := uint32(0xe12fff10 | 12) // JMP (R12)
o3 := uint32(t) // WORD $target
arch.ByteOrder.PutUint32(P, o1)
arch.ByteOrder.PutUint32(P[4:], o2)
@ -464,9 +464,9 @@ func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *l
func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
tramp.SetSize(16) // 4 instructions
P := make([]byte, tramp.Size())
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
o3 := uint32(0xe12fff10 | 11) // JMP (R11)
o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 4) // MOVW 4(R15), R12 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12) // ADD R15, R12, R12
o3 := uint32(0xe12fff10 | 12) // JMP (R12)
o4 := uint32(0) // WORD $(target-pc) // filled in with relocation
arch.ByteOrder.PutUint32(P, o1)
arch.ByteOrder.PutUint32(P[4:], o2)
@ -484,10 +484,10 @@ func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym,
// generate a trampoline to target+offset in dynlink mode (using GOT)
func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
tramp.SetSize(20) // 5 instructions
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
o3 := uint32(0xe5900000 | 11<<12 | 11<<16) // MOVW (R11), R11
o4 := uint32(0xe12fff10 | 11) // JMP (R11)
o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 8) // MOVW 8(R15), R12 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12) // ADD R15, R12, R12
o3 := uint32(0xe5900000 | 12<<12 | 12<<16) // MOVW (R12), R12
o4 := uint32(0xe12fff10 | 12) // JMP (R12)
o5 := uint32(0) // WORD $target@GOT // filled in with relocation
o6 := uint32(0)
if offset != 0 {
@ -495,8 +495,8 @@ func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym,
tramp.SetSize(24) // 6 instructions
o6 = o5
o5 = o4
o4 = 0xe2800000 | 11<<12 | 11<<16 | immrot(uint32(offset)) // ADD $offset, R11, R11
o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12) // MOVW 12(R15), R11
o4 = 0xe2800000 | 12<<12 | 12<<16 | immrot(uint32(offset)) // ADD $offset, R12, R12
o1 = uint32(0xe5900000 | 12<<12 | 15<<16 | 12) // MOVW 12(R15), R12
}
P := make([]byte, tramp.Size())
arch.ByteOrder.PutUint32(P, o1)