aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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