# HG changeset patch
# Parent fed53c0b971e99ae5bf8f6143fa6ff42ca0bc404
Port to Solaris
@@ -96,71 +96,71 @@ main (void)
/* { dg-output "\[^\n\r]*value 128 is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 128.5 is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 132 is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 256 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 256.5 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 260 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -5 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1.5 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1 is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -32773 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -32769.5 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -32769 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 32768 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 32768.5 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 32772 is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 65536 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 65536.5 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 65540 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -5 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1.5 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1 is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 2.14748e\\\+09 is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 4.29497e\\\+09 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 4.29497e\\\+09 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 4.29497e\\\+09 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -5 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1.5 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1 is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -5 is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1.5 is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1 is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
@@ -176,10 +176,10 @@ main (void)
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 9.22337e\\\+18 is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 1.84467e\\\+19 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 1.84467e\\\+19 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value 1.84467e\\\+19 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
@@ -198,7 +198,7 @@ main (void)
/* { dg-output "\[^\n\r]*value -5 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1.5 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*value -1 is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value nan is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -?nan is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value inf is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value -inf is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Nn\]a\[Nn\] is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -?\[Nn\]a\[Nn\] is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value \[Ii\]n\[Ff\] is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*value -\[Ii\]n\[Ff\] is outside the range of representable values of type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
@@ -22,18 +22,22 @@
# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1
# define ASAN_INTERCEPT__LONGJMP 1
# define ASAN_INTERCEPT_STRDUP 1
-# define ASAN_INTERCEPT_INDEX 1
# define ASAN_INTERCEPT_PTHREAD_CREATE 1
# define ASAN_INTERCEPT_MLOCKX 1
#else
# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
# define ASAN_INTERCEPT__LONGJMP 0
# define ASAN_INTERCEPT_STRDUP 0
-# define ASAN_INTERCEPT_INDEX 0
# define ASAN_INTERCEPT_PTHREAD_CREATE 0
# define ASAN_INTERCEPT_MLOCKX 0
#endif
+#if !SANITIZER_WINDOWS && !SANITIZER_SOLARIS
+# define ASAN_INTERCEPT_INDEX 1
+#else
+# define ASAN_INTERCEPT_INDEX 0
+#endif
+
#if SANITIZER_FREEBSD || SANITIZER_LINUX
# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1
#else
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#include "asan_interceptors.h"
#include "asan_internal.h"
@@ -35,7 +35,11 @@
#include <sys/link_elf.h>
#endif
-#if SANITIZER_ANDROID || SANITIZER_FREEBSD
+#ifdef SANITIZER_SOLARIS
+#include <link.h>
+#endif
+
+#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS
#include <ucontext.h>
extern "C" void* _DYNAMIC;
#else
@@ -93,6 +97,17 @@ static int FindFirstDSOCallback(struct d
if (internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0)
return 0;
+#if SANITIZER_SOLARIS
+ if (0)
+ Report("info->dlpi_name = %s\tinfo->dlpi_addr = %x\n",
+ info->dlpi_name, info->dlpi_addr);
+ return 0;
+
+ // Ignore executable on Solaris
+ if (info->dlpi_addr == 0)
+ return 0;
+#endif
+
*(const char **)data = info->dlpi_name;
return 1;
}
@@ -186,6 +201,15 @@ void GetPcSpBp(void *context, uptr *pc,
*sp = ucontext->uc_mcontext.mc_esp;
# else
ucontext_t *ucontext = (ucontext_t*)context;
+# ifndef REG_EIP
+# define REG_EIP REG_PC
+# endif
+# ifndef REG_EBP
+# define REG_EBP REG_FP
+# endif
+# ifndef REG_ESP
+# define REG_ESP REG_SP
+# endif
*pc = ucontext->uc_mcontext.gregs[REG_EIP];
*bp = ucontext->uc_mcontext.gregs[REG_EBP];
*sp = ucontext->uc_mcontext.gregs[REG_ESP];
@@ -243,4 +267,4 @@ void ReadContextStack(void *context, upt
} // namespace __asan
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#include "asan_allocator.h"
@@ -151,4 +151,4 @@ INTERCEPTOR(void, malloc_stats, void) {
__asan_print_accumulated_stats();
}
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
@@ -21,9 +21,13 @@ namespace __asan {
void PoisonShadow(uptr addr, uptr size, u8 value) {
if (!flags()->poison_heap) return;
CHECK(AddrIsAlignedByGranularity(addr));
+#if !(SANITIZER_SOLARIS && defined(_LP64))
CHECK(AddrIsInMem(addr));
+#endif
CHECK(AddrIsAlignedByGranularity(addr + size));
+#if !(SANITIZER_SOLARIS && defined(_LP64))
CHECK(AddrIsInMem(addr + size - SHADOW_GRANULARITY));
+#endif
CHECK(REAL(memset));
FastPoisonShadow(addr, size, value);
}
@@ -555,6 +555,8 @@ static void AsanInitInternal() {
CHECK(!asan_init_is_running && "ASan init calls itself!");
asan_init_is_running = true;
+ InitializeAsanInterceptors();
+
// Initialize flags. This must be done early, because most of the
// initialization steps look at flags().
const char *options = GetEnv("ASAN_OPTIONS");
@@ -591,7 +593,7 @@ static void AsanInitInternal() {
// Setup internal allocator callback.
SetLowLevelAllocateCallback(OnLowLevelAllocate);
- InitializeAsanInterceptors();
+ //InitializeAsanInterceptors();
ReplaceSystemMalloc();
@@ -38,6 +38,8 @@ case "${target}" in
x86_64-*-darwin[1]* | i?86-*-darwin[1]*)
TSAN_SUPPORTED=no
;;
+ x86_64-*-solaris2* | i?86-*-solaris2*)
+ ;;
*)
UNSUPPORTED=1
;;
@@ -14,7 +14,8 @@
#define INTERCEPTION_H
#if !defined(__linux__) && !defined(__FreeBSD__) && \
- !defined(__APPLE__) && !defined(_WIN32)
+ !defined(__APPLE__) && !defined(_WIN32) && \
+ !(defined(__sun__) && defined(__svr4__))
# error "Interception doesn't work on this operating system."
#endif
@@ -234,7 +235,7 @@ typedef unsigned long uptr; // NOLINT
#define INCLUDED_FROM_INTERCEPTION_LIB
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || (defined(__sun__) && defined(__svr4__))
# include "interception_linux.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
# define INTERCEPT_FUNCTION_VER(func, symver) \
@@ -10,7 +10,7 @@
// Linux-specific interception methods.
//===----------------------------------------------------------------------===//
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || (defined(__sun__) && defined(__svr4__))
#include "interception.h"
#include <dlfcn.h> // for dlsym() and dlvsym()
@@ -22,13 +22,14 @@ bool GetRealFunctionAddress(const char *
return real == wrapper;
}
-#if !defined(__ANDROID__) // android does not have dlvsym
+// Android and Solaris do not have dlvsym
+#if !defined(__ANDROID__) && !(defined(__sun__) && defined(__svr4__))
void *GetFuncAddrVer(const char *func_name, const char *ver) {
return dlvsym(RTLD_NEXT, func_name, ver);
}
-#endif // !defined(__ANDROID__)
+#endif // !__ANDROID__ && !(__sun__ && __svr4__)
} // namespace __interception
-#endif // __linux__ || __FreeBSD__
+#endif // __linux__ || __FreeBSD__ || (__sun__ && __svr4__)
@@ -10,7 +10,7 @@
// Linux-specific interception methods.
//===----------------------------------------------------------------------===//
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || (defined(__sun__) && defined(__svr4__))
#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
# error "interception_linux.h should be included from interception library only"
@@ -32,14 +32,15 @@ void *GetFuncAddrVer(const char *func_na
(::__interception::uptr) & (func), \
(::__interception::uptr) & WRAP(func))
-#if !defined(__ANDROID__) // android does not have dlvsym
+// Android and Solaris do not have dlvsym
+#if !defined(__ANDROID__) && !(defined(__sun__) && defined(__svr4__))
# 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 // !defined(__ANDROID__)
+#endif // !__ANDROID__ && !(__sun__ && __svr4__)
#endif // INTERCEPTION_LINUX_H
-#endif // __linux__ || __FreeBSD__
+#endif // __linux__ || __FreeBSD__ || (__sun__ && __svr4__)
@@ -37,6 +37,7 @@ sanitizer_common_files = \
sanitizer_printf.cc \
sanitizer_procmaps_linux.cc \
sanitizer_procmaps_mac.cc \
+ sanitizer_solaris.cc \
sanitizer_stackdepot.cc \
sanitizer_stacktrace.cc \
sanitizer_stacktrace_libcdep.cc \
@@ -511,7 +511,7 @@ const uptr kPthreadDestructorIterations
// Callback type for iterating over a set of memory ranges.
typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
-#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !defined(SANITIZER_GO)
+#if (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) && !defined(SANITIZER_GO)
extern uptr indirect_call_wrapper;
void SetIndirectCallWrapper(uptr wrapper);
@@ -537,12 +537,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;
@@ -45,7 +45,9 @@ static void ioctl_table_fill() {
++ioctl_table_size; \
}
+#if !SANITIZER_SOLARIS
_(FIOASYNC, READ, sizeof(int));
+#endif
_(FIOCLEX, NONE, 0);
_(FIOGETOWN, WRITE, sizeof(int));
_(FIONBIO, READ, sizeof(int));
@@ -71,7 +73,9 @@ static void ioctl_table_fill() {
_(SIOCSIFMTU, READ, struct_ifreq_sz);
_(SIOCSIFNETMASK, READ, struct_ifreq_sz);
_(SIOCSPGRP, READ, sizeof(int));
+#if !SANITIZER_SOLARIS
_(TIOCCONS, NONE, 0);
+#endif
_(TIOCEXCL, NONE, 0);
_(TIOCGETD, WRITE, sizeof(int));
_(TIOCGPGRP, WRITE, pid_t_sz);
@@ -24,7 +24,7 @@
#include "sanitizer_stacktrace.h"
#include "sanitizer_symbolizer.h"
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_SOLARIS
#include <asm/param.h>
#endif
@@ -37,7 +37,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>
@@ -12,7 +12,7 @@
#define SANITIZER_LINUX_H
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_platform_limits_posix.h"
@@ -87,5 +87,5 @@ void CacheBinaryName();
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
} // namespace __sanitizer
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#endif // SANITIZER_LINUX_H
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
@@ -35,6 +35,10 @@
#define pthread_getattr_np pthread_attr_get_np
#endif
+#if SANITIZER_SOLARIS
+#include <thread.h>
+#endif
+
#if SANITIZER_LINUX
#include <sys/prctl.h>
#endif
@@ -72,7 +76,7 @@ void GetThreadStackTopAndBottom(bool at_
uptr *stack_bottom) {
CHECK(stack_top);
CHECK(stack_bottom);
- if (at_initialization) {
+ if (at_initialization && !SANITIZER_SOLARIS) {
// This is the main thread. Libpthread may not be initialized yet.
struct rlimit rl;
CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
@@ -102,15 +106,22 @@ void GetThreadStackTopAndBottom(bool at_
*stack_bottom = end - stacksize;
return;
}
+ uptr stacksize = 0;
+ void *stackaddr = 0;
+#if SANITIZER_SOLARIS
+ stack_t ss;
+ CHECK_EQ(thr_stksegment(&ss), 0);
+ stacksize = ss.ss_size;
+ stackaddr = 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 = 0;
my_pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
pthread_attr_destroy(&attr);
+ CHECK_LE(stacksize, kMaxThreadStackSize); // Sanity check.
+#endif
- CHECK_LE(stacksize, kMaxThreadStackSize); // Sanity check.
*stack_top = (uptr)stackaddr + stacksize;
*stack_bottom = (uptr)stackaddr;
}
@@ -279,7 +290,7 @@ static uptr g_tls_size;
#endif
void InitTlsSize() {
-#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID
+#if !SANITIZER_FREEBSD && !SANITIZER_SOLARIS && !SANITIZER_ANDROID
typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
get_tls_func get_tls;
void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
@@ -291,7 +302,7 @@ void InitTlsSize() {
size_t tls_align = 0;
IndirectExternCall(get_tls)(&tls_size, &tls_align);
g_tls_size = tls_size;
-#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID
+#endif // !SANITIZER_FREEBSD && !SANITIZER_SOLARIS && !SANITIZER_ANDROID
}
#if (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
@@ -399,6 +410,10 @@ static void GetTls(uptr *addr, uptr *siz
*addr = (uptr) dtv[2];
*size = (*addr == 0) ? 0 : ((uptr) segbase[0] - (uptr) dtv[2]);
}
+#elif SANITIZER_SOLARIS
+ // FIXME
+ *addr = 0;
+ *size = 0;
#else
# error "Unknown OS"
#endif
@@ -12,7 +12,8 @@
#define SANITIZER_PLATFORM_H
#if !defined(__linux__) && !defined(__FreeBSD__) && \
- !defined(__APPLE__) && !defined(_WIN32)
+ !defined(__APPLE__) && !defined(_WIN32) && \
+ !(defined(__sun__) && defined(__svr4__))
# error "This operating system is not supported"
#endif
@@ -28,6 +29,12 @@
# define SANITIZER_FREEBSD 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>
@@ -53,7 +60,7 @@
# define SANITIZER_ANDROID 0
#endif
-#define SANITIZER_POSIX (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC)
+#define SANITIZER_POSIX (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_SOLARIS)
#if __LP64__ || defined(_WIN64)
# define SANITIZER_WORDSIZE 64
@@ -45,6 +45,12 @@
# define SI_IOS 0
#endif
+#if SANITIZER_SOLARIS
+# define SI_SOLARIS 1
+#else
+# define SI_SOLARIS 0
+#endif
+
#define SANITIZER_INTERCEPT_STRCMP 1
#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
@@ -146,7 +152,7 @@
#define SANITIZER_INTERCEPT_BACKTRACE SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
#define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_STATFS SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_STATFS SI_NOT_WINDOWS && !SI_SOLARIS
#define SANITIZER_INTERCEPT_STATFS64 \
(SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_STATVFS SI_LINUX_NOT_ANDROID
@@ -12,7 +12,7 @@
#include "sanitizer_platform.h"
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_SOLARIS
#include <arpa/inet.h>
#include <dirent.h>
@@ -160,6 +160,13 @@
#include <sys/sockio.h>
#endif
+#if SANITIZER_SOLARIS
+#include <sys/filio.h>
+#include <sys/sockio.h>
+#include <sys/ptyvar.h>
+#include <sys/ethernet.h>
+#endif
+
// Include these after system headers to avoid name clashes and ambiguities.
#include "sanitizer_internal_defs.h"
#include "sanitizer_platform_limits_posix.h"
@@ -189,7 +196,9 @@ namespace __sanitizer {
unsigned struct_tms_sz = sizeof(struct tms);
unsigned struct_sigevent_sz = sizeof(struct sigevent);
unsigned struct_sched_param_sz = sizeof(struct sched_param);
+#if !SANITIZER_SOLARIS
unsigned struct_statfs_sz = sizeof(struct statfs);
+#endif
#if SANITIZER_MAC && !SANITIZER_IOS
unsigned struct_statfs64_sz = sizeof(struct statfs64);
@@ -391,14 +400,16 @@ namespace __sanitizer {
unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);
#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
-#if !SANITIZER_ANDROID && !SANITIZER_MAC
+#if !SANITIZER_ANDROID && !SANITIZER_MAC && !SANITIZER_SOLARIS
unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
#endif
unsigned IOCTL_NOT_PRESENT = 0;
+#if !SANITIZER_SOLARIS
unsigned IOCTL_FIOASYNC = FIOASYNC;
+#endif
unsigned IOCTL_FIOCLEX = FIOCLEX;
unsigned IOCTL_FIOGETOWN = FIOGETOWN;
unsigned IOCTL_FIONBIO = FIONBIO;
@@ -424,7 +435,9 @@ namespace __sanitizer {
unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
+#if !SANITIZER_SOLARIS
unsigned IOCTL_TIOCCONS = TIOCCONS;
+#endif
unsigned IOCTL_TIOCEXCL = TIOCEXCL;
unsigned IOCTL_TIOCGETD = TIOCGETD;
unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
@@ -1013,8 +1026,10 @@ 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);
+#if !SANITIZER_SOLARIS
CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);
CHECK_SIZE_AND_OFFSET(tm, tm_zone);
+#endif
#if SANITIZER_LINUX
CHECK_TYPE_SIZE(mntent);
@@ -1062,7 +1077,7 @@ 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);
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS
// Compare against the union, because we can't reach into the union in a
// compliant way.
#ifdef ifa_dstaddr
@@ -254,7 +254,12 @@ namespace __sanitizer {
struct __sanitizer_ifaddrs {
struct __sanitizer_ifaddrs *ifa_next;
char *ifa_name;
+#if SANITIZER_SOLARIS
+ // uint64_t
+ u64 ifa_flags;
+#else
unsigned int ifa_flags;
+#endif
void *ifa_addr; // (struct sockaddr *)
void *ifa_netmask; // (struct sockaddr *)
// This is a union on Linux.
@@ -291,8 +296,17 @@ namespace __sanitizer {
struct __sanitizer_passwd {
char *pw_name;
char *pw_passwd;
+#if !SANITIZER_SOLARIS
int pw_uid;
int pw_gid;
+#else
+ // uid_t
+ unsigned int pw_uid;
+ // gid_t
+ unsigned int pw_gid;
+ char *pw_age;
+ char *pw_comment;
+#endif
#if SANITIZER_MAC || SANITIZER_FREEBSD
long pw_change;
char *pw_class;
@@ -344,8 +358,10 @@ namespace __sanitizer {
int tm_wday;
int tm_yday;
int tm_isdst;
+#if !SANITIZER_SOLARIS
long int tm_gmtoff;
const char *tm_zone;
+#endif
};
#if SANITIZER_LINUX
@@ -359,7 +375,7 @@ namespace __sanitizer {
};
#endif
-#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_SOLARIS
struct __sanitizer_msghdr {
void *msg_name;
unsigned msg_namelen;
@@ -488,24 +504,35 @@ namespace __sanitizer {
// uint32_t * 4
unsigned int __bits[4];
};
+#elif SANITIZER_SOLARIS
+ // From <sys/signal.h>.
+ struct __sanitizer_sigset_t {
+ unsigned int __bits[4];
+ };
#endif
// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
struct __sanitizer_sigaction {
+#if SANITIZER_SOLARIS
+ int sa_flags;
+#endif
union {
void (*sigaction)(int sig, void *siginfo, void *uctx);
void (*handler)(int sig);
};
#if SANITIZER_FREEBSD
int sa_flags;
+#endif
__sanitizer_sigset_t sa_mask;
-#else
- __sanitizer_sigset_t sa_mask;
+#if !SANITIZER_FREEBSD && !SANITIZER_SOLARIS
int sa_flags;
#endif
#if SANITIZER_LINUX
void (*sa_restorer)();
#endif
+#if SANITIZER_SOLARIS && !defined(_LP64)
+ int sa_resv[2];
+#endif
};
#if SANITIZER_FREEBSD
@@ -553,7 +580,7 @@ namespace __sanitizer {
int ai_family;
int ai_socktype;
int ai_protocol;
-#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_SOLARIS
unsigned ai_addrlen;
char *ai_canonname;
void *ai_addr;
@@ -631,6 +658,10 @@ namespace __sanitizer {
char *we_strings;
uptr we_nbytes;
#endif
+#if SANITIZER_SOLARIS
+ char **we_wordp;
+ int we_wordn;
+#endif
};
#if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -860,7 +891,9 @@ struct __sanitizer_obstack {
extern unsigned IOCTL_SIOCSIFMTU;
extern unsigned IOCTL_SIOCSIFNETMASK;
extern unsigned IOCTL_SIOCSPGRP;
+#if !SANITIZER_SOLARIS
extern unsigned IOCTL_TIOCCONS;
+#endif
extern unsigned IOCTL_TIOCEXCL;
extern unsigned IOCTL_TIOCGETD;
extern unsigned IOCTL_TIOCGPGRP;
@@ -39,7 +39,12 @@ uptr GetThreadSelf() {
}
void FlushUnneededShadowMemory(uptr addr, uptr size) {
+#if SANITIZER_SOLARIS
+ // FIXME: explain
+ madvise((caddr_t)addr, size, MADV_DONTNEED);
+#else
madvise((void*)addr, size, MADV_DONTNEED);
+#endif
}
void DisableCoreDumper() {
@@ -18,13 +18,13 @@
namespace __sanitizer {
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
struct ProcSelfMapsBuff {
char *data;
uptr mmaped_size;
uptr len;
};
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
class MemoryMappingLayout {
public:
@@ -53,7 +53,7 @@ class MemoryMappingLayout {
// FIXME: Hide implementation details for different platforms in
// platform-specific files.
-# if SANITIZER_FREEBSD || SANITIZER_LINUX
+# if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
ProcSelfMapsBuff proc_self_maps_;
char *current_;
@@ -9,7 +9,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"
@@ -20,6 +20,11 @@
#include <sys/user.h>
#endif
+#if SANITIZER_SOLARIS
+#include <procfs.h>
+#include <limits.h>
+#endif
+
namespace __sanitizer {
// Linker initialized.
@@ -43,6 +48,9 @@ static void ReadProcMaps(ProcSelfMapsBuf
proc_maps->data = (char*)VmMap;
proc_maps->mmaped_size = MmapedSize;
proc_maps->len = Size;
+#elif SANITIZER_SOLARIS
+ proc_maps->len = ReadFileToBuffer("/proc/self/xmap", &proc_maps->data,
+ &proc_maps->mmaped_size, 1 << 26);
#else
proc_maps->len = ReadFileToBuffer("/proc/self/maps", &proc_maps->data,
&proc_maps->mmaped_size, 1 << 26);
@@ -187,7 +195,29 @@ bool MemoryMappingLayout::Next(uptr *sta
}
current_ += VmEntry->kve_structsize;
-#else // !SANITIZER_FREEBSD
+#elif SANITIZER_SOLARIS
+ prxmap_t *xmapentry = (prxmap_t*)current_;
+
+ *start = (uptr)xmapentry->pr_vaddr;
+ *end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size);
+ *offset = (uptr)xmapentry->pr_offset;
+
+ *protection = 0;
+ if ((xmapentry->pr_mflags & MA_READ) != 0)
+ *protection |= kProtectionRead;
+ if ((xmapentry->pr_mflags & MA_WRITE) != 0)
+ *protection |= kProtectionWrite;
+ if ((xmapentry->pr_mflags & MA_EXEC) != 0)
+ *protection |= kProtectionExecute;
+
+ if (filename != NULL && filename_size > 0) {
+ internal_snprintf(filename,
+ Min(filename_size, (uptr)PATH_MAX),
+ "%s", xmapentry->pr_mapname);
+ }
+
+ current_ += sizeof(prxmap_t);
+#else // !SANITIZER_FREEBSD && !SANITIZER_SOLARIS
char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
if (next_line == 0)
next_line = last;
new file mode 100644
@@ -0,0 +1,215 @@
+//===-- 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_procmaps.h"
+
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+namespace __sanitizer {
+
+#include "sanitizer_syscall_generic.inc"
+
+// ---------------------- sanitizer_libc.h
+uptr internal_mmap(void *addr, uptr /*size_t*/ length, int prot, int flags,
+ int fd, u64 offset) {
+ return (uptr)mmap(addr, length, prot, flags, fd, offset);
+}
+
+uptr internal_munmap(void *addr, uptr length) {
+ return munmap(addr, length);
+}
+
+uptr internal_close(fd_t fd) {
+ return close(fd);
+}
+
+uptr internal_open(const char *filename, int flags) {
+ return open(filename, flags);
+}
+
+uptr internal_open(const char *filename, int flags, u32 mode) {
+ return open(filename, flags, mode);
+}
+
+uptr OpenFile(const char *filename, bool write) {
+ return internal_open(filename,
+ write ? O_WRONLY | O_CREAT : O_RDONLY, 0660);
+}
+
+uptr internal_read(fd_t fd, void *buf, uptr count) {
+ return read(fd, buf, count);
+}
+
+uptr internal_write(fd_t fd, const void *buf, uptr count) {
+ return write(fd, buf, count);
+}
+
+uptr internal_stat(const char *path, void *buf) {
+ return stat(path, (struct stat *)buf);
+}
+
+uptr internal_lstat(const char *path, void *buf) {
+ return lstat(path, (struct stat *)buf);
+}
+
+uptr internal_fstat(fd_t fd, void *buf) {
+ return 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;
+}
+
+uptr internal_dup2(int oldfd, int newfd) {
+ return dup2(oldfd, newfd);
+}
+
+uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
+ return readlink(path, buf, bufsize);
+}
+
+uptr internal_sched_yield() {
+ return sched_yield();
+}
+
+void internal__exit(int exitcode) {
+ _exit(exitcode);
+}
+
+uptr internal_getpid() {
+ return getpid();
+}
+
+int internal_fork() {
+ // TODO(glider): this may call user's pthread_atfork() handlers which is bad.
+ return fork();
+}
+
+// ----------------- sanitizer_common.h
+bool FileExists(const char *filename) {
+ struct stat st;
+ if (stat(filename, &st))
+ return false;
+ // Sanity check: filename is a regular file.
+ return S_ISREG(st.st_mode);
+}
+
+uptr GetTid() {
+ return (uptr)pthread_self();
+}
+
+const char *GetEnv(const char *name) {
+ // FIXME: Need non-libc implementation?
+ return getenv(name);
+}
+
+void ReExec() {
+ UNIMPLEMENTED();
+}
+
+void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
+ (void)args;
+ // Nothing here for now.
+}
+
+uptr GetPageSize() {
+ return sysconf(_SC_PAGESIZE);
+}
+
+BlockingMutex::BlockingMutex(LinkerInitialized) {
+ CHECK_EQ(owner_, 0);
+ CHECK_EQ(pthread_mutex_init((pthread_mutex_t *)&opaque_storage_, NULL), 0);
+}
+
+BlockingMutex::BlockingMutex() {
+ internal_memset(this, 0, sizeof(*this));
+ CHECK_EQ(pthread_mutex_init((pthread_mutex_t *)&opaque_storage_, NULL), 0);
+}
+
+void BlockingMutex::Lock() {
+ CHECK(sizeof(pthread_mutex_t) <= sizeof(opaque_storage_));
+ CHECK_NE(owner_, (uptr)pthread_self());
+ CHECK_EQ(pthread_mutex_lock((pthread_mutex_t *)&opaque_storage_), 0);
+ CHECK(!owner_);
+ owner_ = (uptr)pthread_self();
+}
+
+void BlockingMutex::Unlock() {
+ CHECK(owner_ == (uptr)pthread_self());
+ owner_ = 0;
+ CHECK_EQ(pthread_mutex_unlock((pthread_mutex_t *)&opaque_storage_), 0);
+}
+
+void BlockingMutex::CheckLocked() {
+ CHECK_EQ((uptr)pthread_self(), owner_);
+}
+
+u64 NanoTime() {
+ return gethrtime();
+}
+
+bool IsDeadlySignal(int signum) {
+ return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
+}
+
+static char proc_self_exe_cache_str[kMaxPathLength];
+static uptr proc_self_exe_cache_len = 0;
+
+uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
+ const char *execname = getexecname();
+ uptr module_name_len;
+ if (execname != 0) {
+ module_name_len = internal_snprintf(buf, buf_len, execname);
+ } else {
+ if (proc_self_exe_cache_len) {
+ // If available, use the cached module name.
+ CHECK_LE(proc_self_exe_cache_len, buf_len);
+ internal_strncpy(buf, proc_self_exe_cache_str, buf_len);
+ module_name_len = internal_strlen(proc_self_exe_cache_str);
+ } else {
+ // We can't determine execname for some reason, assume the name of the
+ // binary is unknown.
+ Report("WARNING: getexecname() failed, "
+ "some stack frames may not be symbolized\n");
+ module_name_len = 0;
+ }
+ CHECK_LT(module_name_len, buf_len);
+ buf[module_name_len] = '\0';
+ }
+ return module_name_len;
+}
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_SOLARIS
@@ -12,9 +12,10 @@
#ifndef UBSAN_VALUE_H
#define UBSAN_VALUE_H
-// For now, only support Linux, FreeBSD and Darwin. Other platforms should
-// be easy to add, and probably work as-is.
-#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__APPLE__)
+// For now, only support Linux, FreeBSD, Darwin, and Solaris. Other platforms
+// should be easy to add, and probably work as-is.
+#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__APPLE__) && \
+ !(defined(__sun__) && defined(__svr4__))
#error "UBSan not supported for this platform!"
#endif