From: Michael Hudson-Doyle Date: Fri, 16 Oct 2015 08:22:20 +0000 (+1300) Subject: cmd/link, runtime: implement & call addmoduledata on ppc64le X-Git-Tag: go1.6beta1~482 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1ccefcd1b879df2e1603812594cd351978367295;p=gostls13.git cmd/link, runtime: implement & call addmoduledata on ppc64le Change-Id: I3980d82c7df95e69522c3d2c90311f89c6fef0e1 Reviewed-on: https://go-review.googlesource.com/15972 Reviewed-by: Russ Cox --- diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index c16cd3cf7a..06e412431e 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -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 diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index 86d8d04fff..37ba816175 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -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