aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-05-08 11:40:29 -0700
committerIan Lance Taylor <iant@golang.org>2017-05-08 20:06:16 +0000
commit734530e290a467b203e8b9a052039996a201a88a (patch)
tree3f070509be8694184692ce97c52d3baf6fc6ae34
parent79d85a4965ea7c46db483314c3981751909d7883 (diff)
downloadgo-734530e290a467b203e8b9a052039996a201a88a.tar.gz
go-734530e290a467b203e8b9a052039996a201a88a.zip
[release-branch.go1.4] cmd/go: pass -no-pie along with -Wl,-r to gcc when supported on linux
This is a backport of https://golang.org/cl/18359 to the Go 1.4 branch. This fixes the Go 1.4 build on systems for which the compiler defaults to using PIE. Such systems are becoming more common. Original CL description: Go fails to build on a system which has PIE enabled by default like this: /usr/bin/ld: -r and -pie may not be used together collect2: error: ld returned 1 exit status The only system I know that has this property right now is Ubuntu Xenial running on s390x, which is hardly the most accessible system, but it's planned to enable this on amd64 soon too. The fix is to pass -no-pie along with -Wl,-r to the compiler, but unfortunately that flag is very new as well. So this does a test compile of a trivial file to see if the flag is supported. Updates #20276 Change-Id: I80a32fd06e30df1d871a48b5db225ba5bb5d104b Reviewed-on: https://go-review.googlesource.com/42910 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/cmd/go/build.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 1dd4314da6..93bc2200f1 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -2121,6 +2121,36 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
return a
}
+// On systems with PIE (position independent executables) enabled by default,
+// -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
+// not supported by all compilers.
+func (b *builder) gccSupportsNoPie() bool {
+ if goos != "linux" {
+ // On some BSD platforms, error messages from the
+ // compiler make it to the console despite cmd.Std*
+ // all being nil. As -no-pie is only required on linux
+ // systems so far, we only test there.
+ return false
+ }
+ src := filepath.Join(b.work, "trivial.c")
+ if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
+ return false
+ }
+ cmdArgs := b.gccCmd(b.work)
+ cmdArgs = append(cmdArgs, "-no-pie", "-c", "trivial.c")
+ if buildN || buildX {
+ b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
+ if buildN {
+ return false
+ }
+ }
+ cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
+ cmd.Dir = b.work
+ cmd.Env = envForDir(cmd.Dir)
+ err := cmd.Run()
+ return err == nil
+}
+
// gccArchArgs returns arguments to pass to gcc based on the architecture.
func (b *builder) gccArchArgs() []string {
switch archChar {
@@ -2369,6 +2399,10 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi
}
ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
+ if b.gccSupportsNoPie() {
+ ldflags = append(ldflags, "-no-pie")
+ }
+
// Some systems, such as Ubuntu, always add --build-id to
// every link, but we don't want a build ID since we are
// producing an object file. On some of those system a plain