ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/scripts/bundle-libraries.sh b/scripts/bundle-libraries.sh
new file mode 100755
index 0000000..621bf57
--- /dev/null
+++ b/scripts/bundle-libraries.sh
@@ -0,0 +1,212 @@
+#!/usr/bin/env bash
+#
+#   Script to install host system binaries along with required libraries.
+#
+#   Copyright (C) 2012-2017 Jo-Philipp Wich <jo@mein.io>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+DIR="$1"; shift
+
+_cp() {
+	cp ${VERBOSE:+-v} -L "$1" "$2" || {
+		echo "cp($1 $2) failed" >&2
+		exit 1
+	}
+}
+
+_mv() {
+	mv ${VERBOSE:+-v} "$1" "$2" || {
+		echo "mv($1 $2) failed" >&2
+		exit 1
+	}
+}
+
+_md() {
+	mkdir ${VERBOSE:+-v} -p "$1" || {
+		echo "mkdir($1) failed" >&2
+		exit 2
+	}
+}
+
+_ln() {
+	ln ${VERBOSE:+-v} -sf "$1" "$2" || {
+		echo "ln($1 $2) failed" >&2
+		exit 3
+	}
+}
+
+_relpath() {
+	local base="$(readlink -f "$1")"
+	local dest="$(readlink -f "$2")"
+	local up
+
+	[ -d "$base" ] || base="${base%/*}"
+	[ -d "$dest" ] || dest="${dest%/*}"
+
+	while true; do
+		case "$base"
+			in "$dest"/*)
+				echo "$up/${base#$dest/}"
+				break
+			;;
+			*)
+				dest="${dest%/*}"
+				up="${up:+$up/}.."
+			;;
+		esac
+	done
+}
+
+_runas_so() {
+	cat <<-EOT | ${CC:-gcc} -x c -fPIC -shared -o "$1" -
+		#include <unistd.h>
+		#include <stdio.h>
+		#include <stdlib.h>
+
+		int mangle_arg0(int argc, char **argv, char **env) {
+			char *arg0 = getenv("RUNAS_ARG0");
+
+			if (arg0) {
+				argv[0] = arg0;
+				unsetenv("RUNAS_ARG0");
+			}
+
+			return 0;
+		}
+
+		#ifdef __APPLE__
+		__attribute__((section("__DATA,__mod_init_func")))
+		#else
+		__attribute__((section(".init_array")))
+		#endif
+		static void *mangle_arg0_constructor = &mangle_arg0;
+	EOT
+
+	[ -x "$1" ] || {
+		echo "compiling preload library failed" >&2
+		exit 5
+	}
+}
+
+_patch_ldso() {
+	_cp "$1" "$1.patched"
+	sed -i -e 's,/\(usr\|lib\|etc\)/,/###/,g' "$1.patched"
+
+	if "$1.patched" 2>&1 | grep -q -- --library-path; then
+		_mv "$1.patched" "$1"
+	else
+		echo "binary patched ${1##*/} not executable, using original" >&2
+		rm -f "$1.patched"
+	fi
+}
+
+_patch_glibc() {
+	_cp "$1" "$1.patched"
+	sed -i -e 's,/usr/\(\(lib\|share\)/locale\),/###/\1,g' "$1.patched"
+
+	if "$1.patched" 2>&1 | grep -q -- GNU; then
+		_mv "$1.patched" "$1"
+	else
+		echo "binary patched ${1##*/} not executable, using original" >&2
+		rm -f "$1.patched"
+	fi
+}
+
+should_be_patched() {
+	local bin="$1"
+
+	[ -x "$bin" ] || return 1
+
+	case "$bin" in
+		*.so|*.so.[0-9]*)
+			return 1
+		;;
+		*)
+			file "$bin" | grep -sqE "ELF.*(executable|interpreter)" && return 0
+		;;
+	esac
+
+	return 1
+}
+
+for LDD in ${PATH//://ldd }/ldd; do
+	"$LDD" --version >/dev/null 2>/dev/null && break
+	LDD=""
+done
+
+[ -n "$LDD" -a -x "$LDD" ] || LDD=
+
+for BIN in "$@"; do
+	[ -n "$BIN" -a -n "$DIR" ] || {
+		echo "Usage: $0 <destdir> <executable> ..." >&2
+		exit 1
+	}
+
+	[ ! -d "$DIR/lib" ] && {
+		_md "$DIR/lib"
+		_md "$DIR/usr"
+		_ln "../lib" "$DIR/usr/lib"
+	}
+
+	[ ! -x "$DIR/lib/runas.so" ] && {
+		_runas_so "$DIR/lib/runas.so"
+	}
+
+	LDSO=""
+
+	[ -n "$LDD" ] && should_be_patched "$BIN" && {
+		for token in $("$LDD" "$BIN" 2>/dev/null); do
+			case "$token" in */*.so*)
+				dest="$DIR/lib/${token##*/}"
+				ddir="${dest%/*}"
+
+				case "$token" in
+					*/ld-*.so*) LDSO="${token##*/}" ;;
+				esac
+
+				[ -f "$token" -a ! -f "$dest" ] && {
+					_md "$ddir"
+					_cp "$token" "$dest"
+					case "$token" in
+						*/ld-*.so*) _patch_ldso "$dest" ;;
+						*/libc.so.6) _patch_glibc "$dest" ;;
+					esac
+				}
+			;; esac
+		done
+	}
+
+	# is a dynamically linked executable
+	if [ -n "$LDSO" ]; then
+		echo "Bundling ${BIN##*/}"
+
+		RUNDIR="$(readlink -f "$BIN")"; RUNDIR="${RUNDIR%/*}"
+		RUN="${LDSO#ld-}"; RUN="run-${RUN%%.so*}.sh"
+		REL="$(_relpath "$DIR/lib" "$BIN")"
+
+		_mv "$BIN" "$RUNDIR/.${BIN##*/}.bin"
+
+		cat <<-EOF > "$BIN"
+			#!/usr/bin/env bash
+			dir="\$(dirname "\$0")"
+			export RUNAS_ARG0="\$0"
+			export LD_PRELOAD="\${LD_PRELOAD:+\$LD_PRELOAD:}\$dir/${REL:+$REL/}runas.so"
+			exec "\$dir/${REL:+$REL/}$LDSO" --library-path "\$dir/${REL:+$REL/}" "\$dir/.${BIN##*/}.bin" "\$@"
+		EOF
+
+		chmod ${VERBOSE:+-v} 0755 "$BIN"
+	fi
+done