]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, runtime: implement & call addmoduledata on ppc64le
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Fri, 16 Oct 2015 08:22:20 +0000 (21:22 +1300)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Fri, 13 Nov 2015 00:51:45 +0000 (00:51 +0000)
Change-Id: I3980d82c7df95e69522c3d2c90311f89c6fef0e1
Reviewed-on: https://go-review.googlesource.com/15972
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/link/internal/ppc64/asm.go
src/runtime/asm_ppc64x.s

index c16cd3cf7af6d52dba9011f7d0edd85f1b3ccc2c..06e412431ebb91235ee4665ba30c49fc2e088a5a 100644 (file)
@@ -38,7 +38,7 @@ import (
        "log"
 )
 
-func gentext() {
+func genplt() {
        var s *ld.LSym
        var stub *ld.LSym
        var pprevtextp **ld.LSym
@@ -137,6 +137,84 @@ func gentext() {
                        ld.Ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
                }
        }
+
+}
+
+func genaddmoduledata() {
+       addmoduledata := ld.Linkrlookup(ld.Ctxt, "runtime.addmoduledata", 0)
+       if addmoduledata.Type == obj.STEXT {
+               return
+       }
+       addmoduledata.Reachable = true
+       initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
+       initfunc.Type = obj.STEXT
+       initfunc.Local = true
+       initfunc.Reachable = true
+       o := func(op uint32) {
+               ld.Adduint32(ld.Ctxt, initfunc, op)
+       }
+       // addis r2, r12, .TOC.-func@ha
+       rel := ld.Addrel(initfunc)
+       rel.Off = int32(initfunc.Size)
+       rel.Siz = 8
+       rel.Sym = ld.Linklookup(ld.Ctxt, ".TOC.", 0)
+       rel.Type = obj.R_ADDRPOWER_PCREL
+       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
+       rel = ld.Addrel(initfunc)
+       rel.Off = int32(initfunc.Size)
+       rel.Siz = 8
+       rel.Sym = ld.Linklookup(ld.Ctxt, "local.moduledata", 0)
+       rel.Type = obj.R_ADDRPOWER_GOT
+       o(0x3c620000)
+       // ld r3, local.moduledata@got@l(r3)
+       o(0xe8630000)
+       // bl runtime.addmoduledata
+       rel = ld.Addrel(initfunc)
+       rel.Off = int32(initfunc.Size)
+       rel.Siz = 4
+       rel.Sym = addmoduledata
+       rel.Type = obj.R_CALLPOWER
+       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 ld.Ctxt.Etextp != nil {
+               ld.Ctxt.Etextp.Next = initfunc
+       } else {
+               ld.Ctxt.Textp = initfunc
+       }
+       ld.Ctxt.Etextp = initfunc
+
+       initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
+       initarray_entry.Reachable = true
+       initarray_entry.Local = true
+       initarray_entry.Type = obj.SINITARR
+       ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
+}
+
+func gentext() {
+       if ld.DynlinkingGo() {
+               genaddmoduledata()
+       }
+
+       if ld.Linkmode == ld.LinkInternal {
+               genplt()
+       }
 }
 
 // Construct a call stub in stub that calls symbol targ via its PLT
index 86d8d04fff467cda2bb25f0e80727870b6610419..37ba816175a6bf6c7ce22cff82a8b7c44d463bb7 100644 (file)
@@ -1070,3 +1070,13 @@ TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8
       MOVD    sp+0(FP), R3
       MOVD    R2, 24(R3)
       RET
+
+TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
+       ADD     $-8, R1
+       MOVD    R31, 0(R1)
+       MOVD    runtime·lastmoduledatap(SB), R4
+       MOVD    R3, moduledata_next(R4)
+       MOVD    R3, runtime·lastmoduledatap(SB)
+       MOVD    0(R1), R31
+       ADD     $8, R1
+       RET