mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/x86: handle global reference in From3 in dynlink mode
In dynlink mode, we rewrite reference to a global variable to a load from the GOT. Currently this code does not handle the case that the global reference is in From3 of a Prog. Most instructions don't expect a memory operand in From3, but some do, like VGF2P8AFFINEQB. Handle this case. Change-Id: Ibb6773606e6967bcc629d9ef5dac6e050f4008ef Reviewed-on: https://go-review.googlesource.com/c/go/+/722181 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Junyang Shao <shaojunyang@google.com>
This commit is contained in:
parent
790384c6c2
commit
4b740af56a
2 changed files with 25 additions and 5 deletions
|
|
@ -169,3 +169,8 @@ TEXT ·a34(SB), 0, $0-0
|
|||
SHLXQ AX, CX, R15
|
||||
ADDQ $1, R15
|
||||
RET
|
||||
|
||||
// Ensure from3 get GOT-rewritten without errors.
|
||||
TEXT ·a35(SB), 0, $0-0
|
||||
VGF2P8AFFINEQB $0, runtime·writeBarrier(SB), Z1, Z1
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -423,8 +423,12 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
q.From.Reg = reg
|
||||
}
|
||||
}
|
||||
if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
from3 := p.GetFrom3()
|
||||
for i := range p.RestArgs {
|
||||
a := &p.RestArgs[i].Addr
|
||||
if a != from3 && a.Name == obj.NAME_EXTERN && !a.Sym.Local() {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
}
|
||||
var source *obj.Addr
|
||||
// MOVx sym, Ry becomes $MOV sym@GOT, R15; MOVx (R15), Ry
|
||||
|
|
@ -434,9 +438,17 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
||||
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
|
||||
}
|
||||
if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
|
||||
ctxt.Diag("cannot handle NAME_EXTERN on multiple operands in %v with -dynlink", p)
|
||||
}
|
||||
source = &p.From
|
||||
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
||||
if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
|
||||
ctxt.Diag("cannot handle NAME_EXTERN on multiple operands in %v with -dynlink", p)
|
||||
}
|
||||
source = &p.To
|
||||
} else if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
|
||||
source = from3
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
|
@ -501,9 +513,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
p2.As = p.As
|
||||
p2.From = p.From
|
||||
p2.To = p.To
|
||||
if from3 := p.GetFrom3(); from3 != nil {
|
||||
p2.AddRestSource(*from3)
|
||||
}
|
||||
p2.RestArgs = p.RestArgs
|
||||
if p.From.Name == obj.NAME_EXTERN {
|
||||
p2.From.Reg = reg
|
||||
p2.From.Name = obj.NAME_NONE
|
||||
|
|
@ -512,6 +522,11 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
p2.To.Reg = reg
|
||||
p2.To.Name = obj.NAME_NONE
|
||||
p2.To.Sym = nil
|
||||
} else if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
|
||||
from3 = p2.GetFrom3()
|
||||
from3.Reg = reg
|
||||
from3.Name = obj.NAME_NONE
|
||||
from3.Sym = nil
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue