]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go, cmd/link: if -no-pie doesn't work, try -nopie
authorIan Lance Taylor <iant@golang.org>
Tue, 18 Jul 2017 20:15:05 +0000 (13:15 -0700)
committerIan Lance Taylor <iant@golang.org>
Thu, 20 Jul 2017 18:52:06 +0000 (18:52 +0000)
GCC says -no-pie, clang says -nopie.

Fixes #21042

Change-Id: Iadc83ea7a48ea0debc5064c1ee8da4ebff752044
Reviewed-on: https://go-review.googlesource.com/49710
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/go/internal/work/build.go
src/cmd/link/internal/ld/lib.go

index 0ea327f8bc6896182efdb2ea4ef28c0d41d1c9e0..7d667ff552e3aeb339e422348cf1d4d37747f51f 100644 (file)
@@ -2948,8 +2948,8 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out string, allaction
                // libffi.
                ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
 
-               if b.gccSupportsNoPie() {
-                       ldflags = append(ldflags, "-no-pie")
+               if nopie := b.gccNoPie(); nopie != "" {
+                       ldflags = append(ldflags, nopie)
                }
 
                // We are creating an object file, so we don't want a build ID.
@@ -3196,11 +3196,18 @@ 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 {
-       return b.gccSupportsFlag("-no-pie")
+// gccNoPie returns the flag to use to request non-PIE. 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, and clang spells it -nopie.
+func (b *Builder) gccNoPie() string {
+       if b.gccSupportsFlag("-no-pie") {
+               return "-no-pie"
+       }
+       if b.gccSupportsFlag("-nopie") {
+               return "-nopie"
+       }
+       return ""
 }
 
 // gccSupportsFlag checks to see if the compiler supports a flag.
@@ -3531,8 +3538,8 @@ func (b *Builder) collect(p *load.Package, obj, ofile string, cgoLDFLAGS, outObj
 
        ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
 
-       if b.gccSupportsNoPie() {
-               ldflags = append(ldflags, "-no-pie")
+       if flag := b.gccNoPie(); flag != "" {
+               ldflags = append(ldflags, flag)
        }
 
        // We are creating an object file, so we don't want a build ID.
index 625287112cdbbc431f3f210877fe2720a8ca3009..381022081b7bf07d62084e77da3ca739922c83ff 100644 (file)
@@ -1255,13 +1255,20 @@ func (l *Link) hostlink() {
                if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
                        Errorf(nil, "WriteFile trivial.c failed: %v", err)
                }
-               cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c")
-               cmd.Dir = *flagTmpdir
-               cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
-               out, err := cmd.CombinedOutput()
-               supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
-               if supported {
-                       argv = append(argv, "-no-pie")
+
+               // GCC uses -no-pie, clang uses -nopie.
+               for _, nopie := range []string{"-no-pie", "-nopie"} {
+                       cmd := exec.Command(argv[0], "-c", nopie, "trivial.c")
+                       cmd.Dir = *flagTmpdir
+                       cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
+                       out, _ := cmd.CombinedOutput()
+                       // GCC says "unrecognized command line option ‘-no-pie’"
+                       // clang says "unknown argument: '-no-pie'"
+                       supported := !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
+                       if supported {
+                               argv = append(argv, nopie)
+                               break
+                       }
                }
        }