Skip to content

[sanitizer] Extract SANITIZER_FREEBSD version of ThreadDescriptorSizeFallback #109743

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
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
55 changes: 42 additions & 13 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,27 +217,14 @@ static void GetGLibcVersion(int *major, int *minor, int *patch) {
*minor = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0;
*patch = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0;
}
# endif // SANITIZER_GLIBC && !SANITIZER_GO

// 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_GLIBC) && !SANITIZER_GO
// sizeof(struct pthread) from glibc.
static uptr thread_descriptor_size;

// FIXME: Implementation is very GLIBC specific, but it's used by FreeBSD.
static uptr ThreadDescriptorSizeFallback() {
# if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \
SANITIZER_RISCV64
# if SANITIZER_GLIBC
int major;
int minor;
int patch;
GetGLibcVersion(&major, &minor, &patch);
# else // SANITIZER_GLIBC
return 0;
# endif // SANITIZER_GLIBC
# endif

# if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
Expand Down Expand Up @@ -304,6 +291,48 @@ static uptr ThreadDescriptorSizeFallback() {
return 1776; // from glibc.ppc64le 2.20-8.fc21
# endif
}
# endif // SANITIZER_GLIBC && !SANITIZER_GO

# if SANITIZER_FREEBSD && !SANITIZER_GO
// FIXME: Implementation is very GLIBC specific, but it's used by FreeBSD.
static uptr ThreadDescriptorSizeFallback() {
# if 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);
# endif

# if defined(__mips__)
// TODO(sagarthakur): add more values as per different glibc versions.
return FIRST_32_SECOND_64(1152, 1776);
# endif

# if SANITIZER_LOONGARCH64
return 1856; // from glibc 2.36
# endif

# if defined(__aarch64__)
// The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.
return 1776;
# endif

# if defined(__powerpc64__)
return 1776; // from glibc.ppc64le 2.20-8.fc21
# endif

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a hard time believing that that's any point in this: apart from being glibc-specific, as of FreeBSD 14.1 there isn't a s390, sparc, mips, or loongarch64 port of FreeBSD.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are confident, I can drop them in followup PR, so bisecting could be easiers.

According to https://www.freebsd.org/platforms/
Recent Tier 1 are only x86_64 and aarch64, the former works with 0.

I guess implication of having these values invalid is incorrect DTLS detection which will false positive for msan and lsan.

return 0;
}
# endif // SANITIZER_FREEBSD && !SANITIZER_GO

# if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO
// 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.
// sizeof(struct pthread) from glibc.
static uptr thread_descriptor_size;

uptr ThreadDescriptorSize() { return thread_descriptor_size; }

Expand Down
Loading