]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/x86: handle global reference in From3 in dynlink mode
authorCherry Mui <cherryyz@google.com>
Wed, 19 Nov 2025 22:32:12 +0000 (17:32 -0500)
committerCherry Mui <cherryyz@google.com>
Thu, 20 Nov 2025 19:05:03 +0000 (11:05 -0800)
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>
src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s
src/cmd/internal/obj/x86/obj6.go

index 4bf58a39a4326615b5cf94875dce0faa7f316bf0..8b104307cd26979bf16281f56ed3944877c9569e 100644 (file)
@@ -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
index 48287546b387696e7ef43450539e6600df4f52e4..b2023ee48f9f02f7ed46d0c02aa55b4f84d9ad03 100644 (file)
@@ -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
        }