re PR sanitizer/79341 (Many Asan tests fail on s390)

PR sanitizer/79341
	* configure.tgt (s390*-*-linux*): Don't disable libsanitizer on
	s390-linux 31-bit.
	* sanitizer_common/sanitizer_internal_defs.h: Cherry-pick upstream
	r294793.
	* sanitizer_common/sanitizer_common_interceptors.inc: Cherry-pick
	upstream r294790.
	* sanitizer_common/sanitizer_linux_s390.cc: Cherry-pick upstream
	r294799.

From-SVN: r245350
This commit is contained in:
Jakub Jelinek 2017-02-11 00:34:49 +01:00 committed by Jakub Jelinek
parent 42f8e766cc
commit 1509524bcc
5 changed files with 68 additions and 15 deletions

View File

@ -1,3 +1,15 @@
2017-02-11 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/79341
* configure.tgt (s390*-*-linux*): Don't disable libsanitizer on
s390-linux 31-bit.
* sanitizer_common/sanitizer_internal_defs.h: Cherry-pick upstream
r294793.
* sanitizer_common/sanitizer_common_interceptors.inc: Cherry-pick
upstream r294790.
* sanitizer_common/sanitizer_linux_s390.cc: Cherry-pick upstream
r294799.
2017-02-03 Maxim Ostapenko <m.ostapenko@samsung.com> 2017-02-03 Maxim Ostapenko <m.ostapenko@samsung.com>
PR sanitizer/78663 PR sanitizer/78663

View File

@ -40,9 +40,6 @@ case "${target}" in
sparc*-*-linux*) sparc*-*-linux*)
;; ;;
s390*-*-linux*) s390*-*-linux*)
if test x$ac_cv_sizeof_void_p = x4; then
UNSUPPORTED=1
fi
;; ;;
arm*-*-linux*) arm*-*-linux*)
;; ;;

View File

@ -4550,11 +4550,15 @@ void *__tls_get_addr_opt(void *arg);
// descriptor offset as an argument instead of a pointer. GOT address // descriptor offset as an argument instead of a pointer. GOT address
// is passed in r12, so it's necessary to write it in assembly. This is // is passed in r12, so it's necessary to write it in assembly. This is
// the function used by the compiler. // the function used by the compiler.
#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal) extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
DEFINE_REAL(uptr, __tls_get_offset, void *arg)
extern "C" uptr __tls_get_offset(void *arg);
extern "C" uptr __interceptor___tls_get_offset(void *arg);
INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) { INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
void *ctx; void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg); COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
uptr res = REAL(__tls_get_addr_internal)(arg); uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer()); uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
void *ptr = reinterpret_cast<void *>(res + tp); void *ptr = reinterpret_cast<void *>(res + tp);
uptr tls_begin, tls_end; uptr tls_begin, tls_end;
@ -4566,32 +4570,43 @@ INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
} }
return res; return res;
} }
// We need a protected symbol aliasing the above, so that we can jump // We need a hidden symbol aliasing the above, so that we can jump
// directly to it from the assembly below. // directly to it from the assembly below.
extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"), extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
visibility("protected"))) visibility("hidden")))
uptr __interceptor___tls_get_addr_internal_protected(void *arg); uptr __tls_get_addr_hidden(void *arg);
// Now carefully intercept __tls_get_offset. // Now carefully intercept __tls_get_offset.
asm( asm(
".text\n" ".text\n"
".global __tls_get_offset\n"
"__tls_get_offset:\n"
// The __intercept_ version has to exist, so that gen_dynamic_list.py // The __intercept_ version has to exist, so that gen_dynamic_list.py
// exports our symbol. // exports our symbol.
".weak __tls_get_offset\n"
".type __tls_get_offset, @function\n"
"__tls_get_offset:\n"
".global __interceptor___tls_get_offset\n" ".global __interceptor___tls_get_offset\n"
".type __interceptor___tls_get_offset, @function\n"
"__interceptor___tls_get_offset:\n" "__interceptor___tls_get_offset:\n"
#ifdef __s390x__ #ifdef __s390x__
"la %r2, 0(%r2,%r12)\n" "la %r2, 0(%r2,%r12)\n"
"jg __interceptor___tls_get_addr_internal_protected\n" "jg __tls_get_addr_hidden\n"
#else #else
"basr %r3,0\n" "basr %r3,0\n"
"0: la %r2,0(%r2,%r12)\n" "0: la %r2,0(%r2,%r12)\n"
"l %r4,1f-0b(%r3)\n" "l %r4,1f-0b(%r3)\n"
"b 0(%r4,%r3)\n" "b 0(%r4,%r3)\n"
"1: .long __interceptor___tls_get_addr_internal_protected - 0b\n" "1: .long __tls_get_addr_hidden - 0b\n"
#endif #endif
".type __tls_get_offset, @function\n" ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
".size __tls_get_offset, .-__tls_get_offset\n" // Assembly wrapper to call REAL(__tls_get_offset)(arg)
".type __tls_get_offset_wrapper, @function\n"
"__tls_get_offset_wrapper:\n"
#ifdef __s390x__
"sgr %r2,%r12\n"
#else
"sr %r2,%r12\n"
#endif
"br %r3\n"
".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
); );
#endif // SANITIZER_S390 #endif // SANITIZER_S390
#else #else

