Skip to content

Commit b856c9f

Browse files
authored
[sanitizer] Extract SANITIZER_FREEBSD version of ThreadDescriptorSizeFallback (#109743)
This should fix SANITIZER_FREEBSD and simplify SANITIZER_GLIBC version. Also the PR make readers aware of problematic `ThreadDescriptorSizeFallback` for SANITIZER_FREEBSD. Maybe it will encourage FreeBSD maintainers to improve the functions, or prove that it's not needed at all.
1 parent 6fb39ac commit b856c9f

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -217,27 +217,14 @@ static void GetGLibcVersion(int *major, int *minor, int *patch) {
217217
*minor = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0;
218218
*patch = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0;
219219
}
220-
# endif // SANITIZER_GLIBC && !SANITIZER_GO
221220

222-
// On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage
223-
// of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan
224-
// to get the pointer to thread-specific data keys in the thread control block.
225-
# if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO
226-
// sizeof(struct pthread) from glibc.
227-
static uptr thread_descriptor_size;
228-
229-
// FIXME: Implementation is very GLIBC specific, but it's used by FreeBSD.
230221
static uptr ThreadDescriptorSizeFallback() {
231222
# if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \
232223
SANITIZER_RISCV64
233-
# if SANITIZER_GLIBC
234224
int major;
235225
int minor;
236226
int patch;
237227
GetGLibcVersion(&major, &minor, &patch);
238-
# else // SANITIZER_GLIBC
239-
return 0;
240-
# endif // SANITIZER_GLIBC
241228
# endif
242229

243230
# if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
@@ -304,6 +291,48 @@ static uptr ThreadDescriptorSizeFallback() {
304291
return 1776; // from glibc.ppc64le 2.20-8.fc21
305292
# endif
306293
}
294+
# endif // SANITIZER_GLIBC && !SANITIZER_GO
295+
296+
# if SANITIZER_FREEBSD && !SANITIZER_GO
297+
// FIXME: Implementation is very GLIBC specific, but it's used by FreeBSD.
298+
static uptr ThreadDescriptorSizeFallback() {
299+
# if defined(__s390__) || defined(__sparc__)
300+
// The size of a prefix of TCB including pthread::{specific_1stblock,specific}
301+
// suffices. Just return offsetof(struct pthread, specific_used), which hasn't
302+
// changed since 2007-05. Technically this applies to i386/x86_64 as well but
303+
// we call _dl_get_tls_static_info and need the precise size of struct
304+
// pthread.
305+
return FIRST_32_SECOND_64(524, 1552);
306+
# endif
307+
308+
# if defined(__mips__)
309+
// TODO(sagarthakur): add more values as per different glibc versions.
310+
return FIRST_32_SECOND_64(1152, 1776);
311+
# endif
312+
313+
# if SANITIZER_LOONGARCH64
314+
return 1856; // from glibc 2.36
315+
# endif
316+
317+
# if defined(__aarch64__)
318+
// The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.
319+
return 1776;
320+
# endif
321+
322+
# if defined(__powerpc64__)
323+
return 1776; // from glibc.ppc64le 2.20-8.fc21
324+
# endif
325+
326+
return 0;
327+
}
328+
# endif // SANITIZER_FREEBSD && !SANITIZER_GO
329+
330+
# if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO
331+
// On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage
332+
// of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan
333+
// to get the pointer to thread-specific data keys in the thread control block.
334+
// sizeof(struct pthread) from glibc.
335+
static uptr thread_descriptor_size;
307336

308337
uptr ThreadDescriptorSize() { return thread_descriptor_size; }
309338

0 commit comments

Comments
 (0)