[Sanitizer] extend internal libc with stat/fstat/lstat functions
authorAlexey Samsonov <samsonov@google.com>
Mon, 4 Feb 2013 10:16:50 +0000 (10:16 +0000)
committerAlexey Samsonov <samsonov@google.com>
Mon, 4 Feb 2013 10:16:50 +0000 (10:16 +0000)
llvm-svn: 174316

compiler-rt/lib/sanitizer_common/sanitizer_libc.h
compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/lib/sanitizer_common/sanitizer_mac.cc
compiler-rt/lib/sanitizer_common/sanitizer_win.cc
compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc
compiler-rt/lib/tsan/tests/unit/tsan_platform_test.cc

index 911f5af3a4c30e36abb5f10184b41614c5a7ab8f..6bdca3c9b16283ccece7563416c2ff351677a685 100644 (file)
@@ -71,6 +71,10 @@ fd_t internal_open(const char *filename, int flags, u32 mode);
 uptr internal_read(fd_t fd, void *buf, uptr count);
 uptr internal_write(fd_t fd, const void *buf, uptr count);
 uptr internal_filesize(fd_t fd);  // -1 on error.
+int internal_stat(const char *path, void *buf);
+int internal_lstat(const char *path, void *buf);
+int internal_fstat(fd_t fd, void *buf);
+
 int internal_dup2(int oldfd, int newfd);
 uptr internal_readlink(const char *path, char *buf, uptr bufsize);
 int internal_snprintf(char *buffer, uptr length, const char *format, ...);
index f5edbf01a27fcd7859ee23b250315eda60c2bc88..70f330aa9b3d27ca5c2f9654ddc09f2aa256fea1 100644 (file)
@@ -93,16 +93,38 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
   return res;
 }
 
+int internal_stat(const char *path, void *buf) {
+#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+  return syscall(__NR_stat, path, buf);
+#else
+  return syscall(__NR_stat64, path, buf);
+#endif
+}
+
+int internal_lstat(const char *path, void *buf) {
+#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+  return syscall(__NR_lstat, path, buf);
+#else
+  return syscall(__NR_lstat64, path, buf);
+#endif
+}
+
+int internal_fstat(fd_t fd, void *buf) {
+#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+  return syscall(__NR_fstat, fd, buf);
+#else
+  return syscall(__NR_fstat64, fd, buf);
+#endif
+}
+
 uptr internal_filesize(fd_t fd) {
 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   struct stat st;
-  if (syscall(__NR_fstat, fd, &st))
-    return -1;
 #else
   struct stat64 st;
-  if (syscall(__NR_fstat64, fd, &st))
-    return -1;
 #endif
+  if (internal_fstat(fd, &st))
+    return -1;
   return (uptr)st.st_size;
 }
 
index a7bde0309655d2ef625daaa8a70f8e20ea2d2642..1bd50ca1d0601414334afe2e8e7d148eff4dd25f 100644 (file)
@@ -69,9 +69,21 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
   return write(fd, buf, count);
 }
 
+int internal_stat(const char *path, void *buf) {
+  return stat(path, buf);
+}
+
+int internal_lstat(const char *path, void *buf) {
+  return lstat(path, buf);
+}
+
+int internal_fstat(fd_t fd, void *buf) {
+  return fstat(fd, buf);
+}
+
 uptr internal_filesize(fd_t fd) {
   struct stat st;
-  if (fstat(fd, &st))
+  if (internal_fstat(fd, &st))
     return -1;
   return (uptr)st.st_size;
 }
index 28bf8dbf1c52b0bad1214ebba2124d24fff82942..c91d5e30f7e9dca36edccbb51fd19b45a8be711a 100644 (file)
@@ -219,6 +219,18 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
   return ret;
 }
 
+int internal_stat(const char *path, void *buf) {
+  UNIMPLEMENTED();
+}
+
+int internal_lstat(const char *path, void *buf) {
+  UNIMPLEMENTED();
+}
+
+int internal_fstat(fd_t fd, void *buf) {
+  UNIMPLEMENTED();
+}
+
 uptr internal_filesize(fd_t fd) {
   UNIMPLEMENTED();
 }
