diff options
author | Vitaly Buka <vitalybuka@google.com> | 2016-09-28 18:46:52 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2016-09-28 18:46:52 +0000 |
commit | 5969de9283aa0d41c10594ec3816f37f56746863 (patch) | |
tree | 78923af2936c9ca7e3ca20cbba582dad009be0b9 /lib/sanitizer_common/symbolizer/scripts | |
parent | e398a5c93266e5fbcdbbc0772cc3f701eb26c58c (diff) |
Add build script for symbolizer which can be linked into instrumented process.
Reviewers: eugenis
Subscribers: llvm-commits, kubabrecka
Differential Revision: https://reviews.llvm.org/D24974
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@282617 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/symbolizer/scripts')
-rwxr-xr-x | lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh | 183 | ||||
-rw-r--r-- | lib/sanitizer_common/symbolizer/scripts/global_symbols.txt | 130 |
2 files changed, 313 insertions, 0 deletions
diff --git a/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh new file mode 100755 index 000000000..a1206b182 --- /dev/null +++ b/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -0,0 +1,183 @@ +#!/bin/bash -eu +# +# Run as: CLANG=bin/clang ZLIB_SRC=src/zlib \ +# build_symbolizer.sh runtime_build/lib/clang/4.0.0/lib/linux/ +# zlib can be downloaded from from http://www.zlib.net. +# +# Script compiles self-contained object file with symbolization code and injects +# it into the given set of runtime libraries. Script updates only libraries +# which has unresolved __sanitizer_symbolize_* symbols and matches architecture. +# Object file is be compiled from LLVM sources with dependencies like libc++ and +# zlib. Then it internalizes symbols in the file, so that it can be linked +# into arbitrary programs, avoiding conflicts with the program own symbols and +# avoiding dependencies on any program symbols. The only acceptable dependencies +# are libc and __sanitizer::internal_* from sanitizer runtime. +# +# Symbols exported by the object file will be used by Sanitizer runtime +# libraries to symbolize code/data in-process. +# +# The script will modify the output directory which is given as the first +# argument to the script. + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SRC_DIR=$(readlink -f $SCRIPT_DIR/..) +BUILD_DIR=$(readlink -f ./symbolizer) +TARGE_DIR=$(readlink -f $1) +mkdir -p $BUILD_DIR + +LLVM_SRC=$(readlink -f $SCRIPT_DIR/../../../../../..) + +if [[ "$LLVM_SRC" == "" || + ! -d "${LLVM_SRC}/projects/libcxxabi" || + ! -d "${LLVM_SRC}/projects/libcxx" ]]; then + echo "Missing or incomplete LLVM_SRC" + exit 1 +fi +LLVM_SRC=$(readlink -f $LLVM_SRC) + +if [[ "$ZLIB_SRC" == "" || + ! -x "${ZLIB_SRC}/configure" || + ! -f "${ZLIB_SRC}/zlib.h" ]]; then + echo "Missing or incomplete ZLIB_SRC" + exit 1 +fi +ZLIB_SRC=$(readlink -f $ZLIB_SRC) + +J="${J:-50}" + +CLANG="${CLANG:-`which clang`}" +CLANG_DIR=$(readlink -f $(dirname "$CLANG")) + +CC=$CLANG_DIR/clang +CXX=$CLANG_DIR/clang++ +TBLGEN=$CLANG_DIR/llvm-tblgen +LINK=$CLANG_DIR/llvm-link +OPT=$CLANG_DIR/opt +AR=$CLANG_DIR/llvm-ar + +if [[ ! -x "$CC" || + ! -x "$CXX" || + ! -x "$TBLGEN" || + ! -x "$LINK" || + ! -x "$OPT" || + ! -x "$AR" ]]; then + echo "Missing or incomplete CLANG_DIR" + exit 1 +fi + +ZLIB_BUILD=${BUILD_DIR}/zlib +LIBCXX_BUILD=${BUILD_DIR}/libcxx +LLVM_BUILD=${BUILD_DIR}/llvm +SYMBOLIZER_BUILD=${BUILD_DIR}/symbolizer + +FLAGS=${FLAGS:-} +FLAGS="$FLAGS -fPIC -flto -Os -g0 -DNDEBUG" + +# Build zlib. +mkdir -p ${ZLIB_BUILD} +cd ${ZLIB_BUILD} +cp -r ${ZLIB_SRC}/* . +CC=$CC CFLAGS="$FLAGS" RANLIB=/bin/true ./configure --static +make -j${J} libz.a + +# Build and install libcxxabi and libcxx. +if [[ ! -d ${LIBCXX_BUILD} ]]; then + mkdir -p ${LIBCXX_BUILD} + cd ${LIBCXX_BUILD} + LIBCXX_FLAGS="${FLAGS} -I${LLVM_SRC}/projects/libcxxabi/include" + cmake -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_C_FLAGS_RELEASE="${LIBCXX_FLAGS}" \ + -DCMAKE_CXX_FLAGS_RELEASE="${LIBCXX_FLAGS}" \ + -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \ + -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_ENABLE_THREADS=OFF \ + -DLIBCXX_ENABLE_ASSERTIONS=OFF \ + -DLIBCXX_ENABLE_EXCEPTIONS=OFF \ + -DLIBCXX_ENABLE_RTTI=OFF \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXX_ENABLE_THREADS=OFF \ + $LLVM_SRC +fi +cd ${LIBCXX_BUILD} +ninja cxx cxxabi + +FLAGS="${FLAGS} -fno-rtti -fno-exceptions" + +# Build LLVM. +if [[ ! -d ${LLVM_BUILD} ]]; then + mkdir -p ${LLVM_BUILD} + cd ${LLVM_BUILD} + LLVM_FLAGS="${FLAGS} -I${ZLIB_BUILD} -I${LIBCXX_BUILD}/include/c++/v1" + cmake -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_C_FLAGS_RELEASE="${LLVM_FLAGS}" \ + -DCMAKE_CXX_FLAGS_RELEASE="${LLVM_FLAGS}" \ + -DLLVM_TABLEGEN=$TBLGEN \ + -DLLVM_ENABLE_ZLIB=ON \ + -DLLVM_ENABLE_TERMINFO=OFF \ + -DLLVM_ENABLE_THREADS=OFF \ + $LLVM_SRC +fi +cd ${LLVM_BUILD} +ninja LLVMSymbolize LLVMObject LLVMDebugInfoDWARF LLVMSupport LLVMDebugInfoPDB LLVMMC + +cd ${BUILD_DIR} +rm -rf ${SYMBOLIZER_BUILD} +mkdir ${SYMBOLIZER_BUILD} +cd ${SYMBOLIZER_BUILD} + +for A in $LIBCXX_BUILD/lib/libc++.a \ + $LIBCXX_BUILD/lib/libc++abi.a \ + $LLVM_BUILD/lib/libLLVMSymbolize.a \ + $LLVM_BUILD/lib/libLLVMObject.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \ + $LLVM_BUILD/lib/libLLVMSupport.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \ + $LLVM_BUILD/lib/libLLVMMC.a \ + $ZLIB_BUILD/libz.a ; do + for O in $($AR t $A); do + $AR x $A $O + mv -f $O "$(basename $A).$O" # Rename to avoid collisions between libs. + done +done + +echo "Compiling..." +SYMBOLIZER_FLAGS="$FLAGS -std=c++11 -I${LLVM_SRC}/include -I${LLVM_BUILD}/include -I${LIBCXX_BUILD}/include/c++/v1" +$CXX $SYMBOLIZER_FLAGS ${SRC_DIR}/sanitizer_symbolize.cc ${SRC_DIR}/sanitizer_wrappers.cc -c + +SYMBOLIZER_API_LIST=__sanitizer_symbolize_code,__sanitizer_symbolize_data,__sanitizer_symbolize_flush,__sanitizer_symbolize_demangle + +# Merge all the object files together and copy the resulting library back. +$LINK *.o -o all.bc +echo "Optimizing..." +$OPT -internalize -internalize-public-api-list=${SYMBOLIZER_API_LIST} all.bc -o opt.bc +$CC $FLAGS -fno-lto -c opt.bc -o symbolizer.o + +echo "Checking undefined symbols..." +nm -f posix -g symbolizer.o | cut -f 1,2 -d \ | LC_COLLATE=C sort -u > undefined.new +(diff -u $SCRIPT_DIR/global_symbols.txt undefined.new | grep -E "^\+[^+]") && \ + (echo "Failed: unexpected symbols"; exit 1) + +arch() { + objdump -f $1 | grep -m1 -Po "(?<=file format ).*$" +} + +SYMBOLIZER_FORMAT=$(arch symbolizer.o) +echo "Injecting $SYMBOLIZER_FORMAT symbolizer..." +for A in $TARGE_DIR/*.a; do + A_FORMAT=$(arch $A) + if [[ "$A_FORMAT" != "$SYMBOLIZER_FORMAT" ]] ; then + continue + fi + (nm -u $A | grep -E "__sanitizer_symbolize_code" >/dev/null) || continue + echo "$A" + $AR rcs $A symbolizer.o +done + +echo "Success!" diff --git a/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt new file mode 100644 index 000000000..dcaa8cdf3 --- /dev/null +++ b/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -0,0 +1,130 @@ +_ZN11__sanitizer13internal_mmapEPvmiiiy U +_ZN11__sanitizer13internal_openEPKcij U +_ZN11__sanitizer13internal_statEPKcPv U +_ZN11__sanitizer14internal_closeEi U +_ZN11__sanitizer14internal_fstatEiPv U +_ZN11__sanitizer14internal_lstatEPKcPv U +_ZN11__sanitizer15internal_strlenEPKc U +_ZN11__sanitizer16internal_iserrorEmPi U +_ZN11__sanitizer17internal_snprintfEPcmPKcz U +__ctype_b_loc U +__ctype_get_mb_cur_max U +__cxa_atexit U +__dso_handle U +__errno_location U +__interceptor_pread w +__interceptor_read w +__interceptor_realpath w +__sanitizer_symbolize_code T +__sanitizer_symbolize_data T +__sanitizer_symbolize_demangle T +__sanitizer_symbolize_flush T +__strdup U +_exit U +abort U +access U +calloc U +catclose U +catgets U +catopen U +ceil U +cfgetospeed U +dl_iterate_phdr U +dlsym U +dup2 U +environ U +execv U +exit U +fclose U +fflush U +fileno U +fopen U +fork U +fprintf U +fputc U +free U +freelocale U +fwrite U +getc U +getcwd U +getenv U +getpagesize U +getpid U +gettimeofday U +ioctl U +isatty U +isprint U +isupper U +isxdigit U +log10 U +lseek U +malloc U +mbrlen U +mbrtowc U +mbsnrtowcs U +mbsrtowcs U +mbtowc U +memchr U +memcmp U +memcpy U +memmove U +memset U +mkdir U +munmap U +newlocale U +perror U +posix_spawn U +posix_spawn_file_actions_adddup2 U +posix_spawn_file_actions_addopen U +posix_spawn_file_actions_destroy U +posix_spawn_file_actions_init U +qsort U +rand U +readlink U +realloc U +remove U +setvbuf U +sigfillset U +sigprocmask U +snprintf U +sprintf U +srand U +sscanf U +stderr U +stdin U +stdout U +strcat U +strchr U +strcmp U +strcpy U +strdup U +strerror U +strerror_r U +strftime_l U +strncmp U +strncpy U +strrchr U +strsep U +strtod_l U +strtof_l U +strtol U +strtold_l U +strtoll_l U +strtoull_l U +tcgetattr U +uname U +ungetc U +unlink U +uselocale U +vasprintf U +vfprintf U +vsnprintf U +vsscanf U +waitpid U +wcrtomb U +wcslen U +wcsnrtombs U +wmemcpy U +wmemmove U +wmemset U +write U |