From 09c9bced825593aedfd79af5c35916392f43113c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Chigot?= Date: Mon, 30 Sep 2019 11:24:19 +0200 Subject: [PATCH] cmd/internal/obj/ppc64: Fix ADUFFxxxx generation on aix/ppc64 ADUFFCOPY and ADUFFZERO instructions weren't handled by rewriteToUseTOC. These instructions are considered as a simple branch except with -dynlink where they become an indirect call. Fixes #34604 Change-Id: I16ca6a152164966fb9cbf792219a8a39aad2b53b Reviewed-on: https://go-review.googlesource.com/c/go/+/197842 Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/internal/obj/ppc64/obj9.go | 62 ++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index 30a8414d4a..916116d1a3 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -106,10 +106,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { p.As = AADD } } - if c.ctxt.Flag_dynlink { - c.rewriteToUseGot(p) - } else if c.ctxt.Headtype == objabi.Haix { + if c.ctxt.Headtype == objabi.Haix { c.rewriteToUseTOC(p) + } else if c.ctxt.Flag_dynlink { + c.rewriteToUseGot(p) } } @@ -120,6 +120,62 @@ func (c *ctxt9) rewriteToUseTOC(p *obj.Prog) { return } + if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { + // ADUFFZERO/ADUFFCOPY is considered as an ABL except in dynamic + // link where it should be an indirect call. + if !c.ctxt.Flag_dynlink { + return + } + // ADUFFxxx $offset + // becomes + // MOVD runtime.duffxxx@TOC, R12 + // ADD $offset, R12 + // MOVD R12, CTR + // BL (CTR) + var sym *obj.LSym + if p.As == obj.ADUFFZERO { + sym = c.ctxt.Lookup("runtime.duffzero") + } else { + sym = c.ctxt.Lookup("runtime.duffcopy") + } + // Retrieve or create the TOC anchor. + symtoc := c.ctxt.LookupInit("TOC."+sym.Name, func(s *obj.LSym) { + s.Type = objabi.SDATA + s.Set(obj.AttrDuplicateOK, true) + c.ctxt.Data = append(c.ctxt.Data, s) + s.WriteAddr(c.ctxt, 0, 8, sym, 0) + }) + + offset := p.To.Offset + p.As = AMOVD + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_TOCREF + p.From.Sym = symtoc + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R12 + p.To.Name = obj.NAME_NONE + p.To.Offset = 0 + p.To.Sym = nil + p1 := obj.Appendp(p, c.newprog) + p1.As = AADD + p1.From.Type = obj.TYPE_CONST + p1.From.Offset = offset + p1.To.Type = obj.TYPE_REG + p1.To.Reg = REG_R12 + p2 := obj.Appendp(p1, c.newprog) + p2.As = AMOVD + p2.From.Type = obj.TYPE_REG + p2.From.Reg = REG_R12 + p2.To.Type = obj.TYPE_REG + p2.To.Reg = REG_CTR + p3 := obj.Appendp(p2, c.newprog) + p3.As = obj.ACALL + p3.From.Type = obj.TYPE_REG + p3.From.Reg = REG_R12 + p3.To.Type = obj.TYPE_REG + p3.To.Reg = REG_CTR + } + var source *obj.Addr if p.From.Name == obj.NAME_EXTERN || p.From.Name == obj.NAME_STATIC { if p.From.Type == obj.TYPE_ADDR { -- 2.50.0