diff options
| author | Eric Fiselier <eric@efcs.ca> | 2015-08-26 00:14:08 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2015-08-26 00:14:08 +0000 |
| commit | 30130f20709761a7bd8cfd3ae9d77ec985fe9b1d (patch) | |
| tree | 14d2b0f13ec7dc83ce19fb506fc282feafb56dd5 | |
| parent | 54ed7e18f2b139d71888e4353d30374480f726ed (diff) | |
| download | bcm5719-llvm-30130f20709761a7bd8cfd3ae9d77ec985fe9b1d.tar.gz bcm5719-llvm-30130f20709761a7bd8cfd3ae9d77ec985fe9b1d.zip | |
[compiler-rt] Add common interceptor for wcrtomb.
Summary: Currently there is a libc++ test failing under MSAN because wcrtomb is not intercepted. This patch adds an interceptor for it.
Reviewers: samsonov, eugenis
Subscribers: tberghammer, danalbert, srhines, llvm-commits
Differential Revision: http://reviews.llvm.org/D12311
llvm-svn: 245994
3 files changed, 36 insertions, 1 deletions
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index 00dd20a3d77..57938329d27 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -1952,6 +1952,16 @@ TEST(MemorySanitizer, wcsnrtombs) { EXPECT_POISONED(buff[2]); } +TEST(MemorySanitizer, wcrtomb) { + wchar_t x = L'a'; + char buff[10]; + mbstate_t mbs; + memset(&mbs, 0, sizeof(mbs)); + size_t res = wcrtomb(buff, x, &mbs); + EXPECT_EQ(res, (size_t)1); + EXPECT_EQ(buff[0], 'a'); +} + TEST(MemorySanitizer, wmemset) { wchar_t x[25]; break_optimization(x); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index da3fec17130..ec2863b98f2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2717,7 +2717,7 @@ INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, // its metadata. See // https://code.google.com/p/address-sanitizer/issues/detail?id=321. SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); - if (res != (SIZE_T) - 1 && dest && src) { + if (res != ((SIZE_T)-1) && dest && src) { SIZE_T write_cnt = res + !*src; COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); } @@ -2729,6 +2729,28 @@ INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, #define INIT_WCSNRTOMBS #endif + +#if SANITIZER_INTERCEPT_WCRTOMB +INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps); + if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://code.google.com/p/address-sanitizer/issues/detail?id=321. + SIZE_T res = REAL(wcrtomb)(dest, src, ps); + if (res != ((SIZE_T)-1) && dest) { + SIZE_T write_cnt = res; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); + } + return res; +} + +#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb); +#else +#define INIT_WCRTOMB +#endif + #if SANITIZER_INTERCEPT_TCGETATTR INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { void *ctx; @@ -5160,6 +5182,7 @@ static void InitializeCommonInterceptors() { INIT_MBSNRTOWCS; INIT_WCSTOMBS; INIT_WCSNRTOMBS; + INIT_WCRTOMB; INIT_TCGETATTR; INIT_REALPATH; INIT_CANONICALIZE_FILE_NAME; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index a666b252827..551b40ced16 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -143,6 +143,8 @@ #define SANITIZER_INTERCEPT_WCSTOMBS SI_NOT_WINDOWS #define SANITIZER_INTERCEPT_WCSNRTOMBS \ SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_WCRTOMB \ + SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_REALPATH SI_NOT_WINDOWS #define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME SI_LINUX_NOT_ANDROID |

