Commit 1f85d3ad authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

cmd/internal/obj/x86: use LEAx rather than ADDx when calling DUFFxxxx via GOT

DUFFZERO on 386 is not marked as clobbering flags, but rewriteToUseGot rewrote
"ADUFFZERO $offset" to "MOVL runtime.duffxxx@GOT, CX; ADDL $offset, CX; CALL CX"
which does. Luckily the fix is easier than figuring out what the problem was:
replace the ADDL $offset, CX with LEAL $offset(CX), CX.

On amd64 DUFFZERO clobbers flags, on arm, arm64 and ppc64 ADD does not clobber
flags and s390x does not use the duff functions, so I'm fairly confident this
is the only fix required.

I don't know how to write a test though.

Change-Id: I69b0958f5f45771d61db5f5ecb4ded94e8960d4d
Reviewed-on: https://go-review.googlesource.com/41821
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent a2da2108
...@@ -296,15 +296,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ...@@ -296,15 +296,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
var add, lea, mov obj.As var lea, mov obj.As
var reg int16 var reg int16
if ctxt.Arch.Family == sys.AMD64 { if ctxt.Arch.Family == sys.AMD64 {
add = AADDQ
lea = ALEAQ lea = ALEAQ
mov = AMOVQ mov = AMOVQ
reg = REG_R15 reg = REG_R15
} else { } else {
add = AADDL
lea = ALEAL lea = ALEAL
mov = AMOVL mov = AMOVL
reg = REG_CX reg = REG_CX
...@@ -321,8 +319,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ...@@ -321,8 +319,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// ADUFFxxx $offset // ADUFFxxx $offset
// becomes // becomes
// $MOV runtime.duffxxx@GOT, $reg // $MOV runtime.duffxxx@GOT, $reg
// $ADD $offset, $reg // $LEA $offset($reg), $reg
// CALL $reg // CALL $reg
// (we use LEAx rather than ADDx because ADDx clobbers
// flags and duffzero on 386 does not otherwise do so)
var sym *obj.LSym var sym *obj.LSym
if p.As == obj.ADUFFZERO { if p.As == obj.ADUFFZERO {
sym = ctxt.Lookup("runtime.duffzero") sym = ctxt.Lookup("runtime.duffzero")
...@@ -339,9 +339,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ...@@ -339,9 +339,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.To.Offset = 0 p.To.Offset = 0
p.To.Sym = nil p.To.Sym = nil
p1 := obj.Appendp(p, newprog) p1 := obj.Appendp(p, newprog)
p1.As = add p1.As = lea
p1.From.Type = obj.TYPE_CONST p1.From.Type = obj.TYPE_MEM
p1.From.Offset = offset p1.From.Offset = offset
p1.From.Reg = reg
p1.To.Type = obj.TYPE_REG p1.To.Type = obj.TYPE_REG
p1.To.Reg = reg p1.To.Reg = reg
p2 := obj.Appendp(p1, newprog) p2 := obj.Appendp(p1, newprog)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment