aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Hudson-Doyle <michael.hudson@canonical.com>2015-10-16 21:22:20 +1300
committerMichael Hudson-Doyle <michael.hudson@canonical.com>2015-11-13 00:51:45 +0000
commit1ccefcd1b879df2e1603812594cd351978367295 (patch)
tree08d06393a257b3e91e762030c021baa9821ba2da /src
parent64fbca41c8777b2b03f7e545be3bea34862ecf8f (diff)
downloadgo-1ccefcd1b879df2e1603812594cd351978367295.tar.xz
cmd/link, runtime: implement & call addmoduledata on ppc64le
Change-Id: I3980d82c7df95e69522c3d2c90311f89c6fef0e1 Reviewed-on: https://go-review.googlesource.com/15972 Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/link/internal/ppc64/asm.go80
-rw-r--r--src/runtime/asm_ppc64x.s10
2 files changed, 89 insertions, 1 deletions
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