diff options
author | Cherry Zhang <cherryyz@google.com> | 2020-02-11 18:26:38 -0500 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-02-21 22:30:06 +0000 |
commit | d532d5f0fade2630612a5bdb0ac3f95824266ad5 (patch) | |
tree | 356638aa8c13621f1ec39190cdb636855b5bdba8 | |
parent | 240498d63551d0a58a71d5ada457c73a71983a7c (diff) | |
download | go-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.txt | 13 | ||||
-rw-r--r-- | src/cmd/link/internal/amd64/asm.go | 5 | ||||
-rw-r--r-- | src/cmd/link/internal/arm64/asm.go | 5 |
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 } } |