From fd860bc41aa083b8f6fafecb63b242de40659241 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 5 Dec 2014 21:22:36 +0000 Subject: [PATCH] [DFSAN][MIPS] adding support of DFSAN for MIPS64 Minor changes to enable DFSAN on MIPS64 Patch by Kumar Sukhani! Differential Revision: http://reviews.llvm.org/D6437 llvm-svn: 223517 --- compiler-rt/cmake/config-ix.cmake | 2 +- compiler-rt/lib/dfsan/CMakeLists.txt | 5 ++--- compiler-rt/lib/dfsan/dfsan.cc | 25 +++++++++++++++++++++++++ compiler-rt/lib/dfsan/dfsan.h | 4 ++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 90ab7fb..5f921bf 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -173,7 +173,7 @@ filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH x86_64 i386 i686 powerpc64 powerpc64le arm aarch64 mips mips64 mipsel mips64el) filter_available_targets(ASAN_SUPPORTED_ARCH x86_64 i386 i686 powerpc64 powerpc64le arm mips mipsel mips64 mips64el) -filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64) +filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) filter_available_targets(LSAN_SUPPORTED_ARCH x86_64) # LSan common files should be available on all architectures supported # by other sanitizers (even if they build into dummy object files). diff --git a/compiler-rt/lib/dfsan/CMakeLists.txt b/compiler-rt/lib/dfsan/CMakeLists.txt index daad07f..257a15a 100644 --- a/compiler-rt/lib/dfsan/CMakeLists.txt +++ b/compiler-rt/lib/dfsan/CMakeLists.txt @@ -11,8 +11,7 @@ append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CF # Static runtime library. add_custom_target(dfsan) -set(arch "x86_64") -if(CAN_TARGET_${arch}) +foreach(arch ${DFSAN_SUPPORTED_ARCH}) set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS}) append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS) add_compiler_rt_runtime(clang_rt.dfsan-${arch} ${arch} STATIC @@ -30,7 +29,7 @@ if(CAN_TARGET_${arch}) add_dependencies(dfsan clang_rt.dfsan-${arch} clang_rt.dfsan-${arch}-symbols) -endif() +endforeach() set(dfsan_abilist_filename ${COMPILER_RT_OUTPUT_DIR}/dfsan_abilist.txt) add_custom_target(dfsan_abilist ALL diff --git a/compiler-rt/lib/dfsan/dfsan.cc b/compiler-rt/lib/dfsan/dfsan.cc index dcc52b1..941edc5 100644 --- a/compiler-rt/lib/dfsan/dfsan.cc +++ b/compiler-rt/lib/dfsan/dfsan.cc @@ -63,12 +63,37 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64]; // account for the double byte representation of shadow labels and move the // address into the shadow memory range. See the function shadow_for below. +// On Linux/MIPS64, memory is laid out as follows: +// +// +--------------------+ 0x10000000000 (top of memory) +// | application memory | +// +--------------------+ 0xF000008000 (kAppAddr) +// | | +// | unused | +// | | +// +--------------------+ 0x2200000000 (kUnusedAddr) +// | union table | +// +--------------------+ 0x2000000000 (kUnionTableAddr) +// | shadow memory | +// +--------------------+ 0x0000010000 (kShadowAddr) +// | reserved by kernel | +// +--------------------+ 0x0000000000 + typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels]; +#if defined(__x86_64__) static const uptr kShadowAddr = 0x10000; static const uptr kUnionTableAddr = 0x200000000000; static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t); static const uptr kAppAddr = 0x700000008000; +#elif defined(__mips64) +static const uptr kShadowAddr = 0x10000; +static const uptr kUnionTableAddr = 0x2000000000; +static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t); +static const uptr kAppAddr = 0xF000008000; +#else +# error "DFSan not supported for this platform!" +#endif static atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) { return &(*(dfsan_union_table_t *) kUnionTableAddr)[l1][l2]; diff --git a/compiler-rt/lib/dfsan/dfsan.h b/compiler-rt/lib/dfsan/dfsan.h index 1b6c150..bc38be08c 100644 --- a/compiler-rt/lib/dfsan/dfsan.h +++ b/compiler-rt/lib/dfsan/dfsan.h @@ -44,7 +44,11 @@ namespace __dfsan { void InitializeInterceptors(); inline dfsan_label *shadow_for(void *ptr) { +#if defined(__x86_64__) return (dfsan_label *) ((((uptr) ptr) & ~0x700000000000) << 1); +#elif defined(__mips64) + return (dfsan_label *) ((((uptr) ptr) & ~0xF000000000) << 1); +#endif } inline const dfsan_label *shadow_for(const void *ptr) { -- 2.7.4