index b9d8414e0cbf9d21da0181add91a834c1be7fa38..6616f42232ff6bdb0f45fcd220b2f0d0796921ee 100644 (file)
@@ -9,9 +9,17 @@
 // Tests for sanitizer_libc.h.
 //===----------------------------------------------------------------------===//
 
+#include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "gtest/gtest.h"
 
+#if defined(__linux__) || defined(__APPLE__)
+# define SANITIZER_TEST_HAS_STAT_H 1
+# include <sys/stat.h>
+#else
+# define SANITIZER_TEST_HAS_STAT_H 0
+#endif
+
 // A regression test for internal_memmove() implementation.
 TEST(SanitizerCommon, InternalMemmoveRegression) {
   char src[] = "Hello World";
@@ -40,3 +48,39 @@ TEST(SanitizerCommon, mem_is_zero) {
   }
   delete [] x;
 }
+
+TEST(SanitizerCommon, FileOps) {
+  const char *str1 = "qwerty";
+  uptr len1 = internal_strlen(str1);
+  const char *str2 = "zxcv";
+  uptr len2 = internal_strlen(str2);
+
+  const char kTempFileName[] = "/tmp/sanitizer_common.tmp";
+  fd_t fd = OpenFile(kTempFileName, true);
+  EXPECT_NE(fd, kInvalidFd);
+  EXPECT_EQ(len1, internal_write(fd, str1, len1));
+  EXPECT_EQ(len2, internal_write(fd, str2, len2));
+  internal_close(fd);
+
+  fd = OpenFile(kTempFileName, false);
+  EXPECT_NE(fd, kInvalidFd);
+  uptr fsize = internal_filesize(fd);
+  EXPECT_EQ(len1 + len2, fsize);
+
+#if SANITIZER_TEST_HAS_STAT_H
+  struct stat st1, st2, st3;
+  EXPECT_EQ(0, internal_stat(kTempFileName, &st1));
+  EXPECT_EQ(0, internal_lstat(kTempFileName, &st2));
+  EXPECT_EQ(0, internal_fstat(fd, &st3));
+  EXPECT_EQ(fsize, (uptr)st3.st_size);
+#endif
+
+  char buf[64] = {};
+  EXPECT_EQ(len1, internal_read(fd, buf, len1));
+  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
+  EXPECT_EQ((char)0, buf[len1 + 1]);
+  internal_memset(buf, 0, len1);
+  EXPECT_EQ(len2, internal_read(fd, buf, len2));
+  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
+  internal_close(fd);
+}
index d47a325667ea0ca2bec80696adc917f300d61b25..733cc54d3e99111ec9270d34f2e9f142b25ec563 100644 (file)
@@ -61,29 +61,4 @@ TEST(Platform, ThreadInfoWorker) {
   pthread_join(t, 0);
 }
 
-TEST(Platform, FileOps) {
-  const char *str1 = "qwerty";
-  uptr len1 = internal_strlen(str1);
-  const char *str2 = "zxcv";
-  uptr len2 = internal_strlen(str2);
-
-  fd_t fd = OpenFile("./tsan_test.tmp", true);
-  EXPECT_NE(fd, kInvalidFd);
-  EXPECT_EQ(len1, internal_write(fd, str1, len1));
-  EXPECT_EQ(len2, internal_write(fd, str2, len2));
-  internal_close(fd);
-
-  fd = OpenFile("./tsan_test.tmp", false);
-  EXPECT_NE(fd, kInvalidFd);
-  EXPECT_EQ(len1 + len2, internal_filesize(fd));
-  char buf[64] = {};
-  EXPECT_EQ(len1, internal_read(fd, buf, len1));
-  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
-  EXPECT_EQ((char)0, buf[len1 + 1]);
-  internal_memset(buf, 0, len1);
-  EXPECT_EQ(len2, internal_read(fd, buf, len2));
-  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
-  internal_close(fd);
-}
-
 }  // namespace __tsan