[compiler-rt] r229830 - [LSan] [MIPS] adding support of LSan for mips64/mips64el arch

Mohit K. Bhakkad mohit.bhakkad at imgtec.com
Wed Feb 18 23:30:40 PST 2015


Author: mohit.bhakkad
Date: Thu Feb 19 01:30:39 2015
New Revision: 229830

URL: http://llvm.org/viewvc/llvm-project?rev=229830&view=rev
Log:
[LSan] [MIPS] adding support of LSan for mips64/mips64el arch

Patch by Sagar Thakur

Reviewers: petarj, earthdok, kcc.

Subscribers:  samsonov, dsanders, mohit.bhakkad, Anand.Takale, llvm-commits.

Differential Revision: http://reviews.llvm.org/D7013

Modified:
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/lsan/lsan_allocator.cc
    compiler-rt/trunk/lib/lsan/lsan_common.cc
    compiler-rt/trunk/lib/lsan/lsan_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Thu Feb 19 01:30:39 2015
@@ -199,7 +199,7 @@ filter_available_targets(SANITIZER_COMMO
 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 mips64 mips64el)
-filter_available_targets(LSAN_SUPPORTED_ARCH x86_64)
+filter_available_targets(LSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
 # LSan common files should be available on all architectures supported
 # by other sanitizers (even if they build into dummy object files).
 filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH

Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.cc Thu Feb 19 01:30:39 2015
@@ -25,10 +25,6 @@ extern "C" void *memset(void *ptr, int v
 
 namespace __lsan {
 
-static const uptr kMaxAllowedMallocSize = 8UL << 30;
-static const uptr kAllocatorSpace = 0x600000000000ULL;
-static const uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.
-
 struct ChunkMetadata {
   bool allocated : 8;  // Must be first.
   ChunkTag tag : 2;
@@ -36,8 +32,22 @@ struct ChunkMetadata {
   u32 stack_trace_id;
 };
 
+#if defined(__mips64)
+static const uptr kMaxAllowedMallocSize = 4UL << 30;
+static const uptr kRegionSizeLog = 20;
+static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
+typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
+typedef CompactSizeClassMap SizeClassMap;
+typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE,
+    sizeof(ChunkMetadata), SizeClassMap, kRegionSizeLog, ByteMap>
+    PrimaryAllocator;
+#else
+static const uptr kMaxAllowedMallocSize = 8UL << 30;
+static const uptr kAllocatorSpace = 0x600000000000ULL;
+static const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
 typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
         sizeof(ChunkMetadata), DefaultSizeClassMap> PrimaryAllocator;
+#endif
 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
 typedef LargeMmapAllocator<> SecondaryAllocator;
 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Thu Feb 19 01:30:39 2015
@@ -106,9 +106,11 @@ static inline bool CanBeAHeapPointer(upt
   // bound on heap addresses.
   const uptr kMinAddress = 4 * 4096;
   if (p < kMinAddress) return false;
-#ifdef __x86_64__
+#if defined(__x86_64__)
   // Accept only canonical form user-space addresses.
   return ((p >> 47) == 0);
+#elif defined(__mips64)
+  return ((p >> 40) == 0);
 #else
   return true;
 #endif

Modified: compiler-rt/trunk/lib/lsan/lsan_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.h?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.h (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.h Thu Feb 19 01:30:39 2015
@@ -21,7 +21,8 @@
 #include "sanitizer_common/sanitizer_platform.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
-#if SANITIZER_LINUX && defined(__x86_64__) && (SANITIZER_WORDSIZE == 64)
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips64)) \
+    && (SANITIZER_WORDSIZE == 64)
 #define CAN_SANITIZE_LEAKS 1
 #else
 #define CAN_SANITIZE_LEAKS 0

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Feb 19 01:30:39 2015
@@ -860,6 +860,13 @@ uptr internal_clone(int (*fn)(void *), v
                        : "rsp", "memory", "r11", "rcx");
   return res;
 }
+#elif defined(__mips__)
+// TODO(sagarthakur): clone function is to be rewritten in assembly.
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+                    int *parent_tidptr, void *newtls, int *child_tidptr) {
+  return clone(fn, child_stack, flags, arg, parent_tidptr,
+               newtls, child_tidptr);
+}
 #endif  // defined(__x86_64__) && SANITIZER_LINUX
 
 #if SANITIZER_ANDROID

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h Thu Feb 19 01:30:39 2015
@@ -43,7 +43,7 @@ uptr internal_prctl(int option, uptr arg
 // internal_sigaction instead.
 int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
 void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(__mips__)
 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr);
 #endif

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Thu Feb 19 01:30:39 2015
@@ -168,6 +168,20 @@ static uptr g_tls_size;
 # define DL_INTERNAL_FUNCTION
 #endif
 
+#if defined(__mips__)
+// TlsPreTcbSize includes size of struct pthread_descr and size of tcb
+// head structure. It lies before the static tls blocks.
+static uptr TlsPreTcbSize() {
+  const uptr kTcbHead = 16;
+  const uptr kTlsAlign = 16;
+  const uptr kTlsPreTcbSize =
+    (ThreadDescriptorSize() + kTcbHead + kTlsAlign - 1) & ~(kTlsAlign - 1);
+  InitTlsSize();
+  g_tls_size = (g_tls_size + kTlsPreTcbSize + kTlsAlign -1) & ~(kTlsAlign - 1);
+  return kTlsPreTcbSize;
+}
+#endif
+
 void InitTlsSize() {
 #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO
   typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
@@ -184,7 +198,8 @@ void InitTlsSize() {
 #endif  // !SANITIZER_FREEBSD && !SANITIZER_ANDROID
 }
 
-#if (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+    && SANITIZER_LINUX
 // sizeof(struct thread) from glibc.
 static atomic_uintptr_t kThreadDescriptorSize;
 
@@ -192,6 +207,7 @@ uptr ThreadDescriptorSize() {
   uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed);
   if (val)
     return val;
+#if defined(__x86_64__) || defined(__i386__)
 #ifdef _CS_GNU_LIBC_VERSION
   char buf[64];
   uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf));
@@ -224,6 +240,13 @@ uptr ThreadDescriptorSize() {
     return val;
   }
 #endif
+#elif defined(__mips__)
+  // TODO(sagarthakur): add more values as per different glibc versions.
+  val = FIRST_32_SECOND_64(1152, 1776);
+  if (val)
+    atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
+  return val;
+#endif
   return 0;
 }
 
