run(t, "cgo executable", "./bin/execgo")
}
+func checkPIE(t *testing.T, name string) {
+ f, err := elf.Open(name)
+ if err != nil {
+ t.Fatal("elf.Open failed: ", err)
+ }
+ defer f.Close()
+ if f.Type != elf.ET_DYN {
+ t.Errorf("%s has type %v, want ET_DYN", name, f.Type)
+ }
+ if hasDynTag(f, elf.DT_TEXTREL) {
+ t.Errorf("%s has DT_TEXTREL set", name)
+ }
+}
+
+func TestTrivialPIE(t *testing.T) {
+ name := "trivial_pie"
+ goCmd(t, "build", "-buildmode=pie", "-o="+name, "trivial")
+ defer os.Remove(name)
+ run(t, name, "./"+name)
+ checkPIE(t, name)
+}
+
+func TestCgoPIE(t *testing.T) {
+ name := "cgo_pie"
+ goCmd(t, "build", "-buildmode=pie", "-o="+name, "execgo")
+ defer os.Remove(name)
+ run(t, name, "./"+name)
+ checkPIE(t, name)
+}
+
// Build a GOPATH package into a shared library that links against the goroot runtime
// and an executable that links against both.
func TestGopathShlib(t *testing.T) {
Build the listed main packages and everything they import into
executables. Packages not named main are ignored.
+ -buildmode=pie
+ Build the listed main packages and everything they import into
+ position independent executables (PIE). Packages not named
+ main are ignored.
+
File types
fatalf("-buildmode=pie not supported by gccgo")
} else {
switch platform {
- case "android/arm":
+ case "android/arm", "linux/amd64":
codegenArg = "-shared"
default:
fatalf("-buildmode=pie not supported on %s\n", platform)
-buildmode=exe
Build the listed main packages and everything they import into
executables. Packages not named main are ignored.
+
+ -buildmode=pie
+ Build the listed main packages and everything they import into
+ position independent executables (PIE). Packages not named
+ main are ignored.
`,
}
importPaths = append(importPaths, "syscall")
}
- // Currently build mode c-shared, or -linkshared, forces
+ // Currently build modes c-shared, pie, and -linkshared force
// external linking mode, and external linking mode forces an
// import of runtime/cgo.
- if p.Name == "main" && !p.Goroot && (buildBuildmode == "c-shared" || buildLinkshared) {
+ if p.Name == "main" && !p.Goroot && (buildBuildmode == "c-shared" || buildBuildmode == "pie" || buildLinkshared) {
importPaths = append(importPaths, "runtime/cgo")
}
*mode = BuildmodeExe
case "pie":
switch goos {
- case "android":
+ case "android", "linux":
default:
return badmode()
}
Linkmode = LinkExternal
}
+ // Force external linking for PIE executables, as
+ // internal linking does not support TLS_IE.
+ if Buildmode == BuildmodePIE {
+ Linkmode = LinkExternal
+ }
+
// cgo on Darwin must use external linking
// we can always use external linking, but then there will be circular
// dependency problems when compiling natively (external linking requires