Reviewers: jarin,

Message:
Jaro: please take a look.

Kostya: FYI. Any comments?

Description:
ASan support for the Zone

Please review this at https://codereview.chromium.org/208743004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+55, -7 lines):
  M Makefile
  M build/standalone.gypi
  M src/zone-inl.h
  M src/zone.h
  M src/zone.cc


Index: Makefile
diff --git a/Makefile b/Makefile
index f3900286cbd33b5534e0b7d96a483a08a9a1dc74..cdf5d74832fa79bbdc4a5b4abde0faedc8cfa8e2 100644
--- a/Makefile
+++ b/Makefile
@@ -136,7 +136,16 @@ endif
 # deprecation_warnings=on
 ifeq ($(deprecationwarnings), on)
   GYPFLAGS += -Dv8_deprecation_warnings=1
-endif
+endif
+# asan=/path/to/clang++
+ifneq ($(strip $(asan)),)
+  GYPFLAGS += -Dasan=1
+  export CXX="$(asan)"
+  export CXX_host="$(asan)"
+  export LINK="$(asan)"
+  export ASAN_SYMBOLIZER_PATH="$(dir $(asan))llvm-symbolizer"
+endif
+
 # arm specific flags.
 # arm_version=<number | "default">
 ifneq ($(strip $(arm_version)),)
Index: build/standalone.gypi
diff --git a/build/standalone.gypi b/build/standalone.gypi
index 395ec4c733b3c7960c6f372b21baf71c4653cde7..628cfa235b7dbf09084cdeba342b3b3525686d71 100644
--- a/build/standalone.gypi
+++ b/build/standalone.gypi
@@ -184,6 +184,7 @@
         'ldflags': [
           '-fsanitize=address',
         ],
+        'defines': [ 'ADDRESS_SANITIZER' ],
       }
     }],
     ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
Index: src/zone-inl.h
diff --git a/src/zone-inl.h b/src/zone-inl.h
index f257382a2dba5b118cadb98e83c1da68b58ad27a..faf99e3d1fd88b8545db94b2fb1bfa0b57b6f390 100644
--- a/src/zone-inl.h
+++ b/src/zone-inl.h
@@ -30,6 +30,10 @@

 #include "zone.h"

+#ifdef ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif
+
 #include "counters.h"
 #include "isolate.h"
 #include "utils.h"
@@ -39,6 +43,9 @@ namespace v8 {
 namespace internal {


+static const int kASanRedzoneBytes = 24;  // Must be a multiple of 8.
+
+
 inline void* Zone::New(int size) {
   // Round up the requested size to fit the alignment.
   size = RoundUp(size, kAlignment);
@@ -54,12 +61,25 @@ inline void* Zone::New(int size) {
   // Check if the requested size is available without expanding.
   Address result = position_;

-  if (size > limit_ - position_) {
-     result = NewExpand(size);
+  int size_with_redzone =
+#ifdef ADDRESS_SANITIZER
+      size + kASanRedzoneBytes;
+#else
+      size;
+#endif
+
+  if (size_with_redzone > limit_ - position_) {
+     result = NewExpand(size_with_redzone);
   } else {
-     position_ += size;
+     position_ += size_with_redzone;
   }

+#ifdef ADDRESS_SANITIZER
+  Address redzone_position = result + size;
+  ASSERT(redzone_position + kASanRedzoneBytes == position_);
+  ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
+#endif
+
   // Check that the result has the proper alignment and return it.
   ASSERT(IsAddressAligned(result, kAlignment, 0));
   allocation_size_ += size;
@@ -69,6 +89,7 @@ inline void* Zone::New(int size) {

 template <typename T>
 T* Zone::NewArray(int length) {
+ CHECK(std::numeric_limits<int>::max() / static_cast<int>(sizeof(T)) > length);
   return static_cast<T*>(New(length * sizeof(T)));
 }

Index: src/zone.cc
diff --git a/src/zone.cc b/src/zone.cc
index 417f895e5ae29536cf29c4f7eb42344c57d55277..6e0c11d4596d19450c313f1598e5c03232c7e618 100644
--- a/src/zone.cc
+++ b/src/zone.cc
@@ -104,9 +104,13 @@ void Zone::DeleteAll() {
     } else {
       int size = current->size();
 #ifdef DEBUG
+#ifdef ADDRESS_SANITIZER
+      // Un-poison first so the zapping doesn't trigger ASan complaints.
+      ASAN_UNPOISON_MEMORY_REGION(current, size);
+#endif  // ADDRESS_SANITIZER
       // Zap the entire current segment (including the header).
       memset(current, kZapDeadByte, size);
-#endif
+#endif  // DEBUG
       DeleteSegment(current, size);
     }
     current = next;
@@ -120,6 +124,10 @@ void Zone::DeleteAll() {
     Address start = keep->start();
     position_ = RoundUp(start, kAlignment);
     limit_ = keep->end();
+#ifdef ADDRESS_SANITIZER
+    // Un-poison so we can re-use the segment later.
+    ASAN_UNPOISON_MEMORY_REGION(start, keep->capacity());
+#endif
 #ifdef DEBUG
     // Zap the contents of the kept segment (but not the header).
     memset(start, kZapDeadByte, keep->capacity());
@@ -143,9 +151,13 @@ void Zone::DeleteKeptSegment() {
   if (segment_head_ != NULL) {
     int size = segment_head_->size();
 #ifdef DEBUG
+#ifdef ADDRESS_SANITIZER
+    // Un-poison first so the zapping doesn't trigger ASan complaints.
+    ASAN_UNPOISON_MEMORY_REGION(segment_head_, size);
+#endif  // ADDRESS_SANITIZER
     // Zap the entire kept segment (including the header).
     memset(segment_head_, kZapDeadByte, size);
-#endif
+#endif  // DEBUG
     DeleteSegment(segment_head_, size);
     segment_head_ = NULL;
   }
Index: src/zone.h
diff --git a/src/zone.h b/src/zone.h
index bd7cc39b0c4f224b0646792fbd8ed262fdc5f986..75224a6ac8b177b2e14cbc032ae4897d0a7c6fed 100644
--- a/src/zone.h
+++ b/src/zone.h
@@ -89,8 +89,13 @@ class Zone {

// All pointers returned from New() have this alignment. In addition, if the // object being allocated has a size that is divisible by 8 then its alignment
-  // will be 8.
+  // will be 8. ASan requires 8-byte alignment.
+#ifdef ADDRESS_SANITIZER
+  static const int kAlignment = 8;
+  STATIC_ASSERT(kPointerSize <= 8);
+#else
   static const int kAlignment = kPointerSize;
+#endif

   // Never allocate segments smaller than this size in bytes.
   static const int kMinimumSegmentSize = 8 * KB;


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to