[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
This commit is contained in:
Eric Fiselier 2015-08-26 00:14:08 +00:00
parent 54ed7e18f2
commit 30130f2070
3 changed files with 36 additions and 1 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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