diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -401,11 +401,25 @@ __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_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_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_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 @@ 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(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 @@ #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(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 @@ 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 @@ 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 @@ 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);