From 1bed62bda98966091c271cd312756d36bd82bf47 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 16 Apr 2018 17:30:21 -0400 Subject: [PATCH] android: try harder to force PIE for android 5+ This may work around ghc's -no-pie flag. Untested. --- Makefile | 6 ++-- standalone/android/buildapk | 35 +------------------- standalone/android/toolchainpath | 56 ++++++++++++++++++++++++++++++++ standalone/android/wrapper.pl | 3 +- 4 files changed, 62 insertions(+), 38 deletions(-) create mode 100755 standalone/android/toolchainpath diff --git a/Makefile b/Makefile index 5844278a64..9f4c122c3c 100644 --- a/Makefile +++ b/Makefile @@ -261,12 +261,12 @@ android: Build/EvilSplicer if [ ! -e tmp/androidtree/dist/setup-config ]; then \ cd tmp/androidtree && CROSS_COMPILE=Android $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal configure -fAndroid $(ANDROID_FLAGS); \ fi - cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ + PATH=$(shell standalone/android/toolchainpath 4) cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ && mv dist/build/git-annex/git-annex dist/build/git-annex/4.0/git-annex - cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ + PATH=$(shell standalone/android/toolchainpath 4) cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ --ghc-options=-optl-z --ghc-options=-optlnocopyreloc \ && mv dist/build/git-annex/git-annex dist/build/git-annex/4.3/git-annex - cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ + PATH=$(shell standalone/android/toolchainpath 5) cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \ --ghc-options=-optl-z --ghc-options=-optlnocopyreloc --ghc-options=-optl-fPIE --ghc-options=-optl-pie --ghc-options=-optc-fPIE --ghc-options=-optc-pie \ && mv dist/build/git-annex/git-annex dist/build/git-annex/5.0/git-annex diff --git a/standalone/android/buildapk b/standalone/android/buildapk index 063fe6c832..310949c089 100755 --- a/standalone/android/buildapk +++ b/standalone/android/buildapk @@ -13,40 +13,7 @@ fi VER="$(perl -e '$_=<>;print m/\((.*?)\)/'<../../CHANGELOG)" -wrap () { - sed -e "s!PROG!$1!" -e "s!OPTS!$3!" < wrapper.pl > "$2" - chmod +x "$2" -} - -# Add Android cross-compiler to PATH (as installed by ghc-android) -androidtoolchain="$HOME/.ghc/$(cat abiversion)/bin" -# For Android 5, use a wrapped version of the C compiler, -# which sets PIE build flags. -if [ "$androidversion" = 5 ]; then - rm -rf "$androidtoolchain/5" - mkdir -p "$androidtoolchain/5" - for f in $(find "$androidtoolchain" -maxdepth 1 -not -type d -printf '%f\n'); do - src="$androidtoolchain/$f" - dest="$androidtoolchain/5/$f" - case "$f" in - *-ld*) - wrap "$src" "$dest" "-pie" - ;; - *-gcc) - wrap "$src" "$dest" "-pie -fPIE" - ;; - *'-g++') - wrap "$src" "$dest" "-pie -fPIE" - ;; - *) - cp -a "$src" "$dest" - ;; - esac - done - PATH="$androidtoolchain/5:$PATH" -else - PATH="$androidtoolchain:$PATH" -fi +PATH=$(./toolchainpath "$androidversion") export PATH # Paths to the Android SDK and NDK. diff --git a/standalone/android/toolchainpath b/standalone/android/toolchainpath new file mode 100755 index 0000000000..09e855a3a0 --- /dev/null +++ b/standalone/android/toolchainpath @@ -0,0 +1,56 @@ +#!/bin/sh +# Outputs a new PATH setting that is prefixed by the path to the +# Android cross-compiler toolchain to use for a given Android version. +# +# For Android 5, force PIE build flags +# +# Since the ghc-android wrappers actually hardcode the path to the +# toolchain, and we want to wrap the toolchain programs, the binaries +# are moved to bin/orig/ and replaced by wrappers. + +androidversion="$1" + +wrap () { + sed -e "s!PROG!$1!" -e "s!OPTS!$3!" < wrapper.pl > "$2" + chmod +x "$2" +} + +# Allow running from the top or inside this directory. +if [ -e abiversion ]; then + abiversion=$(cat abiversion) +else + abiversion=$(cat standalone/android/abiversion) +fi + +# location to toolchain as installed by ghc-android +androidtoolchain="$HOME/.ghc/$abiversion/bin" + +mkdir -p "$androidtoolchain/orig" + +for f in $(find "$androidtoolchain" -maxdepth 1 -not -type d -printf '%f\n'); do + bin="$androidtoolchain/$f" + orig="$androidtoolchain/orig/$f" + if [ ! -e "$orig" ]; then + cp -a "$bin" "$orig" + fi + if [ "$androidversion" = 5 ]; then + case "$f" in + *-ld*) + wrap "$orig" "$bin" "-pie" + ;; + *-gcc) + wrap "$orig" "$bin" "-pie -fPIE" + ;; + *'-g++') + wrap "$orig" "$bin" "-pie -fPIE" + ;; + *) + cp -a "$orig" "$bin" + ;; + esac + else + cp -a "$orig" "$bin" + fi +done + +echo "$androidtoolchain:$PATH" diff --git a/standalone/android/wrapper.pl b/standalone/android/wrapper.pl index a7136a9509..e7cb98150e 100644 --- a/standalone/android/wrapper.pl +++ b/standalone/android/wrapper.pl @@ -6,5 +6,6 @@ if (grep { $_ eq "-r" || $_ eq "--relocatable" } @ARGV) { exec($prog,@ARGV) || die "failed to run $prog"; } else { - exec($prog,@opts,@ARGV) || die "failed to run $prog"; + my @args=grep { ! m/-no-pie/ } @ARGV; + exec($prog,@opts,@args) || die "failed to run $prog"; }