[DFSAN][MIPS] adding support of DFSAN for MIPS64
authorPeter Collingbourne <peter@pcc.me.uk>
Fri, 5 Dec 2014 21:22:36 +0000 (21:22 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Fri, 5 Dec 2014 21:22:36 +0000 (21:22 +0000)
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
compiler-rt/lib/dfsan/CMakeLists.txt
compiler-rt/lib/dfsan/dfsan.cc
compiler-rt/lib/dfsan/dfsan.h

index 90ab7fb..5f921bf 100644 (file)
@@ -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).
index daad07f..257a15a 100644 (file)
@@ -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
index dcc52b1..941edc5 100644 (file)
@@ -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];
index 1b6c150..bc38be0 100644 (file)
@@ -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) {