diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -226,6 +226,19 @@ endif() endfunction() +# Returns a list of architecture specific target ldflags in @out_var list. +function(get_target_link_flags_for_arch arch out_var) + list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX) + if(ARCH_INDEX EQUAL -1) + message(FATAL_ERROR "Unsupported architecture: ${arch}") + else() + # Workaround for direct calls to __tls_get_addr on Solaris/amd64. + if(OS_NAME MATCHES "SunOS" AND ${arch} MATCHES x86_64) + set(${out_var} "-Wl,-z,relax=transtls" PARENT_SCOPE) + endif() + endif() +endfunction() + # Returns a compiler and CFLAGS that should be used to run tests for the # specific architecture. When cross-compiling, this is controled via # COMPILER_RT_TEST_COMPILER and COMPILER_RT_TEST_COMPILER_CFLAGS. diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -179,11 +179,14 @@ set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) endfunction() + set(TARGET_LINK_FLAGS) + get_target_link_flags_for_arch(${arch} TARGET_LINK_FLAGS) + set(ASAN_INST_TEST_OBJECTS) generate_asan_tests(ASAN_INST_TEST_OBJECTS AsanUnitTests "Asan-${arch}${TEST_KIND}-Test" SUBDIR "${CONFIG_NAME}" - LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} + LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS} SOURCES ${ASAN_INST_TEST_SOURCES} CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${TEST_CFLAGS}) @@ -209,7 +212,7 @@ SUBDIR "${CONFIG_NAME_DYNAMIC}" OBJECTS ${ASAN_INST_TEST_OBJECTS} DEPS asan ${ASAN_INST_TEST_OBJECTS} - LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS} + LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS} ) endif() endif() @@ -220,7 +223,7 @@ AsanUnitTests "Asan-${arch}${TEST_KIND}-Noinst-Test" SUBDIR "${CONFIG_NAME}" CFLAGS ${ASAN_UNITTEST_COMMON_CFLAGS} - LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS} + LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS} ${TARGET_LINK_FLAGS} SOURCES ${ASAN_NOINST_TEST_SOURCES} RUNTIME ${test_runtime}) @@ -230,7 +233,7 @@ SUBDIR "${CONFIG_NAME}" CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} SOURCES ${ASAN_BENCHMARKS_SOURCES} - LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}) + LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS}) endfunction() if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -216,7 +216,8 @@ // On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage // of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan // to get the pointer to thread-specific data keys in the thread control block. -#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID && !SANITIZER_GO +#if (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID && !SANITIZER_GO // sizeof(struct pthread) from glibc. static atomic_uintptr_t thread_descriptor_size; @@ -476,7 +477,7 @@ const uptr pre_tcb_size = TlsPreTcbSize(); *addr = tp - pre_tcb_size; *size = g_tls_size + pre_tcb_size; -#elif SANITIZER_FREEBSD || SANITIZER_LINUX +#elif SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS uptr align; GetStaticTlsBoundary(addr, size, &align); #if defined(__x86_64__) || defined(__i386__) || defined(__s390__) || \ @@ -537,11 +538,6 @@ *addr = (uptr)tcb->tcb_dtv[1]; } } -#elif SANITIZER_SOLARIS - // FIXME - *addr = 0; - *size = 0; -#else #error "Unknown OS" #endif } diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -154,6 +154,8 @@ list(APPEND extra_flags "-D_FILE_OFFSET_BITS=64") endif() get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB) + set(TARGET_LINK_FLAGS) + get_target_link_flags_for_arch(${arch} TARGET_LINK_FLAGS) set(SANITIZER_TEST_OBJECTS) generate_compiler_rt_tests(SANITIZER_TEST_OBJECTS SanitizerUnitTests @@ -163,7 +165,7 @@ COMPILE_DEPS ${SANITIZER_TEST_HEADERS} DEPS gtest CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${extra_flags} - LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON} ${extra_flags}) + LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON} ${TARGET_LINK_FLAGS} ${extra_flags}) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64") # Test that the libc-independent part of sanitizer_common is indeed