]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go, cmd/link: -buildmode=pie for linux/amd64
authorDavid Crawshaw <crawshaw@golang.org>
Mon, 19 Oct 2015 20:31:20 +0000 (16:31 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Fri, 23 Oct 2015 19:51:55 +0000 (19:51 +0000)
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/16072
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

misc/cgo/testshared/shared_test.go
src/cmd/go/alldocs.go
src/cmd/go/build.go
src/cmd/go/help.go
src/cmd/go/pkg.go
src/cmd/link/internal/ld/lib.go

index 7f677d6a371999fc09ef61749b8fb7067467620e..63cdd9b9ce7707bf6b9a15d8fa59f33cf1c8cf1a 100644 (file)
@@ -359,6 +359,36 @@ func TestCgoExecutable(t *testing.T) {
        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) {
index f9aa20dee51e6f7a5277a4e8cfb4557b8f3b603b..001133b0caccdefdbd7254240ee466d3bed96945 100644 (file)
@@ -819,6 +819,11 @@ are:
                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
 
index 1ec98aac523529163a4e5f4c33028d5777e622c0..c2be1351ebe75877abbc58d838142332588c335e 100644 (file)
@@ -374,7 +374,7 @@ func buildModeInit() {
                        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)
index 244451d3ebc51c0db3e242f5cc8e4df2b8c7707f..e9b34c92a9f6d87b0ad987172ca6990b2f8899fc 100644 (file)
@@ -576,5 +576,10 @@ are:
        -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.
 `,
 }
index 78bd72f52b5c148926670979cfb005f58e227d8c..f3d711fd47105f48a75cfa618fd1d65127f023d5 100644 (file)
@@ -825,10 +825,10 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
                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")
        }
 
index 9bcfcbf9225fb8751d5d94681c896750ae9f9a5a..a2f70cbd6ff77032c27e8dde51aac2e73d86bee0 100644 (file)
@@ -303,7 +303,7 @@ func (mode *BuildMode) Set(s string) error {
                *mode = BuildmodeExe
        case "pie":
                switch goos {
-               case "android":
+               case "android", "linux":
                default:
                        return badmode()
                }
@@ -516,6 +516,12 @@ func loadlib() {
                        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