From: Cherry Mui Date: Wed, 19 Nov 2025 22:32:12 +0000 (-0500) Subject: cmd/internal/obj/x86: handle global reference in From3 in dynlink mode X-Git-Tag: go1.26rc1~227 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4b740af56a864eeaf3504d7f873c3d3cb3fcd72e;p=gostls13.git 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 Reviewed-by: Junyang Shao --- diff --git a/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s index 4bf58a39a4..8b104307cd 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s +++ b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s @@ -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 diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 48287546b3..b2023ee48f 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -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 }