aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-29 16:25:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-29 16:25:57 +0000
commit224c1c721b03784d0da2af00884ea8d4eb7a1650 (patch)
treeac9e50e358e85ab37022d6fdafaa0c8dbb4adad2
parent99ea5e489fa5765bf0eb50ca4261ab5cc20abeeb (diff)
downloadsrc-224c1c721b03784d0da2af00884ea8d4eb7a1650.tar.gz
src-224c1c721b03784d0da2af00884ea8d4eb7a1650.zip
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=319144 svn path=/vendor/compiler-rt/compiler-rt-trunk-r304222/; revision=319235; tag=vendor/compiler-rt/compiler-rt-trunk-r304222
-rw-r--r--cmake/base-config-ix.cmake4
-rw-r--r--cmake/builtin-config-ix.cmake2
-rw-r--r--lib/asan/asan_interceptors.cc12
-rw-r--r--lib/asan/asan_win.cc2
-rwxr-xr-xlib/asan/scripts/asan_device_setup5
-rw-r--r--lib/asan/tests/asan_interface_test.cc4
-rw-r--r--lib/asan/tests/asan_noinst_test.cc9
-rw-r--r--lib/asan/tests/asan_test.cc21
-rw-r--r--lib/builtins/CMakeLists.txt6
-rw-r--r--lib/builtins/README.txt4
-rw-r--r--lib/builtins/arm/aeabi_cdcmp.S11
-rw-r--r--lib/builtins/arm/aeabi_cfcmp.S11
-rw-r--r--lib/builtins/arm/eqdf2vfp.S1
-rw-r--r--lib/builtins/arm/eqsf2vfp.S1
-rw-r--r--lib/builtins/arm/gedf2vfp.S1
-rw-r--r--lib/builtins/arm/gesf2vfp.S1
-rw-r--r--lib/builtins/arm/gtdf2vfp.S1
-rw-r--r--lib/builtins/arm/gtsf2vfp.S1
-rw-r--r--lib/builtins/arm/ledf2vfp.S1
-rw-r--r--lib/builtins/arm/lesf2vfp.S1
-rw-r--r--lib/builtins/arm/ltdf2vfp.S1
-rw-r--r--lib/builtins/arm/ltsf2vfp.S1
-rw-r--r--lib/builtins/arm/nedf2vfp.S1
-rw-r--r--lib/builtins/arm/nesf2vfp.S1
-rw-r--r--lib/builtins/arm/unorddf2vfp.S1
-rw-r--r--lib/builtins/arm/unordsf2vfp.S1
-rw-r--r--lib/builtins/assembly.h2
-rw-r--r--lib/builtins/bswapdi2.c27
-rw-r--r--lib/builtins/bswapsi2.c23
-rw-r--r--lib/lsan/lsan_common.cc28
-rw-r--r--lib/lsan/lsan_common_mac.cc7
-rw-r--r--lib/lsan/lsan_flags.inc2
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_primary32.h2
-rw-r--r--lib/sanitizer_common/sanitizer_common.h2
-rw-r--r--lib/sanitizer_common/sanitizer_flag_parser.h5
-rw-r--r--lib/sanitizer_common/sanitizer_flags.h1
-rw-r--r--lib/sanitizer_common/sanitizer_flags.inc10
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_linux_s390.cc7
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc31
-rw-r--r--lib/sanitizer_common/sanitizer_posix_libcdep.cc25
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc4
-rw-r--r--lib/sanitizer_common/tests/sanitizer_flags_test.cc6
-rw-r--r--lib/scudo/scudo_tls_linux.cpp16
-rw-r--r--lib/tsan/rtl/tsan_platform.h1
-rw-r--r--lib/tsan/rtl/tsan_platform_linux.cc14
-rw-r--r--lib/tsan/rtl/tsan_platform_mac.cc41
-rw-r--r--lib/tsan/rtl/tsan_rtl_thread.cc14
-rw-r--r--test/asan/TestCases/Linux/preinstalled_signal.cc105
-rw-r--r--test/asan/TestCases/Linux/sanbox_read_proc_self_maps_test.cc8
-rw-r--r--test/asan/TestCases/Posix/allow_user_segv.cc53
-rw-r--r--test/asan/TestCases/Posix/current_allocated_bytes.cc3
-rw-r--r--test/asan/TestCases/Posix/wait.cc1
-rw-r--r--test/asan/TestCases/Posix/wait3.cc2
-rw-r--r--test/asan/TestCases/Posix/wait4.cc1
-rw-r--r--test/asan/TestCases/Posix/waitid.cc2
-rw-r--r--test/builtins/Unit/bswapdi2_test.c37
-rw-r--r--test/builtins/Unit/bswapsi2_test.c37
-rw-r--r--test/lsan/TestCases/many_tls_keys.cc97
-rw-r--r--test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc6
-rw-r--r--test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc2
-rw-r--r--test/ubsan/TestCases/Integer/negate-overflow.cpp6
62 files changed, 552 insertions, 187 deletions
diff --git a/cmake/base-config-ix.cmake b/cmake/base-config-ix.cmake
index 6f9f15139ad7..b38c6ca96fac 100644
--- a/cmake/base-config-ix.cmake
+++ b/cmake/base-config-ix.cmake
@@ -63,7 +63,9 @@ else()
set(COMPILER_RT_TEST_COMPILER_ID GNU)
endif()
-string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
+if(NOT DEFINED COMPILER_RT_OS_DIR)
+ string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
+endif()
set(COMPILER_RT_LIBRARY_OUTPUT_DIR
${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
set(COMPILER_RT_LIBRARY_INSTALL_DIR
diff --git a/cmake/builtin-config-ix.cmake b/cmake/builtin-config-ix.cmake
index dc2ec16943ac..20bc68476c7d 100644
--- a/cmake/builtin-config-ix.cmake
+++ b/cmake/builtin-config-ix.cmake
@@ -24,7 +24,7 @@ int foo(int x, int y) {
set(ARM64 aarch64)
-set(ARM32 arm armhf armv6m)
+set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k)
set(X86 i386 i686)
set(X86_64 x86_64)
set(MIPS32 mips mipsel)
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index c6969c979a59..cb2214f966ea 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -357,28 +357,22 @@ DEFINE_REAL_PTHREAD_FUNCTIONS
#if SANITIZER_ANDROID
INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
- if (!IsHandledDeadlySignal(signum) ||
- common_flags()->allow_user_segv_handler) {
+ if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
return REAL(bsd_signal)(signum, handler);
- }
return 0;
}
#endif
INTERCEPTOR(void*, signal, int signum, void *handler) {
- if (!IsHandledDeadlySignal(signum) ||
- common_flags()->allow_user_segv_handler) {
+ if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
return REAL(signal)(signum, handler);
- }
return nullptr;
}
INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
struct sigaction *oldact) {
- if (!IsHandledDeadlySignal(signum) ||
- common_flags()->allow_user_segv_handler) {
+ if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
return REAL(sigaction)(signum, act, oldact);
- }
return 0;
}
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc
index 4ab535c42e5a..26db32465da8 100644
--- a/lib/asan/asan_win.cc
+++ b/lib/asan/asan_win.cc
@@ -80,7 +80,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
INTERCEPTOR_WINAPI(LPTOP_LEVEL_EXCEPTION_FILTER, SetUnhandledExceptionFilter,
LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
CHECK(REAL(SetUnhandledExceptionFilter));
- if (ExceptionFilter == &SEHHandler || common_flags()->allow_user_segv_handler)
+ if (ExceptionFilter == &SEHHandler)
return REAL(SetUnhandledExceptionFilter)(ExceptionFilter);
// We record the user provided exception handler to be called for all the
// exceptions unhandled by asan.
diff --git a/lib/asan/scripts/asan_device_setup b/lib/asan/scripts/asan_device_setup
index fdfc46f6e5b8..c807df3cd252 100755
--- a/lib/asan/scripts/asan_device_setup
+++ b/lib/asan/scripts/asan_device_setup
@@ -327,11 +327,6 @@ exec $_to \$@
EOF
}
-# On Android-L not allowing user segv handler breaks some applications.
-if [[ PRE_L -eq 0 ]]; then
- ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
-fi
-
if [[ x$extra_options != x ]] ; then
ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
fi
diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc
index d13962b8f505..7d3e520d81a4 100644
--- a/lib/asan/tests/asan_interface_test.cc
+++ b/lib/asan/tests/asan_interface_test.cc
@@ -102,9 +102,6 @@ TEST(AddressSanitizerInterface, GetHeapSizeTest) {
}
}
-#ifndef __powerpc64__
-// FIXME: This has not reliably worked on powerpc since r279664. Re-enable
-// this once the problem is tracked down and fixed.
static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
static const size_t kManyThreadsIterations = 250;
static const size_t kManyThreadsNumThreads =
@@ -138,7 +135,6 @@ TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
// so we can't check for equality here.
EXPECT_LT(after_test, before_test + (1UL<<20));
}
-#endif
static void DoDoubleFree() {
int *x = Ident(new int);
diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc
index b3a235e478e3..65acb2839ba1 100644
--- a/lib/asan/tests/asan_noinst_test.cc
+++ b/lib/asan/tests/asan_noinst_test.cc
@@ -97,9 +97,6 @@ TEST(AddressSanitizer, NoInstMallocTest) {
MallocStress(ASAN_LOW_MEMORY ? 300000 : 1000000);
}
-#ifndef __powerpc64__
-// FIXME: This has not reliably worked on powerpc since r279664. Re-enable
-// this once the problem is tracked down and fixed.
TEST(AddressSanitizer, ThreadedMallocStressTest) {
const int kNumThreads = 4;
const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;
@@ -112,7 +109,6 @@ TEST(AddressSanitizer, ThreadedMallocStressTest) {
PTHREAD_JOIN(t[i], 0);
}
}
-#endif
static void PrintShadow(const char *tag, uptr ptr, size_t size) {
fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);
@@ -210,10 +206,6 @@ void *ThreadedOneSizeMallocStress(void *unused) {
return NULL;
}
-#ifndef __powerpc64__
-// FIXME: This has not reliably worked on powerpc since r279664. Re-enable
-// this once the problem is tracked down and fixed.
-
TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
const int kNumThreads = 4;
pthread_t t[kNumThreads];
@@ -224,7 +216,6 @@ TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
PTHREAD_JOIN(t[i], 0);
}
}
-#endif
TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {
using __asan::kHighMemEnd;
diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc
index 7ac72955f487..d0128e34de8d 100644
--- a/lib/asan/tests/asan_test.cc
+++ b/lib/asan/tests/asan_test.cc
@@ -251,7 +251,8 @@ TEST(AddressSanitizer, BitFieldNegativeTest) {
namespace {
const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";
-const char kOverriddenHandler[] = "ASan signal handler has been overridden\n";
+const char kOverriddenSigactionHandler[] = "Test sigaction handler\n";
+const char kOverriddenSignalHandler[] = "Test signal handler\n";
TEST(AddressSanitizer, WildAddressTest) {
char *c = (char*)0x123;
@@ -259,12 +260,12 @@ TEST(AddressSanitizer, WildAddressTest) {
}
void my_sigaction_sighandler(int, siginfo_t*, void*) {
- fprintf(stderr, kOverriddenHandler);
+ fprintf(stderr, kOverriddenSigactionHandler);
exit(1);
}
void my_signal_sighandler(int signum) {
- fprintf(stderr, kOverriddenHandler);
+ fprintf(stderr, kOverriddenSignalHandler);
exit(1);
}
@@ -273,16 +274,20 @@ TEST(AddressSanitizer, SignalTest) {
memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = my_sigaction_sighandler;
sigact.sa_flags = SA_SIGINFO;
- // ASan should silently ignore sigaction()...
+ char *c = (char *)0x123;
+
+ EXPECT_DEATH(*c = 0, kSEGVCrash);
+
+ // ASan should allow to set sigaction()...
EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));
#ifdef __APPLE__
EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
#endif
- char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kSEGVCrash);
+ EXPECT_DEATH(*c = 0, kOverriddenSigactionHandler);
+
// ... and signal().
- EXPECT_EQ(0, signal(SIGSEGV, my_signal_sighandler));
- EXPECT_DEATH(*c = 0, kSEGVCrash);
+ EXPECT_NE(SIG_ERR, signal(SIGSEGV, my_signal_sighandler));
+ EXPECT_DEATH(*c = 0, kOverriddenSignalHandler);
}
} // namespace
#endif
diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt
index df80a50444e5..6556e7ac6513 100644
--- a/lib/builtins/CMakeLists.txt
+++ b/lib/builtins/CMakeLists.txt
@@ -42,6 +42,8 @@ set(GENERIC_SOURCES
ashlti3.c
ashrdi3.c
ashrti3.c
+ bswapdi2.c
+ bswapsi2.c
clear_cache.c
clzdi2.c
clzsi2.c
@@ -163,8 +165,7 @@ set(GENERIC_SOURCES
udivti3.c
umoddi3.c
umodsi3.c
- umodti3.c
- emutls.c)
+ umodti3.c)
set(GENERIC_TF_SOURCES
comparetf2.c
@@ -193,6 +194,7 @@ option(COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN
if(NOT COMPILER_RT_BAREMETAL_BUILD)
set(GENERIC_SOURCES
${GENERIC_SOURCES}
+ emutls.c
enable_execute_stack.c)
endif()
diff --git a/lib/builtins/README.txt b/lib/builtins/README.txt
index b3d083614ee0..e603dfa05356 100644
--- a/lib/builtins/README.txt
+++ b/lib/builtins/README.txt
@@ -57,8 +57,8 @@ si_int __popcountsi2(si_int a); // bit population
si_int __popcountdi2(di_int a); // bit population
si_int __popcountti2(ti_int a); // bit population
-uint32_t __bswapsi2(uint32_t a); // a byteswapped, arm only
-uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only
+uint32_t __bswapsi2(uint32_t a); // a byteswapped
+uint64_t __bswapdi2(uint64_t a); // a byteswapped
// Integral arithmetic
diff --git a/lib/builtins/arm/aeabi_cdcmp.S b/lib/builtins/arm/aeabi_cdcmp.S
index b67814d9f20b..3e7a8b86b739 100644
--- a/lib/builtins/arm/aeabi_cdcmp.S
+++ b/lib/builtins/arm/aeabi_cdcmp.S
@@ -48,7 +48,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
// NaN has been ruled out, so __aeabi_cdcmple can't trap
bne __aeabi_cdcmple
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+ mov ip, #APSR_C
+ msr APSR_nzcvq, ip
+#else
msr CPSR_f, #APSR_C
+#endif
JMP(lr)
#endif
END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
@@ -95,17 +100,23 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
lsls r0, r0, #31
pop {r0-r3, pc}
#else
+ ITT(eq)
moveq ip, #0
beq 1f
ldm sp, {r0-r3}
bl __aeabi_dcmpeq
cmp r0, #1
+ ITE(eq)
moveq ip, #(APSR_C | APSR_Z)
movne ip, #(APSR_C)
1:
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+ msr APSR_nzcvq, ip
+#else
msr CPSR_f, ip
+#endif
pop {r0-r3}
POP_PC()
#endif
diff --git a/lib/builtins/arm/aeabi_cfcmp.S b/lib/builtins/arm/aeabi_cfcmp.S
index e37aa3d06c4e..1f304ffd964c 100644
--- a/lib/builtins/arm/aeabi_cfcmp.S
+++ b/lib/builtins/arm/aeabi_cfcmp.S
@@ -48,7 +48,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
// NaN has been ruled out, so __aeabi_cfcmple can't trap
bne __aeabi_cfcmple
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+ mov ip, #APSR_C
+ msr APSR_nzcvq, ip
+#else
msr CPSR_f, #APSR_C
+#endif
JMP(lr)
#endif
END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
@@ -95,17 +100,23 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
lsls r0, r0, #31
pop {r0-r3, pc}
#else
+ ITT(eq)
moveq ip, #0
beq 1f
ldm sp, {r0-r3}
bl __aeabi_fcmpeq
cmp r0, #1
+ ITE(eq)
moveq ip, #(APSR_C | APSR_Z)
movne ip, #(APSR_C)
1:
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+ msr APSR_nzcvq, ip
+#else
msr CPSR_f, ip
+#endif
pop {r0-r3}
POP_PC()
#endif
diff --git a/lib/builtins/arm/eqdf2vfp.S b/lib/builtins/arm/eqdf2vfp.S
index 8fa0b2debc77..d50706570916 100644
--- a/lib/builtins/arm/eqdf2vfp.S
+++ b/lib/builtins/arm/eqdf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(eq)
moveq r0, #1 // set result register to 1 if equal
movne r0, #0
bx lr
diff --git a/lib/builtins/arm/eqsf2vfp.S b/lib/builtins/arm/eqsf2vfp.S
index 3776bf4874c2..fd72b2fdbdee 100644
--- a/lib/builtins/arm/eqsf2vfp.S
+++ b/lib/builtins/arm/eqsf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(eq)
moveq r0, #1 // set result register to 1 if equal
movne r0, #0
bx lr
diff --git a/lib/builtins/arm/gedf2vfp.S b/lib/builtins/arm/gedf2vfp.S
index 14899f00aab6..364fc5b24cd1 100644
--- a/lib/builtins/arm/gedf2vfp.S
+++ b/lib/builtins/arm/gedf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__gedf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ge)
movge r0, #1 // set result register to 1 if greater than or equal
movlt r0, #0
bx lr
diff --git a/lib/builtins/arm/gesf2vfp.S b/lib/builtins/arm/gesf2vfp.S
index b49d04d1c239..346c3473ae4c 100644
--- a/lib/builtins/arm/gesf2vfp.S
+++ b/lib/builtins/arm/gesf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__gesf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ge)
movge r0, #1 // set result register to 1 if greater than or equal
movlt r0, #0
bx lr
diff --git a/lib/builtins/arm/gtdf2vfp.S b/lib/builtins/arm/gtdf2vfp.S
index 8166305e3af1..3389c3ad9737 100644
--- a/lib/builtins/arm/gtdf2vfp.S
+++ b/lib/builtins/arm/gtdf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(gt)
movgt r0, #1 // set result register to 1 if equal
movle r0, #0
bx lr
diff --git a/lib/builtins/arm/gtsf2vfp.S b/lib/builtins/arm/gtsf2vfp.S
index d2d8a2380fc8..afdba8b018e2 100644
--- a/lib/builtins/arm/gtsf2vfp.S
+++ b/lib/builtins/arm/gtsf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(gt)
movgt r0, #1 // set result register to 1 if equal
movle r0, #0
bx lr
diff --git a/lib/builtins/arm/ledf2vfp.S b/lib/builtins/arm/ledf2vfp.S
index a9dab77c1469..4bbe4c86837c 100644
--- a/lib/builtins/arm/ledf2vfp.S
+++ b/lib/builtins/arm/ledf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__ledf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ls)
movls r0, #1 // set result register to 1 if equal
movhi r0, #0
bx lr
diff --git a/lib/builtins/arm/lesf2vfp.S b/lib/builtins/arm/lesf2vfp.S
index 7e127f465cfd..51232bd8cedc 100644
--- a/lib/builtins/arm/lesf2vfp.S
+++ b/lib/builtins/arm/lesf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__lesf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ls)
movls r0, #1 // set result register to 1 if equal
movhi r0, #0
bx lr
diff --git a/lib/builtins/arm/ltdf2vfp.S b/lib/builtins/arm/ltdf2vfp.S
index 8b6f8e4cc8a4..8e2928c813d2 100644
--- a/lib/builtins/arm/ltdf2vfp.S
+++ b/lib/builtins/arm/ltdf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(mi)
movmi r0, #1 // set result register to 1 if equal
movpl r0, #0
bx lr
diff --git a/lib/builtins/arm/ltsf2vfp.S b/lib/builtins/arm/ltsf2vfp.S
index c4ff812b49a3..59c00c6bab67 100644
--- a/lib/builtins/arm/ltsf2vfp.S
+++ b/lib/builtins/arm/ltsf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(mi)
movmi r0, #1 // set result register to 1 if equal
movpl r0, #0
bx lr
diff --git a/lib/builtins/arm/nedf2vfp.S b/lib/builtins/arm/nedf2vfp.S
index 7d884e07204c..aef72eb00974 100644
--- a/lib/builtins/arm/nedf2vfp.S
+++ b/lib/builtins/arm/nedf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__nedf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ne)
movne r0, #1 // set result register to 0 if unequal
moveq r0, #0
bx lr
diff --git a/lib/builtins/arm/nesf2vfp.S b/lib/builtins/arm/nesf2vfp.S
index 97c764f63697..50d60f493005 100644
--- a/lib/builtins/arm/nesf2vfp.S
+++ b/lib/builtins/arm/nesf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__nesf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(ne)
movne r0, #1 // set result register to 1 if unequal
moveq r0, #0
bx lr
diff --git a/lib/builtins/arm/unorddf2vfp.S b/lib/builtins/arm/unorddf2vfp.S
index 855637547003..6625fa8a3119 100644
--- a/lib/builtins/arm/unorddf2vfp.S
+++ b/lib/builtins/arm/unorddf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)
vcmp.f64 d6, d7
#endif
vmrs apsr_nzcv, fpscr
+ ITE(vs)
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
movvc r0, #0
bx lr
diff --git a/lib/builtins/arm/unordsf2vfp.S b/lib/builtins/arm/unordsf2vfp.S
index 2b16b4905c48..0b5da2ba3e17 100644
--- a/lib/builtins/arm/unordsf2vfp.S
+++ b/lib/builtins/arm/unordsf2vfp.S
@@ -27,6 +27,7 @@ DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)
vcmp.f32 s14, s15
#endif
vmrs apsr_nzcv, fpscr
+ ITE(vs)
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
movvc r0, #0
bx lr
diff --git a/lib/builtins/assembly.h b/lib/builtins/assembly.h
index 12c13c495509..b15da52345c8 100644
--- a/lib/builtins/assembly.h
+++ b/lib/builtins/assembly.h
@@ -96,9 +96,11 @@
#if __ARM_ARCH_ISA_THUMB == 2
#define IT(cond) it cond
#define ITT(cond) itt cond
+#define ITE(cond) ite cond
#else
#define IT(cond)
#define ITT(cond)
+#define ITE(cond)
#endif
#if __ARM_ARCH_ISA_THUMB == 2
diff --git a/lib/builtins/bswapdi2.c b/lib/builtins/bswapdi2.c
new file mode 100644
index 000000000000..eb220007bb10
--- /dev/null
+++ b/lib/builtins/bswapdi2.c
@@ -0,0 +1,27 @@
+/* ===-- bswapdi2.c - Implement __bswapdi2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __bswapdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+COMPILER_RT_ABI uint64_t __bswapdi2(uint64_t u) {
+ return (
+ (((u)&0xff00000000000000ULL) >> 56) |
+ (((u)&0x00ff000000000000ULL) >> 40) |
+ (((u)&0x0000ff0000000000ULL) >> 24) |
+ (((u)&0x000000ff00000000ULL) >> 8) |
+ (((u)&0x00000000ff000000ULL) << 8) |
+ (((u)&0x0000000000ff0000ULL) << 24) |
+ (((u)&0x000000000000ff00ULL) << 40) |
+ (((u)&0x00000000000000ffULL) << 56));
+}
diff --git a/lib/builtins/bswapsi2.c b/lib/builtins/bswapsi2.c
new file mode 100644
index 000000000000..5d941e69f7c4
--- /dev/null
+++ b/lib/builtins/bswapsi2.c
@@ -0,0 +1,23 @@
+/* ===-- bswapsi2.c - Implement __bswapsi2 ---------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __bswapsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+COMPILER_RT_ABI uint32_t __bswapsi2(uint32_t u) {
+ return (
+ (((u)&0xff000000) >> 24) |
+ (((u)&0x00ff0000) >> 8) |
+ (((u)&0x0000ff00) << 8) |
+ (((u)&0x000000ff) << 24));
+}
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index a6b3453f5a0b..a5ffc6835f5f 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -265,19 +265,21 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
}
if (flags()->use_tls) {
- LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end);
- if (cache_begin == cache_end) {
- ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
- } else {
- // Because LSan should not be loaded with dlopen(), we can assume
- // that allocator cache will be part of static TLS image.
- CHECK_LE(tls_begin, cache_begin);
- CHECK_GE(tls_end, cache_end);
- if (tls_begin < cache_begin)
- ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
- kReachable);
- if (tls_end > cache_end)
- ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable);
+ if (tls_begin) {
+ LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end);
+ // If the tls and cache ranges don't overlap, scan full tls range,
+ // otherwise, only scan the non-overlapping portions
+ if (cache_begin == cache_end || tls_end < cache_begin ||
+ tls_begin > cache_end) {
+ ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
+ } else {
+ if (tls_begin < cache_begin)
+ ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
+ kReachable);
+ if (tls_end > cache_end)
+ ScanRangeForPointers(cache_end, tls_end, frontier, "TLS",
+ kReachable);
+ }
}
if (dtls && !DTLSInDestruction(dtls)) {
for (uptr j = 0; j < dtls->dtv_size; ++j) {
diff --git a/lib/lsan/lsan_common_mac.cc b/lib/lsan/lsan_common_mac.cc
index ae10955439c8..114dd8c9019e 100644
--- a/lib/lsan/lsan_common_mac.cc
+++ b/lib/lsan/lsan_common_mac.cc
@@ -91,12 +91,7 @@ LoadedModule *GetLinker() { return nullptr; }
// Required on Linux for initialization of TLS behavior, but should not be
// required on Darwin.
-void InitializePlatformSpecificModules() {
- if (flags()->use_tls) {
- Report("use_tls=1 is not supported on Darwin.\n");
- Die();
- }
-}
+void InitializePlatformSpecificModules() {}
// Scans global variables for heap pointers.
void ProcessGlobalRegions(Frontier *frontier) {
diff --git a/lib/lsan/lsan_flags.inc b/lib/lsan/lsan_flags.inc
index 8135bdcff01a..e390e2ae5a1b 100644
--- a/lib/lsan/lsan_flags.inc
+++ b/lib/lsan/lsan_flags.inc
@@ -30,7 +30,7 @@ LSAN_FLAG(bool, use_globals, true,
"Root set: include global variables (.data and .bss)")
LSAN_FLAG(bool, use_stacks, true, "Root set: include thread stacks")
LSAN_FLAG(bool, use_registers, true, "Root set: include thread registers")
-LSAN_FLAG(bool, use_tls, !SANITIZER_MAC,
+LSAN_FLAG(bool, use_tls, true,
"Root set: include TLS and thread-specific storage")
LSAN_FLAG(bool, use_root_regions, true,
"Root set: include regions added via __lsan_register_root_region().")
diff --git a/lib/sanitizer_common/sanitizer_allocator_primary32.h b/lib/sanitizer_common/sanitizer_allocator_primary32.h
index 0f6f4f7f8503..e13510ba33b9 100644
--- a/lib/sanitizer_common/sanitizer_allocator_primary32.h
+++ b/lib/sanitizer_common/sanitizer_allocator_primary32.h
@@ -319,5 +319,3 @@ class SizeClassAllocator32 {
ByteMap possible_regions;
SizeClassInfo size_class_info_array[kNumClasses];
};
-
-
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 33e652e6c3df..a1c9c5a57a84 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -380,7 +380,7 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));
// Functions related to signal handling.
typedef void (*SignalHandlerType)(int, void *, void *);
-bool IsHandledDeadlySignal(int signum);
+HandleSignalMode GetHandleSignalMode(int signum);
void InstallDeadlySignalHandlers(SignalHandlerType handler);
const char *DescribeSignalOrException(int signo);
// Alternative signal stack (POSIX-only).
diff --git a/lib/sanitizer_common/sanitizer_flag_parser.h b/lib/sanitizer_common/sanitizer_flag_parser.h
index b6ae307fc93e..4988fbb7a86d 100644
--- a/lib/sanitizer_common/sanitizer_flag_parser.h
+++ b/lib/sanitizer_common/sanitizer_flag_parser.h
@@ -64,6 +64,11 @@ inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) {
*t_ = b ? kHandleSignalYes : kHandleSignalNo;
return true;
}
+ if (internal_strcmp(value, "2") == 0 ||
+ internal_strcmp(value, "exclusive") == 0) {
+ *t_ = kHandleSignalExclusive;
+ return true;
+ }
Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);
return false;
}
diff --git a/lib/sanitizer_common/sanitizer_flags.h b/lib/sanitizer_common/sanitizer_flags.h
index f22593395ed5..c2ec29d1656e 100644
--- a/lib/sanitizer_common/sanitizer_flags.h
+++ b/lib/sanitizer_common/sanitizer_flags.h
@@ -21,6 +21,7 @@ namespace __sanitizer {
enum HandleSignalMode {
kHandleSignalNo,
kHandleSignalYes,
+ kHandleSignalExclusive,
};
struct CommonFlags {
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index c5aaf411fcc2..12c126fa707c 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -75,12 +75,13 @@ COMMON_FLAG(bool, print_summary, true,
"If false, disable printing error summaries in addition to error "
"reports.")
COMMON_FLAG(int, print_module_map, 0,
- "OS X only. 0 = don't print, 1 = print only once before process "
- "exits, 2 = print after each report.")
+ "OS X only (0 - don't print, 1 - print only once before process "
+ "exits, 2 - print after each report).")
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
#define COMMON_FLAG_HANDLE_SIGNAL_HELP(signal) \
"Controls custom tool's " #signal " handler (0 - do not registers the " \
- "handler, 1 - register the handler). "
+ "handler, 1 - register the handler and allow user to set own, " \
+ "2 - registers the handler and block user from changing it). "
COMMON_FLAG(HandleSignalMode, handle_segv, kHandleSignalYes,
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGSEGV))
COMMON_FLAG(HandleSignalMode, handle_sigbus, kHandleSignalYes,
@@ -92,9 +93,6 @@ COMMON_FLAG(HandleSignalMode, handle_sigill, kHandleSignalNo,
COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes,
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE))
#undef COMMON_FLAG_HANDLE_SIGNAL_HELP
-COMMON_FLAG(bool, allow_user_segv_handler, false,
- "If set, allows user to register a SEGV handler even if the tool "
- "registers one.")
COMMON_FLAG(bool, use_sigaltstack, true,
"If set, uses alternate stack for signal handling.")
COMMON_FLAG(bool, detect_deadlocks, false,
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 87f32c44d71a..3bda35655d9e 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -549,7 +549,7 @@ void BlockingMutex::Lock() {
void BlockingMutex::Unlock() {
atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
- u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed);
+ u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
CHECK_NE(v, MtxUnlocked);
if (v == MtxSleeping) {
#if SANITIZER_FREEBSD
@@ -1394,7 +1394,7 @@ AndroidApiLevel AndroidGetApiLevel() {
#endif
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
switch (signum) {
case SIGABRT:
return common_flags()->handle_abort;
@@ -1407,7 +1407,7 @@ bool IsHandledDeadlySignal(int signum) {
case SIGBUS:
return common_flags()->handle_sigbus;
}
- return false;
+ return kHandleSignalNo;
}
#if !SANITIZER_GO
diff --git a/lib/sanitizer_common/sanitizer_linux_s390.cc b/lib/sanitizer_common/sanitizer_linux_s390.cc
index c2b03b27e66c..a6da82ecb1d2 100644
--- a/lib/sanitizer_common/sanitizer_linux_s390.cc
+++ b/lib/sanitizer_common/sanitizer_linux_s390.cc
@@ -178,6 +178,13 @@ static bool FixedCVE_2016_2143() {
// 4.4.6+ is OK.
if (minor == 4 && patch >= 6)
return true;
+ if (minor == 4 && patch == 0 && ptr[0] == '-' &&
+ internal_strstr(buf.version, "Ubuntu")) {
+ // Check Ubuntu 16.04
+ int r1 = internal_simple_strtoll(ptr+1, &ptr, 10);
+ if (r1 >= 13) // 4.4.0-13 or later
+ return true;
+ }
// Otherwise, OK if 4.5+.
return minor >= 5;
} else {
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index f1a6bf91635c..f1b9e5fda5c0 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -370,6 +370,27 @@ uptr GetTlsSize() {
void InitTlsSize() {
}
+uptr TlsBaseAddr() {
+ uptr segbase = 0;
+#if defined(__x86_64__)
+ asm("movq %%gs:0,%0" : "=r"(segbase));
+#elif defined(__i386__)
+ asm("movl %%gs:0,%0" : "=r"(segbase));
+#endif
+ return segbase;
+}
+
+// The size of the tls on darwin does not appear to be well documented,
+// however the vm memory map suggests that it is 1024 uptrs in size,
+// with a size of 0x2000 bytes on x86_64 and 0x1000 bytes on i386.
+uptr TlsSize() {
+#if defined(__x86_64__) || defined(__i386__)
+ return 1024 * sizeof(uptr);
+#else
+ return 0;
+#endif
+}
+
void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
#if !SANITIZER_GO
@@ -377,8 +398,8 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
*stk_size = stack_top - stack_bottom;
- *tls_addr = 0;
- *tls_size = 0;
+ *tls_addr = TlsBaseAddr();
+ *tls_size = TlsSize();
#else
*stk_addr = 0;
*stk_size = 0;
@@ -393,10 +414,10 @@ void ListOfModules::init() {
memory_mapping.DumpListOfModules(&modules_);
}
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
// Handling fatal signals on watchOS and tvOS devices is disallowed.
if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
- return false;
+ return kHandleSignalNo;
switch (signum) {
case SIGABRT:
return common_flags()->handle_abort;
@@ -409,7 +430,7 @@ bool IsHandledDeadlySignal(int signum) {
case SIGBUS:
return common_flags()->handle_sigbus;
}
- return false;
+ return kHandleSignalNo;
}
MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 8d688f3778b5..791ff4481ca8 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -134,7 +134,8 @@ void SleepForMillis(int millis) {
void Abort() {
#if !SANITIZER_GO
// If we are handling SIGABRT, unhandle it first.
- if (IsHandledDeadlySignal(SIGABRT)) {
+ // TODO(vitalybuka): Check if handler belongs to sanitizer.
+ if (GetHandleSignalMode(SIGABRT) != kHandleSignalNo) {
struct sigaction sigact;
internal_memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = (sa_sigaction_t)SIG_DFL;
@@ -188,8 +189,26 @@ void UnsetAlternateSignalStack() {
static void MaybeInstallSigaction(int signum,
SignalHandlerType handler) {
- if (!IsHandledDeadlySignal(signum))
- return;
+ switch (GetHandleSignalMode(signum)) {
+ case kHandleSignalNo:
+ return;
+ case kHandleSignalYes: {
+ struct sigaction sigact;
+ internal_memset(&sigact, 0, sizeof(sigact));
+ CHECK_EQ(0, internal_sigaction(signum, nullptr, &sigact));
+ if (sigact.sa_flags & SA_SIGINFO) {
+ if (sigact.sa_sigaction) return;
+ } else {
+ if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN &&
+ sigact.sa_handler != SIG_ERR)
+ return;
+ }
+ break;
+ }
+ case kHandleSignalExclusive:
+ break;
+ }
+
struct sigaction sigact;
internal_memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = (sa_sigaction_t)handler;
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index d0a5c078cd68..c912e8fa2aa3 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -832,9 +832,9 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
// FIXME: Decide what to do on Windows.
}
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
// FIXME: Decide what to do on Windows.
- return false;
+ return kHandleSignalNo;
}
// Check based on flags if we should handle this exception.
diff --git a/lib/sanitizer_common/tests/sanitizer_flags_test.cc b/lib/sanitizer_common/tests/sanitizer_flags_test.cc
index 34d7067f85ff..0af84a20b7f5 100644
--- a/lib/sanitizer_common/tests/sanitizer_flags_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_flags_test.cc
@@ -78,13 +78,15 @@ TEST(SanitizerCommon, HandleSignalMode) {
TestFlag(kHandleSignalYes, "flag_name=0", kHandleSignalNo);
TestFlag(kHandleSignalYes, "flag_name=no", kHandleSignalNo);
TestFlag(kHandleSignalYes, "flag_name=false", kHandleSignalNo);
+ TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalExclusive);
+ TestFlag(kHandleSignalYes, "flag_name=exclusive", kHandleSignalExclusive);
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name", kHandleSignalNo),
"expected '='");
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=", kHandleSignalNo),
"Invalid value for signal handler option: ''");
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalNo),
- "Invalid value for signal handler option: '2'");
+ EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=3", kHandleSignalNo),
+ "Invalid value for signal handler option: '3'");
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=-1", kHandleSignalNo),
"Invalid value for signal handler option: '-1'");
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=on", kHandleSignalNo),
diff --git a/lib/scudo/scudo_tls_linux.cpp b/lib/scudo/scudo_tls_linux.cpp
index 5a9cc998bccf..1e38233f339c 100644
--- a/lib/scudo/scudo_tls_linux.cpp
+++ b/lib/scudo/scudo_tls_linux.cpp
@@ -18,7 +18,6 @@
#include "scudo_tls.h"
-#include <limits.h>
#include <pthread.h>
namespace __scudo {
@@ -32,15 +31,17 @@ __attribute__((tls_model("initial-exec")))
THREADLOCAL ScudoThreadContext ThreadLocalContext;
static void teardownThread(void *Ptr) {
- uptr Iteration = reinterpret_cast<uptr>(Ptr);
+ uptr I = reinterpret_cast<uptr>(Ptr);
// The glibc POSIX thread-local-storage deallocation routine calls user
// provided destructors in a loop of PTHREAD_DESTRUCTOR_ITERATIONS.
// We want to be called last since other destructors might call free and the
// like, so we wait until PTHREAD_DESTRUCTOR_ITERATIONS before draining the
// quarantine and swallowing the cache.
- if (Iteration < PTHREAD_DESTRUCTOR_ITERATIONS) {
- pthread_setspecific(PThreadKey, reinterpret_cast<void *>(Iteration + 1));
- return;
+ if (I > 1) {
+ // If pthread_setspecific fails, we will go ahead with the teardown.
+ if (LIKELY(pthread_setspecific(PThreadKey,
+ reinterpret_cast<void *>(I - 1)) == 0))
+ return;
}
ThreadLocalContext.commitBack();
ScudoThreadState = ThreadTornDown;
@@ -53,8 +54,9 @@ static void initOnce() {
}
void initThread() {
- pthread_once(&GlobalInitialized, initOnce);
- pthread_setspecific(PThreadKey, reinterpret_cast<void *>(1));
+ CHECK_EQ(pthread_once(&GlobalInitialized, initOnce), 0);
+ CHECK_EQ(pthread_setspecific(PThreadKey, reinterpret_cast<void *>(
+ GetPthreadDestructorIterations())), 0);
ThreadLocalContext.init();
ScudoThreadState = ThreadInitialized;
}
diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h
index 1dd9d91d4c92..60d9b9d8c452 100644
--- a/lib/tsan/rtl/tsan_platform.h
+++ b/lib/tsan/rtl/tsan_platform.h
@@ -816,6 +816,7 @@ void FlushShadowMemory();
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
int ExtractResolvFDs(void *state, int *fds, int nfd);
int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
+void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
void *abstime), void *c, void *m, void *abstime,
diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc
index 2d488cadd4fe..d05c0e701e72 100644
--- a/lib/tsan/rtl/tsan_platform_linux.cc
+++ b/lib/tsan/rtl/tsan_platform_linux.cc
@@ -320,6 +320,20 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {
return res;
}
+void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
+ // Check that the thr object is in tls;
+ const uptr thr_beg = (uptr)thr;
+ const uptr thr_end = (uptr)thr + sizeof(*thr);
+ CHECK_GE(thr_beg, tls_addr);
+ CHECK_LE(thr_beg, tls_addr + tls_size);
+ CHECK_GE(thr_end, tls_addr);
+ CHECK_LE(thr_end, tls_addr + tls_size);
+ // Since the thr object is huge, skip it.
+ MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr, thr_beg - tls_addr);
+ MemoryRangeImitateWrite(thr, /*pc=*/2, thr_end,
+ tls_addr + tls_size - thr_end);
+}
+
// Note: this function runs with async signals enabled,
// so it must not touch any tsan state.
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
diff --git a/lib/tsan/rtl/tsan_platform_mac.cc b/lib/tsan/rtl/tsan_platform_mac.cc
index b8d3d5528bb5..a82bcd01bbf4 100644
--- a/lib/tsan/rtl/tsan_platform_mac.cc
+++ b/lib/tsan/rtl/tsan_platform_mac.cc
@@ -75,12 +75,18 @@ static void *SignalSafeGetOrAllocate(uptr *dst, uptr size) {
static uptr main_thread_identity = 0;
ALIGNED(64) static char main_thread_state[sizeof(ThreadState)];
+ThreadState **cur_thread_location() {
+ ThreadState **thread_identity = (ThreadState **)pthread_self();
+ return ((uptr)thread_identity == main_thread_identity) ? nullptr
+ : thread_identity;
+}
+
ThreadState *cur_thread() {
- uptr thread_identity = (uptr)pthread_self();
- if (thread_identity == main_thread_identity || main_thread_identity == 0) {
+ ThreadState **thr_state_loc = cur_thread_location();
+ if (thr_state_loc == nullptr || main_thread_identity == 0) {
return (ThreadState *)&main_thread_state;
}
- ThreadState **fake_tls = (ThreadState **)MemToShadow(thread_identity);
+ ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc);
ThreadState *thr = (ThreadState *)SignalSafeGetOrAllocate(
(uptr *)fake_tls, sizeof(ThreadState));
return thr;
@@ -90,13 +96,13 @@ ThreadState *cur_thread() {
// munmap first and then clear `fake_tls`; if we receive a signal in between,
// handler will try to access the unmapped ThreadState.
void cur_thread_finalize() {
- uptr thread_identity = (uptr)pthread_self();
- if (thread_identity == main_thread_identity) {
+ ThreadState **thr_state_loc = cur_thread_location();
+ if (thr_state_loc == nullptr) {
// Calling dispatch_main() or xpc_main() actually invokes pthread_exit to
// exit the main thread. Let's keep the main thread's ThreadState.
return;
}
- ThreadState **fake_tls = (ThreadState **)MemToShadow(thread_identity);
+ ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc);
internal_munmap(*fake_tls, sizeof(ThreadState));
*fake_tls = nullptr;
}
@@ -240,6 +246,29 @@ void InitializePlatform() {
}
#if !SANITIZER_GO
+void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
+ // The pointer to the ThreadState object is stored in the shadow memory
+ // of the tls.
+ uptr tls_end = tls_addr + tls_size;
+ ThreadState **thr_state_loc = cur_thread_location();
+ if (thr_state_loc == nullptr) {
+ MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr, tls_size);
+ } else {
+ uptr thr_state_start = (uptr)thr_state_loc;
+ uptr thr_state_end = thr_state_start + sizeof(uptr);
+ CHECK_GE(thr_state_start, tls_addr);
+ CHECK_LE(thr_state_start, tls_addr + tls_size);
+ CHECK_GE(thr_state_end, tls_addr);
+ CHECK_LE(thr_state_end, tls_addr + tls_size);
+ MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr,
+ thr_state_start - tls_addr);
+ MemoryRangeImitateWrite(thr, /*pc=*/2, thr_state_end,
+ tls_end - thr_state_end);
+ }
+}
+#endif
+
+#if !SANITIZER_GO
// Note: this function runs with async signals enabled,
// so it must not touch any tsan state.
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cc
index 6a0943c49588..edb60980c76f 100644
--- a/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -248,19 +248,7 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) {
if (stk_addr && stk_size)
MemoryRangeImitateWrite(thr, /*pc=*/ 1, stk_addr, stk_size);
- if (tls_addr && tls_size) {
- // Check that the thr object is in tls;
- const uptr thr_beg = (uptr)thr;
- const uptr thr_end = (uptr)thr + sizeof(*thr);
- CHECK_GE(thr_beg, tls_addr);
- CHECK_LE(thr_beg, tls_addr + tls_size);
- CHECK_GE(thr_end, tls_addr);
- CHECK_LE(thr_end, tls_addr + tls_size);
- // Since the thr object is huge, skip it.
- MemoryRangeImitateWrite(thr, /*pc=*/ 2, tls_addr, thr_beg - tls_addr);
- MemoryRangeImitateWrite(thr, /*pc=*/ 2,
- thr_end, tls_addr + tls_size - thr_end);
- }
+ if (tls_addr && tls_size) ImitateTlsWrite(thr, tls_addr, tls_size);
}
#endif
diff --git a/test/asan/TestCases/Linux/preinstalled_signal.cc b/test/asan/TestCases/Linux/preinstalled_signal.cc
new file mode 100644
index 000000000000..40dadf43dc4e
--- /dev/null
+++ b/test/asan/TestCases/Linux/preinstalled_signal.cc
@@ -0,0 +1,105 @@
+// clang-format off
+// RUN: %clangxx -std=c++11 %s -o %t
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_HANDLER %s -o %t
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-HANDLER %s
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_ACTION %s -o %t
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ACTION %s
+// RUN: env LD_PRELOAD=%shared_libasan %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: asan-dynamic-runtime
+
+// This way of setting LD_PRELOAD does not work with Android test runner.
+// REQUIRES: not-android
+// clang-format on
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+const char *handler = nullptr;
+void SigHandler(int signum) { handler = "TestSigHandler"; }
+void SigAction(int, siginfo_t *, void *) { handler = "TestSigAction"; }
+
+struct KernelSigaction {
+ __sighandler_t handler;
+ unsigned long flags;
+ void (*restorer)();
+ char unused[1024];
+};
+
+#if defined(__x86_64__)
+extern "C" void restorer();
+asm("restorer:mov $15,%rax\nsyscall");
+#endif
+
+int InternalSigaction(int sig, KernelSigaction *act, KernelSigaction *oact) {
+ if (act) {
+#if defined(__x86_64__)
+ act->flags |= 0x04000000;
+ act->restorer = &restorer;
+#endif
+ }
+ return syscall(__NR_rt_sigaction, sig, act, oact, NSIG / 8);
+}
+
+struct KernelSigaction sigact = {};
+
+static void Init() {
+ int res = InternalSigaction(SIGSEGV, nullptr, &sigact);
+ assert(res >= 0);
+ assert(sigact.handler == SIG_DFL || sigact.handler == SIG_IGN);
+#if defined(TEST_INSTALL_SIG_HANDLER)
+ sigact = {};
+ sigact.handler = &SigHandler;
+ res = InternalSigaction(SIGSEGV, &sigact, nullptr);
+ assert(res >= 0);
+#elif defined(TEST_INSTALL_SIG_ACTION)
+ sigact = {};
+ sigact.flags = SA_SIGINFO | SA_NODEFER;
+ sigact.handler = (__sighandler_t)&SigAction;
+ res = InternalSigaction(SIGSEGV, &sigact, nullptr);
+ assert(res >= 0);
+#endif
+}
+
+__attribute__((section(".preinit_array"), used))
+void (*__local_test_preinit)(void) = Init;
+
+bool ShouldAsanInstallHandlers() {
+#if defined(TEST_INSTALL_SIG_HANDLER) || defined(TEST_INSTALL_SIG_ACTION)
+ return !strcmp(getenv("ASAN_OPTIONS"), "handle_segv=2");
+#endif
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ KernelSigaction sigact_asan = {};
+ InternalSigaction(SIGSEGV, nullptr, &sigact_asan);
+
+ assert(sigact_asan.handler != SIG_DFL);
+ assert(sigact_asan.handler != SIG_IGN);
+ assert(ShouldAsanInstallHandlers() ==
+ (sigact_asan.handler != sigact.handler));
+
+ raise(SIGSEGV);
+ printf("%s\n", handler);
+ return 1;
+}
+
+// CHECK-NOT: TestSig
+// CHECK: ASAN:DEADLYSIGNAL
+
+// CHECK-HANDLER-NOT: ASAN:DEADLYSIGNAL
+// CHECK-HANDLER: TestSigHandler
+
+// CHECK-ACTION-NOT: ASAN:DEADLYSIGNAL
+// CHECK-ACTION: TestSigAction
diff --git a/test/asan/TestCases/Linux/sanbox_read_proc_self_maps_test.cc b/test/asan/TestCases/Linux/sanbox_read_proc_self_maps_test.cc
index a845721d5982..d9099edffcac 100644
--- a/test/asan/TestCases/Linux/sanbox_read_proc_self_maps_test.cc
+++ b/test/asan/TestCases/Linux/sanbox_read_proc_self_maps_test.cc
@@ -14,17 +14,15 @@ int main() {
if (unshare(CLONE_NEWUSER)) {
printf("unshare failed\n");
- abort();
+ return 1;
}
// remove access to /proc/self/maps
if (chroot("/tmp")) {
printf("chroot failed\n");
- abort();
+ return 2;
}
*(volatile int*)0x42 = 0;
-// CHECK: AddressSanitizer: SEGV on unknown address 0x000000000042
-// CHECK-NOT: AddressSanitizer CHECK failed
-// CHECK: SUMMARY: AddressSanitizer: SEGV
+// CHECK-NOT: CHECK failed
}
diff --git a/test/asan/TestCases/Posix/allow_user_segv.cc b/test/asan/TestCases/Posix/allow_user_segv.cc
index 69c1df9a1d3f..52f4f046da9d 100644
--- a/test/asan/TestCases/Posix/allow_user_segv.cc
+++ b/test/asan/TestCases/Posix/allow_user_segv.cc
@@ -1,8 +1,14 @@
// Regression test for
// https://code.google.com/p/address-sanitizer/issues/detail?id=180
-// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
#include <signal.h>
#include <stdio.h>
@@ -22,10 +28,14 @@ void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) {
printf("Invalid signum");
exit(1);
}
- if (original_sigaction.sa_flags | SA_SIGINFO)
- original_sigaction.sa_sigaction(signum, siginfo, context);
- else
- original_sigaction.sa_handler(signum);
+ if (original_sigaction.sa_flags | SA_SIGINFO) {
+ if (original_sigaction.sa_sigaction)
+ original_sigaction.sa_sigaction(signum, siginfo, context);
+ } else {
+ if (original_sigaction.sa_handler)
+ original_sigaction.sa_handler(signum);
+ }
+ exit(1);
}
int DoSEGV() {
@@ -33,27 +43,38 @@ int DoSEGV() {
return *x;
}
-int InstallHandler(int signum, struct sigaction *original_sigaction) {
+bool InstallHandler(int signum, struct sigaction *original_sigaction) {
struct sigaction user_sigaction;
user_sigaction.sa_sigaction = User_OnSIGSEGV;
user_sigaction.sa_flags = SA_SIGINFO;
if (sigaction(signum, &user_sigaction, original_sigaction)) {
perror("sigaction");
- return 1;
+ return false;
}
- return 0;
+ return true;
}
int main() {
// Let's install handlers for both SIGSEGV and SIGBUS, since pre-Yosemite
// 32-bit Darwin triggers SIGBUS instead.
- if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv)) return 1;
- if (InstallHandler(SIGBUS, &original_sigaction_sigbus)) return 1;
- fprintf(stderr, "User sigaction installed\n");
+ if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv) &&
+ InstallHandler(SIGBUS, &original_sigaction_sigbus)) {
+ fprintf(stderr, "User sigaction installed\n");
+ }
return DoSEGV();
}
-// CHECK: User sigaction installed
-// CHECK-NEXT: User sigaction called
-// CHECK-NEXT: ASAN:DEADLYSIGNAL
-// CHECK: AddressSanitizer: SEGV on unknown address
+// CHECK0-NOT: ASAN:DEADLYSIGNAL
+// CHECK0-NOT: AddressSanitizer: SEGV on unknown address
+// CHECK0: User sigaction installed
+// CHECK0-NEXT: User sigaction called
+
+// CHECK1: User sigaction installed
+// CHECK1-NEXT: User sigaction called
+// CHECK1-NEXT: ASAN:DEADLYSIGNAL
+// CHECK1: AddressSanitizer: SEGV on unknown address
+
+// CHECK2-NOT: User sigaction called
+// CHECK2: User sigaction installed
+// CHECK2-NEXT: ASAN:DEADLYSIGNAL
+// CHECK2: AddressSanitizer: SEGV on unknown address
diff --git a/test/asan/TestCases/Posix/current_allocated_bytes.cc b/test/asan/TestCases/Posix/current_allocated_bytes.cc
index 51630cfd8a6b..c49e433b1e8b 100644
--- a/test/asan/TestCases/Posix/current_allocated_bytes.cc
+++ b/test/asan/TestCases/Posix/current_allocated_bytes.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_asan -O0 %s -pthread -o %t && %run %t
// RUN: %clangxx_asan -O2 %s -pthread -o %t && %run %t
// REQUIRES: stable-runtime
-// UNSUPPORTED: powerpc64le
-// FIXME: This test occasionally fails on powerpc64 LE possibly starting with
-// r279664. Re-enable the test once the problem(s) have been fixed.
#include <assert.h>
#include <pthread.h>
diff --git a/test/asan/TestCases/Posix/wait.cc b/test/asan/TestCases/Posix/wait.cc
index ed6f326b57d6..85e819369c0d 100644
--- a/test/asan/TestCases/Posix/wait.cc
+++ b/test/asan/TestCases/Posix/wait.cc
@@ -4,6 +4,7 @@
// RUN: %clangxx_asan -DWAITPID -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -DWAITPID -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include <assert.h>
#include <sys/wait.h>
diff --git a/test/asan/TestCases/Posix/wait3.cc b/test/asan/TestCases/Posix/wait3.cc
index 2da816fed1aa..081a73e16f0b 100644
--- a/test/asan/TestCases/Posix/wait3.cc
+++ b/test/asan/TestCases/Posix/wait3.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_asan -DWAIT3_RUSAGE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -DWAIT3_RUSAGE -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: android
+// UNSUPPORTED: android,darwin
#include <assert.h>
#include <sys/wait.h>
diff --git a/test/asan/TestCases/Posix/wait4.cc b/test/asan/TestCases/Posix/wait4.cc
index b95246efa0e4..aee5570b82e1 100644
--- a/test/asan/TestCases/Posix/wait4.cc
+++ b/test/asan/TestCases/Posix/wait4.cc
@@ -5,6 +5,7 @@
// RUN: %clangxx_asan -DWAIT4_RUSAGE -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
// XFAIL: android
+// UNSUPPORTED: darwin
#include <assert.h>
#include <sys/wait.h>
diff --git a/test/asan/TestCases/Posix/waitid.cc b/test/asan/TestCases/Posix/waitid.cc
index 8b516dca9086..20fb0c694386 100644
--- a/test/asan/TestCases/Posix/waitid.cc
+++ b/test/asan/TestCases/Posix/waitid.cc
@@ -1,6 +1,8 @@
// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
+
#include <assert.h>
#include <sys/wait.h>
#include <unistd.h>
diff --git a/test/builtins/Unit/bswapdi2_test.c b/test/builtins/Unit/bswapdi2_test.c
index 6881c8092cbb..57ee38b786e1 100644
--- a/test/builtins/Unit/bswapdi2_test.c
+++ b/test/builtins/Unit/bswapdi2_test.c
@@ -13,34 +13,25 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <math.h>
#include <stdint.h>
#include <stdio.h>
-#include <math.h>
-
+#include <stdlib.h>
extern uint64_t __bswapdi2(uint64_t);
-#if __arm__
-int test__bswapdi2(uint64_t a, uint64_t expected)
-{
- uint64_t actual = __bswapdi2(a);
- if (actual != expected)
- printf("error in test__bswapsi2(0x%0llX) = 0x%0llX, expected 0x%0llX\n",
- a, actual, expected);
- return actual != expected;
+int test__bswapdi2(uint64_t a, uint64_t expected) {
+ uint64_t actual = __bswapdi2(a);
+ if (actual != expected)
+ printf("error in test__bswapsi2(0x%0llX) = 0x%0llX, expected 0x%0llX\n", a,
+ actual, expected);
+ return actual != expected;
}
-#endif
-int main()
-{
-#if __arm__
- if (test__bswapdi2(0x123456789ABCDEF0LL, 0xF0DEBC9A78563412LL))
- return 1;
- if (test__bswapdi2(0x0000000100000002LL, 0x0200000001000000LL))
- return 1;
-#else
- printf("skipped\n");
-#endif
- return 0;
+int main() {
+ if (test__bswapdi2(0x123456789ABCDEF0LL, 0xF0DEBC9A78563412LL))
+ return 1;
+ if (test__bswapdi2(0x0000000100000002LL, 0x0200000001000000LL))
+ return 1;
+ return 0;
}
diff --git a/test/builtins/Unit/bswapsi2_test.c b/test/builtins/Unit/bswapsi2_test.c
index c32cbb442199..899c251d9581 100644
--- a/test/builtins/Unit/bswapsi2_test.c
+++ b/test/builtins/Unit/bswapsi2_test.c
@@ -13,34 +13,25 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <math.h>
#include <stdint.h>
#include <stdio.h>
-#include <math.h>
-
+#include <stdlib.h>
extern uint32_t __bswapsi2(uint32_t);
-#if __arm__
-int test__bswapsi2(uint32_t a, uint32_t expected)
-{
- uint32_t actual = __bswapsi2(a);
- if (actual != expected)
- printf("error in test__bswapsi2(0x%0X) = 0x%0X, expected 0x%0X\n",
- a, actual, expected);
- return actual != expected;
+int test__bswapsi2(uint32_t a, uint32_t expected) {
+ uint32_t actual = __bswapsi2(a);
+ if (actual != expected)
+ printf("error in test__bswapsi2(0x%0X) = 0x%0X, expected 0x%0X\n", a,
+ actual, expected);
+ return actual != expected;
}
-#endif
-int main()
-{
-#if __arm__
- if (test__bswapsi2(0x12345678, 0x78563412))
- return 1;
- if (test__bswapsi2(0x00000001, 0x01000000))
- return 1;
-#else
- printf("skipped\n");
-#endif
- return 0;
+int main() {
+ if (test__bswapsi2(0x12345678, 0x78563412))
+ return 1;
+ if (test__bswapsi2(0x00000001, 0x01000000))
+ return 1;
+ return 0;
}
diff --git a/test/lsan/TestCases/many_tls_keys.cc b/test/lsan/TestCases/many_tls_keys.cc
new file mode 100644
index 000000000000..5b5d692a5901
--- /dev/null
+++ b/test/lsan/TestCases/many_tls_keys.cc
@@ -0,0 +1,97 @@
+// Test that lsan handles tls correctly for many threads
+// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0"
+// RUN: %clangxx_lsan %s -DUSE_THREAD -o %t-thread
+// RUN: %clangxx_lsan %s -DUSE_PTHREAD -o %t-pthread
+// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t-thread 2>&1 | FileCheck %s
+// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t-thread 2>&1
+// RUN: %env_lsan_opts="" %run %t-thread 2>&1
+// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t-pthread 2>&1 | FileCheck %s
+// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t-pthread 2>&1
+// RUN: %env_lsan_opts="" %run %t-pthread 2>&1
+
+// Patch r303906 did not fix all the problems.
+// UNSUPPORTED: arm-linux,armhf-linux
+
+#include <assert.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static const int NUM_THREADS = 10;
+
+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+int finished = 0;
+
+#if USE_THREAD
+__thread void *ptr1;
+__thread void *ptr2;
+__thread void *ptr3;
+__thread void *ptr4;
+__thread void *ptr5;
+
+void alloc() {
+ ptr1 = malloc(1111);
+ ptr2 = malloc(2222);
+ ptr3 = malloc(3333);
+ ptr4 = malloc(4444);
+ ptr5 = malloc(5555);
+}
+
+#elif USE_PTHREAD
+// We won't be able to create the maximum number of keys, due to other users
+// of the tls, but we'll use as many keys as we can before failing to create
+// a new key.
+pthread_key_t keys[PTHREAD_KEYS_MAX];
+static const int PTHREAD_KEY_INVALID = 0xffffffff;
+
+void alloc() {
+ for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) {
+ void *ptr = malloc(123);
+ if ((keys[i] == PTHREAD_KEY_INVALID) || pthread_setspecific(keys[i], ptr)) {
+ free(ptr);
+ break;
+ }
+ }
+}
+
+void pthread_destructor(void *arg) {
+ assert(0 && "pthread destructors shouldn't be called");
+}
+#endif
+
+void *thread_start(void *arg) {
+ alloc();
+
+ pthread_mutex_lock(&mutex);
+ finished++;
+ pthread_mutex_unlock(&mutex);
+
+ // don't exit, to intentionally leak tls data
+ while (1)
+ sleep(100);
+}
+
+int main() {
+#if USE_PTHREAD
+ for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) {
+ if (pthread_key_create(&keys[i], pthread_destructor)) {
+ keys[i] = PTHREAD_KEY_INVALID;
+ break;
+ }
+ }
+#endif
+
+ pthread_t thread[NUM_THREADS];
+ for (int i = 0; i < NUM_THREADS; ++i) {
+ assert(0 == pthread_create(&thread[i], 0, thread_start, 0));
+ }
+ // spin until all threads have finished
+ while (finished < NUM_THREADS)
+ sleep(1);
+ exit(0);
+}
+
+// CHECK: LeakSanitizer: detected memory leaks
+// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer:
diff --git a/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
index 92557b7592cb..b7e8721a1b9e 100644
--- a/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
+++ b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
@@ -8,8 +8,12 @@
#include <string.h>
#include <stdint.h>
+// On powerpc64be semval_t must be 64 bits even with "old" versions of glibc.
+#if __PPC64__ && __BIG_ENDIAN__
+typedef uint64_t semval_t;
+
// This condition needs to correspond to __HAVE_64B_ATOMICS macro in glibc.
-#if (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
+#elif (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
defined(__s390x__) || defined(__sparc64__) || defined(__alpha__) || \
defined(__ia64__) || defined(__m68k__)) && __GLIBC_PREREQ(2, 21)
typedef uint64_t semval_t;
diff --git a/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc b/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc
index 643fb48ae773..51e8bdb6e95d 100644
--- a/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc
+++ b/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc
@@ -1,4 +1,4 @@
-// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0 allow_user_segv_handler=1" %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0" %run %t 2>&1 | FileCheck %s
// JVM uses SEGV to preempt threads. All threads do a load from a known address
// periodically. When runtime needs to preempt threads, it unmaps the page.
diff --git a/test/ubsan/TestCases/Integer/negate-overflow.cpp b/test/ubsan/TestCases/Integer/negate-overflow.cpp
index 628291eb4b95..72438d3fba7f 100644
--- a/test/ubsan/TestCases/Integer/negate-overflow.cpp
+++ b/test/ubsan/TestCases/Integer/negate-overflow.cpp
@@ -6,7 +6,9 @@ int main() {
// CHECKU: negate-overflow.cpp:[[@LINE+2]]:3: runtime error: negation of 2147483648 cannot be represented in type 'unsigned int'
// CHECKU-NOT: cast to an unsigned
-unsigned(-0x7fffffff - 1); // ok
- // CHECKS: negate-overflow.cpp:[[@LINE+2]]:10: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
+ // CHECKS: negate-overflow.cpp:[[@LINE+2]]:3: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
// CHECKU-NOT: runtime error
- return -(-0x7fffffff - 1);
+ -(-0x7fffffff - 1);
+
+ return 0;
}