View File

@ -287,7 +287,12 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
enum LinkerInitialized { LINKER_INITIALIZED = 0 }; enum LinkerInitialized { LINKER_INITIALIZED = 0 };
#if !defined(_MSC_VER) || defined(__clang__) #if !defined(_MSC_VER) || defined(__clang__)
# define GET_CALLER_PC() (uptr)__builtin_return_address(0) # if SANITIZER_S390_31
# define GET_CALLER_PC() \
(uptr)__builtin_extract_return_addr(__builtin_return_address(0))
# else
# define GET_CALLER_PC() (uptr)__builtin_return_address(0)
# endif
# define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0) # define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0)
inline void Trap() { inline void Trap() {
__builtin_trap(); __builtin_trap();

View File

@ -134,6 +134,18 @@ static bool FixedCVE_2016_2143() {
if (ptr[0] == '.') if (ptr[0] == '.')
patch = internal_simple_strtoll(ptr+1, &ptr, 10); patch = internal_simple_strtoll(ptr+1, &ptr, 10);
if (major < 3) { if (major < 3) {
if (major == 2 && minor == 6 && patch == 32 && ptr[0] == '-' &&
internal_strstr(ptr, ".el6")) {
// Check RHEL6
int r1 = internal_simple_strtoll(ptr+1, &ptr, 10);
if (r1 >= 657) // 2.6.32-657.el6 or later
return true;
if (r1 == 642 && ptr[0] == '.') {
int r2 = internal_simple_strtoll(ptr+1, &ptr, 10);
if (r2 >= 9) // 2.6.32-642.9.1.el6 or later
return true;
}
}
// <3.0 is bad. // <3.0 is bad.
return false; return false;
} else if (major == 3) { } else if (major == 3) {
@ -143,6 +155,18 @@ static bool FixedCVE_2016_2143() {
// 3.12.58+ is OK. // 3.12.58+ is OK.
if (minor == 12 && patch >= 58) if (minor == 12 && patch >= 58)
return true; return true;
if (minor == 10 && patch == 0 && ptr[0] == '-' &&
internal_strstr(ptr, ".el7")) {
// Check RHEL7
int r1 = internal_simple_strtoll(ptr+1, &ptr, 10);
if (r1 >= 426) // 3.10.0-426.el7 or later
return true;
if (r1 == 327 && ptr[0] == '.') {
int r2 = internal_simple_strtoll(ptr+1, &ptr, 10);
if (r2 >= 27) // 3.10.0-327.27.1.el7 or later
return true;
}
}
// Otherwise, bad. // Otherwise, bad.
return false; return false;
} else if (major == 4) { } else if (major == 4) {