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 <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index a2084da..94b4753 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1697,13 +1697,10 @@
 	}
 	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 8784e9d..764f610 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -177,7 +177,12 @@
 // 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 @@
 const (
 	BuildmodeUnset BuildMode = iota
 	BuildmodeExe
+	BuildmodePIE
 	BuildmodeCArchive
 	BuildmodeCShared
 	BuildmodeShared
@@ -294,6 +300,13 @@
 		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 @@
 		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 @@
 		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 @@
 	// 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 @@
 		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 918ca8a..f711586 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -351,7 +351,7 @@
 	// 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 @@
 	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"