forked from OSchip/llvm-project
[sanitizer] Fix glibc sparc build and add GetTls support
sanitizer_linux_libcdep.cpp doesn't build for Linux sparc (with minimum support but can build) after D98926. I wasn't aware because the file didn't mention `__sparc__`. While here, add the relevant support since it does not add complexity (the D99566 approach). Adds an explicit `#error` for unsupported non-Android Linux and FreeBSD architectures. ThreadDescriptorSize is only used by lsan to scan thread-specific data keys in the thread control block. On TLS Variant II architectures (i386/x86_64/s390/sparc), our dl_iterate_phdr based approach can cover the region from the first byte of the static TLS block (static TLS surplus) to the thread pointer. We just need to extend the range to include the first few members of struct pthread. offsetof(struct pthread, specific_used) satisfies the requirement and has not changed since 2007-05-10. We don't need to update ThreadDescriptorSize for each glibc version. Technically we could use the 524/1552 for x86_64 as well but there is potential risk that large applications with thousands of shared object dependency may dislike the time complexity increase if there are many threads, so I don't make the simplification for now. Differential Revision: https://reviews.llvm.org/D100892
This commit is contained in:
parent
81cad0be68
commit
031c40dc3c
|
@ -216,10 +216,7 @@ 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 (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \
|
||||
defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \
|
||||
defined(__arm__) || SANITIZER_RISCV64) && \
|
||||
(SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID
|
||||
#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID
|
||||
// sizeof(struct pthread) from glibc.
|
||||
static atomic_uintptr_t thread_descriptor_size;
|
||||
|
||||
|
@ -257,6 +254,13 @@ uptr ThreadDescriptorSize() {
|
|||
else // minor == 32
|
||||
val = FIRST_32_SECOND_64(1344, 2496);
|
||||
}
|
||||
#elif defined(__s390__) || defined(__sparc__)
|
||||
// The size of a prefix of TCB including pthread::{specific_1stblock,specific}
|
||||
// suffices. Just return offsetof(struct pthread, specific_used), which hasn't
|
||||
// changed since 2007-05. Technically this applies to i386/x86_64 as well but
|
||||
// we call _dl_get_tls_static_info and need the precise size of struct
|
||||
// pthread.
|
||||
return FIRST_32_SECOND_64(524, 1552);
|
||||
#elif defined(__mips__)
|
||||
// TODO(sagarthakur): add more values as per different glibc versions.
|
||||
val = FIRST_32_SECOND_64(1152, 1776);
|
||||
|
@ -280,8 +284,6 @@ uptr ThreadDescriptorSize() {
|
|||
val = 1776;
|
||||
#elif defined(__powerpc64__)
|
||||
val = 1776; // from glibc.ppc64le 2.20-8.fc21
|
||||
#elif defined(__s390__)
|
||||
val = FIRST_32_SECOND_64(1152, 1776); // valid for glibc 2.22
|
||||
#endif
|
||||
if (val)
|
||||
atomic_store_relaxed(&thread_descriptor_size, val);
|
||||
|
@ -441,12 +443,13 @@ static void GetTls(uptr *addr, uptr *size) {
|
|||
#elif SANITIZER_FREEBSD || SANITIZER_LINUX
|
||||
uptr align;
|
||||
GetStaticTlsBoundary(addr, size, &align);
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__s390__)
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__s390__) || \
|
||||
defined(__sparc__)
|
||||
if (SANITIZER_GLIBC) {
|
||||
#if defined(__s390__)
|
||||
align = Max<uptr>(align, 16);
|
||||
#else
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
align = Max<uptr>(align, 64);
|
||||
#else
|
||||
align = Max<uptr>(align, 16);
|
||||
#endif
|
||||
}
|
||||
const uptr tp = RoundUpTo(*addr + *size, align);
|
||||
|
|
Loading…
Reference in New Issue