re PR sanitizer/84761 (AddressSanitizer is not compatible with glibc 2.27 on x86)

PR sanitizer/84761
	* sanitizer_common/sanitizer_linux_libcdep.cc (__GLIBC_PREREQ):
	Define if not defined.
	(DL_INTERNAL_FUNCTION): Don't define.
	(InitTlsSize): For __i386__ if not compiled against glibc 2.27+
	determine at runtime whether to use regparm(3), stdcall calling
	convention for older glibcs or normal calling convention for
	newer glibcs for call to _dl_get_tls_static_info.

From-SVN: r258663
This commit is contained in:
Jakub Jelinek 2018-03-19 21:47:29 +01:00 committed by Jakub Jelinek
parent 42f8338d59
commit 359ea407e9
2 changed files with 40 additions and 14 deletions

View File

@ -1,3 +1,14 @@
2018-03-19 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/84761
* sanitizer_common/sanitizer_linux_libcdep.cc (__GLIBC_PREREQ):
Define if not defined.
(DL_INTERNAL_FUNCTION): Don't define.
(InitTlsSize): For __i386__ if not compiled against glibc 2.27+
determine at runtime whether to use regparm(3), stdcall calling
convention for older glibcs or normal calling convention for
newer glibcs for call to _dl_get_tls_static_info.
2018-03-14 Segher Boessenkool <segher@kernel.crashing.org>
* sanitizer_common/sanitizer_stacktrace.cc

View File

@ -147,29 +147,44 @@ bool SanitizerGetThreadName(char *name, int max_len) {
#endif
}
#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(x, y) 0
#endif
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
!SANITIZER_NETBSD
static uptr g_tls_size;
#ifdef __i386__
# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))
#else
# define DL_INTERNAL_FUNCTION
#endif
void InitTlsSize() {
// all current supported platforms have 16 bytes stack alignment
const size_t kStackAlign = 16;
typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
get_tls_func get_tls;
size_t tls_size = 0;
size_t tls_align = 0;
void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
#if defined(__i386__) && !__GLIBC_PREREQ(2, 27)
/* On i?86, _dl_get_tls_static_info used to be internal_function, i.e.
__attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal
function in 2.27 and later. */
if (!dlvsym(RTLD_NEXT, "glob", "GLIBC_2.27")) {
typedef void (*get_tls_func)(size_t*, size_t*)
__attribute__((regparm(3), stdcall));
get_tls_func get_tls;
CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));
internal_memcpy(&get_tls, &get_tls_static_info_ptr,
sizeof(get_tls_static_info_ptr));
CHECK_NE(get_tls, 0);
size_t tls_size = 0;
size_t tls_align = 0;
get_tls(&tls_size, &tls_align);
} else
#endif
{
typedef void (*get_tls_func)(size_t*, size_t*);
get_tls_func get_tls;
CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));
internal_memcpy(&get_tls, &get_tls_static_info_ptr,
sizeof(get_tls_static_info_ptr));
CHECK_NE(get_tls, 0);
get_tls(&tls_size, &tls_align);
}
if (tls_align < kStackAlign)
tls_align = kStackAlign;
g_tls_size = RoundUpTo(tls_size, tls_align);