diff options
author | Richard Biener <rguenther@suse.de> | 2018-06-07 11:56:25 +0000 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2018-06-07 11:56:25 +0000 |
commit | fbceeb300f2982a9fd59ff481299c9a2496ebb4e (patch) | |
tree | 8b265d01beb3f505719915fcc8d60af42a7eaf34 | |
parent | a72ac91b71c91ec22f27720d84ab1627b0eedb5c (diff) |
2018-06-07 Richard Biener <rguenther@suse.de>
Backport from mainline
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.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@261272 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libsanitizer/ChangeLog | 14 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc | 43 |
2 files changed, 43 insertions, 14 deletions
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index b8f13a60413..3a1619045eb 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,17 @@ +2018-06-07 Richard Biener <rguenther@suse.de> + + Backport from mainline + 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-05-31 Matthias Klose <doko@ubuntu.com> PR sanitizer/86012 diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc index 63e70660cf3..dc342de6e10 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc @@ -153,28 +153,43 @@ 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 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; - void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); - 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); + 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); + 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); |