From: Paul E. Murphy Date: Tue, 10 Jan 2023 21:14:46 +0000 (-0600) Subject: cmd/link/internal/ppc64: generate PCrel trampolines on P10 X-Git-Tag: go1.21rc1~1004 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a3df6c0e81cd14aef0b4967721821d34b962b7be;p=gostls13.git 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 TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Run-TryBot: Paul Murphy --- diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 9141d05ffb..333411a53d 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -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