env/corellium: add scripts for setting up Corellium builders

The Corellium builders run off device snapshots that took forever to
prepare. These scripts represents a recording of my redoing the Android
and iOS device setups.

The scripts are raw, but they're one step closer to converting the
Corelliums from pets to cattle.

Change-Id: Ic7c3d936d4b79e9590053b09b2e28125bbd34e1f
Reviewed-on: https://go-review.googlesource.com/c/build/+/207277
Run-TryBot: Elias Naur <mail@eliasnaur.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/env/corellium/android/files/builder.sh b/env/corellium/android/files/builder.sh
new file mode 100644
index 0000000..7d50235
--- /dev/null
+++ b/env/corellium/android/files/builder.sh
@@ -0,0 +1,13 @@
+export CC=$HOME/clangwrap
+export GO_BUILDER_ENV=host-android-arm64-corellium-android
+(
+	flock -n 9 || exit 0
+	while true; do
+		go get golang.org/x/build/cmd/buildlet
+		# unset LD_PRELOAD libtermux-exec for 32-bit binaries
+		(unset LD_PRELOAD && 
+			$HOME/go/bin/buildlet -reverse-type host-android-arm64-corellium-android -coordinator farmer.golang.org)
+		sleep 1
+		#/system/bin/reboot
+	done
+) 9>$PREFIX/tmp/builder.lock
diff --git a/env/corellium/android/files/clangwrap.go b/env/corellium/android/files/clangwrap.go
new file mode 100644
index 0000000..7e00be8
--- /dev/null
+++ b/env/corellium/android/files/clangwrap.go
@@ -0,0 +1,29 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"os"
+	"os/exec"
+)
+
+func main() {
+	args := os.Args[1:]
+	cmd := exec.Command("clang")
+	if os.Getenv("GOARCH") == "arm" {
+		pref := os.Getenv("PREFIX")
+		cmd.Args = append(cmd.Args, "-target", "armv7a-linux-androideabi", "-Qunused-arguments", "-L"+pref+"/../home/arm-linux-androideabi/lib", "-B"+pref+"/../home/arm-linux-androideabi/lib")
+	}
+	cmd.Args = append(cmd.Args, args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		if err, ok := err.(*exec.ExitError); ok {
+			os.Exit(err.ExitCode())
+		}
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
diff --git a/env/corellium/android/files/exec.sh b/env/corellium/android/files/exec.sh
new file mode 100644
index 0000000..e4c873b
--- /dev/null
+++ b/env/corellium/android/files/exec.sh
@@ -0,0 +1,13 @@
+#!/system/bin/sh
+
+# Executes command with the Termux environment.
+
+export PREFIX='/data/data/com.termux/files/usr'
+export HOME='/data/data/com.termux/files/home'
+export LD_LIBRARY_PATH='/data/data/com.termux/files/usr/lib'
+export PATH="/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets:$PATH"
+export TMPDIR=$HOME/tmpdir
+
+cd $HOME
+
+exec "$@"
diff --git a/env/corellium/android/files/profile b/env/corellium/android/files/profile
new file mode 100644
index 0000000..4dfe0e6
--- /dev/null
+++ b/env/corellium/android/files/profile
@@ -0,0 +1,3 @@
+export GOROOT_BOOTSTRAP=$HOME/go-android-arm64-bootstrap
+export PATH=$HOME/go/bin:$PATH
+export TMPDIR=$HOME/tmpdir
diff --git a/env/corellium/android/files/run-builder-at-boot b/env/corellium/android/files/run-builder-at-boot
new file mode 100644
index 0000000..5017886
--- /dev/null
+++ b/env/corellium/android/files/run-builder-at-boot
@@ -0,0 +1,3 @@
+termux-wake-lock
+sshd
+tmux new-session -d /data/data/com.termux/files/home/builder.sh
diff --git a/env/corellium/android/install.sh b/env/corellium/android/install.sh
new file mode 100755
index 0000000..aafb80f
--- /dev/null
+++ b/env/corellium/android/install.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# install.sh sets up newly installed Android Corellium device.
+# Connect to the device with "adb connect <ip>:5001" where
+# <ip> is the device adb address.
+#
+# place a valid builder key in the `buildkey` file.
+
+curl -o com.termux.apk "https://f-droid.org/repo/com.termux_77.apk"
+curl -o com.termux.boot.apk "https://f-droid.org/repo/com.termux.boot_7.apk"
+
+adb install com.termux.apk
+adb install com.termux.boot.apk
+
+# Run boot app once to enable run-on-boot.
+adb shell monkey -p com.termux.boot -c android.intent.category.LAUNCHER 1
+
+# Run Termux to set up filesystem.
+adb shell monkey -p com.termux -c android.intent.category.LAUNCHER 1
+
+# Wait for the Termux filesystem.
+sleep 5
+
+adb root
+adb push buildkey /data/data/com.termux/files/home/.gobuildkey-host-android-arm64-corellium-android
+adb push files/exec.sh /data/data/com.termux
+adb push files/clangwrap.go /data/data/com.termux/files/home
+adb push files/builder.sh /data/data/com.termux/files/home
+adb push files/profile /data/data/com.termux/files/home/.profile
+adb shell chmod +x /data/data/com.termux/exec.sh
+adb shell chmod +x /data/data/com.termux/files/home/builder.sh
+# Get Termux username.
+USER=$(adb shell stat -c "%U" /data/data/com.termux)
+
+termux() {
+	adb shell su "$USER" /data/data/com.termux/exec.sh "$@"
+}
+
+termux mkdir -p /data/data/com.termux/files/home/tmpdir
+# Run builder at boot.
+termux mkdir -p /data/data/com.termux/files/home/.termux/boot
+adb push files/run-builder-at-boot /data/data/com.termux/files/home/.termux/boot
+termux pkg install -y openssh tmux ndk-multilib clang git golang
+termux go build clangwrap.go
+
+# Move the arm 32-bit sysroot so 32-bit arm binaries use the Android
+# system libraries at runtime, not those in the build sysroot. If
+# we don't, runtime linking fails.
+termux mv /data/data/com.termux/files/usr/arm-linux-androideabi /data/data/com.termux/files/home/arm-linux-androideabi
+
+termux /system/bin/reboot
+
diff --git a/env/corellium/ios/files/arwrap.go b/env/corellium/ios/files/arwrap.go
new file mode 100755
index 0000000..0c1f573
--- /dev/null
+++ b/env/corellium/ios/files/arwrap.go
@@ -0,0 +1,42 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// The arhost binary is a wrapper for llvm-ar, designed to be called by
+// cmd/link. The -extar flag is not enough because llvm-ar and ar don't
+// use the same flags.
+//
+// It is useful when the standard ar is broken, such as on self-hosted
+// iOS.
+package main
+
+import (
+	"os"
+	"os/exec"
+)
+
+func main() {
+	args := os.Args[1:]
+	// cmd/link invokes ar with -q -c -s. Replace with
+	// just q.
+	for i := len(args) - 1; i >= 0; i-- {
+		switch args[i] {
+		case "-q":
+			args[i] = "q"
+		case "-c", "-s":
+			args = append(args[:i], args[i+1:]...)
+		}
+	}
+	cmd := exec.Command("llvm-ar", args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		if err, ok := err.(*exec.ExitError); ok {
+			os.Exit(err.ExitCode())
+		}
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
diff --git a/env/corellium/ios/files/builder.sh b/env/corellium/ios/files/builder.sh
new file mode 100755
index 0000000..0ac9393
--- /dev/null
+++ b/env/corellium/ios/files/builder.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+export HOME=/var/root
+export CC=$HOME/bin/clangwrap
+export GO_BUILDER_ENV=host-darwin-arm64-corellium-ios
+export GOROOT_BOOTSTRAP=$HOME/go-darwin-arm64-bootstrap
+export PATH=$HOME/bin:$PATH
+while true; do
+	$GOROOT_BOOTSTRAP/bin/go get golang.org/x/build/cmd/buildlet
+	$HOME/go/bin/buildlet -reverse-type host-darwin-arm64-corellium-ios -coordinator farmer.golang.org
+	sleep 1
+done
diff --git a/env/corellium/ios/files/clangwrap.go b/env/corellium/ios/files/clangwrap.go
new file mode 100755
index 0000000..c2c9499
--- /dev/null
+++ b/env/corellium/ios/files/clangwrap.go
@@ -0,0 +1,38 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// The clanghost binary is like clangwrap.sh but for self-hosted iOS.
+//
+// Use -ldflags="-X main.sdkpath=<path to iPhoneOS.sdk>" when building
+// the wrapper.
+package main
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+)
+
+var sdkpath = ""
+
+func main() {
+	if sdkpath == "" {
+		fmt.Fprintf(os.Stderr, "no SDK is set; use -ldflags=\"-X main.sdkpath=<sdk path>\" when building this wrapper.\n")
+		os.Exit(1)
+	}
+	args := os.Args[1:]
+	cmd := exec.Command("clang", "-isysroot", sdkpath, "-mios-version-min=6.0")
+	cmd.Args = append(cmd.Args, args...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		if err, ok := err.(*exec.ExitError); ok {
+			os.Exit(err.ExitCode())
+		}
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
diff --git a/env/corellium/ios/files/org.golang.builder.plist b/env/corellium/ios/files/org.golang.builder.plist
new file mode 100644
index 0000000..b96b956
--- /dev/null
+++ b/env/corellium/ios/files/org.golang.builder.plist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+    <dict>
+        <key>Label</key>
+        <string>org.golang.builder</string>
+        <key>Program</key>
+	<string>/usr/bin/tmux</string>
+	<key>ProgramArguments</key>
+	<array>
+		<string>/usr/bin/tmux</string>
+		<string>-C</string>
+		<string>new-session</string>
+		<string>/var/root/builder.sh</string>
+	</array>
+	<key>StandardErrorPath</key>
+	<string>/private/var/mobile/stderr-builder</string>
+	<key>StandardOutPath</key>
+	<string>/private/var/mobile/stdout-builder</string>
+        <key>RunAtLoad</key>
+        <true/>
+	<!--<key>KeepAlive</key>
+	<true/>-->
+	<key>UserName</key>
+	<string>root</string>
+	<key>GroupName</key>
+	<string>wheel</string>
+    </dict>
+</plist>
diff --git a/env/corellium/ios/files/profile b/env/corellium/ios/files/profile
new file mode 100644
index 0000000..ede168b
--- /dev/null
+++ b/env/corellium/ios/files/profile
@@ -0,0 +1,2 @@
+export PATH=$HOME/bin:$HOME/go/bin:$PATH
+export GOROOT_BOOTSTRAP=$HOME/go-darwin-arm64-bootstrap
diff --git a/env/corellium/ios/files/sources.list b/env/corellium/ios/files/sources.list
new file mode 100644
index 0000000..735534c
--- /dev/null
+++ b/env/corellium/ios/files/sources.list
@@ -0,0 +1,6 @@
+deb https://apt.bingner.com/ ios/1570.15 main
+deb http://apt.thebigboss.org/repofiles/cydia/ stable main
+deb http://cydia.zodttd.com/repo/cydia/ stable main
+deb http://apt.modmyi.com/ stable main
+deb https://repo.chariz.io/ ./
+deb https://repo.dynastic.co/ ./
diff --git a/env/corellium/ios/install.sh b/env/corellium/ios/install.sh
new file mode 100755
index 0000000..b5d811a
--- /dev/null
+++ b/env/corellium/ios/install.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# install.sh sets up a newly created Corellium iPhone device.
+# Set HOST to root@<ip> where <ip> is the device ssh
+# address.
+#
+# Put a builder key in `buildkey`.
+#
+# Use `bootstrap.bash` from the Go standard distribution to build a
+# darwin/arm64 bootstrap toolchain and put it in
+# `go-darwin-arm64-bootstrap.tbz`.
+#
+# Finally, install.sh assumes an iPhone SDK in `iPhoneOS.sdk`.
+
+ios() {
+	ssh "$HOST" "$@"
+}
+
+# Replace the builtin packages sources with a list of sources
+# that contain aworking toolchain.
+scp files/sources.list $HOST:/etc/apt/sources.list.d/sources.list
+ios rm /etc/apt/sources.list.d/electra.list
+ios apt-get update
+ios apt install -y --allow-unauthenticated git tmux rsync org.coolstar.iostoolchain ld64 com.linusyang.localeutf8
+
+# Run builder at boot.
+scp files/org.golang.builder.plist $HOST:/Library/LaunchDaemons/
+ios launchctl load -w /Library/LaunchDaemons/org.golang.builder.plist
+scp files/builder.sh $HOST:/var/root
+
+scp go-darwin-arm64-bootstrap.tbz $HOST:/var/root
+ios tar xjf go-darwin-arm64-bootstrap.tbz
+scp buildkey $HOST:/var/root/.gobuildkey-host-darwin-arm64-corellium-ios
+scp files/profile $HOST:/var/root/.profile
+rsync -va iPhoneOS.sdk $HOST:/var/root/
+
+# Dummy sign Go bootstrap toolchain.
+ios find go-darwin-arm64-bootstrap -executable -type f| ios xargs -n1 ldid -S
+
+ios mkdir -p /var/root/bin
+
+# Build wrappers on the host.
+CGO_ENABLED=1 GOOS=darwin CC=$(go env GOROOT)/misc/ios/clangwrap.sh GOARCH=arm64 go build -o clangwrap -ldflags="-X main.sdkpath=/var/root/iPhoneOS.sdk" files/clangwrap.go
+CGO_ENABLED=1 GOOS=darwin CC=$(go env GOROOT)/misc/ios/clangwrap.sh GOARCH=arm64 go build -o arwrap files/arwrap.go
+scp arwrap $HOST:/var/root/bin/ar
+scp clangwrap $HOST:/var/root/bin/clangwrap
+# Dummy sign them.
+ios ldid -S /var/root/bin/clangwrap
+ios ldid -S /var/root/bin/ar
+ios reboot