diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/symbolizer')
3 files changed, 107 insertions, 61 deletions
diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp index 2bc0444050f8..4bdf75332bf3 100644 --- a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp +++ b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -17,6 +17,7 @@ #include "llvm/DebugInfo/Symbolize/DIPrinter.h" #include "llvm/DebugInfo/Symbolize/Symbolize.h" +#include "llvm/Demangle/Demangle.h" static llvm::symbolize::LLVMSymbolizer *Symbolizer = nullptr; static bool Demangle = true; @@ -27,6 +28,7 @@ static llvm::symbolize::LLVMSymbolizer *getDefaultSymbolizer() { return Symbolizer; llvm::symbolize::LLVMSymbolizer::Options Opts; Opts.Demangle = Demangle; + Opts.UntagAddresses = true; Symbolizer = new llvm::symbolize::LLVMSymbolizer(Opts); return Symbolizer; } @@ -52,8 +54,7 @@ static llvm::symbolize::ErrorHandler symbolize_error_handler( } namespace __sanitizer { -int internal_snprintf(char *buffer, uintptr_t length, const char *format, - ...); +int internal_snprintf(char *buffer, uintptr_t length, const char *format, ...); } // namespace __sanitizer extern "C" { @@ -76,13 +77,16 @@ bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset, auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( ModuleName, {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); - Printer->print(Request, - ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); + if (!ResOrErr) + return false; + Printer->print(Request, ResOrErr.get()); } else { auto ResOrErr = getDefaultSymbolizer()->symbolizeCode( ModuleName, {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); - Printer->print(Request, ResOrErr ? ResOrErr.get() : llvm::DILineInfo()); + if (!ResOrErr) + return false; + Printer->print(Request, ResOrErr.get()); } } return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", @@ -104,7 +108,32 @@ bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset, auto ResOrErr = getDefaultSymbolizer()->symbolizeData( ModuleName, {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); - Printer->print(Request, ResOrErr ? ResOrErr.get() : llvm::DIGlobal()); + if (!ResOrErr) + return false; + Printer->print(Request, ResOrErr.get()); + } + return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", + Result.c_str()) < MaxLength; +} + +bool __sanitizer_symbolize_frame(const char *ModuleName, uint64_t ModuleOffset, + char *Buffer, int MaxLength) { + std::string Result; + { + llvm::symbolize::PrinterConfig Config = getDefaultPrinterConfig(); + llvm::raw_string_ostream OS(Result); + llvm::symbolize::Request Request{ModuleName, ModuleOffset}; + auto Printer = std::make_unique<llvm::symbolize::LLVMPrinter>( + OS, symbolize_error_handler(OS), Config); + + // TODO: it is neccessary to set proper SectionIndex here. + // object::SectionedAddress::UndefSection works for only absolute addresses. + auto ResOrErr = getDefaultSymbolizer()->symbolizeFrame( + ModuleName, + {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); + if (!ResOrErr) + return false; + Printer->print(Request, ResOrErr.get()); } return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", Result.c_str()) < MaxLength; @@ -115,14 +144,13 @@ void __sanitizer_symbolize_flush() { Symbolizer->flush(); } -int __sanitizer_symbolize_demangle(const char *Name, char *Buffer, - int MaxLength) { - std::string Result = - llvm::symbolize::LLVMSymbolizer::DemangleName(Name, nullptr); +bool __sanitizer_symbolize_demangle(const char *Name, char *Buffer, + int MaxLength) { + std::string Result; + if (!llvm::nonMicrosoftDemangle(Name, Result)) + return false; return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", - Result.c_str()) < MaxLength - ? static_cast<int>(Result.size() + 1) - : 0; + Result.c_str()) < MaxLength; } bool __sanitizer_symbolize_set_demangle(bool Value) { diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh index 835685686100..c9e31be61cb7 100755 --- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh +++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -1,29 +1,19 @@ #!/usr/bin/env bash # -# Run as: CLANG=bin/clang ZLIB_SRC=src/zlib \ -# build_symbolizer.sh runtime_build/lib/clang/4.0.0/lib/linux/ +# Run as: CLANG=bin/clang build_symbolizer.sh out.o +# If you want to use a local copy of zlib, set ZLIB_SRC. # zlib can be downloaded 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. +# Script compiles self-contained object file with symbolization code. # # 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. -# # FIXME: We should really be using a simpler approach to building this object # file, and it should be available as a regular cmake rule. Conceptually, we # want to be doing "ld -r" followed by "objcopy -G" to create a relocatable # object file with only our entry points exposed. However, this does not work at -# present, see PR30750. +# present, see https://github.com/llvm/llvm-project/issues/30098. set -x set -e @@ -31,26 +21,20 @@ set -u SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) SRC_DIR=$(readlink -f $SCRIPT_DIR/..) -TARGE_DIR=$(readlink -f $1) -COMPILER_RT_SRC=$(readlink -f ${SCRIPT_DIR}/../../../..) -LLVM_SRC=${LLVM_SRC:-${COMPILER_RT_SRC}/../llvm} -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" +if [[ $# -ne 1 ]]; then + echo "Missing output file" exit 1 fi -ZLIB_SRC=$(readlink -f $ZLIB_SRC) + +OUTPUT=$(readlink -f $1) +COMPILER_RT_SRC=$(readlink -f ${SCRIPT_DIR}/../../../..) +LLVM_SRC=${LLVM_SRC:-${COMPILER_RT_SRC}/../llvm} +LLVM_SRC=$(readlink -f $LLVM_SRC) CLANG="${CLANG:-`which clang`}" CLANG_DIR=$(readlink -f $(dirname "$CLANG")) -BUILD_DIR=$(readlink -f ./symbolizer) -mkdir -p $BUILD_DIR -cd $BUILD_DIR - CC=$CLANG_DIR/clang CXX=$CLANG_DIR/clang++ TBLGEN=$CLANG_DIR/llvm-tblgen @@ -65,37 +49,57 @@ for F in $CC $CXX $TBLGEN $LINK $OPT $AR; do fi done +BUILD_DIR=${PWD}/symbolizer +mkdir -p $BUILD_DIR +cd $BUILD_DIR + ZLIB_BUILD=${BUILD_DIR}/zlib LIBCXX_BUILD=${BUILD_DIR}/libcxx LLVM_BUILD=${BUILD_DIR}/llvm SYMBOLIZER_BUILD=${BUILD_DIR}/symbolizer FLAGS=${FLAGS:-} +ZLIB_SRC=${ZLIB_SRC:-} TARGET_TRIPLE=$($CC -print-target-triple $FLAGS) if [[ "$FLAGS" =~ "-m32" ]] ; then # Avoid new wrappers. FLAGS+=" -U_FILE_OFFSET_BITS" fi FLAGS+=" -fPIC -flto -Oz -g0 -DNDEBUG -target $TARGET_TRIPLE -Wno-unused-command-line-argument" +FLAGS+=" -include ${SRC_DIR}/../sanitizer_redefine_builtins.h -DSANITIZER_COMMON_REDEFINE_BUILTINS_IN_STD -Wno-language-extension-token" + LINKFLAGS="-fuse-ld=lld -target $TARGET_TRIPLE" # Build zlib. -mkdir -p ${ZLIB_BUILD} +if [[ ! -d ${ZLIB_BUILD} ]]; then + if [[ -z "${ZLIB_SRC}" ]]; then + git clone https://github.com/madler/zlib ${ZLIB_BUILD} + else + ZLIB_SRC=$(readlink -f $ZLIB_SRC) + mkdir -p ${ZLIB_BUILD} + cp -r ${ZLIB_SRC}/* ${ZLIB_BUILD}/ + fi +fi + cd ${ZLIB_BUILD} -cp -r ${ZLIB_SRC}/* . AR="${AR}" CC="${CC}" CFLAGS="$FLAGS -Wno-deprecated-non-prototype" RANLIB=/bin/true ./configure --static make -j libz.a # Build and install libcxxabi and libcxx. -if [[ ! -d ${LIBCXX_BUILD} ]]; then +if [[ ! -f ${LLVM_BUILD}/build.ninja ]]; then + rm -rf ${LIBCXX_BUILD} mkdir -p ${LIBCXX_BUILD} cd ${LIBCXX_BUILD} LIBCXX_FLAGS="${FLAGS} -Wno-macro-redefined" cmake -GNinja \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER_WORKS=ON \ + -DCMAKE_CXX_COMPILER_WORKS=ON \ -DCMAKE_C_COMPILER=$CC \ -DCMAKE_CXX_COMPILER=$CXX \ + -DLIBCXX_ABI_NAMESPACE=__InternalSymbolizer \ + '-DLIBCXX_EXTRA_SITE_DEFINES=_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS;_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS' \ -DCMAKE_C_FLAGS_RELEASE="${LIBCXX_FLAGS}" \ -DCMAKE_CXX_FLAGS_RELEASE="${LIBCXX_FLAGS}" \ -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \ @@ -104,6 +108,8 @@ if [[ ! -d ${LIBCXX_BUILD} ]]; then -DLIBCXX_ENABLE_EXCEPTIONS=OFF \ -DLIBCXX_ENABLE_RTTI=OFF \ -DCMAKE_SHARED_LINKER_FLAGS="$LINKFLAGS" \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ $LLVM_SRC/../runtimes fi cd ${LIBCXX_BUILD} @@ -114,18 +120,24 @@ LLVM_CFLAGS="${FLAGS} -Wno-global-constructors" LLVM_CXXFLAGS="${LLVM_CFLAGS} -nostdinc++ -I${ZLIB_BUILD} -isystem ${LIBCXX_BUILD}/include -isystem ${LIBCXX_BUILD}/include/c++/v1" # Build LLVM. -if [[ ! -d ${LLVM_BUILD} ]]; then +if [[ ! -f ${LLVM_BUILD}/build.ninja ]]; then + rm -rf ${LLVM_BUILD} mkdir -p ${LLVM_BUILD} cd ${LLVM_BUILD} cmake -GNinja \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER_WORKS=ON \ + -DCMAKE_CXX_COMPILER_WORKS=ON \ -DCMAKE_C_COMPILER=$CC \ -DCMAKE_CXX_COMPILER=$CXX \ - -DCMAKE_C_FLAGS="${LLVM_CFLAGS}" \ - -DCMAKE_CXX_FLAGS="${LLVM_CXXFLAGS}" \ + -DLLVM_ENABLE_LIBCXX=ON \ + -DCMAKE_C_FLAGS_RELEASE="${LLVM_CFLAGS}" \ + -DCMAKE_CXX_FLAGS_RELEASE="${LLVM_CXXFLAGS}" \ -DCMAKE_EXE_LINKER_FLAGS="$LINKFLAGS -stdlib=libc++ -L${LIBCXX_BUILD}/lib" \ -DLLVM_TABLEGEN=$TBLGEN \ + -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_ENABLE_ZLIB=ON \ + -DLLVM_ENABLE_ZSTD=OFF \ -DLLVM_ENABLE_TERMINFO=OFF \ -DLLVM_ENABLE_THREADS=OFF \ $LLVM_SRC @@ -145,6 +157,7 @@ $AR rc symbolizer.a sanitizer_symbolize.o sanitizer_wrappers.o SYMBOLIZER_API_LIST=__sanitizer_symbolize_code SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_data +SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_frame SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_flush SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_demangle SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_set_demangle @@ -181,20 +194,6 @@ nm -f posix -g symbolizer.o | cut -f 1,2 -d \ | LC_COLLATE=C sort -u > undefine (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/libclang_rt.*san*.a; do - A_FORMAT=$(arch $A) - if [[ "$A_FORMAT" != "$SYMBOLIZER_FORMAT" ]] ; then - continue - fi - (nm -u $A 2>/dev/null | grep -E "__sanitizer_symbolize_code" >/dev/null) || continue - echo "$A" - $AR rcs $A symbolizer.o -done +cp -f symbolizer.o $OUTPUT echo "Success!" diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt index 509e3f19fe38..0a4bc6989a0d 100644 --- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt +++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -11,6 +11,13 @@ _ZN11__sanitizer16internal_iserrorEjPi U _ZN11__sanitizer16internal_iserrorEmPi U _ZN11__sanitizer17internal_snprintfEPcjPKcz U _ZN11__sanitizer17internal_snprintfEPcmPKcz U +__aarch64_cas8_acq_rel U +__aarch64_ldadd4_acq_rel U +__aarch64_ldadd8_acq_rel U +__aarch64_ldadd8_relax U +__aarch64_swp8_acq_rel U +__ashldi3 U +__ashrdi3 U __ctype_b_loc U __ctype_get_mb_cur_max U __cxa_atexit U @@ -34,13 +41,25 @@ __interceptor_pthread_setspecific w __interceptor_read w __interceptor_realpath w __isinf U +__isoc23_sscanf U +__isoc23_strtol U +__isoc23_strtoll U +__isoc23_strtoll_l U +__isoc23_strtoull U +__isoc23_strtoull_l U +__isoc23_vsscanf U __isoc99_sscanf U __isoc99_vsscanf U +__lshrdi3 U __moddi3 U +__sanitizer_internal_memcpy U +__sanitizer_internal_memmove U +__sanitizer_internal_memset U __sanitizer_symbolize_code T __sanitizer_symbolize_data T __sanitizer_symbolize_demangle T __sanitizer_symbolize_flush T +__sanitizer_symbolize_frame T __sanitizer_symbolize_set_demangle T __sanitizer_symbolize_set_inline_frames T __strdup U |