@@ -240,12 +263,25 @@ uptr ThreadSelf() {
   asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
 # elif defined(__x86_64__)
   asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
+# elif defined(__mips__)
+  // MIPS uses TLS variant I. The thread pointer (in hardware register $29)
+  // points to the end of the TCB + 0x7000. The pthread_descr structure is
+  // immediately in front of the TCB. TlsPreTcbSize() includes the size of the
+  // TCB and the size of pthread_descr.
+  const uptr kTlsTcbOffset = 0x7000;
+  uptr thread_pointer;
+  asm volatile(".set push;\
+                .set mips64r2;\
+                rdhwr %0,$29;\
+                .set pop" : "=r" (thread_pointer));
+  descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
 # else
 #  error "unsupported CPU arch"
 # endif
   return descr_addr;
 }
-#endif  // (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+#endif  // (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+        // && SANITIZER_LINUX
 
 #if SANITIZER_FREEBSD
 static void **ThreadSelfSegbase() {
@@ -275,6 +311,9 @@ static void GetTls(uptr *addr, uptr *siz
   *size = GetTlsSize();
   *addr -= *size;
   *addr += ThreadDescriptorSize();
+# elif defined(__mips__)
+  *addr = ThreadSelf();
+  *size = GetTlsSize();
 # else
   *addr = 0;
   *size = 0;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h Thu Feb 19 01:30:39 2015
@@ -547,6 +547,10 @@ namespace __sanitizer {
 
 #if SANITIZER_FREEBSD
   typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
+#elif defined(__mips__)
+  struct __sanitizer_kernel_sigset_t {
+    u8 sig[16];
+  };
 #else
   struct __sanitizer_kernel_sigset_t {
     u8 sig[8];

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc Thu Feb 19 01:30:39 2015
@@ -14,7 +14,7 @@
 
 
 #include "sanitizer_platform.h"
-#if SANITIZER_LINUX && defined(__x86_64__)
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))
 
 #include "sanitizer_stoptheworld.h"
 
@@ -451,4 +451,4 @@ uptr SuspendedThreadsList::RegisterCount
 }
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_LINUX && defined(__x86_64__)
+#endif  // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc?rev=229830&r1=229829&r2=229830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc Thu Feb 19 01:30:39 2015
@@ -255,6 +255,14 @@ TEST(SanitizerCommon, LibraryNameIs) {
     }
 }
 
+#if defined(__mips64)
+// Effectively, this is a test for ThreadDescriptorSize() which is used to
+// compute ThreadSelf().
+TEST(SanitizerLinux, ThreadSelfTest) {
+  ASSERT_EQ(pthread_self(), ThreadSelf());
+}
+#endif
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_LINUX





More information about the llvm-commits mailing list