Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -173,7 +173,7 @@ 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). Index: lib/dfsan/CMakeLists.txt =================================================================== --- lib/dfsan/CMakeLists.txt +++ lib/dfsan/CMakeLists.txt @@ -11,8 +11,7 @@ # 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 @@ 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 Index: lib/dfsan/dfsan.h =================================================================== --- lib/dfsan/dfsan.h +++ lib/dfsan/dfsan.h @@ -44,7 +44,11 @@ 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) { Index: lib/dfsan/dfsan.cc =================================================================== --- lib/dfsan/dfsan.cc +++ lib/dfsan/dfsan.cc @@ -63,12 +63,37 @@ // 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 = 0x7000008000; +#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];