mirror of
https://github.com/golang/go
synced 2024-10-03 06:21:21 -06:00
cmd/6g: call duffcopy, duffzero via got when dynamically linking go
Jumping to an offset past a symbol isn't something that is really supported by dynamic linkers, so do it by hand. Change-Id: Ifff8834c6cdfa3d521ebd8479d2e93906df9b258 Reviewed-on: https://go-review.googlesource.com/8238 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
8bf0ed5147
commit
1d1c61ba7d
@ -3450,6 +3450,10 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
log.Fatalf("bad code")
|
log.Fatalf("bad code")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if yt.zcase == Zcallduff && ctxt.Flag_dynlink {
|
||||||
|
ctxt.Diag("directly calling duff when dynamically linking Go")
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Framepointer_enabled != 0 && yt.zcase == Zcallduff && p.Mode == 64 {
|
if obj.Framepointer_enabled != 0 && yt.zcase == Zcallduff && p.Mode == 64 {
|
||||||
// Maintain BP around call, since duffcopy/duffzero can't do it
|
// Maintain BP around call, since duffcopy/duffzero can't do it
|
||||||
// (the call jumps into the middle of the function).
|
// (the call jumps into the middle of the function).
|
||||||
|
@ -298,6 +298,34 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctxt.Flag_dynlink && (p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO) {
|
||||||
|
var sym *obj.LSym
|
||||||
|
if p.As == obj.ADUFFZERO {
|
||||||
|
sym = obj.Linklookup(ctxt, "runtime.duffzero", 0)
|
||||||
|
} else {
|
||||||
|
sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0)
|
||||||
|
}
|
||||||
|
offset := p.To.Offset
|
||||||
|
p.As = AMOVQ
|
||||||
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Name = obj.NAME_GOTREF
|
||||||
|
p.From.Sym = sym
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = REG_R15
|
||||||
|
p.To.Offset = 0
|
||||||
|
p.To.Sym = nil
|
||||||
|
p1 := obj.Appendp(ctxt, p)
|
||||||
|
p1.As = AADDQ
|
||||||
|
p1.From.Type = obj.TYPE_CONST
|
||||||
|
p1.From.Offset = offset
|
||||||
|
p1.To.Type = obj.TYPE_REG
|
||||||
|
p1.To.Reg = REG_R15
|
||||||
|
p2 := obj.Appendp(ctxt, p1)
|
||||||
|
p2.As = obj.ACALL
|
||||||
|
p2.To.Type = obj.TYPE_REG
|
||||||
|
p2.To.Reg = REG_R15
|
||||||
|
}
|
||||||
|
|
||||||
if ctxt.Flag_dynlink {
|
if ctxt.Flag_dynlink {
|
||||||
if p.As == ALEAQ && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN {
|
if p.As == ALEAQ && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN {
|
||||||
p.As = AMOVQ
|
p.As = AMOVQ
|
||||||
|
Loading…
Reference in New Issue
Block a user