[sanitizer] Fix dirent interceptors.

The new version reads d_reclen for (struct dirent) size.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@185067 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index f476e1c..28994f8 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1269,16 +1269,16 @@
 #endif
 
 #if SANITIZER_INTERCEPT_READDIR
-INTERCEPTOR(void *, readdir, void *dirp) {
+INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
-  void *res = REAL(readdir)(dirp);
+  __sanitizer_dirent *res = REAL(readdir)(dirp);
   if (res)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_dirent_sz);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   return res;
 }
 
-INTERCEPTOR(int, readdir_r, void *dirp, void *entry, void **result) {
+INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, __sanitizer_dirent **result) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
   int res = REAL(readdir_r)(dirp, entry, result);
@@ -1286,7 +1286,7 @@
     if (result)
       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
     if (entry)
-      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, struct_dirent_sz);
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
   }
   return res;
 }
@@ -1299,16 +1299,16 @@
 #endif
 
 #if SANITIZER_INTERCEPT_READDIR64
-INTERCEPTOR(void *, readdir64, void *dirp) {
+INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
-  void *res = REAL(readdir64)(dirp);
+  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
   if (res)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_dirent64_sz);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   return res;
 }
 
-INTERCEPTOR(int, readdir64_r, void *dirp, void *entry, void **result) {
+INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, __sanitizer_dirent64 **result) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
   int res = REAL(readdir64_r)(dirp, entry, result);
@@ -1316,7 +1316,7 @@
     if (result)
       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
     if (entry)
-      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, struct_dirent64_sz);
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
   }
   return res;
 }
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 79e89bb..7f26940 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -94,7 +94,6 @@
 #endif
 
 namespace __sanitizer {
-  unsigned struct_dirent_sz = sizeof(struct dirent);
   unsigned struct_utsname_sz = sizeof(struct utsname);
   unsigned struct_stat_sz = sizeof(struct stat);
   unsigned struct_stat64_sz = sizeof(struct stat64);
@@ -123,7 +122,6 @@
 #endif // SANITIZER_LINUX
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
-  unsigned struct_dirent64_sz = sizeof(struct dirent64);
   unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
   unsigned struct_statfs64_sz = sizeof(struct statfs64);
 #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -743,6 +741,12 @@
 CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
 CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
 
+CHECK_SIZE_AND_OFFSET(dirent, d_ino);
+#ifndef SANITIZER_MAC
+CHECK_SIZE_AND_OFFSET(dirent, d_off);
+#endif
+CHECK_SIZE_AND_OFFSET(dirent, d_reclen);
+
 CHECK_TYPE_SIZE(ifconf);
 CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
 CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 6e4c655..576e535 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -18,7 +18,6 @@
 #include "sanitizer_platform.h"
 
 namespace __sanitizer {
-  extern unsigned struct_dirent_sz;
   extern unsigned struct_utsname_sz;
   extern unsigned struct_stat_sz;
   extern unsigned struct_stat64_sz;
@@ -47,7 +46,6 @@
 #endif // SANITIZER_LINUX
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
-  extern unsigned struct_dirent64_sz;
   extern unsigned struct_rlimit64_sz;
   extern unsigned struct_statfs64_sz;
 #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -89,6 +87,37 @@
   };
 #endif
 
+#if SANITIZER_MAC
+  struct __sanitizer_dirent {
+    unsigned d_ino;
+    unsigned short d_reclen;
+    // more fields that we don't care about
+  };
+#elif SANITIZER_ANDROID
+  struct __sanitizer_dirent {
+    unsigned long long d_ino;
+    unsigned long long d_off;
+    unsigned short d_reclen;
+    // more fields that we don't care about
+  };
+#else
+  struct __sanitizer_dirent {
+    uptr d_ino;
+    uptr d_off;
+    unsigned short d_reclen;
+    // more fields that we don't care about
+  };
+#endif
+
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
+  struct __sanitizer_dirent64 {
+    uptr d_ino;
+    uptr d_off;
+    unsigned short d_reclen;
+    // more fields that we don't care about
+  };
+#endif
+
   // This thing depends on the platform. We are only interested in the upper
   // limit. Verified with a compiler assert in .cc.
   const int pthread_attr_t_max_sz = 128;