summaryrefslogtreecommitdiff
path: root/libsanitizer
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-02-10 23:34:49 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-02-10 23:34:49 +0000
commita479e13e2f44326f75d99d0ad90bda4cbbf6dafc (patch)
tree02d0911eed20219e443b49643f417e95a31eb25c /libsanitizer
parent6debdcc9222f6e24091aa7f6a8927be60beac03a (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@245350 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer')
-rw-r--r--libsanitizer/ChangeLog12
-rw-r--r--libsanitizer/configure.tgt3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc37
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_internal_defs.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_s390.cc24
5 files changed, 68 insertions, 15 deletions
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index c0e5563ac6fb..e60f31bbc466 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -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>
PR sanitizer/78663
diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt
index e648051aab82..82e8a5513c59 100644
--- a/libsanitizer/configure.tgt
+++ b/libsanitizer/configure.tgt
@@ -40,9 +40,6 @@ case "${target}" in
sparc*-*-linux*)
;;
s390*-*-linux*)
- if test x$ac_cv_sizeof_void_p = x4; then
- UNSUPPORTED=1
- fi
;;
arm*-*-linux*)
;;
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
index 38390ed96215..0970eda5ee64 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
@@ -4550,11 +4550,15 @@ void *__tls_get_addr_opt(void *arg);
// 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
// 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) {
void *ctx;
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());
void *ptr = reinterpret_cast<void *>(res + tp);
uptr tls_begin, tls_end;
@@ -4566,32 +4570,43 @@ INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
}
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.
extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
- visibility("protected")))
-uptr __interceptor___tls_get_addr_internal_protected(void *arg);
+ visibility("hidden")))
+uptr __tls_get_addr_hidden(void *arg);
// Now carefully intercept __tls_get_offset.
asm(
".text\n"
- ".global __tls_get_offset\n"
- "__tls_get_offset:\n"
// The __intercept_ version has to exist, so that gen_dynamic_list.py
// exports our symbol.
+ ".weak __tls_get_offset\n"
+ ".type __tls_get_offset, @function\n"
+ "__tls_get_offset:\n"
".global __interceptor___tls_get_offset\n"
+ ".type __interceptor___tls_get_offset, @function\n"
"__interceptor___tls_get_offset:\n"
#ifdef __s390x__
"la %r2, 0(%r2,%r12)\n"
- "jg __interceptor___tls_get_addr_internal_protected\n"
+ "jg __tls_get_addr_hidden\n"
#else
"basr %r3,0\n"
"0: la %r2,0(%r2,%r12)\n"
"l %r4,1f-0b(%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
- ".type __tls_get_offset, @function\n"
- ".size __tls_get_offset, .-__tls_get_offset\n"
+ ".size __interceptor___tls_get_offset, .-__interceptor___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
#else
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index b9c906669dee..676ade143d88 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -287,7 +287,12 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
enum LinkerInitialized { LINKER_INITIALIZED = 0 };
#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)
inline void Trap() {
__builtin_trap();
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc
index c7d647528aba..3faaa1c26ac3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc
@@ -134,6 +134,18 @@ static bool FixedCVE_2016_2143() {
if (ptr[0] == '.')
patch = internal_simple_strtoll(ptr+1, &ptr, 10);
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.
return false;
} else if (major == 3) {
@@ -143,6 +155,18 @@ static bool FixedCVE_2016_2143() {
// 3.12.58+ is OK.
if (minor == 12 && patch >= 58)
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.
return false;
} else if (major == 4) {