[release-branch.go1.4] cmd/go: if -no-pie doesn't work, try -nopie

This is a backport of https://golang.org/cl/49710 to the Go 1.4 branch.

Original CL description:
    GCC says -no-pie, clang says -nopie.

Updates #21042

Change-Id: I67b755ccb0149324098b79e07ee4bbc49429c44c
Reviewed-on: https://go-review.googlesource.com/49711
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Ian Lance Taylor 2017-07-18 13:22:39 -07:00
parent d6bb5454a7
commit a3310f9981

View File

@ -2121,34 +2121,40 @@ 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 {
// 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 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
return ""
}
src := filepath.Join(b.work, "trivial.c")
if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
return false
return ""
}
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
for _, nopie := range []string{"-no-pie", "-nopie"} {
cmdArgs := b.gccCmd(b.work)
cmdArgs = append(cmdArgs, nopie, "-c", "trivial.c")
if buildN || buildX {
b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
if buildN {
return ""
}
}
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Dir = b.work
cmd.Env = envForDir(cmd.Dir)
err := cmd.Run()
if err == nil {
return nopie
}
}
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Dir = b.work
cmd.Env = envForDir(cmd.Dir)
err := cmd.Run()
return err == nil
return ""
}
// gccArchArgs returns arguments to pass to gcc based on the architecture.
@ -2399,8 +2405,8 @@ 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")
if flag := b.gccNoPie(); flag != "" {
ldflags = append(ldflags, flag)
}
// Some systems, such as Ubuntu, always add --build-id to