aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hudson-Doyle <michael.hudson@canonical.com>2016-01-08 12:57:02 +1300
committerMichael Hudson-Doyle <michael.hudson@canonical.com>2016-01-11 21:20:00 +0000
commitb80b098bc523871d0657f8f68ed71882558f557f (patch)
tree86683f09ff6c06547dd0836256619c7abe9077cf
parentba593d6ab861222ee03b87a6f733afac48f5a04e (diff)
downloadgo-b80b098bc523871d0657f8f68ed71882558f557f.tar.gz
go-b80b098bc523871d0657f8f68ed71882558f557f.zip
cmd/go: pass -no-pie along with -Wl,-r to gcc when supported on linux
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. Change-Id: I1345571142b7c3a96212e43297d19e84ec4a3d41 Reviewed-on: https://go-review.googlesource.com/18359 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/go/build.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 6c6d551e79..ee20a89d86 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -2711,6 +2711,10 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions
// libffi.
ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
+ if b.gccSupportsNoPie() {
+ ldflags = append(ldflags, "-no-pie")
+ }
+
// We are creating an object file, so we don't want a build ID.
ldflags = b.disableBuildID(ldflags)
@@ -2902,6 +2906,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, os.Environ())
+ err := cmd.Run()
+ return err == nil
+}
+
// gccArchArgs returns arguments to pass to gcc based on the architecture.
func (b *builder) gccArchArgs() []string {
switch goarch {
@@ -3158,6 +3192,10 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofi
}
ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
+ if b.gccSupportsNoPie() {
+ ldflags = append(ldflags, "-no-pie")
+ }
+
// We are creating an object file, so we don't want a build ID.
ldflags = b.disableBuildID(ldflags)