@@ -401,11 +401,25 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
401
401
__msan_unpoison (endptr, sizeof (*endptr)); \
402
402
return res;
403
403
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
+
404
412
#define INTERCEPTOR_STRTO (ret_type, func, char_type ) \
405
413
INTERCEPTOR (ret_type, func, const char_type *nptr, char_type **endptr) { \
406
414
INTERCEPTOR_STRTO_BODY (ret_type, func, nptr, endptr); \
407
415
}
408
416
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
+
409
423
#define INTERCEPTOR_STRTO_BASE (ret_type, func, char_type ) \
410
424
INTERCEPTOR (ret_type, func, const char_type *nptr, char_type **endptr, \
411
425
int base) { \
@@ -418,6 +432,12 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
418
432
INTERCEPTOR_STRTO_BODY (ret_type, func, nptr, endptr, loc); \
419
433
}
420
434
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
+
421
441
#define INTERCEPTOR_STRTO_BASE_LOC (ret_type, func, char_type ) \
422
442
INTERCEPTOR (ret_type, func, const char_type *nptr, char_type **endptr, \
423
443
int base, void *loc) { \
@@ -429,6 +449,10 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
429
449
INTERCEPTOR_STRTO (ret_type, func, char_type) \
430
450
INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)
431
451
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
+
432
456
#define INTERCEPTORS_STRTO_BASE (ret_type, func, char_type ) \
433
457
INTERCEPTOR_STRTO_BASE (ret_type, func, char_type) \
434
458
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) {
440
464
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
441
465
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
442
466
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
+
443
473
#define INTERCEPTORS_STRTO_BASE (ret_type, func, char_type ) \
444
474
INTERCEPTOR_STRTO_BASE (ret_type, func, char_type) \
445
475
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) {
449
479
450
480
INTERCEPTORS_STRTO (double , strtod, char )
451
481
INTERCEPTORS_STRTO(float , strtof, char )
482
+ #ifdef __s390x__
483
+ INTERCEPTORS_STRTO_SRET (long double , strtold, char )
484
+ #else
452
485
INTERCEPTORS_STRTO (long double , strtold, char )
486
+ #endif
453
487
INTERCEPTORS_STRTO_BASE (long , strtol, char )
454
488
INTERCEPTORS_STRTO_BASE(long long , strtoll, char )
455
489
INTERCEPTORS_STRTO_BASE(unsigned long , strtoul, char )
@@ -458,7 +492,11 @@ INTERCEPTORS_STRTO_BASE(u64, strtouq, char)
458
492
459
493
INTERCEPTORS_STRTO(double , wcstod, wchar_t )
460
494
INTERCEPTORS_STRTO(float , wcstof, wchar_t )
495
+ #ifdef __s390x__
496
+ INTERCEPTORS_STRTO_SRET (long double , wcstold, wchar_t )
497
+ #else
461
498
INTERCEPTORS_STRTO (long double , wcstold, wchar_t )
499
+ #endif
462
500
INTERCEPTORS_STRTO_BASE (long , wcstol, wchar_t )
463
501
INTERCEPTORS_STRTO_BASE(long long , wcstoll, wchar_t )
464
502
INTERCEPTORS_STRTO_BASE(unsigned long , wcstoul, wchar_t )
@@ -467,7 +505,11 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)
467
505
#if SANITIZER_GLIBC
468
506
INTERCEPTORS_STRTO (double , __isoc23_strtod, char )
469
507
INTERCEPTORS_STRTO(float , __isoc23_strtof, char )
508
+ #ifdef __s390x__
509
+ INTERCEPTORS_STRTO_SRET (long double , __isoc23_strtold, char )
510
+ #else
470
511
INTERCEPTORS_STRTO (long double , __isoc23_strtold, char )
512
+ #endif
471
513
INTERCEPTORS_STRTO_BASE (long , __isoc23_strtol, char )
472
514
INTERCEPTORS_STRTO_BASE(long long , __isoc23_strtoll, char )
473
515
INTERCEPTORS_STRTO_BASE(unsigned long , __isoc23_strtoul, char )
@@ -476,7 +518,11 @@ INTERCEPTORS_STRTO_BASE(u64, __isoc23_strtouq, char)
476
518
477
519
INTERCEPTORS_STRTO(double , __isoc23_wcstod, wchar_t )
478
520
INTERCEPTORS_STRTO(float , __isoc23_wcstof, wchar_t )
521
+ #ifdef __s390x__
522
+ INTERCEPTORS_STRTO_SRET (long double , __isoc23_wcstold, wchar_t )
523
+ #else
479
524
INTERCEPTORS_STRTO (long double , __isoc23_wcstold, wchar_t )
525
+ #endif
480
526
INTERCEPTORS_STRTO_BASE (long , __isoc23_wcstol, wchar_t )
481
527
INTERCEPTORS_STRTO_BASE(long long , __isoc23_wcstoll, wchar_t )
482
528
INTERCEPTORS_STRTO_BASE(unsigned long , __isoc23_wcstoul, wchar_t )
@@ -493,6 +539,12 @@ INTERCEPTORS_STRTO_BASE(unsigned long long, __isoc23_wcstoull, wchar_t)
493
539
INTERCEPT_FUNCTION (func##_l); \
494
540
INTERCEPT_FUNCTION (__##func##_l); \
495
541
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);
496
548
#endif
497
549
498
550
@@ -1754,15 +1806,23 @@ void InitializeInterceptors() {
1754
1806
INTERCEPT_FUNCTION (strncat);
1755
1807
INTERCEPT_STRTO (strtod);
1756
1808
INTERCEPT_STRTO (strtof);
1809
+ #ifdef SANITIZER_NLDBL_VERSION
1810
+ INTERCEPT_STRTO_VER (strtold, SANITIZER_NLDBL_VERSION);
1811
+ #else
1757
1812
INTERCEPT_STRTO (strtold);
1813
+ #endif
1758
1814
INTERCEPT_STRTO (strtol);
1759
1815
INTERCEPT_STRTO (strtoul);
1760
1816
INTERCEPT_STRTO (strtoll);
1761
1817
INTERCEPT_STRTO (strtoull);
1762
1818
INTERCEPT_STRTO (strtouq);
1763
1819
INTERCEPT_STRTO (wcstod);
1764
1820
INTERCEPT_STRTO (wcstof);
1821
+ #ifdef SANITIZER_NLDBL_VERSION
1822
+ INTERCEPT_STRTO_VER (wcstold, SANITIZER_NLDBL_VERSION);
1823
+ #else
1765
1824
INTERCEPT_STRTO (wcstold);
1825
+ #endif
1766
1826
INTERCEPT_STRTO (wcstol);
1767
1827
INTERCEPT_STRTO (wcstoul);
1768
1828
INTERCEPT_STRTO (wcstoll);
0 commit comments