[sanitizer_common] Use GetStaticTlsBoundary on Solaris 11.4

This is a restricted alternative to D91605
<https://reviews.llvm.org/D91605> which only works on Solaris 11.4 SRU 10+,
but would break the build on Solaris 11.3 and Illumos which lack
`dlpi_tls_modid`.

Apart from that, the patch is trivial.  One caveat is that the
`sanitizer_common` and `asan` tests need to be linked explicitly with `ld
-z relax=transtls` on Solaris/amd64 since the archives with calls to
`__tls_get_addr` are linked in directly.

Tested on `amd64-pc-solaris2.11`, `sparcv9-sun-solaris2.11`, and
`x86_64-pc-linux-gnu`.

Differential Revision: https://reviews.llvm.org/D120048
This commit is contained in:
Rainer Orth 2022-02-22 20:18:22 +01:00
parent b1fc966d2e
commit cb8e9bea95
4 changed files with 26 additions and 12 deletions

View File

@ -226,6 +226,19 @@ function(get_target_flags_for_arch arch out_var)
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.

View File

@ -179,11 +179,14 @@ function(add_asan_tests arch test_runtime)
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 @@ function(add_asan_tests arch test_runtime)
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 @@ function(add_asan_tests arch test_runtime)
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 @@ function(add_asan_tests arch test_runtime)
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)

View File

@ -216,7 +216,8 @@ void InitTlsSize() { }
// 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 @@ static void GetTls(uptr *addr, uptr *size) {
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 @@ static void GetTls(uptr *addr, uptr *size) {
*addr = (uptr)tcb->tcb_dtv[1];
}
}
#elif SANITIZER_SOLARIS
// FIXME
*addr = 0;
*size = 0;
#else
#error "Unknown OS"
#endif
}

View File

@ -154,6 +154,8 @@ macro(add_sanitizer_tests_for_arch arch)
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 @@ macro(add_sanitizer_tests_for_arch arch)
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