diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2023-09-02 12:36:53 +0200 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2023-09-02 12:36:53 +0200 |
commit | 208f9a2afcc9882c2eebe0c00d296bd1226de103 (patch) | |
tree | e1b49a56472626740d9d42ca16ba23f3b560617b | |
parent | 6081d3342d0e641b03368c0dc8688c3e9ca3c193 (diff) | |
download | llvm-208f9a2afcc9882c2eebe0c00d296bd1226de103.zip llvm-208f9a2afcc9882c2eebe0c00d296bd1226de103.tar.gz llvm-208f9a2afcc9882c2eebe0c00d296bd1226de103.tar.bz2 |
[msan][s390x] Fix long double interceptors
s390x is one of the architectures where the "long double" type was changed
from a 64-bit IEEE to a 128-bit IEEE type back in the glibc 2.4 days.
This means that glibc still exports two versions of the long double functions
(those that already existed back then), and we have to intercept the correct
version. There is already an existing define SANITIZER_NLDBL_VERSION that
indicates this situation, we simply have to respect it when intercepting
strtold and wcstold.
In addition, on s390x a long double return value is passed in memory via
implicit reference. This means the interceptor for functions returning
long double has to unpoison that memory slot, or else we will get
false-positive uninitialized memory reference warnings when the caller
accesses that return value - similar to what is already done in the
mallinfo interceptor. Create a variant macro INTERCEPTOR_STRTO_SRET and
use it on s390x.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D159378
-rw-r--r-- | compiler-rt/lib/msan/msan_interceptors.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index ba92bd1..bac7564 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -401,11 +401,25 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { __msan_unpoison(endptr, sizeof(*endptr)); \ return res; +// On s390x, long double return values are passed via implicit reference, +// which needs to be unpoisoned. We make the implicit pointer explicit. +#define INTERCEPTOR_STRTO_SRET_BODY(func, sret, ...) \ + ENSURE_MSAN_INITED(); \ + REAL(func)(sret, __VA_ARGS__); \ + __msan_unpoison(sret, sizeof(*sret)); \ + __msan_unpoison(endptr, sizeof(*endptr)); + #define INTERCEPTOR_STRTO(ret_type, func, char_type) \ INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \ INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \ } +#define INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \ + INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \ + char_type **endptr) { \ + INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr); \ + } + #define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \ int base) { \ @@ -418,6 +432,12 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \ } +#define INTERCEPTOR_STRTO_SRET_LOC(ret_type, func, char_type) \ + INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \ + char_type **endptr, void *loc) { \ + INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr, loc); \ + } + #define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \ INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \ int base, void *loc) { \ @@ -429,6 +449,10 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { INTERCEPTOR_STRTO(ret_type, func, char_type) \ INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) +#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \ + INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \ + INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type) + #define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \ INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) @@ -440,6 +464,12 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \ INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type) +#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \ + INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \ + INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type) \ + INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_l, char_type) \ + INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_internal, char_type) + #define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \ INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) \ @@ -449,7 +479,11 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { INTERCEPTORS_STRTO(double, strtod, char) INTERCEPTORS_STRTO(float, strtof, char) +#ifdef __s390x__ +INTERCEPTORS_STRTO_SRET(long double, strtold, char) +#else INTERCEPTORS_STRTO(long double, strtold, char) +#endif INTERCEPTORS_STRTO_BASE(long, strtol, char) INTERCEPTORS_STRTO_BASE(long long, strtoll, char) INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char) @@ -458,7 +492,11 @@ INTERCEPTORS_STRTO_BASE(u64, strtouq, char) INTERCEPTORS_STRTO(double, wcstod, wchar_t) INTERCEPTORS_STRTO(float, wcstof, wchar_t) +#ifdef __s390x__ +INTERCEPTORS_STRTO_SRET(long double, wcstold, wchar_t) +#else INTERCEPTORS_STRTO(long double, wcstold, wchar_t) +#endif INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t) INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t) INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t) @@ -467,7 +505,11 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t) #if SANITIZER_GLIBC INTERCEPTORS_STRTO(double, __isoc23_strtod, char) INTERCEPTORS_STRTO(float, __isoc23_strtof, char) +#ifdef __s390x__ +INTERCEPTORS_STRTO_SRET(long double, __isoc23_strtold, char) +#else INTERCEPTORS_STRTO(long double, __isoc23_strtold, char) +#endif INTERCEPTORS_STRTO_BASE(long, __isoc23_strtol, char) INTERCEPTORS_STRTO_BASE(long long, __isoc23_strtoll, char) INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_strtoul, char) @@ -476,7 +518,11 @@ INTERCEPTORS_STRTO_BASE(u64, __isoc23_strtouq, char) INTERCEPTORS_STRTO(double, __isoc23_wcstod, wchar_t) INTERCEPTORS_STRTO(float, __isoc23_wcstof, wchar_t) +#ifdef __s390x__ +INTERCEPTORS_STRTO_SRET(long double, __isoc23_wcstold, wchar_t) +#else INTERCEPTORS_STRTO(long double, __isoc23_wcstold, wchar_t) +#endif INTERCEPTORS_STRTO_BASE(long, __isoc23_wcstol, wchar_t) INTERCEPTORS_STRTO_BASE(long long, __isoc23_wcstoll, wchar_t) INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_wcstoul, wchar_t) @@ -493,6 +539,12 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, __isoc23_wcstoull, wchar_t) INTERCEPT_FUNCTION(func##_l); \ INTERCEPT_FUNCTION(__##func##_l); \ INTERCEPT_FUNCTION(__##func##_internal); + +#define INTERCEPT_STRTO_VER(func, ver) \ + INTERCEPT_FUNCTION_VER(func, ver); \ + INTERCEPT_FUNCTION_VER(func##_l, ver); \ + INTERCEPT_FUNCTION_VER(__##func##_l, ver); \ + INTERCEPT_FUNCTION_VER(__##func##_internal, ver); #endif @@ -1754,7 +1806,11 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(strncat); INTERCEPT_STRTO(strtod); INTERCEPT_STRTO(strtof); +#ifdef SANITIZER_NLDBL_VERSION + INTERCEPT_STRTO_VER(strtold, SANITIZER_NLDBL_VERSION); +#else INTERCEPT_STRTO(strtold); +#endif INTERCEPT_STRTO(strtol); INTERCEPT_STRTO(strtoul); INTERCEPT_STRTO(strtoll); @@ -1762,7 +1818,11 @@ void InitializeInterceptors() { INTERCEPT_STRTO(strtouq); INTERCEPT_STRTO(wcstod); INTERCEPT_STRTO(wcstof); +#ifdef SANITIZER_NLDBL_VERSION + INTERCEPT_STRTO_VER(wcstold, SANITIZER_NLDBL_VERSION); +#else INTERCEPT_STRTO(wcstold); +#endif INTERCEPT_STRTO(wcstol); INTERCEPT_STRTO(wcstoul); INTERCEPT_STRTO(wcstoll); |