aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2020-02-11 18:26:38 -0500
committerCherry Zhang <cherryyz@google.com>2020-02-21 22:30:06 +0000
commitd532d5f0fade2630612a5bdb0ac3f95824266ad5 (patch)
tree356638aa8c13621f1ec39190cdb636855b5bdba8
parent240498d63551d0a58a71d5ada457c73a71983a7c (diff)
downloadgo-d532d5f0fade2630612a5bdb0ac3f95824266ad5.tar.gz
go-d532d5f0fade2630612a5bdb0ac3f95824266ad5.zip
cmd/link: also apply R_ADDR relocation statically when internal linking PIE
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>
-rw-r--r--src/cmd/go/testdata/script/version.txt13
-rw-r--r--src/cmd/link/internal/amd64/asm.go5
-rw-r--r--src/cmd/link/internal/arm64/asm.go5
3 files changed, 20 insertions, 3 deletions
diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt
index 42526247f1..4eafe1f184 100644
--- a/src/cmd/go/testdata/script/version.txt
+++ b/src/cmd/go/testdata/script/version.txt
@@ -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
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index 5de77180fc..26208cc619 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -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
}
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index ef9540b2a7..9c3f442238 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -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
}
}