From: jkummerow@chromium.org Date: Wed, 26 Mar 2014 10:01:53 +0000 (+0000) Subject: ASan support for the Zone X-Git-Tag: upstream/4.7.83~9998 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c6bff48f09008d36af9fd7718b893b2821c1cef9;p=platform%2Fupstream%2Fv8.git ASan support for the Zone R=jarin@chromium.org, kcc@google.com Review URL: https://codereview.chromium.org/208743004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20266 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/Makefile b/Makefile index f390028..cdf5d74 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= ifneq ($(strip $(arm_version)),) diff --git a/build/standalone.gypi b/build/standalone.gypi index 395ec4c..116cf8d 100644 --- a/build/standalone.gypi +++ b/build/standalone.gypi @@ -184,7 +184,10 @@ 'ldflags': [ '-fsanitize=address', ], - } + 'defines': [ + 'ADDRESS_SANITIZER', + ], + }, }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \ or OS=="netbsd"', { diff --git a/src/zone-inl.h b/src/zone-inl.h index f257382..9a5de34 100644 --- a/src/zone-inl.h +++ b/src/zone-inl.h @@ -30,6 +30,12 @@ #include "zone.h" +#ifdef ADDRESS_SANITIZER + #include +#else + #define ASAN_UNPOISON_MEMORY_REGION(start, size) ((void) 0) +#endif + #include "counters.h" #include "isolate.h" #include "utils.h" @@ -39,6 +45,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 +63,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 +91,7 @@ inline void* Zone::New(int size) { template T* Zone::NewArray(int length) { + CHECK(std::numeric_limits::max() / static_cast(sizeof(T)) > length); return static_cast(New(length * sizeof(T))); } diff --git a/src/zone.cc b/src/zone.cc index 417f895..4f91371 100644 --- a/src/zone.cc +++ b/src/zone.cc @@ -104,6 +104,8 @@ void Zone::DeleteAll() { } else { int size = current->size(); #ifdef DEBUG + // Un-poison first so the zapping doesn't trigger ASan complaints. + ASAN_UNPOISON_MEMORY_REGION(current, size); // Zap the entire current segment (including the header). memset(current, kZapDeadByte, size); #endif @@ -120,6 +122,8 @@ void Zone::DeleteAll() { Address start = keep->start(); position_ = RoundUp(start, kAlignment); limit_ = keep->end(); + // Un-poison so we can re-use the segment later. + ASAN_UNPOISON_MEMORY_REGION(start, keep->capacity()); #ifdef DEBUG // Zap the contents of the kept segment (but not the header). memset(start, kZapDeadByte, keep->capacity()); @@ -143,6 +147,8 @@ void Zone::DeleteKeptSegment() { if (segment_head_ != NULL) { int size = segment_head_->size(); #ifdef DEBUG + // Un-poison first so the zapping doesn't trigger ASan complaints. + ASAN_UNPOISON_MEMORY_REGION(segment_head_, size); // Zap the entire kept segment (including the header). memset(segment_head_, kZapDeadByte, size); #endif diff --git a/src/zone.h b/src/zone.h index bd7cc39..75224a6 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;