]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: Fix ADUFFxxxx generation on aix/ppc64
authorClément Chigot <clement.chigot@atos.net>
Mon, 30 Sep 2019 09:24:19 +0000 (11:24 +0200)
committerCherry Zhang <cherryyz@google.com>
Tue, 1 Oct 2019 18:30:25 +0000 (18:30 +0000)
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 <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/internal/obj/ppc64/obj9.go

index 30a8414d4ad401c60a8f686e7bb6931b99d4ee59..916116d1a302340cd2eec5c2426266157c33d650 100644 (file)
@@ -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 {