Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -173,7 +173,7 @@ filter_available_targets(ASAN_SUPPORTED_ARCH x86_64 i386 i686 powerpc64 arm mips mipsel) filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64) -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 Index: lib/lsan/lsan_allocator.cc =================================================================== --- lib/lsan/lsan_allocator.cc +++ lib/lsan/lsan_allocator.cc @@ -26,8 +26,13 @@ namespace __lsan { static const uptr kMaxAllowedMallocSize = 8UL << 30; +#if defined(__mips64) +static const uptr kAllocatorSpace = 0x4000000000ULL; +static const uptr kAllocatorSize = 0x4000000000ULL; // 256GB. +#else static const uptr kAllocatorSpace = 0x600000000000ULL; static const uptr kAllocatorSize = 0x40000000000ULL; // 4T. +#endif struct ChunkMetadata { bool allocated : 8; // Must be first. Index: lib/lsan/lsan_common.h =================================================================== --- lib/lsan/lsan_common.h +++ lib/lsan/lsan_common.h @@ -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 Index: lib/lsan/lsan_common.cc =================================================================== --- lib/lsan/lsan_common.cc +++ lib/lsan/lsan_common.cc @@ -144,6 +144,8 @@ #ifdef __x86_64__ // Accept only canonical form user-space addresses. return ((p >> 47) == 0); +#elif defined(__mipe64) + return ((p >> 40) == 0); #else return true; #endif Index: lib/sanitizer_common/sanitizer_linux.h =================================================================== --- lib/sanitizer_common/sanitizer_linux.h +++ lib/sanitizer_common/sanitizer_linux.h @@ -43,7 +43,7 @@ // 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 Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -833,6 +833,13 @@ : "rsp", "memory", "r11", "rcx"); return res; } +#elif defined(__mips__) +// TODO(kumarsukhani): 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 Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -177,7 +177,8 @@ #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; @@ -231,13 +232,26 @@ 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__) +// For MIPS TLS variant I is used +// The thread pointer (in hardware register $29) points to +// the end of the TCB + 0x7000 + + const uptr kTlsTcbOffset = 0x7000; + const uptr kTlsPreTcbSize = 0x10; + + asm volatile(".set push;\ + .set mips32r2;\ + rdhwr %0,$29;\ + .set\tpop" : "=r" (descr_addr)); + descr_addr -= (kTlsTcbOffset + kTlsPreTcbSize); # 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() { void **segbase = 0; @@ -265,6 +279,9 @@ *size = GetTlsSize(); *addr -= *size; *addr += ThreadDescriptorSize(); +# elif defined(__mips__) + *addr = ThreadSelf(); + *size = GetTlsSize(); # else *addr = 0; *size = 0; Index: lib/sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -538,6 +538,10 @@ #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]; Index: lib/sanitizer_common/sanitizer_printf.cc =================================================================== --- lib/sanitizer_common/sanitizer_printf.cc +++ lib/sanitizer_common/sanitizer_printf.cc @@ -112,8 +112,14 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) { int result = 0; result += AppendString(buff, buff_end, -1, "0x"); +#ifdef __mips__ +// Addressable memory of mips64 is 40 bits + result += AppendUnsigned(buff, buff_end, ptr_value, 16, + (SANITIZER_WORDSIZE == 64) ? 10 : 8, true); +#else result += AppendUnsigned(buff, buff_end, ptr_value, 16, (SANITIZER_WORDSIZE == 64) ? 12 : 8, true); +#endif return result; } Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -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" @@ -459,4 +459,4 @@ } } // namespace __sanitizer -#endif // SANITIZER_LINUX && defined(__x86_64__) +#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))