From d532d5f0fade2630612a5bdb0ac3f95824266ad5 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Tue, 11 Feb 2020 18:26:38 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/go/testdata/script/version.txt | 13 ++++++++++++- src/cmd/link/internal/amd64/asm.go | 5 ++++- 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 } } -- 2.50.0