mirror of
https://github.com/golang/go
synced 2024-11-26 23:41:37 -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:
parent
949fdd9f0d
commit
a3df6c0e81
@ -39,11 +39,15 @@ import (
|
|||||||
"debug/elf"
|
"debug/elf"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"internal/buildcfg"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"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) {
|
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
|
// The ppc64 ABI PLT has similar concepts to other
|
||||||
// architectures, but is laid out quite differently. When we
|
// 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())
|
P := make([]byte, tramp.Size())
|
||||||
var o1, o2 uint32
|
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() {
|
if ctxt.IsAIX() {
|
||||||
// On AIX, the address is retrieved with a TOC symbol.
|
// On AIX, the address is retrieved with a TOC symbol.
|
||||||
// For internal linking, the "Linux" way might still be used.
|
// 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.SetOff(0)
|
||||||
r.SetSiz(8) // generates 2 relocations: HA + LO
|
r.SetSiz(8) // generates 2 relocations: HA + LO
|
||||||
r.SetSym(toctramp.Sym())
|
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 {
|
} else {
|
||||||
// Used for default build mode for an executable
|
// Used for default build mode for an executable
|
||||||
// Address of the call target is generated using
|
// 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
|
o1 = uint32(0x3c000000) | 12<<21 // lis r12,targetaddr hi
|
||||||
o2 = uint32(0x38000000) | 12<<21 | 12<<16 // addi r12,r12,targetaddr lo
|
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)
|
t := ldr.SymValue(target)
|
||||||
if t == 0 || r2Valid(ctxt) || ctxt.IsExternal() {
|
if t == 0 || r2Valid(ctxt) || ctxt.IsExternal() {
|
||||||
// Target address is unknown, generate relocations
|
// Target address is unknown, generate relocations
|
||||||
|
Loading…
Reference in New Issue
Block a user