Commit b7e4de4b authored by David Crawshaw's avatar David Crawshaw

cmd/go, cmd/link: -buildmode=pie for linux/amd64

Depends on external linking right now. I have no immediate use for
this, but wanted to check how hard it is to support as android/amd64
is coming and it will require PIE.

Change-Id: I65c6b19159f40db4c79cf312cd0368c2b2527bfd
Reviewed-on: https://go-review.googlesource.com/16072Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 22d4c8bf
...@@ -359,6 +359,36 @@ func TestCgoExecutable(t *testing.T) { ...@@ -359,6 +359,36 @@ func TestCgoExecutable(t *testing.T) {
run(t, "cgo executable", "./bin/execgo") 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 // Build a GOPATH package into a shared library that links against the goroot runtime
// and an executable that links against both. // and an executable that links against both.
func TestGopathShlib(t *testing.T) { func TestGopathShlib(t *testing.T) {
......
...@@ -819,6 +819,11 @@ are: ...@@ -819,6 +819,11 @@ are:
Build the listed main packages and everything they import into Build the listed main packages and everything they import into
executables. Packages not named main are ignored. 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 File types
......
...@@ -374,7 +374,7 @@ func buildModeInit() { ...@@ -374,7 +374,7 @@ func buildModeInit() {
fatalf("-buildmode=pie not supported by gccgo") fatalf("-buildmode=pie not supported by gccgo")
} else { } else {
switch platform { switch platform {
case "android/arm": case "android/arm", "linux/amd64":
codegenArg = "-shared" codegenArg = "-shared"
default: default:
fatalf("-buildmode=pie not supported on %s\n", platform) fatalf("-buildmode=pie not supported on %s\n", platform)
......
...@@ -576,5 +576,10 @@ are: ...@@ -576,5 +576,10 @@ are:
-buildmode=exe -buildmode=exe
Build the listed main packages and everything they import into Build the listed main packages and everything they import into
executables. Packages not named main are ignored. 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.
`, `,
} }
...@@ -825,10 +825,10 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -825,10 +825,10 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
importPaths = append(importPaths, "syscall") 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 // external linking mode, and external linking mode forces an
// import of runtime/cgo. // 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") importPaths = append(importPaths, "runtime/cgo")
} }
......
...@@ -303,7 +303,7 @@ func (mode *BuildMode) Set(s string) error { ...@@ -303,7 +303,7 @@ func (mode *BuildMode) Set(s string) error {
*mode = BuildmodeExe *mode = BuildmodeExe
case "pie": case "pie":
switch goos { switch goos {
case "android": case "android", "linux":
default: default:
return badmode() return badmode()
} }
...@@ -516,6 +516,12 @@ func loadlib() { ...@@ -516,6 +516,12 @@ func loadlib() {
Linkmode = LinkExternal 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 // cgo on Darwin must use external linking
// we can always use external linking, but then there will be circular // we can always use external linking, but then there will be circular
// dependency problems when compiling natively (external linking requires // dependency problems when compiling natively (external linking requires
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment