[compiler-rt] r320740 - [Sanitizers] Basic sanitizer Solaris support (PR 33274)

Kamil Rytarowski via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 14 12:14:29 PST 2017


Author: kamil
Date: Thu Dec 14 12:14:29 2017
New Revision: 320740

URL: http://llvm.org/viewvc/llvm-project?rev=320740&view=rev
Log:
[Sanitizers] Basic sanitizer Solaris support (PR 33274)

Summary:
This is the first mostly working version of the Sanitizer port to 32-bit Solaris/x86.
It is currently based on Solaris 11.4 Beta.

This part was initially developed inside libsanitizer in the GCC tree and should apply to
both.  Subsequent parts will address changes to clang, the compiler-rt build system
and testsuite.

I'm not yet sure what the right patch granularity is: if it's profitable to split the patch
up, I'd like to get guidance on how to do so.

Most of the changes are probably straightforward with a few exceptions:

* The Solaris syscall interface isn't stable, undocumented and can change within an
  OS release.  The stable interface is the libc interface, which I'm using here, if possible
  using the internal _-prefixed names.

* While the patch primarily target 32-bit x86, I've left a few sparc changes in.  They
  cannot currently be used with clang due to a backend limitation, but have worked
  fine inside the gcc tree.

* Some functions (e.g. largefile versions of functions like open64) only exist in 32-bit
  Solaris, so I've introduced a separate SANITIZER_SOLARIS32 to check for that.

The patch (with the subsequent ones to be submitted shortly) was tested
on i386-pc-solaris2.11.  Only a few failures remain, some of them analyzed, some
still TBD:

    AddressSanitizer-i386-sunos :: TestCases/Posix/concurrent_overflow.cc
    AddressSanitizer-i386-sunos :: TestCases/init-order-atexit.cc
    AddressSanitizer-i386-sunos :: TestCases/log-path_test.cc
    AddressSanitizer-i386-sunos :: TestCases/malloc-no-intercept.c
    AddressSanitizer-i386-sunos-dynamic :: TestCases/Posix/concurrent_overflow.cc
    AddressSanitizer-i386-sunos-dynamic :: TestCases/Posix/start-deactivated.cc
    AddressSanitizer-i386-sunos-dynamic :: TestCases/default_options.cc
    AddressSanitizer-i386-sunos-dynamic :: TestCases/init-order-atexit.cc
    AddressSanitizer-i386-sunos-dynamic :: TestCases/log-path_test.cc
    AddressSanitizer-i386-sunos-dynamic :: TestCases/malloc-no-intercept.c

   SanitizerCommon-Unit :: ./Sanitizer-i386-Test/MemoryMappingLayout.DumpListOfModules
    SanitizerCommon-Unit :: ./Sanitizer-i386-Test/SanitizerCommon.PthreadDestructorIterations

Maybe this is good enough the get the ball rolling.

Reviewers: kcc, alekseyshl

Reviewed By: alekseyshl

Subscribers: srhines, jyknight, kubamracek, krytarowski, fedor.sergeev, llvm-commits, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D40898

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_solaris.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
    compiler-rt/trunk/lib/interception/interception.h
    compiler-rt/trunk/lib/interception/interception_linux.cc
    compiler-rt/trunk/lib/interception/interception_linux.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_errno.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.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_mutex.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_syscall_generic.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
    compiler-rt/trunk/lib/ubsan/ubsan_platform.h

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Thu Dec 14 12:14:29 2017
@@ -55,13 +55,14 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT_FORK 0
 #endif
 
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1
 #else
 # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
 #endif
 
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS
 # define ASAN_INTERCEPT_SWAPCONTEXT 1
 #else
 # define ASAN_INTERCEPT_SWAPCONTEXT 0
@@ -81,7 +82,8 @@ void InitializePlatformInterceptors();
 
 // Android bug: https://code.google.com/p/android/issues/detail?id=61799
 #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && \
-    !(SANITIZER_ANDROID && defined(__i386))
+    !(SANITIZER_ANDROID && defined(__i386)) && \
+    !SANITIZER_SOLARIS
 # define ASAN_INTERCEPT___CXA_THROW 1
 #else
 # define ASAN_INTERCEPT___CXA_THROW 0

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Thu Dec 14 12:14:29 2017
@@ -13,7 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #include "asan_interceptors.h"
 #include "asan_internal.h"
@@ -40,7 +41,11 @@
 #include <sys/link_elf.h>
 #endif
 
-#if SANITIZER_ANDROID || SANITIZER_FREEBSD
+#if SANITIZER_SOLARIS
+#include <link.h>
+#endif
+
+#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS
 #include <ucontext.h>
 extern "C" void* _DYNAMIC;
 #elif SANITIZER_NETBSD
@@ -140,6 +145,9 @@ void AsanCheckIncompatibleRT() {}
 #else
 static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,
                                 void *data) {
+  VReport(2, "info->dlpi_name = %s\tinfo->dlpi_addr = %p\n",
+          info->dlpi_name, info->dlpi_addr);
+
   // Continue until the first dynamic library is found
   if (!info->dlpi_name || info->dlpi_name[0] == 0)
     return 0;
@@ -157,6 +165,12 @@ static int FindFirstDSOCallback(struct d
   }
 #endif
 
+#if SANITIZER_SOLARIS
+  // Ignore executable on Solaris
+  if (info->dlpi_addr == 0)
+    return 0;
+#endif
+
   *(const char **)data = info->dlpi_name;
   return 1;
 }
@@ -235,4 +249,5 @@ void *AsanDlSymNext(const char *sym) {
 
 } // namespace __asan
 
-#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_linux.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc Thu Dec 14 12:14:29 2017
@@ -16,7 +16,7 @@
 
 #include "sanitizer_common/sanitizer_platform.h"
 #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
-    SANITIZER_NETBSD
+    SANITIZER_NETBSD || SANITIZER_SOLARIS
 
 #include "sanitizer_common/sanitizer_tls_get_addr.h"
 #include "asan_allocator.h"
@@ -236,4 +236,4 @@ void ReplaceSystemMalloc() {
 #endif  // SANITIZER_ANDROID
 
 #endif  // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX ||
-        // SANITIZER_NETBSD
+        // SANITIZER_NETBSD || SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/interception/interception.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception.h (original)
+++ compiler-rt/trunk/lib/interception/interception.h Thu Dec 14 12:14:29 2017
@@ -18,7 +18,8 @@
 #include "sanitizer_common/sanitizer_internal_defs.h"
 
 #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
-    !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA
+    !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
+    !SANITIZER_SOLARIS
 # error "Interception doesn't work on this operating system."
 #endif
 
@@ -264,7 +265,9 @@ typedef unsigned long uptr;  // NOLINT
 
 #define INCLUDED_FROM_INTERCEPTION_LIB
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
+
 # include "interception_linux.h"
 # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
 # define INTERCEPT_FUNCTION_VER(func, symver) \

Modified: compiler-rt/trunk/lib/interception/interception_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception_linux.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_linux.cc (original)
+++ compiler-rt/trunk/lib/interception/interception_linux.cc Thu Dec 14 12:14:29 2017
@@ -14,7 +14,8 @@
 
 #include "interception.h"
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #include <dlfcn.h>   // for dlsym() and dlvsym()
 
@@ -41,7 +42,8 @@ bool GetRealFunctionAddress(const char *
   return real == wrapper;
 }
 
-#if !SANITIZER_ANDROID  // android does not have dlvsym
+// Android and Solaris do not have dlvsym
+#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS
 void *GetFuncAddrVer(const char *func_name, const char *ver) {
   return dlvsym(RTLD_NEXT, func_name, ver);
 }
@@ -49,4 +51,5 @@ void *GetFuncAddrVer(const char *func_na
 
 }  // namespace __interception
 
-#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/interception/interception_linux.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception_linux.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_linux.h (original)
+++ compiler-rt/trunk/lib/interception/interception_linux.h Thu Dec 14 12:14:29 2017
@@ -12,7 +12,8 @@
 // Linux-specific interception methods.
 //===----------------------------------------------------------------------===//
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
 # error "interception_linux.h should be included from interception library only"
@@ -34,14 +35,16 @@ void *GetFuncAddrVer(const char *func_na
       (::__interception::uptr) & (func),                                   \
       (::__interception::uptr) & WRAP(func))
 
-#if !SANITIZER_ANDROID  // android does not have dlvsym
+// Android and Solaris do not have dlvsym
+#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS
 #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
   (::__interception::real_##func = (func##_f)(                \
        unsigned long)::__interception::GetFuncAddrVer(#func, symver))
 #else
 #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
   INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
-#endif  // !SANITIZER_ANDROID
+#endif  // !SANITIZER_ANDROID && !SANITIZER_SOLARIS
 
 #endif  // INTERCEPTION_LINUX_H
-#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Dec 14 12:14:29 2017
@@ -1217,12 +1217,14 @@ INTERCEPTOR(unsigned long, time, unsigne
 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
+#if !SANITIZER_SOLARIS
   if (tm->tm_zone) {
     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
     // can point to shared memory and tsan would report a data race.
     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
                                         REAL(strlen(tm->tm_zone)) + 1);
   }
+#endif
 }
 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
   void *ctx;
@@ -2113,6 +2115,18 @@ static void unpoison_glob_t(void *ctx, _
   }
 }
 
+#if SANITIZER_SOLARIS
+INTERCEPTOR(int, glob, const char *pattern, int flags,
+            int (*errfunc)(const char *epath, int eerrno),
+            __sanitizer_glob_t *pglob) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
+  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
+  int res = REAL(glob)(pattern, flags, errfunc, pglob);
+  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
+  return res;
+}
+#else
 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
 
 static void wrapped_gl_closedir(void *dir) {
@@ -2176,7 +2190,14 @@ INTERCEPTOR(int, glob, const char *patte
   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   return res;
 }
+#endif  // SANITIZER_SOLARIS
+#define INIT_GLOB                  \
+  COMMON_INTERCEPT_FUNCTION(glob);
+#else  // SANITIZER_INTERCEPT_GLOB
+#define INIT_GLOB
+#endif  // SANITIZER_INTERCEPT_GLOB
 
+#if SANITIZER_INTERCEPT_GLOB64
 INTERCEPTOR(int, glob64, const char *pattern, int flags,
             int (*errfunc)(const char *epath, int eerrno),
             __sanitizer_glob_t *pglob) {
@@ -2205,12 +2226,11 @@ INTERCEPTOR(int, glob64, const char *pat
   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   return res;
 }
-#define INIT_GLOB                  \
-  COMMON_INTERCEPT_FUNCTION(glob); \
+#define INIT_GLOB64                \
   COMMON_INTERCEPT_FUNCTION(glob64);
-#else  // SANITIZER_INTERCEPT_GLOB
-#define INIT_GLOB
-#endif  // SANITIZER_INTERCEPT_GLOB
+#else  // SANITIZER_INTERCEPT_GLOB64
+#define INIT_GLOB64
+#endif  // SANITIZER_INTERCEPT_GLOB64
 
 #if SANITIZER_INTERCEPT_WAIT
 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
@@ -2515,7 +2535,15 @@ INTERCEPTOR(struct __sanitizer_hostent *
   if (res) write_hostent(ctx, res);
   return res;
 }
+#define INIT_GETHOSTBYNAME                  \
+  COMMON_INTERCEPT_FUNCTION(gethostent);    \
+  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
+  COMMON_INTERCEPT_FUNCTION(gethostbyname);
+#else
+#define INIT_GETHOSTBYNAME
+#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME
 
+#if SANITIZER_INTERCEPT_GETHOSTBYNAME2
 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
@@ -2523,14 +2551,10 @@ INTERCEPTOR(struct __sanitizer_hostent *
   if (res) write_hostent(ctx, res);
   return res;
 }
-#define INIT_GETHOSTBYNAME                  \
-  COMMON_INTERCEPT_FUNCTION(gethostent);    \
-  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
-  COMMON_INTERCEPT_FUNCTION(gethostbyname); \
-  COMMON_INTERCEPT_FUNCTION(gethostbyname2);
+#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
 #else
-#define INIT_GETHOSTBYNAME
-#endif
+#define INIT_GETHOSTBYNAME2
+#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME2
 
 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
@@ -6384,6 +6408,7 @@ static void InitializeCommonInterceptors
   INIT_GETITIMER;
   INIT_TIME;
   INIT_GLOB;
+  INIT_GLOB64;
   INIT_WAIT;
   INIT_WAIT4;
   INIT_INET;
@@ -6392,6 +6417,7 @@ static void InitializeCommonInterceptors
   INIT_GETNAMEINFO;
   INIT_GETSOCKNAME;
   INIT_GETHOSTBYNAME;
+  INIT_GETHOSTBYNAME2;
   INIT_GETHOSTBYNAME_R;
   INIT_GETHOSTBYNAME2_R;
   INIT_GETHOSTBYADDR_R;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc Thu Dec 14 12:14:29 2017
@@ -57,7 +57,9 @@ static void ioctl_table_fill() {
   _(SIOCGIFCONF, CUSTOM, 0);
   _(SIOCGPGRP, WRITE, sizeof(int));
   _(SIOCSPGRP, READ, sizeof(int));
+#if !SANITIZER_SOLARIS
   _(TIOCCONS, NONE, 0);
+#endif
   _(TIOCEXCL, NONE, 0);
   _(TIOCGETD, WRITE, sizeof(int));
   _(TIOCGPGRP, WRITE, pid_t_sz);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_errno.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_errno.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_errno.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_errno.h Thu Dec 14 12:14:29 2017
@@ -26,6 +26,8 @@
 #  define __errno_location __error
 #elif SANITIZER_ANDROID || SANITIZER_NETBSD
 #  define __errno_location __errno
+#elif SANITIZER_SOLARIS
+#  define __errno_location ___errno
 #elif SANITIZER_WINDOWS
 #  define __errno_location _errno
 #endif

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Thu Dec 14 12:14:29 2017
@@ -65,7 +65,7 @@
 // SANITIZER_SUPPORTS_WEAK_HOOKS means that we support real weak functions that
 // will evaluate to a null pointer when not defined.
 #ifndef SANITIZER_SUPPORTS_WEAK_HOOKS
-#if (SANITIZER_LINUX || SANITIZER_MAC) && !SANITIZER_GO
+#if (SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_SOLARIS) && !SANITIZER_GO
 # define SANITIZER_SUPPORTS_WEAK_HOOKS 1
 #else
 # define SANITIZER_SUPPORTS_WEAK_HOOKS 0
@@ -91,6 +91,10 @@
 // FIXME: do we have anything like this on Mac?
 #if SANITIZER_LINUX && !SANITIZER_ANDROID && !defined(PIC)
 # define SANITIZER_CAN_USE_PREINIT_ARRAY 1
+// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld.
+// FIXME: Check for those conditions.
+#elif SANITIZER_SOLARIS && !defined(PIC)
+# define SANITIZER_CAN_USE_PREINIT_ARRAY 1
 #else
 # define SANITIZER_CAN_USE_PREINIT_ARRAY 0
 #endif
@@ -137,7 +141,11 @@ typedef unsigned error_t;
 typedef int fd_t;
 typedef int error_t;
 #endif
+#if SANITIZER_SOLARIS && !defined(_LP64)
+typedef long pid_t;
+#else
 typedef int pid_t;
+#endif
 
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \
     (SANITIZER_LINUX && defined(__x86_64__))

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=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Dec 14 12:14:29 2017
@@ -14,7 +14,8 @@
 
 #include "sanitizer_platform.h"
 
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #include "sanitizer_common.h"
 #include "sanitizer_flags.h"
@@ -55,7 +56,9 @@
 #include <pthread.h>
 #include <sched.h>
 #include <sys/mman.h>
+#if !SANITIZER_SOLARIS
 #include <sys/ptrace.h>
+#endif
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -92,6 +95,14 @@ extern char **environ;  // provided by c
 extern struct ps_strings *__ps_strings;
 #endif  // SANITIZER_NETBSD
 
+#if SANITIZER_SOLARIS
+#include <stdlib.h>
+#include <thread.h>
+
+extern char **_environ;
+#define environ _environ
+#endif
+
 #if !SANITIZER_ANDROID
 #include <sys/signal.h>
 #endif
@@ -146,6 +157,7 @@ namespace __sanitizer {
 #endif
 
 // --------------- sanitizer_libc.h
+#if !SANITIZER_SOLARIS
 #if !SANITIZER_S390
 uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
                    OFF_T offset) {
@@ -424,6 +436,7 @@ uptr internal_execve(const char *filenam
   return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv,
                           (uptr)envp);
 }
+#endif // !SANITIZER_SOLARIS
 
 // ----------------- sanitizer_common.h
 bool FileExists(const char *filename) {
@@ -443,11 +456,14 @@ tid_t GetTid() {
   return (uptr)pthread_self();
 #elif SANITIZER_NETBSD
   return _lwp_self();
+#elif SANITIZER_SOLARIS
+  return (uptr)thr_self();
 #else
   return internal_syscall(SYSCALL(gettid));
 #endif
 }
 
+#if !SANITIZER_SOLARIS
 u64 NanoTime() {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
   timeval tv;
@@ -462,12 +478,13 @@ u64 NanoTime() {
 uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
   return internal_syscall_ptr(SYSCALL(clock_gettime), clk_id, tp);
 }
+#endif // !SANITIZER_SOLARIS
 
 // Like getenv, but reads env directly from /proc (on Linux) or parses the
-// 'environ' array (on FreeBSD) and does not use libc. This function should be
-// called first inside __asan_init.
+// 'environ' array (on some others) and does not use libc. This function
+// should be called first inside __asan_init.
 const char *GetEnv(const char *name) {
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS
   if (::environ != 0) {
     uptr NameLen = internal_strlen(name);
     for (char **Env = ::environ; *Env != 0; Env++) {
@@ -590,6 +607,9 @@ void ReExec() {
   len = sizeof(path);
   if (sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
     pathname = path;
+#elif SANITIZER_SOLARIS
+  pathname = getexecname();
+  CHECK_NE(pathname, NULL);
 #endif
 
   GetArgsAndEnv(&argv, &envp);
@@ -600,6 +620,7 @@ void ReExec() {
   Die();
 }
 
+#if !SANITIZER_SOLARIS
 enum MutexState {
   MtxUnlocked = 0,
   MtxLocked = 1,
@@ -619,7 +640,7 @@ void BlockingMutex::Lock() {
 #if SANITIZER_FREEBSD
     _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0);
 #elif SANITIZER_NETBSD
-    sched_yield(); /* No userspace futex-like synchromization */
+    sched_yield(); /* No userspace futex-like synchronization */
 #else
     internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0);
 #endif
@@ -634,7 +655,7 @@ void BlockingMutex::Unlock() {
 #if SANITIZER_FREEBSD
     _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0);
 #elif SANITIZER_NETBSD
-                   /* No userspace futex-like synchromization */
+                   /* No userspace futex-like synchronization */
 #else
     internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE, 1, 0, 0, 0);
 #endif
@@ -645,6 +666,7 @@ void BlockingMutex::CheckLocked() {
   atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
   CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
 }
+#endif // !SANITIZER_SOLARIS
 
 // ----------------- sanitizer_linux.h
 // The actual size of this structure is specified by d_reclen.
@@ -677,6 +699,7 @@ struct linux_dirent {
 };
 #endif
 
+#if !SANITIZER_SOLARIS
 // Syscall wrappers.
 uptr internal_ptrace(int request, int pid, void *addr, void *data) {
 #if SANITIZER_NETBSD
@@ -854,6 +877,7 @@ bool internal_sigismember(__sanitizer_si
   return k_set->sig[idx] & (1 << bit);
 }
 #endif  // SANITIZER_LINUX
+#endif // !SANITIZER_SOLARIS
 
 // ThreadLister implementation.
 ThreadLister::ThreadLister(int pid)
@@ -1011,6 +1035,11 @@ uptr GetPageSize() {
 }
 
 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
+#if SANITIZER_SOLARIS
+  const char *default_module_name = getexecname();
+  CHECK_NE(default_module_name, NULL);
+  return internal_snprintf(buf, buf_len, "%s", default_module_name);
+#else
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
 #if SANITIZER_FREEBSD
   const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
@@ -1028,7 +1057,7 @@ uptr ReadBinaryName(/*out*/char *buf, up
       default_module_name, buf, buf_len);
   int readlink_error;
   bool IsErr = internal_iserror(module_name_len, &readlink_error);
-#endif
+#endif  // SANITIZER_SOLARIS
   if (IsErr) {
     // We can't read binary name for some reason, assume it's unknown.
     Report("WARNING: reading executable name failed with errno %d, "
@@ -1038,6 +1067,7 @@ uptr ReadBinaryName(/*out*/char *buf, up
     CHECK_LT(module_name_len, buf_len);
   }
   return module_name_len;
+#endif
 }
 
 uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
@@ -1662,6 +1692,9 @@ SignalContext::WriteFlag SignalContext::
   uptr err = ucontext->uc_mcontext.mc_err;
 #elif SANITIZER_NETBSD
   uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
+#elif SANITIZER_SOLARIS && defined(__i386__)
+# define ERR 13
+  uptr err = ucontext->uc_mcontext.gregs[ERR];
 #else
   uptr err = ucontext->uc_mcontext.gregs[REG_ERR];
 #endif
@@ -1675,6 +1708,12 @@ SignalContext::WriteFlag SignalContext::
   u64 esr;
   if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN;
   return esr & ESR_ELx_WNR ? WRITE : READ;
+#elif SANITIZER_SOLARIS && defined(__sparc__)
+  // Decode the instruction to determine the access type.
+  // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype).
+  uptr pc = ucontext->uc_mcontext.gregs[REG_PC];
+  u32 instr = *(u32 *)pc;
+  return (instr >> 21) & 1 ? WRITE: READ;
 #else
   (void)ucontext;
   return UNKNOWN;  // FIXME: Implement.
@@ -1732,6 +1771,19 @@ static void GetPcSpBp(void *context, upt
   *sp = ucontext->uc_mcontext.__gregs[_REG_ESP];
 # else
   ucontext_t *ucontext = (ucontext_t*)context;
+# if SANITIZER_SOLARIS
+  /* Use the numeric values: the symbolic ones are undefined by llvm
+     include/llvm/Support/Solaris.h.  */
+# ifndef REG_EIP
+#  define REG_EIP 14 // REG_PC
+# endif
+# ifndef REG_EBP
+#  define REG_EBP  6 // REG_FP
+# endif
+# ifndef REG_ESP
+#  define REG_ESP 17 // REG_SP
+# endif
+# endif
   *pc = ucontext->uc_mcontext.gregs[REG_EIP];
   *bp = ucontext->uc_mcontext.gregs[REG_EBP];
   *sp = ucontext->uc_mcontext.gregs[REG_ESP];
@@ -1746,7 +1798,16 @@ static void GetPcSpBp(void *context, upt
 #elif defined(__sparc__)
   ucontext_t *ucontext = (ucontext_t*)context;
   uptr *stk_ptr;
-# if defined (__arch64__)
+# if defined (__sparcv9)
+# ifndef MC_PC
+#  define MC_PC REG_PC
+# endif
+# ifndef MC_O6
+#  define MC_O6 REG_O6
+# endif
+# ifdef SANITIZER_SOLARIS
+#  define mc_gregs gregs
+# endif
   *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
   *sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
   stk_ptr = (uptr *) (*sp + 2047);
@@ -1835,4 +1896,6 @@ bool GetRandom(void *buffer, uptr length
 
 } // namespace __sanitizer
 
-#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS
+

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=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h Thu Dec 14 12:14:29 2017
@@ -14,11 +14,13 @@
 #define SANITIZER_LINUX_H
 
 #include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 #include "sanitizer_common.h"
 #include "sanitizer_internal_defs.h"
 #include "sanitizer_platform_limits_netbsd.h"
 #include "sanitizer_platform_limits_posix.h"
+#include "sanitizer_platform_limits_solaris.h"
 #include "sanitizer_posix.h"
 
 struct link_map;  // Opaque type returned by dlopen().
@@ -143,5 +145,6 @@ ALWAYS_INLINE uptr *get_android_tls_ptr(
 
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS
 #endif  // SANITIZER_LINUX_H

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=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Thu Dec 14 12:14:29 2017
@@ -14,7 +14,8 @@
 
 #include "sanitizer_platform.h"
 
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #include "sanitizer_allocator_internal.h"
 #include "sanitizer_atomic.h"
@@ -46,6 +47,10 @@
 #include <sys/tls.h>
 #endif
 
+#if SANITIZER_SOLARIS
+#include <thread.h>
+#endif
+
 #if SANITIZER_LINUX
 #include <sys/prctl.h>
 #endif
@@ -115,13 +120,20 @@ void GetThreadStackTopAndBottom(bool at_
     *stack_bottom = segment.end - stacksize;
     return;
   }
+  uptr stacksize = 0;
+  void *stackaddr = nullptr;
+#if SANITIZER_SOLARIS
+  stack_t ss;
+  CHECK_EQ(thr_stksegment(&ss), 0);
+  stacksize = ss.ss_size;
+  stackaddr = (char *)ss.ss_sp - stacksize;
+#else // !SANITIZER_SOLARIS
   pthread_attr_t attr;
   pthread_attr_init(&attr);
   CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
-  uptr stacksize = 0;
-  void *stackaddr = nullptr;
   my_pthread_attr_getstack(&attr, &stackaddr, &stacksize);
   pthread_attr_destroy(&attr);
+#endif // SANITIZER_SOLARIS
 
   *stack_top = (uptr)stackaddr + stacksize;
   *stack_bottom = (uptr)stackaddr;
@@ -162,7 +174,7 @@ bool SanitizerGetThreadName(char *name,
 }
 
 #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
-    !SANITIZER_NETBSD
+    !SANITIZER_NETBSD && !SANITIZER_SOLARIS
 static uptr g_tls_size;
 
 #ifdef __i386__
@@ -191,7 +203,7 @@ void InitTlsSize() {
 #else
 void InitTlsSize() { }
 #endif  // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO &&
-        // !SANITIZER_NETBSD
+        // !SANITIZER_NETBSD && !SANITIZER_SOLARIS
 
 #if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \
     || defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) \
@@ -423,6 +435,10 @@ static void GetTls(uptr *addr, uptr *siz
 #elif SANITIZER_ANDROID
   *addr = 0;
   *size = 0;
+#elif SANITIZER_SOLARIS
+  // FIXME
+  *addr = 0;
+  *size = 0;
 #else
 # error "Unknown OS"
 #endif
@@ -431,7 +447,8 @@ static void GetTls(uptr *addr, uptr *siz
 
 #if !SANITIZER_GO
 uptr GetTlsSize() {
-#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
   uptr addr, size;
   GetTls(&addr, &size);
   return size;
@@ -591,7 +608,8 @@ uptr GetRSS() {
   return rss * GetPageSizeCached();
 }
 
-// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory.
+// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as
+// they allocate memory.
 u32 GetNumberOfCPUs() {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
   u32 ncpu;
@@ -637,6 +655,8 @@ u32 GetNumberOfCPUs() {
   }
   internal_close(fd);
   return n_cpus;
+#elif SANITIZER_SOLARIS
+  return sysconf(_SC_NPROCESSORS_ONLN);
 #else
   cpu_set_t CPUs;
   CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h Thu Dec 14 12:14:29 2017
@@ -92,8 +92,10 @@ class BlockingMutex {
   // checks that the mutex is owned, and assumes callers to be generally
   // well-behaved.
   void CheckLocked();
+
  private:
-  uptr opaque_storage_[10];
+  // Solaris mutex_t has a member that requires 64-bit alignment.
+  ALIGNED(8) uptr opaque_storage_[10];
   uptr owner_;  // for debugging
 };
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform.h Thu Dec 14 12:14:29 2017
@@ -14,7 +14,8 @@
 #define SANITIZER_PLATFORM_H
 
 #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
-  !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__)
+  !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
+  !(defined(__sun__) && defined(__svr4__))
 # error "This operating system is not supported"
 #endif
 
@@ -36,6 +37,12 @@
 # define SANITIZER_NETBSD 0
 #endif
 
+#if defined(__sun__) && defined(__svr4__)
+# define SANITIZER_SOLARIS 1
+#else
+# define SANITIZER_SOLARIS 0
+#endif
+
 #if defined(__APPLE__)
 # define SANITIZER_MAC     1
 # include <TargetConditionals.h>
@@ -92,7 +99,8 @@
 #endif
 
 #define SANITIZER_POSIX \
-  (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD)
+  (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
+    SANITIZER_NETBSD || SANITIZER_SOLARIS)
 
 #if __LP64__ || defined(_WIN64)
 #  define SANITIZER_WORDSIZE 64
@@ -181,6 +189,12 @@
 # define SANITIZER_ARM 0
 #endif
 
+#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32
+# define SANITIZER_SOLARIS32 1
+#else
+# define SANITIZER_SOLARIS32 0
+#endif
+
 // By default we allow to use SizeClassAllocator64 on 64-bit platform.
 // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
 // does not work well and we need to fallback to SizeClassAllocator32.
@@ -282,7 +296,7 @@
 # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
 #endif
 
-#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS
 # define SANITIZER_MADVISE_DONTNEED MADV_FREE
 #else
 # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Dec 14 12:14:29 2017
@@ -35,6 +35,7 @@
 #if SI_POSIX
 # include "sanitizer_platform_limits_netbsd.h"
 # include "sanitizer_platform_limits_posix.h"
+# include "sanitizer_platform_limits_solaris.h"
 #endif
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -87,6 +88,18 @@
 # define SI_NOT_FUCHSIA 1
 #endif
 
+#if SANITIZER_SOLARIS
+# define SI_SOLARIS 1
+#else
+# define SI_SOLARIS 0
+#endif
+
+#if SANITIZER_SOLARIS32
+# define SI_SOLARIS32 1
+#else
+# define SI_SOLARIS32 0
+#endif
+
 #if SANITIZER_POSIX && !SANITIZER_MAC
 # define SI_POSIX_NOT_MAC 1
 #else
@@ -110,7 +123,7 @@
 #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX
 #define SANITIZER_INTERCEPT_MEMSET 1
 #define SANITIZER_INTERCEPT_MEMMOVE 1
@@ -138,8 +151,8 @@
 #define SANITIZER_INTERCEPT_FREAD SI_POSIX
 #define SANITIZER_INTERCEPT_FWRITE SI_POSIX
 
-#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
+#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
 
 #define SANITIZER_INTERCEPT_READV SI_POSIX
 #define SANITIZER_INTERCEPT_WRITEV SI_POSIX
@@ -169,17 +182,20 @@
 
 #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
 #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETPWENT \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_GETPWENT_R \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_SETPWENT (SI_MAC || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_CLOCK_GETTIME (SI_FREEBSD || SI_NETBSD || SI_LINUX)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_SETPWENT \
+  (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_CLOCK_GETTIME \
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX
 #define SANITIZER_INTERCEPT_TIME SI_POSIX
-#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID || SI_SOLARIS
+#define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_WAIT SI_POSIX
 #define SANITIZER_INTERCEPT_INET SI_POSIX
 #define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX
@@ -187,11 +203,15 @@
 #define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX
 #define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX
 #define SANITIZER_INTERCEPT_GETHOSTBYNAME SI_POSIX
-#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R (SI_FREEBSD || SI_LINUX)
+#define SANITIZER_INTERCEPT_GETHOSTBYNAME2 SI_POSIX && !SI_SOLARIS
+#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R \
+  (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETHOSTBYNAME2_R \
   (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_GETHOSTENT_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
+#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R \
+  (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_GETHOSTENT_R \
+  (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX
 #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX
 #define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID
@@ -203,7 +223,7 @@
 #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX
 #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX
 #define SANITIZER_INTERCEPT_READDIR SI_POSIX
-#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
 #if SI_LINUX_NOT_ANDROID && \
   (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
     defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
@@ -217,43 +237,46 @@
 #define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STRTOIMAX SI_POSIX
 #define SANITIZER_INTERCEPT_MBSTOWCS SI_POSIX
-#define SANITIZER_INTERCEPT_MBSNRTOWCS (SI_MAC || SI_LINUX_NOT_ANDROID)
+#define SANITIZER_INTERCEPT_MBSNRTOWCS \
+  (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_WCSTOMBS SI_POSIX
 #define SANITIZER_INTERCEPT_WCSNRTOMBS \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_WCRTOMB \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_REALPATH SI_POSIX
-#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \
+  (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_CONFSTR \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_STRERROR SI_POSIX
 #define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX
 #define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_SCANDIR \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
 #define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX
 #define SANITIZER_INTERCEPT_POLL SI_POSIX
-#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_WORDEXP \
-  (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \
+    SI_SOLARIS)
 #define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX
-#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS
+#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_SIGSETOPS \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX
 #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX
 #define SANITIZER_INTERCEPT_BACKTRACE \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
 #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STATFS \
-  (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_STATFS64 \
   ((SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_STATVFS \
@@ -265,67 +288,69 @@
   (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_SHMCTL                       \
-  (SI_NETBSD || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \
+  (SI_NETBSD || SI_SOLARIS || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \
                  SANITIZER_WORDSIZE == 64))  // NOLINT
 #define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX
 #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \
   (SI_POSIX && !SI_NETBSD)
 #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX
 #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \
-  (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
-  (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID)
-#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST SI_LINUX_NOT_ANDROID
+  (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST \
+  (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED \
   (SI_POSIX && !SI_NETBSD)
 #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED \
   (SI_POSIX && !SI_NETBSD)
-#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \
+  (SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \
   (SI_LINUX_NOT_ANDROID && !SI_NETBSD)
 #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX
-#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
 #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
-#define SANITIZER_INTERCEPT_SINCOS SI_LINUX
+#define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS
 #define SANITIZER_INTERCEPT_REMQUO SI_POSIX
 #define SANITIZER_INTERCEPT_LGAMMA SI_POSIX
-#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX)
-#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_RAND_R \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_ICONV \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_TIMES SI_POSIX
 
 // FIXME: getline seems to be available on OSX 10.7
 #define SANITIZER_INTERCEPT_GETLINE \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 
 #define SANITIZER_INTERCEPT__EXIT \
-  (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC)
+  (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS)
 
 #define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_POSIX
 #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 
 #define SANITIZER_INTERCEPT_TLS_GET_ADDR \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 
 #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETRESID SI_LINUX
 #define SANITIZER_INTERCEPT_GETIFADDRS \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_IF_INDEXTONAME \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID
 #if SI_LINUX && defined(__arm__)
 #define SANITIZER_INTERCEPT_AEABI_MEM 1
@@ -334,20 +359,21 @@
 #endif
 #define SANITIZER_INTERCEPT___BZERO SI_MAC
 #define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX)
-#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_TSEARCH \
-  (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD)
+  (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_FOPEN SI_POSIX
-#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM (SI_LINUX_NOT_ANDROID || SI_NETBSD)
+#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
+#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \
+  (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_FFLUSH SI_POSIX
 #define SANITIZER_INTERCEPT_FCLOSE SI_POSIX
 
 #ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
 #define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \
-  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC)
+  (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
 #endif
 
 #define SANITIZER_INTERCEPT_GETPASS \
@@ -356,13 +382,14 @@
 
 #define SANITIZER_INTERCEPT_MLOCKX SI_POSIX
 #define SANITIZER_INTERCEPT_FOPENCOOKIE SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_SEM (SI_LINUX || SI_FREEBSD || SI_NETBSD)
+#define SANITIZER_INTERCEPT_SEM \
+  (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX
-#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD)
+#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX
 #define SANITIZER_INTERCEPT_CTERMID \
-  (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD)
-#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD)
+  (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS)
 
 #define SANITIZER_INTERCEPTOR_HOOKS (SI_LINUX || SI_MAC || SI_WINDOWS)
 #define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX
@@ -370,7 +397,7 @@
 #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX
 
 #define SANITIZER_INTERCEPT_STAT \
-  (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD)
+  (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS)
 #define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX)
 #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc?rev=320740&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc Thu Dec 14 12:14:29 2017
@@ -0,0 +1,366 @@
+//===-- sanitizer_platform_limits_solaris.cc ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific Solaris data structures.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_SOLARIS
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <glob.h>
+#include <grp.h>
+#include <ifaddrs.h>
+#include <limits.h>
+#include <link.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netdb.h>
+#include <netinet/ip_mroute.h>
+#include <poll.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <rpc/xdr.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ethernet.h>
+#include <sys/filio.h>
+#include <sys/ipc.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/mtio.h>
+#include <sys/ptyvar.h>
+#include <sys/resource.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <termios.h>
+#include <time.h>
+#include <utmp.h>
+#include <utmpx.h>
+#include <wchar.h>
+#include <wordexp.h>
+
+// Include these after system headers to avoid name clashes and ambiguities.
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform_limits_solaris.h"
+
+namespace __sanitizer {
+  unsigned struct_utsname_sz = sizeof(struct utsname);
+  unsigned struct_stat_sz = sizeof(struct stat);
+  unsigned struct_stat64_sz = sizeof(struct stat64);
+  unsigned struct_rusage_sz = sizeof(struct rusage);
+  unsigned struct_tm_sz = sizeof(struct tm);
+  unsigned struct_passwd_sz = sizeof(struct passwd);
+  unsigned struct_group_sz = sizeof(struct group);
+  unsigned siginfo_t_sz = sizeof(siginfo_t);
+  unsigned struct_sigaction_sz = sizeof(struct sigaction);
+  unsigned struct_itimerval_sz = sizeof(struct itimerval);
+  unsigned pthread_t_sz = sizeof(pthread_t);
+  unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
+  unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);
+  unsigned pid_t_sz = sizeof(pid_t);
+  unsigned timeval_sz = sizeof(timeval);
+  unsigned uid_t_sz = sizeof(uid_t);
+  unsigned gid_t_sz = sizeof(gid_t);
+  unsigned mbstate_t_sz = sizeof(mbstate_t);
+  unsigned sigset_t_sz = sizeof(sigset_t);
+  unsigned struct_timezone_sz = sizeof(struct timezone);
+  unsigned struct_tms_sz = sizeof(struct tms);
+  unsigned struct_sigevent_sz = sizeof(struct sigevent);
+  unsigned struct_sched_param_sz = sizeof(struct sched_param);
+  unsigned struct_statfs_sz = sizeof(struct statfs);
+  unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
+  unsigned ucontext_t_sz = sizeof(ucontext_t);
+  unsigned struct_timespec_sz = sizeof(struct timespec);
+#if SANITIZER_SOLARIS32
+  unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
+#endif
+  unsigned struct_statvfs_sz = sizeof(struct statvfs);
+
+  const uptr sig_ign = (uptr)SIG_IGN;
+  const uptr sig_dfl = (uptr)SIG_DFL;
+  const uptr sig_err = (uptr)SIG_ERR;
+  const uptr sa_siginfo = (uptr)SA_SIGINFO;
+
+  int shmctl_ipc_stat = (int)IPC_STAT;
+
+  unsigned struct_utmp_sz = sizeof(struct utmp);
+  unsigned struct_utmpx_sz = sizeof(struct utmpx);
+
+  int map_fixed = MAP_FIXED;
+
+  int af_inet = (int)AF_INET;
+  int af_inet6 = (int)AF_INET6;
+
+  uptr __sanitizer_in_addr_sz(int af) {
+    if (af == AF_INET)
+      return sizeof(struct in_addr);
+    else if (af == AF_INET6)
+      return sizeof(struct in6_addr);
+    else
+      return 0;
+  }
+
+  unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr));
+
+  int glob_nomatch = GLOB_NOMATCH;
+
+  unsigned path_max = PATH_MAX;
+
+  // ioctl arguments
+  unsigned struct_ifreq_sz = sizeof(struct ifreq);
+  unsigned struct_termios_sz = sizeof(struct termios);
+  unsigned struct_winsize_sz = sizeof(struct winsize);
+
+  unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
+  unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
+
+  const unsigned IOCTL_NOT_PRESENT = 0;
+
+  unsigned IOCTL_FIOASYNC = FIOASYNC;
+  unsigned IOCTL_FIOCLEX = FIOCLEX;
+  unsigned IOCTL_FIOGETOWN = FIOGETOWN;
+  unsigned IOCTL_FIONBIO = FIONBIO;
+  unsigned IOCTL_FIONCLEX = FIONCLEX;
+  unsigned IOCTL_FIOSETOWN = FIOSETOWN;
+  unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;
+  unsigned IOCTL_SIOCATMARK = SIOCATMARK;
+  unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;
+  unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR;
+  unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR;
+  unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF;
+  unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR;
+  unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS;
+  unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC;
+  unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU;
+  unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK;
+  unsigned IOCTL_SIOCGPGRP = SIOCGPGRP;
+  unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR;
+  unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR;
+  unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR;
+  unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS;
+  unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC;
+  unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
+  unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
+  unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
+  unsigned IOCTL_TIOCEXCL = TIOCEXCL;
+  unsigned IOCTL_TIOCGETD = TIOCGETD;
+  unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
+  unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;
+  unsigned IOCTL_TIOCMBIC = TIOCMBIC;
+  unsigned IOCTL_TIOCMBIS = TIOCMBIS;
+  unsigned IOCTL_TIOCMGET = TIOCMGET;
+  unsigned IOCTL_TIOCMSET = TIOCMSET;
+  unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
+  unsigned IOCTL_TIOCNXCL = TIOCNXCL;
+  unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;
+  unsigned IOCTL_TIOCPKT = TIOCPKT;
+  unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;
+  unsigned IOCTL_TIOCSETD = TIOCSETD;
+  unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
+  unsigned IOCTL_TIOCSTI = TIOCSTI;
+  unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
+
+  unsigned IOCTL_MTIOCGET = MTIOCGET;
+  unsigned IOCTL_MTIOCTOP = MTIOCTOP;
+
+  const int si_SEGV_MAPERR = SEGV_MAPERR;
+  const int si_SEGV_ACCERR = SEGV_ACCERR;
+} // namespace __sanitizer
+
+using namespace __sanitizer;
+
+COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
+
+COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
+CHECK_TYPE_SIZE(pthread_key_t);
+
+// There are more undocumented fields in dl_phdr_info that we are not interested
+// in.
+COMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info));
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
+
+CHECK_TYPE_SIZE(glob_t);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
+
+CHECK_TYPE_SIZE(addrinfo);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_family);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);
+
+CHECK_TYPE_SIZE(hostent);
+CHECK_SIZE_AND_OFFSET(hostent, h_name);
+CHECK_SIZE_AND_OFFSET(hostent, h_aliases);
+CHECK_SIZE_AND_OFFSET(hostent, h_addrtype);
+CHECK_SIZE_AND_OFFSET(hostent, h_length);
+CHECK_SIZE_AND_OFFSET(hostent, h_addr_list);
+
+CHECK_TYPE_SIZE(iovec);
+CHECK_SIZE_AND_OFFSET(iovec, iov_base);
+CHECK_SIZE_AND_OFFSET(iovec, iov_len);
+
+CHECK_TYPE_SIZE(msghdr);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_name);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_iov);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_control);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_flags);
+
+CHECK_TYPE_SIZE(cmsghdr);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
+
+COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
+CHECK_SIZE_AND_OFFSET(dirent, d_ino);
+CHECK_SIZE_AND_OFFSET(dirent, d_off);
+CHECK_SIZE_AND_OFFSET(dirent, d_reclen);
+
+#if SANITIZER_SOLARIS32
+COMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64));
+CHECK_SIZE_AND_OFFSET(dirent64, d_ino);
+CHECK_SIZE_AND_OFFSET(dirent64, d_off);
+CHECK_SIZE_AND_OFFSET(dirent64, d_reclen);
+#endif
+
+CHECK_TYPE_SIZE(ifconf);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
+
+CHECK_TYPE_SIZE(pollfd);
+CHECK_SIZE_AND_OFFSET(pollfd, fd);
+CHECK_SIZE_AND_OFFSET(pollfd, events);
+CHECK_SIZE_AND_OFFSET(pollfd, revents);
+
+CHECK_TYPE_SIZE(nfds_t);
+
+CHECK_TYPE_SIZE(sigset_t);
+
+COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));
+// Can't write checks for sa_handler and sa_sigaction due to them being
+// preprocessor macros.
+CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
+CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);
+
+CHECK_TYPE_SIZE(wordexp_t);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs);
+
+CHECK_TYPE_SIZE(tm);
+CHECK_SIZE_AND_OFFSET(tm, tm_sec);
+CHECK_SIZE_AND_OFFSET(tm, tm_min);
+CHECK_SIZE_AND_OFFSET(tm, tm_hour);
+CHECK_SIZE_AND_OFFSET(tm, tm_mday);
+CHECK_SIZE_AND_OFFSET(tm, tm_mon);
+CHECK_SIZE_AND_OFFSET(tm, tm_year);
+CHECK_SIZE_AND_OFFSET(tm, tm_wday);
+CHECK_SIZE_AND_OFFSET(tm, tm_yday);
+CHECK_SIZE_AND_OFFSET(tm, tm_isdst);
+
+CHECK_TYPE_SIZE(ether_addr);
+
+CHECK_TYPE_SIZE(ipc_perm);
+CHECK_SIZE_AND_OFFSET(ipc_perm, key);
+CHECK_SIZE_AND_OFFSET(ipc_perm, seq);
+CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
+
+CHECK_TYPE_SIZE(shmid_ds);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch);
+
+CHECK_TYPE_SIZE(clock_t);
+
+CHECK_TYPE_SIZE(ifaddrs);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);
+// Compare against the union, because we can't reach into the union in a
+// compliant way.
+#ifdef ifa_dstaddr
+#undef ifa_dstaddr
+#endif
+COMPILER_CHECK(sizeof(((__sanitizer_ifaddrs *)nullptr)->ifa_dstaddr) ==
+               sizeof(((ifaddrs *)nullptr)->ifa_ifu));
+COMPILER_CHECK(offsetof(__sanitizer_ifaddrs, ifa_dstaddr) ==
+               offsetof(ifaddrs, ifa_ifu));
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
+
+CHECK_TYPE_SIZE(timeb);
+CHECK_SIZE_AND_OFFSET(timeb, time);
+CHECK_SIZE_AND_OFFSET(timeb, millitm);
+CHECK_SIZE_AND_OFFSET(timeb, timezone);
+CHECK_SIZE_AND_OFFSET(timeb, dstflag);
+
+CHECK_TYPE_SIZE(passwd);
+CHECK_SIZE_AND_OFFSET(passwd, pw_name);
+CHECK_SIZE_AND_OFFSET(passwd, pw_passwd);
+CHECK_SIZE_AND_OFFSET(passwd, pw_uid);
+CHECK_SIZE_AND_OFFSET(passwd, pw_gid);
+CHECK_SIZE_AND_OFFSET(passwd, pw_dir);
+CHECK_SIZE_AND_OFFSET(passwd, pw_shell);
+
+CHECK_SIZE_AND_OFFSET(passwd, pw_gecos);
+
+CHECK_TYPE_SIZE(group);
+CHECK_SIZE_AND_OFFSET(group, gr_name);
+CHECK_SIZE_AND_OFFSET(group, gr_passwd);
+CHECK_SIZE_AND_OFFSET(group, gr_gid);
+CHECK_SIZE_AND_OFFSET(group, gr_mem);
+
+CHECK_TYPE_SIZE(XDR);
+CHECK_SIZE_AND_OFFSET(XDR, x_op);
+CHECK_SIZE_AND_OFFSET(XDR, x_ops);
+CHECK_SIZE_AND_OFFSET(XDR, x_public);
+CHECK_SIZE_AND_OFFSET(XDR, x_private);
+CHECK_SIZE_AND_OFFSET(XDR, x_base);
+CHECK_SIZE_AND_OFFSET(XDR, x_handy);
+COMPILER_CHECK(__sanitizer_XDR_ENCODE == XDR_ENCODE);
+COMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE);
+COMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE);
+
+CHECK_TYPE_SIZE(sem_t);
+
+#endif  // SANITIZER_SOLARIS

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.h?rev=320740&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_solaris.h Thu Dec 14 12:14:29 2017
@@ -0,0 +1,485 @@
+//===-- sanitizer_platform_limits_solaris.h -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific Solaris data structures.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_PLATFORM_LIMITS_SOLARIS_H
+#define SANITIZER_PLATFORM_LIMITS_SOLARIS_H
+
+#if SANITIZER_SOLARIS
+
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform.h"
+
+namespace __sanitizer {
+extern unsigned struct_utsname_sz;
+extern unsigned struct_stat_sz;
+extern unsigned struct_stat64_sz;
+extern unsigned struct_rusage_sz;
+extern unsigned siginfo_t_sz;
+extern unsigned struct_itimerval_sz;
+extern unsigned pthread_t_sz;
+extern unsigned pthread_mutex_t_sz;
+extern unsigned pthread_cond_t_sz;
+extern unsigned pid_t_sz;
+extern unsigned timeval_sz;
+extern unsigned uid_t_sz;
+extern unsigned gid_t_sz;
+extern unsigned mbstate_t_sz;
+extern unsigned struct_timezone_sz;
+extern unsigned struct_tms_sz;
+extern unsigned struct_itimerspec_sz;
+extern unsigned struct_sigevent_sz;
+extern unsigned struct_sched_param_sz;
+extern unsigned struct_statfs64_sz;
+extern unsigned struct_statfs_sz;
+extern unsigned struct_sockaddr_sz;
+extern unsigned ucontext_t_sz;
+
+extern unsigned struct_timespec_sz;
+extern unsigned struct_rlimit_sz;
+extern unsigned struct_utimbuf_sz;
+
+struct __sanitizer_sem_t {
+  //u64 data[6];
+  u32 sem_count;
+  u16 sem_type;
+  u16 sem_magic;
+  u64 sem_pad1[3];
+  u64 sem_pad2[2];
+};
+
+struct __sanitizer_ipc_perm {
+  unsigned int uid;           // uid_t
+  unsigned int gid;           // gid_t
+  unsigned int cuid;          // uid_t
+  unsigned int cgid;          // gid_t
+  unsigned int mode;          // mode_t
+  unsigned int seq;           // uint_t
+  int key;                    // key_t
+#if !defined(_LP64)
+  int pad[4];
+#endif
+  };
+
+struct __sanitizer_shmid_ds {
+  __sanitizer_ipc_perm shm_perm;
+  unsigned long shm_segsz;    // size_t
+  unsigned long shm_flags;    // uintptr_t
+  unsigned short shm_lkcnt;   // ushort_t
+  int shm_lpid;               // pid_t
+  int shm_cpid;               // pid_t
+  unsigned long shm_nattch;   // shmatt_t
+  unsigned long shm_cnattch;  // ulong_t
+#if defined(_LP64)
+  long shm_atime;             // time_t
+  long shm_dtime;
+  long shm_ctime;
+  void *shm_amp;
+  u64 shm_gransize;           // uint64_t
+  u64 shm_allocated;          // uint64_t
+  u64 shm_pad4[1];            // int64_t
+#else
+  long shm_atime;             // time_t
+  int shm_pad1;               // int32_t
+  long shm_dtime;             // time_t
+  int shm_pad2;               // int32_t
+  long shm_ctime;             // time_t
+  void *shm_amp;
+  u64 shm_gransize;           // uint64_t
+  u64 shm_allocated;          // uint64_t
+#endif
+};
+
+extern unsigned struct_statvfs_sz;
+#if SANITIZER_SOLARIS32
+extern unsigned struct_statvfs64_sz;
+#endif
+
+struct __sanitizer_iovec {
+  void *iov_base;
+  uptr iov_len;
+};
+
+struct __sanitizer_ifaddrs {
+  struct __sanitizer_ifaddrs *ifa_next;
+  char *ifa_name;
+  u64 ifa_flags;     // uint64_t
+  void *ifa_addr;    // (struct sockaddr *)
+  void *ifa_netmask; // (struct sockaddr *)
+  // This is a union on Linux.
+# ifdef ifa_dstaddr
+# undef ifa_dstaddr
+# endif
+  void *ifa_dstaddr; // (struct sockaddr *)
+  void *ifa_data;
+};
+
+typedef unsigned __sanitizer_pthread_key_t;
+
+struct __sanitizer_XDR {
+  int x_op;
+  void *x_ops;
+  uptr x_public;
+  uptr x_private;
+  uptr x_base;
+  unsigned x_handy;
+};
+
+const int __sanitizer_XDR_ENCODE = 0;
+const int __sanitizer_XDR_DECODE = 1;
+const int __sanitizer_XDR_FREE = 2;
+
+struct __sanitizer_passwd {
+  char *pw_name;
+  char *pw_passwd;
+  unsigned int pw_uid;    // uid_t
+  unsigned int pw_gid;    // gid_t
+  char *pw_age;
+  char *pw_comment;
+  char *pw_gecos;
+  char *pw_dir;
+  char *pw_shell;
+};
+
+struct __sanitizer_group {
+  char *gr_name;
+  char *gr_passwd;
+  int gr_gid;
+  char **gr_mem;
+};
+
+typedef long __sanitizer_time_t;
+
+struct __sanitizer_timeb {
+  __sanitizer_time_t time;
+  unsigned short millitm;
+  short timezone;
+  short dstflag;
+};
+
+struct __sanitizer_ether_addr {
+  u8 octet[6];
+};
+
+struct __sanitizer_tm {
+  int tm_sec;
+  int tm_min;
+  int tm_hour;
+  int tm_mday;
+  int tm_mon;
+  int tm_year;
+  int tm_wday;
+  int tm_yday;
+  int tm_isdst;
+};
+
+struct __sanitizer_msghdr {
+  void *msg_name;
+  unsigned msg_namelen;
+  struct __sanitizer_iovec *msg_iov;
+  unsigned msg_iovlen;
+  void *msg_control;
+  unsigned msg_controllen;
+  int msg_flags;
+};
+struct __sanitizer_cmsghdr {
+  unsigned cmsg_len;
+  int cmsg_level;
+  int cmsg_type;
+};
+
+#if SANITIZER_SOLARIS32 && 0
+// FIXME: need to deal with large file and non-large file cases
+struct __sanitizer_dirent {
+  unsigned long long d_ino;
+  long long d_off;
+  unsigned short d_reclen;
+  // more fields that we don't care about
+};
+#else
+struct __sanitizer_dirent {
+  unsigned long d_ino;
+  long d_off;
+  unsigned short d_reclen;
+  // more fields that we don't care about
+};
+#endif
+
+struct __sanitizer_dirent64 {
+  unsigned long long d_ino;
+  unsigned long long d_off;
+  unsigned short d_reclen;
+  // more fields that we don't care about
+};
+
+typedef long __sanitizer_clock_t;
+typedef int __sanitizer_clockid_t;
+
+// This thing depends on the platform. We are only interested in the upper
+// limit. Verified with a compiler assert in .cc.
+const int pthread_attr_t_max_sz = 128;
+union __sanitizer_pthread_attr_t {
+  char size[pthread_attr_t_max_sz]; // NOLINT
+  void *align;
+};
+
+struct __sanitizer_sigset_t {
+  // uint32_t * 4
+  unsigned int __bits[4];
+};
+
+struct __sanitizer_siginfo {
+  // The size is determined by looking at sizeof of real siginfo_t on linux.
+  u64 opaque[128 / sizeof(u64)];
+};
+
+using __sanitizer_sighandler_ptr = void (*)(int sig);
+using __sanitizer_sigactionhandler_ptr =
+    void (*)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
+
+struct __sanitizer_sigaction {
+  int sa_flags;
+  union {
+    __sanitizer_sigactionhandler_ptr sigaction;
+    __sanitizer_sighandler_ptr handler;
+  };
+  __sanitizer_sigset_t sa_mask;
+#if !defined(_LP64)
+  int sa_resv[2];
+#endif
+};
+
+struct __sanitizer_kernel_sigset_t {
+  u8 sig[8];
+};
+
+struct __sanitizer_kernel_sigaction_t {
+  union {
+    void (*handler)(int signo);
+    void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx);
+  };
+  unsigned long sa_flags;
+  void (*sa_restorer)(void);
+  __sanitizer_kernel_sigset_t sa_mask;
+};
+
+extern const uptr sig_ign;
+extern const uptr sig_dfl;
+extern const uptr sig_err;
+extern const uptr sa_siginfo;
+
+extern int af_inet;
+extern int af_inet6;
+uptr __sanitizer_in_addr_sz(int af);
+
+struct __sanitizer_dl_phdr_info {
+  uptr dlpi_addr;
+  const char *dlpi_name;
+  const void *dlpi_phdr;
+  short dlpi_phnum;
+};
+
+extern unsigned struct_ElfW_Phdr_sz;
+
+struct __sanitizer_addrinfo {
+  int ai_flags;
+  int ai_family;
+  int ai_socktype;
+  int ai_protocol;
+#if defined(__sparcv9)
+  int _ai_pad;
+#endif
+  unsigned ai_addrlen;
+  char *ai_canonname;
+  void *ai_addr;
+  struct __sanitizer_addrinfo *ai_next;
+};
+
+struct __sanitizer_hostent {
+  char *h_name;
+  char **h_aliases;
+  int h_addrtype;
+  int h_length;
+  char **h_addr_list;
+};
+
+struct __sanitizer_pollfd {
+  int fd;
+  short events;
+  short revents;
+};
+
+typedef unsigned long __sanitizer_nfds_t;
+
+struct __sanitizer_glob_t {
+  uptr gl_pathc;
+  char **gl_pathv;
+  uptr gl_offs;
+  char **gl_pathp;
+  int gl_pathn;
+};
+
+extern int glob_nomatch;
+extern int glob_altdirfunc;
+
+extern unsigned path_max;
+
+struct __sanitizer_wordexp_t {
+  uptr we_wordc;
+  char **we_wordv;
+  uptr we_offs;
+  char **we_wordp;
+  int we_wordn;
+};
+
+typedef void __sanitizer_FILE;
+#define SANITIZER_HAS_STRUCT_FILE 0
+
+// This simplifies generic code
+#define struct_shminfo_sz -1
+#define struct_shm_info_sz -1
+#define shmctl_shm_stat -1
+#define shmctl_ipc_info -1
+#define shmctl_shm_info -1
+
+extern int shmctl_ipc_stat;
+
+extern unsigned struct_utmp_sz;
+extern unsigned struct_utmpx_sz;
+
+extern int map_fixed;
+
+// ioctl arguments
+struct __sanitizer_ifconf {
+  int ifc_len;
+  union {
+    void *ifcu_req;
+  } ifc_ifcu;
+};
+
+// <sys/ioccom.h>
+#define IOC_NRBITS 8
+#define IOC_TYPEBITS 8
+#define IOC_SIZEBITS 12
+#define IOC_DIRBITS 4
+#undef IOC_NONE
+#define IOC_NONE 2U     // IOC_VOID
+#define IOC_READ 4U     // IOC_OUT
+#define IOC_WRITE 8U    // IOC_IN
+
+#define IOC_NRMASK ((1 << IOC_NRBITS) - 1)
+#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1)
+#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1)
+#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1)
+#define IOC_NRSHIFT 0
+#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS)
+#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS)
+#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS)
+
+#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
+#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
+#define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
+
+#if defined(__sparc__)
+// In sparc the 14 bits SIZE field overlaps with the
+// least significant bit of DIR, so either IOC_READ or
+// IOC_WRITE shall be 1 in order to get a non-zero SIZE.
+#define IOC_SIZE(nr) \
+  ((((((nr) >> 29) & 0x7) & (4U | 2U)) == 0) ? 0 : (((nr) >> 16) & 0x3fff))
+#else
+#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK)
+#endif
+
+extern unsigned struct_ifreq_sz;
+extern unsigned struct_termios_sz;
+extern unsigned struct_winsize_sz;
+
+extern unsigned struct_sioc_sg_req_sz;
+extern unsigned struct_sioc_vif_req_sz;
+
+// ioctl request identifiers
+
+// A special value to mark ioctls that are not present on the target platform,
+// when it can not be determined without including any system headers.
+extern const unsigned IOCTL_NOT_PRESENT;
+
+extern unsigned IOCTL_FIOASYNC;
+extern unsigned IOCTL_FIOCLEX;
+extern unsigned IOCTL_FIOGETOWN;
+extern unsigned IOCTL_FIONBIO;
+extern unsigned IOCTL_FIONCLEX;
+extern unsigned IOCTL_FIOSETOWN;
+extern unsigned IOCTL_SIOCADDMULTI;
+extern unsigned IOCTL_SIOCATMARK;
+extern unsigned IOCTL_SIOCDELMULTI;
+extern unsigned IOCTL_SIOCGIFADDR;
+extern unsigned IOCTL_SIOCGIFBRDADDR;
+extern unsigned IOCTL_SIOCGIFCONF;
+extern unsigned IOCTL_SIOCGIFDSTADDR;
+extern unsigned IOCTL_SIOCGIFFLAGS;
+extern unsigned IOCTL_SIOCGIFMETRIC;
+extern unsigned IOCTL_SIOCGIFMTU;
+extern unsigned IOCTL_SIOCGIFNETMASK;
+extern unsigned IOCTL_SIOCGPGRP;
+extern unsigned IOCTL_SIOCSIFADDR;
+extern unsigned IOCTL_SIOCSIFBRDADDR;
+extern unsigned IOCTL_SIOCSIFDSTADDR;
+extern unsigned IOCTL_SIOCSIFFLAGS;
+extern unsigned IOCTL_SIOCSIFMETRIC;
+extern unsigned IOCTL_SIOCSIFMTU;
+extern unsigned IOCTL_SIOCSIFNETMASK;
+extern unsigned IOCTL_SIOCSPGRP;
+extern unsigned IOCTL_TIOCEXCL;
+extern unsigned IOCTL_TIOCGETD;
+extern unsigned IOCTL_TIOCGPGRP;
+extern unsigned IOCTL_TIOCGWINSZ;
+extern unsigned IOCTL_TIOCMBIC;
+extern unsigned IOCTL_TIOCMBIS;
+extern unsigned IOCTL_TIOCMGET;
+extern unsigned IOCTL_TIOCMSET;
+extern unsigned IOCTL_TIOCNOTTY;
+extern unsigned IOCTL_TIOCNXCL;
+extern unsigned IOCTL_TIOCOUTQ;
+extern unsigned IOCTL_TIOCPKT;
+extern unsigned IOCTL_TIOCSCTTY;
+extern unsigned IOCTL_TIOCSETD;
+extern unsigned IOCTL_TIOCSPGRP;
+extern unsigned IOCTL_TIOCSTI;
+extern unsigned IOCTL_TIOCSWINSZ;
+extern unsigned IOCTL_MTIOCGET;
+extern unsigned IOCTL_MTIOCTOP;
+
+extern const int si_SEGV_MAPERR;
+extern const int si_SEGV_ACCERR;
+}  // namespace __sanitizer
+
+#define CHECK_TYPE_SIZE(TYPE) \
+  COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
+
+#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER)                       \
+  COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \
+                 sizeof(((CLASS *) NULL)->MEMBER));                \
+  COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) ==          \
+                 offsetof(CLASS, MEMBER))
+
+// For sigaction, which is a function and struct at the same time,
+// and thus requires explicit "struct" in sizeof() expression.
+#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER)                       \
+  COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *) NULL)->MEMBER) == \
+                 sizeof(((struct CLASS *) NULL)->MEMBER));                \
+  COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) ==          \
+                 offsetof(struct CLASS, MEMBER))
+
+#endif  // SANITIZER_SOLARIS
+
+#endif

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h Thu Dec 14 12:14:29 2017
@@ -18,6 +18,7 @@
 #include "sanitizer_internal_defs.h"
 #include "sanitizer_platform_limits_netbsd.h"
 #include "sanitizer_platform_limits_posix.h"
+#include "sanitizer_platform_limits_solaris.h"
 
 #if !SANITIZER_POSIX
 // Make it hard to accidentally use any of functions declared in this file:

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc Thu Dec 14 12:14:29 2017
@@ -20,6 +20,7 @@
 #include "sanitizer_flags.h"
 #include "sanitizer_platform_limits_netbsd.h"
 #include "sanitizer_platform_limits_posix.h"
+#include "sanitizer_platform_limits_solaris.h"
 #include "sanitizer_posix.h"
 #include "sanitizer_procmaps.h"
 #include "sanitizer_stacktrace.h"
@@ -62,7 +63,10 @@ void ReleaseMemoryPagesToOS(uptr beg, up
   uptr beg_aligned = RoundUpTo(beg, page_size);
   uptr end_aligned = RoundDownTo(end, page_size);
   if (beg_aligned < end_aligned)
-    madvise((void *)beg_aligned, end_aligned - beg_aligned,
+    // In the default Solaris compilation environment, madvise() is declared
+    // to take a caddr_t arg; casting it to void * results in an invalid
+    // conversion error, so use char * instead.
+    madvise((char *)beg_aligned, end_aligned - beg_aligned,
             SANITIZER_MADVISE_DONTNEED);
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h Thu Dec 14 12:14:29 2017
@@ -16,7 +16,8 @@
 
 #include "sanitizer_platform.h"
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+    SANITIZER_MAC || SANITIZER_SOLARIS
 
 #include "sanitizer_common.h"
 #include "sanitizer_internal_defs.h"
@@ -95,5 +96,5 @@ uptr ParseHex(const char **p);
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
-        // SANITIZER_MAC
+        // SANITIZER_MAC || SANITIZER_SOLARIS
 #endif  // SANITIZER_PROCMAPS_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc Thu Dec 14 12:14:29 2017
@@ -12,7 +12,8 @@
 
 #include "sanitizer_platform.h"
 
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 
 #include "sanitizer_common.h"
 #include "sanitizer_placement_new.h"
@@ -169,4 +170,5 @@ void GetMemoryProfile(fill_profile_f cb,
 
 } // namespace __sanitizer
 
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
+       // SANITIZER_SOLARIS

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_solaris.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_solaris.cc?rev=320740&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_solaris.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_solaris.cc Thu Dec 14 12:14:29 2017
@@ -0,0 +1,57 @@
+//===-- sanitizer_procmaps_solaris.cc -------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Information about the process mappings (Solaris-specific parts).
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#if SANITIZER_SOLARIS
+#include "sanitizer_common.h"
+#include "sanitizer_procmaps.h"
+
+#include <procfs.h>
+#include <limits.h>
+
+namespace __sanitizer {
+
+void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
+  ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size,
+                   &proc_maps->len);
+}
+
+bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+  char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
+  if (data_.current >= last) return false;
+
+  prxmap_t *xmapentry = (prxmap_t*)data_.current;
+
+  segment->start = (uptr)xmapentry->pr_vaddr;
+  segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size);
+  segment->offset = (uptr)xmapentry->pr_offset;
+
+  segment->protection = 0;
+  if ((xmapentry->pr_mflags & MA_READ) != 0)
+    segment->protection |= kProtectionRead;
+  if ((xmapentry->pr_mflags & MA_WRITE) != 0)
+    segment->protection |= kProtectionWrite;
+  if ((xmapentry->pr_mflags & MA_EXEC) != 0)
+    segment->protection |= kProtectionExecute;
+
+  if (segment->filename != NULL && segment->filename_size > 0) {
+    internal_snprintf(segment->filename,
+                      Min(segment->filename_size, (uptr)PATH_MAX), "%s",
+                      xmapentry->pr_mapname);
+  }
+
+  data_.current += sizeof(prxmap_t);
+
+  return true;
+}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_SOLARIS

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc?rev=320740&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc Thu Dec 14 12:14:29 2017
@@ -0,0 +1,219 @@
+//===-- sanitizer_solaris.cc ----------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries and
+// implements Solaris-specific functions.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#if SANITIZER_SOLARIS
+
+#include <stdio.h>
+
+#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_libc.h"
+#include "sanitizer_placement_new.h"
+#include "sanitizer_platform_limits_posix.h"
+#include "sanitizer_procmaps.h"
+
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <thread.h>
+#include <synch.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+namespace __sanitizer {
+
+//#include "sanitizer_syscall_generic.inc"
+
+#define _REAL(func) _ ## func
+#define DECLARE__REAL(ret_type, func, ...) \
+  extern "C" ret_type _REAL(func)(__VA_ARGS__)
+#define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \
+  DECLARE__REAL(ret_type, func, __VA_ARGS__); \
+  ret_type internal_ ## func(__VA_ARGS__)
+
+// ---------------------- sanitizer_libc.h
+DECLARE__REAL_AND_INTERNAL(uptr, mmap, void *addr, uptr /*size_t*/ length,
+                           int prot, int flags, int fd, OFF_T offset) {
+  return (uptr)_REAL(mmap)(addr, length, prot, flags, fd, offset);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) {
+  return _REAL(munmap)(addr, length);
+}
+
+DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
+  return _REAL(mprotect)(addr, length, prot);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {
+  return _REAL(close)(fd);
+}
+
+extern "C" int _REAL(open)(const char *, int, ...);
+
+uptr internal_open(const char *filename, int flags) {
+  return _REAL(open)(filename, flags);
+}
+
+uptr internal_open(const char *filename, int flags, u32 mode) {
+  return _REAL(open)(filename, flags, mode);
+}
+
+uptr OpenFile(const char *filename, bool write) {
+  return internal_open(filename,
+      write ? O_WRONLY | O_CREAT : O_RDONLY, 0660);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
+  return _REAL(read)(fd, buf, count);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) {
+  return _REAL(write)(fd, buf, count);
+}
+
+// FIXME: There's only _ftruncate64 beginning with Solaris 11.
+DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) {
+  return ftruncate(fd, size);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, stat, const char *path, void *buf) {
+  return _REAL(stat)(path, (struct stat *)buf);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, lstat, const char *path, void *buf) {
+  return _REAL(lstat)(path, (struct stat *)buf);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, fstat, fd_t fd, void *buf) {
+  return _REAL(fstat)(fd, (struct stat *)buf);
+}
+
+uptr internal_filesize(fd_t fd) {
+  struct stat st;
+  if (internal_fstat(fd, &st))
+    return -1;
+  return (uptr)st.st_size;
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) {
+  return _REAL(dup2)(oldfd, newfd);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf,
+                           uptr bufsize) {
+  return _REAL(readlink)(path, buf, bufsize);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) {
+  return _REAL(unlink)(path);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath,
+                           const char *newpath) {
+  return _REAL(rename)(oldpath, newpath);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) {
+  return sched_yield();
+}
+
+DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) {
+  _exit(exitcode);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,
+                           char *const argv[], char *const envp[]) {
+  return _REAL(execve)(filename, argv, envp);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) {
+  return _REAL(waitpid)(pid, status, options);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) {
+  return _REAL(getpid)();
+}
+
+// FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *.
+DECLARE__REAL_AND_INTERNAL(uptr, getdents, fd_t fd, struct linux_dirent *dirp,
+                           unsigned int count) {
+  return _REAL(getdents)(fd, dirp, count);
+}
+
+DECLARE__REAL_AND_INTERNAL(uptr, lseek, fd_t fd, OFF_T offset, int whence) {
+  return _REAL(lseek)(fd, offset, whence);
+}
+
+// FIXME: This might be wrong: _sigfillset doesn't take a
+// __sanitizer_sigset_t *.
+DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) {
+  _REAL(sigfillset)(set);
+}
+
+// FIXME: This might be wrong: _sigprocmask doesn't take __sanitizer_sigset_t *.
+DECLARE__REAL_AND_INTERNAL(uptr, sigprocmask, int how,
+                           __sanitizer_sigset_t *set,
+                           __sanitizer_sigset_t *oldset) {
+  return _REAL(sigprocmask)(how, set, oldset);
+}
+
+DECLARE__REAL_AND_INTERNAL(int, fork, void) {
+  // TODO(glider): this may call user's pthread_atfork() handlers which is bad.
+  return _REAL(fork)();
+}
+
+u64 NanoTime() {
+  return gethrtime();
+}
+
+uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
+  // FIXME: No internal variant.
+  return clock_gettime(clk_id, (timespec *)tp);
+}
+
+// ----------------- sanitizer_common.h
+BlockingMutex::BlockingMutex() {
+  CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_));
+  internal_memset(this, 0, sizeof(*this));
+  CHECK_EQ(mutex_init((mutex_t *)&opaque_storage_, USYNC_THREAD, NULL), 0);
+}
+
+void BlockingMutex::Lock() {
+  CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_));
+  CHECK_NE(owner_, (uptr)thr_self());
+  CHECK_EQ(mutex_lock((mutex_t *)&opaque_storage_), 0);
+  CHECK(!owner_);
+  owner_ = (uptr)thr_self();
+}
+
+void BlockingMutex::Unlock() {
+  CHECK(owner_ == (uptr)thr_self());
+  owner_ = 0;
+  CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0);
+}
+
+void BlockingMutex::CheckLocked() {
+  CHECK_EQ((uptr)thr_self(), owner_);
+}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_syscall_generic.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_syscall_generic.inc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_syscall_generic.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_syscall_generic.inc Thu Dec 14 12:14:29 2017
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS
 # define SYSCALL(name) SYS_ ## name
 #else
 # define SYSCALL(name) __NR_ ## name

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc Thu Dec 14 12:14:29 2017
@@ -8,11 +8,12 @@
 //===----------------------------------------------------------------------===//
 //
 // This file contains the unwind.h-based (aka "slow") stack unwinding routines
-// available to the tools on Linux, Android, NetBSD and FreeBSD.
+// available to the tools on Linux, Android, NetBSD, FreeBSD, and Solaris.
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
+    SANITIZER_SOLARIS
 #include "sanitizer_common.h"
 #include "sanitizer_stacktrace.h"
 
@@ -166,4 +167,5 @@ void BufferedStackTrace::SlowUnwindStack
 
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
+        // SANITIZER_SOLARIS

Modified: compiler-rt/trunk/lib/ubsan/ubsan_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_platform.h?rev=320740&r1=320739&r2=320740&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_platform.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_platform.h Thu Dec 14 12:14:29 2017
@@ -18,7 +18,7 @@
      defined(__NetBSD__)) &&                                                   \
     (defined(__x86_64__) || defined(__i386__) || defined(__arm__) ||           \
      defined(__aarch64__) || defined(__mips__) || defined(__powerpc64__) ||    \
-     defined(__s390__))
+     defined(__s390__)) || (defined(__sun__) && defined(__svr4__))
 # define CAN_SANITIZE_UB 1
 #elif defined(_WIN32) || defined(__Fuchsia__)
 # define CAN_SANITIZE_UB 1




More information about the llvm-commits mailing list