Skip to content

Commit 208f9a2

Browse files
committed
[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
1 parent 6081d33 commit 208f9a2

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

compiler-rt/lib/msan/msan_interceptors.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,25 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
401401
__msan_unpoison(endptr, sizeof(*endptr)); \
402402
return res;
403403

404+
// On s390x, long double return values are passed via implicit reference,
405+
// which needs to be unpoisoned. We make the implicit pointer explicit.
406+
#define INTERCEPTOR_STRTO_SRET_BODY(func, sret, ...) \
407+
ENSURE_MSAN_INITED(); \
408+
REAL(func)(sret, __VA_ARGS__); \
409+
__msan_unpoison(sret, sizeof(*sret)); \
410+
__msan_unpoison(endptr, sizeof(*endptr));
411+
404412
#define INTERCEPTOR_STRTO(ret_type, func, char_type) \
405413
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \
406414
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \
407415
}
408416

417+
#define INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \
418+
INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \
419+
char_type **endptr) { \
420+
INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr); \
421+
}
422+
409423
#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
410424
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
411425
int base) { \
@@ -418,6 +432,12 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
418432
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \
419433
}
420434

435+
#define INTERCEPTOR_STRTO_SRET_LOC(ret_type, func, char_type) \
436+
INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \
437+
char_type **endptr, void *loc) { \
438+
INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr, loc); \
439+
}
440+
421441
#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \
422442
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
423443
int base, void *loc) { \
@@ -429,6 +449,10 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
429449
INTERCEPTOR_STRTO(ret_type, func, char_type) \
430450
INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)
431451

452+
#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \
453+
INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \
454+
INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type)
455+
432456
#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
433457
INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
434458
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) {
440464
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
441465
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
442466

467+
#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \
468+
INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \
469+
INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type) \
470+
INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_l, char_type) \
471+
INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_internal, char_type)
472+
443473
#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
444474
INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
445475
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) {
449479

450480
INTERCEPTORS_STRTO(double, strtod, char)
451481
INTERCEPTORS_STRTO(float, strtof, char)
482+
#ifdef __s390x__
483+
INTERCEPTORS_STRTO_SRET(long double, strtold, char)
484+
#else
452485
INTERCEPTORS_STRTO(long double, strtold, char)
486+
#endif
453487
INTERCEPTORS_STRTO_BASE(long, strtol, char)
454488
INTERCEPTORS_STRTO_BASE(long long, strtoll, char)
455489
INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)
@@ -458,7 +492,11 @@ INTERCEPTORS_STRTO_BASE(u64, strtouq, char)
458492

459493
INTERCEPTORS_STRTO(double, wcstod, wchar_t)
460494
INTERCEPTORS_STRTO(float, wcstof, wchar_t)
495+
#ifdef __s390x__
496+
INTERCEPTORS_STRTO_SRET(long double, wcstold, wchar_t)
497+
#else
461498
INTERCEPTORS_STRTO(long double, wcstold, wchar_t)
499+
#endif
462500
INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)
463501
INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)
464502
INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)
@@ -467,7 +505,11 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)
467505
#if SANITIZER_GLIBC
468506
INTERCEPTORS_STRTO(double, __isoc23_strtod, char)
469507
INTERCEPTORS_STRTO(float, __isoc23_strtof, char)
508+
#ifdef __s390x__
509+
INTERCEPTORS_STRTO_SRET(long double, __isoc23_strtold, char)
510+
#else
470511
INTERCEPTORS_STRTO(long double, __isoc23_strtold, char)
512+
#endif
471513
INTERCEPTORS_STRTO_BASE(long, __isoc23_strtol, char)
472514
INTERCEPTORS_STRTO_BASE(long long, __isoc23_strtoll, char)
473515
INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_strtoul, char)
@@ -476,7 +518,11 @@ INTERCEPTORS_STRTO_BASE(u64, __isoc23_strtouq, char)
476518

477519
INTERCEPTORS_STRTO(double, __isoc23_wcstod, wchar_t)
478520
INTERCEPTORS_STRTO(float, __isoc23_wcstof, wchar_t)
521+
#ifdef __s390x__
522+
INTERCEPTORS_STRTO_SRET(long double, __isoc23_wcstold, wchar_t)
523+
#else
479524
INTERCEPTORS_STRTO(long double, __isoc23_wcstold, wchar_t)
525+
#endif
480526
INTERCEPTORS_STRTO_BASE(long, __isoc23_wcstol, wchar_t)
481527
INTERCEPTORS_STRTO_BASE(long long, __isoc23_wcstoll, wchar_t)
482528
INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_wcstoul, wchar_t)
@@ -493,6 +539,12 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, __isoc23_wcstoull, wchar_t)
493539
INTERCEPT_FUNCTION(func##_l); \
494540
INTERCEPT_FUNCTION(__##func##_l); \
495541
INTERCEPT_FUNCTION(__##func##_internal);
542+
543+
#define INTERCEPT_STRTO_VER(func, ver) \
544+
INTERCEPT_FUNCTION_VER(func, ver); \
545+
INTERCEPT_FUNCTION_VER(func##_l, ver); \
546+
INTERCEPT_FUNCTION_VER(__##func##_l, ver); \
547+
INTERCEPT_FUNCTION_VER(__##func##_internal, ver);
496548
#endif
497549

498550

@@ -1754,15 +1806,23 @@ void InitializeInterceptors() {
17541806
INTERCEPT_FUNCTION(strncat);
17551807
INTERCEPT_STRTO(strtod);
17561808
INTERCEPT_STRTO(strtof);
1809+
#ifdef SANITIZER_NLDBL_VERSION
1810+
INTERCEPT_STRTO_VER(strtold, SANITIZER_NLDBL_VERSION);
1811+
#else
17571812
INTERCEPT_STRTO(strtold);
1813+
#endif
17581814
INTERCEPT_STRTO(strtol);
17591815
INTERCEPT_STRTO(strtoul);
17601816
INTERCEPT_STRTO(strtoll);
17611817
INTERCEPT_STRTO(strtoull);
17621818
INTERCEPT_STRTO(strtouq);
17631819
INTERCEPT_STRTO(wcstod);
17641820
INTERCEPT_STRTO(wcstof);
1821+
#ifdef SANITIZER_NLDBL_VERSION
1822+
INTERCEPT_STRTO_VER(wcstold, SANITIZER_NLDBL_VERSION);
1823+
#else
17651824
INTERCEPT_STRTO(wcstold);
1825+
#endif
17661826
INTERCEPT_STRTO(wcstol);
17671827
INTERCEPT_STRTO(wcstoul);
17681828
INTERCEPT_STRTO(wcstoll);

0 commit comments

Comments
 (0)