From 26205cb3c098b4d02d658658fd938f58e8dcdd68 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Mon, 19 Oct 2015 12:53:36 -0400 Subject: [PATCH] cmd/link: PIE executables for android/arm For #10807 Change-Id: Ied826d06cb622edf6413b6f2cdcc46987ab0b05a Reviewed-on: https://go-review.googlesource.com/16054 Reviewed-by: Ian Lance Taylor Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot --- src/cmd/link/internal/ld/elf.go | 5 +---- src/cmd/link/internal/ld/lib.go | 28 ++++++++++++++++++++++++---- src/cmd/link/internal/ld/symtab.go | 5 +++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index a2084dae26..94b4753984 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -1697,13 +1697,10 @@ func doelf() { } Addstring(shstrtab, ".elfdata") Addstring(shstrtab, ".rodata") - if Buildmode == BuildmodeShared || Buildmode == BuildmodeCShared { - Addstring(shstrtab, ".data.rel.ro") - } // See the comment about data.rel.ro.FOO section names in data.go. relro_prefix := "" - if UseRelro() { + Addstring(shstrtab, ".data.rel.ro") relro_prefix = ".data.rel.ro" } Addstring(shstrtab, relro_prefix+".typelink") diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 8784e9d38f..764f610bcd 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -177,7 +177,12 @@ func DynlinkingGo() bool { // UseRelro returns whether to make use of "read only relocations" aka // relro. func UseRelro() bool { - return (Buildmode == BuildmodeCShared || Buildmode == BuildmodeShared) && Iself + switch Buildmode { + case BuildmodeCShared, BuildmodeShared, BuildmodePIE: + return Iself + default: + return false + } } var ( @@ -278,6 +283,7 @@ type BuildMode uint8 const ( BuildmodeUnset BuildMode = iota BuildmodeExe + BuildmodePIE BuildmodeCArchive BuildmodeCShared BuildmodeShared @@ -294,6 +300,13 @@ func (mode *BuildMode) Set(s string) error { return fmt.Errorf("invalid buildmode: %q", s) case "exe": *mode = BuildmodeExe + case "pie": + switch goos { + case "android": + default: + return badmode() + } + *mode = BuildmodePIE case "c-archive": switch goos { case "darwin", "linux": @@ -321,6 +334,8 @@ func (mode *BuildMode) String() string { return "" // avoid showing a default in usage message case BuildmodeExe: return "exe" + case BuildmodePIE: + return "pie" case BuildmodeCArchive: return "c-archive" case BuildmodeCShared: @@ -375,7 +390,7 @@ func libinit() { switch Buildmode { case BuildmodeCShared, BuildmodeCArchive: INITENTRY = fmt.Sprintf("_rt0_%s_%s_lib", goarch, goos) - case BuildmodeExe: + case BuildmodeExe, BuildmodePIE: INITENTRY = fmt.Sprintf("_rt0_%s_%s", goarch, goos) case BuildmodeShared: // No INITENTRY for -buildmode=shared @@ -623,8 +638,11 @@ func loadlib() { // binaries, so leave it enabled on OS X (Mach-O) binaries. // Also leave it enabled on Solaris which doesn't support // statically linked binaries. - if Buildmode == BuildmodeExe && havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { - Debug['d'] = 1 + switch Buildmode { + case BuildmodeExe, BuildmodePIE: + if havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { + Debug['d'] = 1 + } } importcycles() @@ -978,6 +996,8 @@ func hostlink() { if HEADTYPE == obj.Hdarwin { argv = append(argv, "-Wl,-pagezero_size,4000000") } + case BuildmodePIE: + argv = append(argv, "-pie") case BuildmodeCShared: if HEADTYPE == obj.Hdarwin { argv = append(argv, "-dynamiclib") diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 918ca8ac13..f71158663c 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -351,7 +351,7 @@ func symtab() { // pseudo-symbols to mark locations of type, string, and go string data. var symtype *LSym var symtyperel *LSym - if UseRelro() && Buildmode == BuildmodeCShared { + if UseRelro() && (Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) { s = Linklookup(Ctxt, "type.*", 0) s.Type = obj.STYPE @@ -512,7 +512,8 @@ func symtab() { adduint(Ctxt, moduledata, uint64(ntypelinks)) if len(Ctxt.Shlibs) > 0 { thismodulename := filepath.Base(outfile) - if Buildmode == BuildmodeExe { + switch Buildmode { + case BuildmodeExe, BuildmodePIE: // When linking an executable, outfile is just "a.out". Make // it something slightly more comprehensible. thismodulename = "the executable" -- 2.50.0