https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/108920
>From 28b3ccb28062cfcd83a2cf2f8df92c905e3a0865 Mon Sep 17 00:00:00 2001 From: Vitaly Buka <vitalyb...@google.com> Date: Mon, 16 Sep 2024 20:52:04 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 [skip ci] --- .../sanitizer_linux_libcdep.cpp | 142 ++++++++++-------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index a5101291904430..53add5a9b16423 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -200,21 +200,6 @@ bool SetEnv(const char *name, const char *value) { } # endif -__attribute__((unused)) static bool GetLibcVersion(int *major, int *minor, - int *patch) { -# if SANITIZER_GLIBC - const char *p = gnu_get_libc_version(); - *major = internal_simple_strtoll(p, &p, 10); - // Caller does not expect anything else. - CHECK_EQ(*major, 2); - *minor = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; - *patch = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; - return true; -# else - return false; -# endif -} - // True if we can use dlpi_tls_data. glibc before 2.25 may leave NULL (BZ // #19826) so dlpi_tls_data cannot be used. // @@ -224,11 +209,22 @@ __attribute__((unused)) static bool GetLibcVersion(int *major, int *minor, __attribute__((unused)) static int g_use_dlpi_tls_data; # if SANITIZER_GLIBC && !SANITIZER_GO + +static void GetGLibcVersion(int *major, int *minor, int *patch) { + const char *p = gnu_get_libc_version(); + *major = internal_simple_strtoll(p, &p, 10); + // Caller does not expect anything else. + CHECK_EQ(*major, 2); + *minor = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; + *patch = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; +} + __attribute__((unused)) static size_t g_tls_size; + void InitTlsSize() { int major, minor, patch; - g_use_dlpi_tls_data = - GetLibcVersion(&major, &minor, &patch) && major == 2 && minor >= 25; + GetGLibcVersion(&major, &minor, &patch); + g_use_dlpi_tls_data = major == 2 && minor >= 25; # if defined(__aarch64__) || defined(__x86_64__) || \ defined(__powerpc64__) || defined(__loongarch__) @@ -244,73 +240,85 @@ 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_SOLARIS) && \ - !SANITIZER_ANDROID && !SANITIZER_GO +# if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO // sizeof(struct pthread) from glibc. static atomic_uintptr_t 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__) +# if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \ + SANITIZER_RISCV64 +# if SANITIZER_GLIBC int major; int minor; int patch; - if (GetLibcVersion(&major, &minor, &patch) && major == 2) { - /* sizeof(struct pthread) values from various glibc versions. */ - if (SANITIZER_X32) - return 1728; // Assume only one particular version for x32. - // For ARM sizeof(struct pthread) changed in Glibc 2.23. - if (SANITIZER_ARM) - return minor <= 22 ? 1120 : 1216; - if (minor <= 3) - return FIRST_32_SECOND_64(1104, 1696); - if (minor == 4) - return FIRST_32_SECOND_64(1120, 1728); - if (minor == 5) - return FIRST_32_SECOND_64(1136, 1728); - if (minor <= 9) - return FIRST_32_SECOND_64(1136, 1712); - if (minor == 10) - return FIRST_32_SECOND_64(1168, 1776); - if (minor == 11 || (minor == 12 && patch == 1)) - return FIRST_32_SECOND_64(1168, 2288); - if (minor <= 14) - return FIRST_32_SECOND_64(1168, 2304); - if (minor < 32) // Unknown version - return FIRST_32_SECOND_64(1216, 2304); - // minor == 32 - return FIRST_32_SECOND_64(1344, 2496); - } + GetGLibcVersion(&major, &minor, &patch); +# else // SANITIZER_GLIBC return 0; -# elif defined(__s390__) || defined(__sparc__) +# endif // SANITIZER_GLIBC +# endif + +# if defined(__x86_64__) || defined(__i386__) || defined(__arm__) + /* sizeof(struct pthread) values from various glibc versions. */ + if (SANITIZER_X32) + return 1728; // Assume only one particular version for x32. + // For ARM sizeof(struct pthread) changed in Glibc 2.23. + if (SANITIZER_ARM) + return minor <= 22 ? 1120 : 1216; + if (minor <= 3) + return FIRST_32_SECOND_64(1104, 1696); + if (minor == 4) + return FIRST_32_SECOND_64(1120, 1728); + if (minor == 5) + return FIRST_32_SECOND_64(1136, 1728); + if (minor <= 9) + return FIRST_32_SECOND_64(1136, 1712); + if (minor == 10) + return FIRST_32_SECOND_64(1168, 1776); + if (minor == 11 || (minor == 12 && patch == 1)) + return FIRST_32_SECOND_64(1168, 2288); + if (minor <= 14) + return FIRST_32_SECOND_64(1168, 2304); + if (minor < 32) // Unknown version + return FIRST_32_SECOND_64(1216, 2304); + // minor == 32 + return FIRST_32_SECOND_64(1344, 2496); +# endif + +# if SANITIZER_RISCV64 + // TODO: consider adding an optional runtime check for an unknown (untested) + // glibc version + if (minor <= 28) // WARNING: the highest tested version is 2.29 + return 1772; // no guarantees for this one + if (minor <= 31) + return 1772; // tested against glibc 2.29, 2.31 + return 1936; // tested against glibc 2.32 +# endif + +# 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); -# elif defined(__mips__) +# endif + +# if defined(__mips__) // TODO(sagarthakur): add more values as per different glibc versions. return FIRST_32_SECOND_64(1152, 1776); -# elif SANITIZER_LOONGARCH64 +# endif + +# if SANITIZER_LOONGARCH64 return 1856; // from glibc 2.36 -# elif SANITIZER_RISCV64 - int major; - int minor; - int patch; - if (GetLibcVersion(&major, &minor, &patch) && major == 2) { - // TODO: consider adding an optional runtime check for an unknown (untested) - // glibc version - if (minor <= 28) // WARNING: the highest tested version is 2.29 - return 1772; // no guarantees for this one - if (minor <= 31) - return 1772; // tested against glibc 2.29, 2.31 - return 1936; // tested against glibc 2.32 - } - return 0; -# elif defined(__aarch64__) +# endif + +# if defined(__aarch64__) // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22. return 1776; -# elif defined(__powerpc64__) +# endif + +# if defined(__powerpc64__) return 1776; // from glibc.ppc64le 2.20-8.fc21 # endif } @@ -351,6 +359,10 @@ static uptr TlsPreTcbSize() { } # endif +# endif + +# if (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID && !SANITIZER_GO namespace { struct TlsBlock { uptr begin, end, align; >From 19fbf2135d7ed48f7e9673a7b0833f86bc8d4afa Mon Sep 17 00:00:00 2001 From: Vitaly Buka <vitalyb...@google.com> Date: Mon, 16 Sep 2024 21:27:00 -0700 Subject: [PATCH 2/2] keep in_symbolizer Created using spr 1.3.4 --- .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 924339191df133..eaa0f6d0de60c2 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -254,9 +254,12 @@ SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionBegin() {} SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionEnd() {} #endif +// FIXME: Use for `in_symbolizer()` as well. As-is we can't use +// `DlSymAllocator`, because it uses the primary allocator only. Symbolizer +// requires support of the secondary allocator for larger blocks. struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { static bool UseImpl() { - return in_symbolizer() || (ctx && !ctx->initialized); + return (ctx && !ctx->initialized); } }; @@ -667,6 +670,8 @@ TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { #if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, malloc, uptr size) { + if (in_symbolizer()) + return InternalAlloc(size); if (DlsymAlloc::Use()) return DlsymAlloc::Allocate(size); void *p = 0; @@ -686,7 +691,9 @@ TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) { return user_memalign(thr, pc, align, sz); } -TSAN_INTERCEPTOR(void*, calloc, uptr n, uptr size) { +TSAN_INTERCEPTOR(void *, calloc, uptr n, uptr size) { + if (in_symbolizer()) + return InternalCalloc(n, size); if (DlsymAlloc::Use()) return DlsymAlloc::Callocate(n, size); void *p = 0; @@ -699,6 +706,8 @@ TSAN_INTERCEPTOR(void*, calloc, uptr n, uptr size) { } TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { + if (in_symbolizer()) + return InternalRealloc(p, size); if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(p)) return DlsymAlloc::Realloc(p, size); if (p) @@ -711,9 +720,9 @@ TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { return p; } -TSAN_INTERCEPTOR(void*, reallocarray, void *p, uptr n, uptr size) { - if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(p)) - return DlsymAlloc::ReallocArray(p, n, size); +TSAN_INTERCEPTOR(void *, reallocarray, void *p, uptr n, uptr size) { + if (in_symbolizer()) + return InternalReallocArray(p, n, size); if (p) invoke_free_hook(p); { @@ -727,6 +736,8 @@ TSAN_INTERCEPTOR(void*, reallocarray, void *p, uptr n, uptr size) { TSAN_INTERCEPTOR(void, free, void *p) { if (UNLIKELY(!p)) return; + if (in_symbolizer()) + return InternalFree(p); if (DlsymAlloc::PointerIsMine(p)) return DlsymAlloc::Free(p); invoke_free_hook(p); @@ -737,6 +748,8 @@ TSAN_INTERCEPTOR(void, free, void *p) { TSAN_INTERCEPTOR(void, cfree, void *p) { if (UNLIKELY(!p)) return; + if (in_symbolizer()) + return InternalFree(p); if (DlsymAlloc::PointerIsMine(p)) return DlsymAlloc::Free(p); invoke_free_hook(p); @@ -826,15 +839,15 @@ TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { #if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) { - if (DlsymAlloc::Use()) - return DlsymAlloc::Allocate(sz, align); + if (in_symbolizer()) + return InternalAlloc(sz, nullptr, align); SCOPED_INTERCEPTOR_RAW(aligned_alloc, align, sz); return user_aligned_alloc(thr, pc, align, sz); } TSAN_INTERCEPTOR(void*, valloc, uptr sz) { - if (DlsymAlloc::Use()) - return DlsymAlloc::Allocate(sz, GetPageSizeCached()); + if (in_symbolizer()) + return InternalAlloc(sz, nullptr, GetPageSizeCached()); SCOPED_INTERCEPTOR_RAW(valloc, sz); return user_valloc(thr, pc, sz); } @@ -842,10 +855,10 @@ TSAN_INTERCEPTOR(void*, valloc, uptr sz) { #if SANITIZER_LINUX TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { - if (DlsymAlloc::Use()) { + if (in_symbolizer()) { uptr PageSize = GetPageSizeCached(); sz = sz ? RoundUpTo(sz, PageSize) : PageSize; - return DlsymAlloc::Allocate(sz, PageSize); + return InternalAlloc(sz, nullptr, PageSize); } SCOPED_INTERCEPTOR_RAW(pvalloc, sz); return user_pvalloc(thr, pc, sz); @@ -857,8 +870,8 @@ TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { #if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { - if (DlsymAlloc::Use()) { - void *p = DlsymAlloc::Allocate(sz, align); + if (in_symbolizer()) { + void *p = InternalAlloc(sz, nullptr, align); if (!p) return errno_ENOMEM; *memptr = p; _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits