mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/go, cmd/link: enable buildmode=pie on darwin/amd64
Change some configurations to enable the feature. Also add the test. This CL doesn't include internal linking support which is tentatively disabled due to #18968. We could do that another day. Fixes #21220 Change-Id: I601d2d78446d36332acc70be0d5b9461ac635208 Reviewed-on: https://go-review.googlesource.com/54790 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
9fbc06e6aa
commit
b7c600d6ba
5 changed files with 75 additions and 6 deletions
|
|
@ -6,6 +6,8 @@ package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"debug/elf"
|
||||||
|
"debug/macho"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
"go/format"
|
||||||
"internal/race"
|
"internal/race"
|
||||||
|
|
@ -4331,3 +4333,59 @@ func TestListTests(t *testing.T) {
|
||||||
t.Run("Example1", testWith("Example", "ExampleSimple"))
|
t.Run("Example1", testWith("Example", "ExampleSimple"))
|
||||||
t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
|
t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildmodePIE(t *testing.T) {
|
||||||
|
if runtime.Compiler == "gccgo" {
|
||||||
|
t.Skipf("skipping test because buildmode=pie is not supported on gccgo")
|
||||||
|
}
|
||||||
|
|
||||||
|
platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
|
switch platform {
|
||||||
|
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
|
||||||
|
"android/amd64", "android/arm", "android/arm64", "android/386":
|
||||||
|
case "darwin/amd64":
|
||||||
|
default:
|
||||||
|
t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
tg := testgo(t)
|
||||||
|
defer tg.cleanup()
|
||||||
|
|
||||||
|
tg.tempFile("main.go", `package main; func main() { print("hello") }`)
|
||||||
|
src := tg.path("main.go")
|
||||||
|
obj := tg.path("main")
|
||||||
|
tg.run("build", "-buildmode=pie", "-o", obj, src)
|
||||||
|
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "linux", "android":
|
||||||
|
f, err := elf.Open(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if f.Type != elf.ET_DYN {
|
||||||
|
t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
|
||||||
|
}
|
||||||
|
case "darwin":
|
||||||
|
f, err := macho.Open(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if f.Flags&macho.FlagDyldLink == 0 {
|
||||||
|
t.Error("PIE must have DyldLink flag, but not")
|
||||||
|
}
|
||||||
|
if f.Flags&macho.FlagPIE == 0 {
|
||||||
|
t.Error("PIE must have PIE flag, but not")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := exec.Command(obj).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(out) != "hello" {
|
||||||
|
t.Errorf("got %q; want %q", out, "hello")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,8 @@ func BuildModeInit() {
|
||||||
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
|
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
|
||||||
"android/amd64", "android/arm", "android/arm64", "android/386":
|
"android/amd64", "android/arm", "android/arm64", "android/386":
|
||||||
codegenArg = "-shared"
|
codegenArg = "-shared"
|
||||||
|
case "darwin/amd64":
|
||||||
|
codegenArg = "-shared"
|
||||||
default:
|
default:
|
||||||
base.Fatalf("-buildmode=pie not supported on %s\n", platform)
|
base.Fatalf("-buildmode=pie not supported on %s\n", platform)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,12 @@ func (mode *BuildMode) Set(s string) error {
|
||||||
case "pie":
|
case "pie":
|
||||||
switch objabi.GOOS {
|
switch objabi.GOOS {
|
||||||
case "android", "linux":
|
case "android", "linux":
|
||||||
|
case "darwin":
|
||||||
|
switch objabi.GOARCH {
|
||||||
|
case "amd64":
|
||||||
|
default:
|
||||||
|
return badmode()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return badmode()
|
return badmode()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1095,7 +1095,7 @@ func (l *Link) hostlink() {
|
||||||
argv = append(argv, "-Wl,-headerpad,1144")
|
argv = append(argv, "-Wl,-headerpad,1144")
|
||||||
if l.DynlinkingGo() {
|
if l.DynlinkingGo() {
|
||||||
argv = append(argv, "-Wl,-flat_namespace")
|
argv = append(argv, "-Wl,-flat_namespace")
|
||||||
} else if !SysArch.InFamily(sys.ARM64) {
|
} else if !SysArch.InFamily(sys.ARM64) && Buildmode != BuildmodePIE {
|
||||||
argv = append(argv, "-Wl,-no_pie")
|
argv = append(argv, "-Wl,-no_pie")
|
||||||
}
|
}
|
||||||
case objabi.Hopenbsd:
|
case objabi.Hopenbsd:
|
||||||
|
|
@ -1114,10 +1114,13 @@ func (l *Link) hostlink() {
|
||||||
argv = append(argv, "-Wl,-pagezero_size,4000000")
|
argv = append(argv, "-Wl,-pagezero_size,4000000")
|
||||||
}
|
}
|
||||||
case BuildmodePIE:
|
case BuildmodePIE:
|
||||||
if UseRelro() {
|
// ELF.
|
||||||
argv = append(argv, "-Wl,-z,relro")
|
if Headtype != objabi.Hdarwin {
|
||||||
|
if UseRelro() {
|
||||||
|
argv = append(argv, "-Wl,-z,relro")
|
||||||
|
}
|
||||||
|
argv = append(argv, "-pie")
|
||||||
}
|
}
|
||||||
argv = append(argv, "-pie")
|
|
||||||
case BuildmodeCShared:
|
case BuildmodeCShared:
|
||||||
if Headtype == objabi.Hdarwin {
|
if Headtype == objabi.Hdarwin {
|
||||||
argv = append(argv, "-dynamiclib")
|
argv = append(argv, "-dynamiclib")
|
||||||
|
|
|
||||||
|
|
@ -401,8 +401,8 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
|
||||||
|
|
||||||
var msect *MachoSect
|
var msect *MachoSect
|
||||||
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
|
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
|
||||||
(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin)) ||
|
(SysArch.Family == sys.AMD64 && Buildmode != BuildmodeExe) ||
|
||||||
(SysArch.Family == sys.ARM && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin))) {
|
(SysArch.Family == sys.ARM && Buildmode != BuildmodeExe)) {
|
||||||
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
|
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
|
||||||
// complains about absolute relocs in __TEXT, so if the section is not
|
// complains about absolute relocs in __TEXT, so if the section is not
|
||||||
// executable, put it in __DATA segment.
|
// executable, put it in __DATA segment.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue