mirror of
https://github.com/golang/go
synced 2024-11-18 19:54:44 -07:00
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 <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
a49067aab6
commit
09c9bced82
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user