Index: lsan/lsan_allocator.cc
===================================================================
--- lsan/lsan_allocator.cc
+++ lsan/lsan_allocator.cc
@@ -24,10 +24,10 @@
 
 namespace __lsan {
 
-static const uptr kMaxAllowedMallocSize = 8UL << 30;
+#if SANITIZER_WORDSIZE == 64
 static const uptr kAllocatorSpace = 0x600000000000ULL;
 static const uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.
-
+typedef DefaultSizeClassMap SizeClassMap;
 struct ChunkMetadata {
   bool allocated : 8;  // Must be first.
   ChunkTag tag : 2;
@@ -36,7 +36,29 @@
 };
 
 typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
-        sizeof(ChunkMetadata), DefaultSizeClassMap> PrimaryAllocator;
+        sizeof(ChunkMetadata), SizeClassMap> PrimaryAllocator;
+
+#elif SANITIZER_WORDSIZE == 32
+static const u64 kAddressSpaceSize = 1ULL << 32;
+typedef CompactSizeClassMap SizeClassMap;
+static const uptr kRegionSizeLog = 20;
+static const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog;
+struct ChunkMetadata {
+  bool allocated : 8;  // Must be first.
+  ChunkTag tag : 2;
+  uptr requested_size : 22;
+  u32 stack_trace_id;
+};
+
+typedef SizeClassAllocator32<0, kAddressSpaceSize, sizeof(ChunkMetadata),
+  SizeClassMap, kRegionSizeLog,
+  FlatByteMap<kFlatByteMapSize> >
+  PrimaryAllocator;
+
+#endif
+
+static const uptr kMaxAllowedMallocSize = FIRST_32_SECOND_64(3UL << 27, 8UL << 30);
+
 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
 typedef LargeMmapAllocator<> SecondaryAllocator;
 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
Index: lsan/lsan_common.h
===================================================================
--- lsan/lsan_common.h
+++ lsan/lsan_common.h
@@ -21,7 +21,7 @@
 #include "sanitizer_common/sanitizer_platform.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
-#if SANITIZER_LINUX && defined(__x86_64__)
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__arm__))
 #define CAN_SANITIZE_LEAKS 1
 #else
 #define CAN_SANITIZE_LEAKS 0
Index: lsan/lsan_common.cc
===================================================================
--- lsan/lsan_common.cc
+++ lsan/lsan_common.cc
@@ -247,7 +247,8 @@
                            kReachable);
       ForEachExtraStackRange(os_id, ForEachExtraStackRangeCb, frontier);
     }
-
+// TODO: implement for arm.
+#if defined(__x86_64__)
     if (flags()->use_tls) {
       LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end);
       if (cache_begin == cache_end) {
@@ -264,6 +265,7 @@
           ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable);
       }
     }
+#endif
   }
 }
 
Index: lsan/lsan_interceptors.cc
===================================================================
--- lsan/lsan_interceptors.cc
+++ lsan/lsan_interceptors.cc
@@ -23,6 +23,7 @@
 #include "lsan.h"
 #include "lsan_allocator.h"
 #include "lsan_thread.h"
+#include <stddef.h>
 
 using namespace __lsan;
 
@@ -160,13 +161,13 @@
   return Allocate(stack, size, 1, kAlwaysClearMemory);
 
 INTERCEPTOR_ATTRIBUTE
-void *operator new(uptr size) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size) { OPERATOR_NEW_BODY; }
 INTERCEPTOR_ATTRIBUTE
-void *operator new[](uptr size) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
 INTERCEPTOR_ATTRIBUTE
-void *operator new(uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
 INTERCEPTOR_ATTRIBUTE
-void *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
 
 #define OPERATOR_DELETE_BODY \
   ENSURE_LSAN_INITED;        \
Index: sanitizer_common/sanitizer_linux.h
===================================================================
--- sanitizer_common/sanitizer_linux.h
+++ 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(__arm__)
 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr);
 #endif
Index: sanitizer_common/sanitizer_linux.cc
===================================================================
--- sanitizer_common/sanitizer_linux.cc
+++ sanitizer_common/sanitizer_linux.cc
@@ -794,6 +794,53 @@
                        : "rsp", "memory", "r11", "rcx");
   return res;
 }
+#elif defined(__arm__) && SANITIZER_LINUX
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+                    int *parent_tidptr, void *newtls, int *child_tidptr) {
+  unsigned int res;
+  if (!fn || !child_stack)
+    return -EINVAL;
+  CHECK_EQ(0, (uptr)child_stack % 16);
+  child_stack = (char *)child_stack - 2 * sizeof(unsigned int);
+  ((unsigned int *)child_stack)[0] = (uptr)fn;
+  ((unsigned int *)child_stack)[1] = (uptr)arg;
+  register int r0 __asm__("r0") = flags;
+  register void *r1 __asm__("r1") = child_stack;
+  register int *r2 __asm__("r2") = parent_tidptr;
+  register void *r3 __asm__("r3") = newtls;
+  register int *r4 __asm__("r4") = child_tidptr;
+  register int r7 __asm__("r7") = __NR_clone;
+  __asm__ __volatile__(
+                       "push    {r4, r7}\n"
+                       "swi 0x0\n"
+                       "cmp r0, #0\n"
+                       "bne 1f\n"
+                       "ldr r0, [sp, #4]\n"
+#if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
+                       "ldr     ip, [sp], #8\n"
+                       "mov lr, pc\n"
+                       "bx      ip\n"
+#else
+                       "ldr     lr, [sp], #8\n"
+                       "blx lr\n"
+#endif
+                       "mov r7, %7\n"
+                       "swi 0x0\n"
+                     "1:\n"
+                       "pop {r4, r7}\n"
+                       "mov %0, r0\n"
+                       : "=r" (res)
+                       : "r"(r0),
+                         "r"(r1),
+                         "r"(r2),
+                         "r"(r3),
+                         "r"(r4),
+                         "r"(r7),
+                         "i"(__NR_exit)
+                       : "memory");
+  return res;
+}
+
 #endif  // defined(__x86_64__) && SANITIZER_LINUX
 
 #if SANITIZER_ANDROID
Index: sanitizer_common/sanitizer_platform_limits_posix.h
===================================================================
--- sanitizer_common/sanitizer_platform_limits_posix.h
+++ sanitizer_common/sanitizer_platform_limits_posix.h
@@ -275,10 +275,15 @@
 #endif
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if defined(__x86_64__) || defined(__i386__)
+  const unsigned xdr_ops_fn_num = 10;
+#elif defined(__arm__)
+  const unsigned xdr_ops_fn_num = 9;
+#endif
   struct __sanitizer_XDR {
     int x_op;
     struct xdr_ops {
-      uptr fns[10];
+      uptr fns[xdr_ops_fn_num];
     } *x_ops;
     uptr x_public;
     uptr x_private;
Index: sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
===================================================================
--- sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ 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(__arm__))
 
 #include "sanitizer_stoptheworld.h"
 
@@ -459,4 +459,4 @@
 }
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_LINUX && defined(__x86_64__)
+#endif  // SANITIZER_LINUX && (defined(__x86_64__) || defined(__arm__))