Skip to content

[sanitizer] Switch from lazy ThreadDescriptorSize #108923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ static void GetGLibcVersion(int *major, int *minor, int *patch) {
// to get the pointer to thread-specific data keys in the thread control block.
# if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO
// sizeof(struct pthread) from glibc.
static atomic_uintptr_t thread_descriptor_size;
static uptr thread_descriptor_size;

// FIXME: Implementation is very GLIBC specific, but it's used by FREEBSD.
static uptr ThreadDescriptorSizeFallback() {
Expand Down Expand Up @@ -305,20 +305,7 @@ static uptr ThreadDescriptorSizeFallback() {
# endif
}

uptr ThreadDescriptorSize() {
uptr val = atomic_load_relaxed(&thread_descriptor_size);
if (val)
return val;
// _thread_db_sizeof_pthread is a GLIBC_PRIVATE symbol that is exported in
// glibc 2.34 and later.
if (unsigned *psizeof = static_cast<unsigned *>(
dlsym(RTLD_DEFAULT, "_thread_db_sizeof_pthread")))
val = *psizeof;
if (!val)
val = ThreadDescriptorSizeFallback();
atomic_store_relaxed(&thread_descriptor_size, val);
return val;
}
uptr ThreadDescriptorSize() { return thread_descriptor_size; }

# if SANITIZER_GLIBC
__attribute__((unused)) static size_t g_tls_size;
Expand All @@ -330,6 +317,15 @@ void InitTlsSize() {
GetGLibcVersion(&major, &minor, &patch);
g_use_dlpi_tls_data = major == 2 && minor >= 25;

if (major == 2 && minor >= 34) {
// _thread_db_sizeof_pthread is a GLIBC_PRIVATE symbol that is exported in
// glibc 2.34 and later.
if (unsigned *psizeof = static_cast<unsigned *>(
dlsym(RTLD_DEFAULT, "_thread_db_sizeof_pthread"))) {
thread_descriptor_size = *psizeof;
}
}

# if defined(__aarch64__) || defined(__x86_64__) || \
defined(__powerpc64__) || defined(__loongarch__)
auto *get_tls_static_info = (void (*)(size_t *, size_t *))dlsym(
Expand All @@ -339,7 +335,11 @@ void InitTlsSize() {
if (get_tls_static_info)
get_tls_static_info(&g_tls_size, &tls_align);
# endif

# endif // SANITIZER_GLIBC

if (!thread_descriptor_size)
thread_descriptor_size = ThreadDescriptorSizeFallback();
}

# if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ TEST(SanitizerLinux, ThreadDescriptorSize) {
void *result;
ASSERT_EQ(0, pthread_create(&tid, 0, thread_descriptor_size_test_func, 0));
ASSERT_EQ(0, pthread_join(tid, &result));
EXPECT_EQ(0u, ThreadDescriptorSize());
InitTlsSize();
EXPECT_EQ((uptr)result, ThreadDescriptorSize());
}
# endif
Expand Down
Loading