From 64fbca41c8777b2b03f7e545be3bea34862ecf8f Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 16 Oct 2015 20:50:59 +1300 Subject: [PATCH] cmd/internal/obj/ppc64: avoid calling morestack via a PLT when dynamically linking Change-Id: Ie79f72786b1d7154f1910e717a0faf354b913b89 Reviewed-on: https://go-review.googlesource.com/15970 Reviewed-by: Russ Cox --- src/cmd/internal/obj/ppc64/obj9.go | 59 ++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index a876b99a76..696f6e5834 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -940,19 +940,62 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { q.Pcond = p } - // BL runtime.morestack(SB) - p = obj.Appendp(ctxt, p) - - p.As = ABL - p.To.Type = obj.TYPE_BRANCH + var morestacksym *obj.LSym if ctxt.Cursym.Cfunc != 0 { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) + morestacksym = obj.Linklookup(ctxt, "runtime.morestackc", 0) } else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) + morestacksym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) } else { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack", 0) + morestacksym = obj.Linklookup(ctxt, "runtime.morestack", 0) } + if ctxt.Flag_dynlink { + // Avoid calling morestack via a PLT when dynamically linking. The + // PLT stubs generated by the system linker on ppc64le when "std r2, + // 24(r1)" to save the TOC pointer in their callers stack + // frame. Unfortunately (and necessarily) morestack is called before + // the function that calls it sets up its frame and so the PLT ends + // up smashing the saved TOC pointer for its caller's caller. + // + // According to the ABI documentation there is a mechanism to avoid + // the TOC save that the PLT stub does (put a R_PPC64_TOCSAVE + // relocation on the nop after the call to morestack) but at the time + // of writing it is not supported at all by gold and my attempt to + // use it with ld.bfd caused an internal linker error. So this hack + // seems preferable. + + // MOVD $runtime.morestack(SB), R12 + p = obj.Appendp(ctxt, p) + p.As = AMOVD + p.From.Type = obj.TYPE_MEM + p.From.Sym = morestacksym + p.From.Name = obj.NAME_GOTREF + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R12 + + // MOVD R12, CTR + p = obj.Appendp(ctxt, p) + p.As = AMOVD + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R12 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CTR + + // BL CTR + p = obj.Appendp(ctxt, p) + p.As = obj.ACALL + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R12 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CTR + } else { + // BL runtime.morestack(SB) + p = obj.Appendp(ctxt, p) + + p.As = ABL + p.To.Type = obj.TYPE_BRANCH + p.To.Sym = morestacksym + } // BR start p = obj.Appendp(ctxt, p) -- 2.48.1