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

cmd/link/internal/ppc64: generate PCrel trampolines on P10

PCrelative trampolines have no dependence on the TOC pointer or build
mode, thus they are preferable to use when supported.

This is a step towards eliminating the need to use and maintain the
TOC pointer in R2 when PCrel is supported.

Change-Id: I1b1a7e16831cfd6732b31f7fad8df2a7c88c8f84
Reviewed-on: https://go-review.googlesource.com/c/go/+/461599
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
This commit is contained in:
Paul E. Murphy 2023-01-10 15:14:46 -06:00 committed by Paul Murphy
parent 949fdd9f0d
commit a3df6c0e81

View File

@ -39,11 +39,15 @@ import (
"debug/elf"
"encoding/binary"
"fmt"
"internal/buildcfg"
"log"
"strconv"
"strings"
)
// The build configuration supports PC-relative instructions and relocations.
var hasPCrel = buildcfg.GOPPC64 >= 10 && buildcfg.GOOS == "linux" && buildcfg.GOARCH == "ppc64le"
func genpltstub(ctxt *ld.Link, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (sym loader.Sym, firstUse bool) {
// The ppc64 ABI PLT has similar concepts to other
// architectures, but is laid out quite differently. When we
@ -1027,6 +1031,13 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
P := make([]byte, tramp.Size())
var o1, o2 uint32
// ELFv2 save/restore functions use R0/R12 in special ways, therefore trampolines
// as generated here will not always work correctly.
if strings.HasPrefix(ldr.SymName(target), "runtime.elf_") {
log.Fatalf("Internal linker does not support trampolines to ELFv2 ABI"+
" register save/restore function %s", ldr.SymName(target))
}
if ctxt.IsAIX() {
// On AIX, the address is retrieved with a TOC symbol.
// For internal linking, the "Linux" way might still be used.
@ -1044,6 +1055,17 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
r.SetOff(0)
r.SetSiz(8) // generates 2 relocations: HA + LO
r.SetSym(toctramp.Sym())
} else if hasPCrel {
// pla r12, addr (PCrel). This works for static or PIC, with or without a valid TOC pointer.
o1 = uint32(0x06100000)
o2 = uint32(0x39800000) // pla r12, addr
// The trampoline's position is not known yet, insert a relocation.
r, _ := tramp.AddRel(objabi.R_ADDRPOWER_PCREL34)
r.SetOff(0)
r.SetSiz(8) // This spans 2 words.
r.SetSym(target)
r.SetAdd(offset)
} else {
// Used for default build mode for an executable
// Address of the call target is generated using
@ -1051,13 +1073,6 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
o1 = uint32(0x3c000000) | 12<<21 // lis r12,targetaddr hi
o2 = uint32(0x38000000) | 12<<21 | 12<<16 // addi r12,r12,targetaddr lo
// ELFv2 save/restore functions use R0/R12 in special ways, therefore trampolines
// as generated here will not always work correctly.
if strings.HasPrefix(ldr.SymName(target), "runtime.elf_") {
log.Fatalf("Internal linker does not support trampolines to ELFv2 ABI"+
" register save/restore function %s", ldr.SymName(target))
}
t := ldr.SymValue(target)
if t == 0 || r2Valid(ctxt) || ctxt.IsExternal() {
// Target address is unknown, generate relocations