]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link/internal/ppc64: Use PCrel relocs in runtime.addmoduledata if supported
authorPaul E. Murphy <murp@ibm.com>
Thu, 12 Jan 2023 21:57:51 +0000 (15:57 -0600)
committerPaul Murphy <murp@ibm.com>
Fri, 21 Apr 2023 16:11:03 +0000 (16:11 +0000)
This is another step towards supporting TOC-free operations.

Change-Id: I77edcf066c757b8ec815c701d7f6d72cd645eca9
Reviewed-on: https://go-review.googlesource.com/c/go/+/483437
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/cmd/link/internal/ppc64/asm.go

index 445180bb791d80ef880ae8609ec2db86faa4057a..c716c2a5e023695b399d9835075e0eafb8516e1e 100644 (file)
@@ -219,20 +219,23 @@ func genaddmoduledata(ctxt *ld.Link, ldr *loader.Loader) {
                initfunc.AddUint32(ctxt.Arch, op)
        }
 
-       // addis r2, r12, .TOC.-func@ha
-       toc := ctxt.DotTOC[0]
-       rel1, _ := initfunc.AddRel(objabi.R_ADDRPOWER_PCREL)
-       rel1.SetOff(0)
-       rel1.SetSiz(8)
-       rel1.SetSym(toc)
-       o(0x3c4c0000)
-       // addi r2, r2, .TOC.-func@l
-       o(0x38420000)
-       // mflr r31
-       o(0x7c0802a6)
-       // stdu r31, -32(r1)
-       o(0xf801ffe1)
-       // addis r3, r2, local.moduledata@got@ha
+       // Write a function to load this module's local.moduledata. This is shared code.
+       //
+       // package link
+       // void addmoduledata() {
+       //      runtime.addmoduledata(local.moduledata)
+       // }
+
+       // Regenerate TOC from R12 (the address of this function).
+       sz := initfunc.AddSymRef(ctxt.Arch, ctxt.DotTOC[0], 0, objabi.R_ADDRPOWER_PCREL, 8)
+       initfunc.SetUint32(ctxt.Arch, sz-8, 0x3c4c0000) // addis r2, r12, .TOC.-func@ha
+       initfunc.SetUint32(ctxt.Arch, sz-4, 0x38420000) // addi r2, r2, .TOC.-func@l
+
+       // This is Go ABI. Stack a frame and save LR.
+       o(0x7c0802a6) // mflr r31
+       o(0xf801ffe1) // stdu r31, -32(r1)
+
+       // Get the moduledata pointer from GOT and put into R3.
        var tgt loader.Sym
        if s := ldr.Lookup("local.moduledata", 0); s != 0 {
                tgt = s
@@ -241,29 +244,29 @@ func genaddmoduledata(ctxt *ld.Link, ldr *loader.Loader) {
        } else {
                tgt = ldr.LookupOrCreateSym("runtime.firstmoduledata", 0)
        }
-       rel2, _ := initfunc.AddRel(objabi.R_ADDRPOWER_GOT)
-       rel2.SetOff(int32(initfunc.Size()))
-       rel2.SetSiz(8)
-       rel2.SetSym(tgt)
-       o(0x3c620000)
-       // ld r3, local.moduledata@got@l(r3)
-       o(0xe8630000)
-       // bl runtime.addmoduledata
-       rel3, _ := initfunc.AddRel(objabi.R_CALLPOWER)
-       rel3.SetOff(int32(initfunc.Size()))
-       rel3.SetSiz(4)
-       rel3.SetSym(addmoduledata)
-       o(0x48000001)
-       // nop
-       o(0x60000000)
-       // ld r31, 0(r1)
-       o(0xe8010000)
-       // mtlr r31
-       o(0x7c0803a6)
-       // addi r1,r1,32
-       o(0x38210020)
-       // blr
-       o(0x4e800020)
+
+       if !hasPCrel {
+               sz = initfunc.AddSymRef(ctxt.Arch, tgt, 0, objabi.R_ADDRPOWER_GOT, 8)
+               initfunc.SetUint32(ctxt.Arch, sz-8, 0x3c620000) // addis r3, r2, local.moduledata@got@ha
+               initfunc.SetUint32(ctxt.Arch, sz-4, 0xe8630000) // ld r3, local.moduledata@got@l(r3)
+       } else {
+               sz = initfunc.AddSymRef(ctxt.Arch, tgt, 0, objabi.R_ADDRPOWER_GOT_PCREL34, 8)
+               // Note, this is prefixed instruction. It must not cross a 64B boundary.
+               // It is doubleworld aligned here, so it will never cross (this function is 16B aligned, minimum).
+               initfunc.SetUint32(ctxt.Arch, sz-8, 0x04100000)
+               initfunc.SetUint32(ctxt.Arch, sz-4, 0xe4600000) // pld r3, local.moduledata@got@pcrel
+       }
+
+       // Call runtime.addmoduledata
+       sz = initfunc.AddSymRef(ctxt.Arch, addmoduledata, 0, objabi.R_CALLPOWER, 4)
+       initfunc.SetUint32(ctxt.Arch, sz-4, 0x48000001) // bl runtime.addmoduledata
+       o(0x60000000)                                   // nop (for TOC restore)
+
+       // Pop stack frame and return.
+       o(0xe8010000) // ld r31, 0(r1)
+       o(0x7c0803a6) // mtlr r31
+       o(0x38210020) // addi r1,r1,32
+       o(0x4e800020) // blr
 }
 
 // Rewrite ELF (v1 or v2) calls to _savegpr0_n, _savegpr1_n, _savefpr_n, _restfpr_n, _savevr_m, or