]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: also apply R_ADDR relocation statically when internal linking PIE
authorCherry Zhang <cherryyz@google.com>
Tue, 11 Feb 2020 23:26:38 +0000 (18:26 -0500)
committerCherry Zhang <cherryyz@google.com>
Fri, 21 Feb 2020 22:30:06 +0000 (22:30 +0000)
When internal linking PIE, R_ADDR relocations cannot be resolved
statically so we generate dynamic relocations for it. We don't
apply the relocations statically, so the bytes in the file are
left unset (likely zero). This makes some tool that examines the
file statically, e.g. go version, to fail to find the referenced
addresses.

This CL makes the linker also apply the relocations to the file
content, so it holds the correct offsets and so can be examined
statically.

Fixes #37173.

Change-Id: Ia5c6b661f1a91a232843ca4224264bfd7a5509eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/219199
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/testdata/script/version.txt
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm64/asm.go

index 42526247f1e7e62a67222911d01390d648569609..4eafe1f1845327d8ab698ad0946272956739c314 100644 (file)
@@ -12,7 +12,7 @@ stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 # Repeat the test with -buildmode=pie.
 # TODO(golang.org/issue/27144): don't skip after -buildmode=pie is implemented
 # on Windows.
-[windows] skip # -buildmode=pie not supported
+[!buildmode:pie] stop
 go build -buildmode=pie -o external.exe rsc.io/fortune
 go version external.exe
 stdout '^external.exe: .+'
@@ -20,5 +20,16 @@ go version -m external.exe
 stdout '^\tpath\trsc.io/fortune'
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
+# Also test PIE with internal linking.
+# currently only supported on linux/amd64 and linux/arm64.
+[!linux] stop
+[!amd64] [!arm64] stop
+go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune
+go version internal.exe
+stdout '^internal.exe: .+'
+go version -m internal.exe
+stdout '^\tpath\trsc.io/fortune'
+stdout '^\tmod\trsc.io/fortune\tv1.0.0'
+
 -- go.mod --
 module m
index 5de77180fcc456ff000bb14192d2422c5b218cf1..26208cc61932d2879a432edd6b73965fdbc8bb44 100644 (file)
@@ -353,7 +353,10 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
                                ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
                        }
                        rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-                       r.Type = objabi.ElfRelocOffset // ignore during relocsym
+                       // Not mark r done here. So we still apply it statically,
+                       // so in the file content we'll also have the right offset
+                       // to the relocation target. So it can be examined statically
+                       // (e.g. go version).
                        return true
                }
 
index ef9540b2a7b5f70a6912a12ab7984c0c8980f095..9c3f4422384f563d1d617ac55fd60a061a654854 100644 (file)
@@ -309,7 +309,10 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
                                ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
                        }
                        rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-                       r.Type = objabi.ElfRelocOffset // ignore during relocsym
+                       // Not mark r done here. So we still apply it statically,
+                       // so in the file content we'll also have the right offset
+                       // to the relocation target. So it can be examined statically
+                       // (e.g. go version).
                        return true
                }
        }