1#!/bin/bash 2# 3# honggfuzz libunwind build help script 4# ----------------------------------------- 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18if [ -z "$NDK" ]; then 19 # Search in $PATH 20 if [[ $(which ndk-build) != "" ]]; then 21 NDK=$(dirname $(which ndk-build)) 22 else 23 echo "[-] Could not detect Android NDK dir" 24 exit 1 25 fi 26fi 27 28if [ $# -ne 2 ]; then 29 echo "[-] Invalid arguments" 30 echo "[!] $0 <LIBUNWIND_DIR> <ARCH>" 31 echo " ARCH: arm arm64 x86 x86_64" 32 exit 1 33fi 34 35readonly LIBUNWIND_DIR=$1 36 37# Fetch if not already there 38if [ ! -d $LIBUNWIND_DIR ]; then 39 echo "[!] libunwind not found. Fetching a fresh copy" 40 git clone git://git.sv.gnu.org/libunwind.git $LIBUNWIND_DIR 41fi 42 43case "$2" in 44 arm|arm64|x86|x86_64) 45 readonly ARCH=$2 46 if [ ! -d $LIBUNWIND_DIR/$ARCH ] ; then mkdir -p $LIBUNWIND_DIR/$ARCH; fi 47 ;; 48 *) 49 echo "[-] Invalid architecture" 50 exit 1 51 ;; 52esac 53 54LC_LDFLAGS="-static" 55 56# For debugging 57# Remember to export UNW_DEBUG_LEVEL=<level> 58# where 1 < level < 16 (usually values up to 5 are enough) 59#LC_CFLAGS="$LC_FLAGS -DDEBUG" 60 61# Change workdir to simplify args 62cd $LIBUNWIND_DIR 63 64# Prepare toolchain 65case "$ARCH" in 66 arm) 67 TOOLCHAIN=arm-linux-androideabi 68 TOOLCHAIN_S=arm-linux-androideabi-4.9 69 ;; 70 arm64) 71 TOOLCHAIN=aarch64-linux-android 72 TOOLCHAIN_S=aarch64-linux-android-4.9 73 ;; 74 x86) 75 TOOLCHAIN=i686-linux-android 76 TOOLCHAIN_S=x86-4.9 77 ;; 78 x86_64) 79 TOOLCHAIN=x86_64-linux-android 80 TOOLCHAIN_S=x86_64-4.9 81 ;; 82esac 83 84# Apply patches required for Android 85# TODO: Automate global patching when all archs have been tested 86 87# Ptrace patches due to Android incompatibilities 88patch -N --dry-run --silent src/ptrace/_UPT_access_reg.c < ../patches/ptrace-libunwind_1.patch &>/dev/null 89if [ $? -eq 0 ]; then 90 patch src/ptrace/_UPT_access_reg.c < ../patches/ptrace-libunwind_1.patch 91 if [ $? -ne 0 ]; then 92 echo "[-] ptrace-libunwind_1 patch failed" 93 exit 1 94 fi 95fi 96 97patch -N --dry-run --silent src/ptrace/_UPT_access_fpreg.c < ../patches/ptrace-libunwind_2.patch &>/dev/null 98if [ $? -eq 0 ]; then 99 patch src/ptrace/_UPT_access_fpreg.c < ../patches/ptrace-libunwind_2.patch 100 if [ $? -ne 0 ]; then 101 echo "[-] ptrace-libunwind_2 patch failed" 102 exit 1 103 fi 104fi 105 106if [ "$ARCH" == "arm64" ]; then 107 # Missing libc functionality 108 patch -N --dry-run --silent include/libunwind-aarch64.h < ../patches/aarch64-libunwind_1.patch &>/dev/null 109 if [ $? -eq 0 ]; then 110 patch include/libunwind-aarch64.h < ../patches/aarch64-libunwind_1.patch 111 if [ $? -ne 0 ]; then 112 echo "[-] aarch64-libunwind_1 patch failed" 113 exit 1 114 fi 115 fi 116 # Frames ip bugs 117 patch -N --dry-run --silent src/aarch64/Gstep.c < ../patches/aarch64-libunwind_2.patch &>/dev/null 118 if [ $? -eq 0 ]; then 119 patch src/aarch64/Gstep.c < ../patches/aarch64-libunwind_2.patch 120 if [ $? -ne 0 ]; then 121 echo "[-] aarch64-libunwind_2 patch failed" 122 exit 1 123 fi 124 fi 125fi 126 127if [ "$ARCH" == "x86" ]; then 128 # Missing syscalls 129 patch -N --dry-run --silent src/x86/Gos-linux.c < ../patches/x86-libunwind.patch &>/dev/null 130 if [ $? -eq 0 ]; then 131 patch src/x86/Gos-linux.c < ../patches/x86-libunwind.patch 132 if [ $? -ne 0 ]; then 133 echo "[-] x86-libunwind patch failed" 134 exit 1 135 fi 136 fi 137fi 138 139# Support both Linux & Darwin 140HOST_OS=$(uname -s | tr '[:upper:]' '[:lower:]') 141HOST_ARCH=$(uname -m) 142 143SYSROOT="$NDK/platforms/android-21/arch-$ARCH" 144export CC="$NDK/toolchains/$TOOLCHAIN_S/prebuilt/$HOST_OS-$HOST_ARCH/bin/$TOOLCHAIN-gcc --sysroot=$SYSROOT" 145export CXX="$NDK/toolchains/$TOOLCHAIN_S/prebuilt/$HOST_OS-$HOST_ARCH/bin/$TOOLCHAIN-g++ --sysroot=$SYSROOT" 146export PATH="$NDK/toolchains/$TOOLCHAIN_S/prebuilt/$HOST_OS-$HOST_ARCH/bin":$PATH 147 148if [ ! -f configure ]; then 149 autoreconf -i 150 if [ $? -ne 0 ]; then 151 echo "[-] autoreconf failed" 152 exit 1 153 fi 154 # Patch configure 155 sed -i -e 's/-lgcc_s/-lgcc/g' configure 156else 157 make clean 158fi 159 160./configure --host=$TOOLCHAIN --disable-coredump 161if [ $? -ne 0 ]; then 162 echo "[-] configure failed" 163 exit 1 164fi 165 166# Fix stuff that configure failed to detect 167# TODO: Investigate for more elegant patches 168if [ "$ARCH" == "arm64" ]; then 169 sed -i -e 's/#define HAVE_DECL_PTRACE_POKEUSER 1/#define HAVE_DECL_PTRACE_POKEUSER 0/g' include/config.h 170 echo "#define HAVE_DECL_PT_GETREGSET 1" >> include/config.h 171fi 172 173make CFLAGS="$LC_CFLAGS" LDFLAGS="$LC_LDFLAGS" 174if [ $? -ne 0 ]; then 175 echo "[-] Compilation failed" 176 cd - &>/dev/null 177 exit 1 178else 179 echo "[*] '$ARCH' libunwind available at '$LIBUNWIND_DIR/$ARCH'" 180 cp src/.libs/*.a $ARCH 181 cd - &>/dev/null 182fi 183