mirror of https://github.com/golang/go.git
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 <rsc@golang.org>
This commit is contained in:
parent
2ac993107f
commit
64fbca41c8
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue