[sanitizer] Intercept mbtowc, mbrtowc, get_current_dir_name.

Move getcwd to common interceptors.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@185424 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 04764b5..720c635 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -405,6 +405,20 @@
   return res;
 }
 
+INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
+  ENSURE_MSAN_INITED();
+  int res = REAL(mbtowc)(dest, src, n);
+  if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
+  return res;
+}
+
+INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
+  ENSURE_MSAN_INITED();
+  SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
+  if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
+  return res;
+}
+
 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
   ENSURE_MSAN_INITED();
   SIZE_T res = REAL(wcslen)(s);
@@ -605,14 +619,6 @@
   return res;
 }
 
-INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
-  ENSURE_MSAN_INITED();
-  char *res = REAL(getcwd)(buf, size);
-  if (res)
-    __msan_unpoison(res, REAL(strlen)(res) + 1);
-  return res;
-}
-
 INTERCEPTOR(char *, realpath, char *path, char *abspath) {
   ENSURE_MSAN_INITED();
   char *res = REAL(realpath)(path, abspath);
@@ -1172,6 +1178,8 @@
   INTERCEPT_FUNCTION(strftime);
   INTERCEPT_FUNCTION(wcstombs);
   INTERCEPT_FUNCTION(mbstowcs);
+  INTERCEPT_FUNCTION(mbtowc);
+  INTERCEPT_FUNCTION(mbrtowc);
   INTERCEPT_FUNCTION(wcslen);
   INTERCEPT_FUNCTION(wcschr);
   INTERCEPT_FUNCTION(wcscpy);
@@ -1191,7 +1199,6 @@
   INTERCEPT_FUNCTION(socketpair);
   INTERCEPT_FUNCTION(fgets);
   INTERCEPT_FUNCTION(fgets_unlocked);
-  INTERCEPT_FUNCTION(getcwd);
   INTERCEPT_FUNCTION(realpath);
   INTERCEPT_FUNCTION(getrlimit);
   INTERCEPT_FUNCTION(getrlimit64);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 0af2f57..dd869f8 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -904,6 +904,13 @@
   free(res);
 }
 
+TEST(MemorySanitizer, get_current_dir_name) {
+  char* res = get_current_dir_name();
+  assert(res);
+  EXPECT_NOT_POISONED(res[0]);
+  free(res);
+}
+
 TEST(MemorySanitizer, readdir) {
   DIR *dir = opendir(".");
   struct dirent *d = readdir(dir);
@@ -1173,6 +1180,24 @@
   EXPECT_EQ(buff[2], 'c');
 }
 
+TEST(MemorySanitizer, mbtowc) {
+  const char *x = "abc";
+  wchar_t wx;
+  int res = mbtowc(&wx, x, 3);
+  EXPECT_GT(res, 0);
+  EXPECT_NOT_POISONED(wx);
+}
+
+TEST(MemorySanitizer, mbrtowc) {
+  const char *x = "abc";
+  wchar_t wx;
+  mbstate_t mbs;
+  memset(&mbs, 0, sizeof(mbs));
+  int res = mbrtowc(&wx, x, 3, &mbs);
+  EXPECT_GT(res, 0);
+  EXPECT_NOT_POISONED(wx);
+}
+
 TEST(MemorySanitizer, gettimeofday) {
   struct timeval tv;
   struct timezone tz;
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 7d39e29..867e998 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1405,7 +1405,7 @@
   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
   if (locale)
     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
-  char * res = REAL(setlocale)(category, locale);
+  char *res = REAL(setlocale)(category, locale);
   if (res)
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   return res;
@@ -1417,6 +1417,36 @@
 #define INIT_SETLOCALE
 #endif
 
+#if SANITIZER_INTERCEPT_GETCWD
+INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
+  char *res = REAL(getcwd)(buf, size);
+  if (res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+  return res;
+}
+#define INIT_GETCWD           \
+  INTERCEPT_FUNCTION(getcwd);
+#else
+#define INIT_GETCWD
+#endif
+
+#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
+INTERCEPTOR(char *, get_current_dir_name) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name);
+  char *res = REAL(get_current_dir_name)();
+  if (res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+  return res;
+}
+
+#define INIT_GET_CURRENT_DIR_NAME           \
+  INTERCEPT_FUNCTION(get_current_dir_name);
+#else
+#define INIT_GET_CURRENT_DIR_NAME
+#endif
 
 #define SANITIZER_COMMON_INTERCEPTORS_INIT \
   INIT_STRCASECMP;                         \
@@ -1464,4 +1494,6 @@
   INIT_READDIR;                            \
   INIT_READDIR64;                          \
   INIT_PTRACE;                             \
-  INIT_SETLOCALE;
+  INIT_SETLOCALE;                          \
+  INIT_GETCWD;                             \
+  INIT_GET_CURRENT_DIR_NAME;
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index b749a62..5d82dd1 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -97,5 +97,7 @@
 # define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID
 # define SANITIZER_INTERCEPT_PTRACE SI_LINUX_NOT_ANDROID
 # define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index 01ca2d3..5982180 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -338,6 +338,8 @@
   name[StatInt_readdir64_r]              = "  readdir64_r                     ";
   name[StatInt_ptrace]                   = "  ptrace                          ";
   name[StatInt_setlocale]                = "  setlocale                       ";
+  name[StatInt_getcwd]                   = "  getcwd                          ";
+  name[StatInt_get_current_dir_name]     = "  get_current_dir_name            ";
 
   name[StatAnnotation]                   = "Dynamic annotations               ";
   name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index a67e457..1bef6e9 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -333,6 +333,8 @@
   StatInt_readdir64_r,
   StatInt_ptrace,
   StatInt_setlocale,
+  StatInt_getcwd,
+  StatInt_get_current_dir_name,
 
   // Dynamic annotations.
   StatAnnotation,