diff options
author | Mikhail Kashkarov <m.kashkarov@partner.samsung.com> | 2019-06-28 21:31:32 +0300 |
---|---|---|
committer | Dongkyun Son <dongkyun.s@samsung.com> | 2019-07-22 12:16:35 +0000 |
commit | d0abe09c4a743e0176d949ca4e10186369b51498 (patch) | |
tree | 813998f197ff82df47d8de3b33ffd61d7b55e734 | |
parent | 1f34038093e95f5e302bf8f010e3efec921c69d5 (diff) | |
download | linaro-gcc-d0abe09c4a743e0176d949ca4e10186369b51498.tar.gz linaro-gcc-d0abe09c4a743e0176d949ca4e10186369b51498.tar.bz2 linaro-gcc-d0abe09c4a743e0176d949ca4e10186369b51498.zip |
Enable build-tunable asan shadow scale size
Use the following for the project config (3 is default):
%define asan_shadow_scale 3
Macros:
asan_shadow_scale 3
:Macros
+ backport https://reviews.llvm.org/D39471 for x86_64 shadow offset
+ backport https://reviews.llvm.org/D39472 for minimum redzone size
+ backport https://reviews.llvm.org/D39473 for internal alloc min alignment
+ backport https://reviews.llvm.org/D39474 to avoid assert failure for non-default shadow scale
Change-Id: I23b231f03d6ab47c6b4264f8c7837eb1197f4cc4
-rw-r--r-- | gcc/asan.h | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 15 | ||||
-rw-r--r-- | libsanitizer/asan/asan_activation.cc | 7 | ||||
-rw-r--r-- | libsanitizer/asan/asan_fake_stack.cc | 4 | ||||
-rw-r--r-- | libsanitizer/asan/asan_flags.cc | 4 | ||||
-rw-r--r-- | libsanitizer/asan/asan_mapping.h | 7 | ||||
-rw-r--r-- | libsanitizer/asan/asan_rtl.cc | 1 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_allocator.cc | 9 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_common.h | 2 | ||||
-rw-r--r-- | packaging/gcc-aarch64.spec | 1 | ||||
-rw-r--r-- | packaging/gcc-armv7hl.spec | 1 | ||||
-rw-r--r-- | packaging/gcc-armv7l.spec | 1 | ||||
-rw-r--r-- | packaging/linaro-gcc.spec | 1 |
13 files changed, 48 insertions, 9 deletions
diff --git a/gcc/asan.h b/gcc/asan.h index 511da9a5bbc..66f7e901a5a 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -43,7 +43,11 @@ extern hash_set <tree> *asan_used_labels; /* Shadow memory is found at (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset (). */ +#if defined(ASAN_SHADOW_SCALE) +#define ASAN_SHADOW_SHIFT ASAN_SHADOW_SCALE +#else #define ASAN_SHADOW_SHIFT 3 +#endif #define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT) /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 898c2470895..bd043c4c79a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "dojump.h" #include "fold-const-call.h" #include "tree-ssanames.h" +#include "asan.h" /* This file should be included last. */ #include "target-def.h" @@ -7374,12 +7375,20 @@ ix86_legitimate_combined_insn (rtx_insn *insn) /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ +#if !defined(TARGET_MACHO) && !defined(ASAN_SHADOW_SHIFT) +# error ASAN_SHADOW_SHIFT is not defined +#endif + +static const unsigned HOST_WIDE_INT asan_short_64bit_shadow_offset = + 0x7FFFFFFF & (~0xFFFULL << ASAN_SHADOW_SHIFT); + static unsigned HOST_WIDE_INT ix86_asan_shadow_offset (void) { - return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44) - : HOST_WIDE_INT_C (0x7fff8000)) - : (HOST_WIDE_INT_1 << 29); + return TARGET_LP64 + ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44) + : asan_short_64bit_shadow_offset) + : (HOST_WIDE_INT_1 << 29); } /* Argument support functions. */ diff --git a/libsanitizer/asan/asan_activation.cc b/libsanitizer/asan/asan_activation.cc index 26798e7103b..0c0ae095cb8 100644 --- a/libsanitizer/asan/asan_activation.cc +++ b/libsanitizer/asan/asan_activation.cc @@ -14,8 +14,10 @@ #include "asan_allocator.h" #include "asan_flags.h" #include "asan_internal.h" +#include "asan_mapping.h" #include "asan_poisoning.h" #include "asan_stack.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" namespace __asan { @@ -107,8 +109,9 @@ void AsanDeactivate() { AllocatorOptions disabled = asan_deactivated_flags.allocator_options; disabled.quarantine_size_mb = 0; - disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. - disabled.max_redzone = 16; + // Redzone must be at least Max(16, granularity) bytes long. + disabled.min_redzone = Max(16, (int)SHADOW_GRANULARITY); + disabled.max_redzone = disabled.min_redzone; disabled.alloc_dealloc_mismatch = false; disabled.may_return_null = true; ReInitializeAllocator(disabled); diff --git a/libsanitizer/asan/asan_fake_stack.cc b/libsanitizer/asan/asan_fake_stack.cc index bf7566a334e..a2e3f4ecc90 100644 --- a/libsanitizer/asan/asan_fake_stack.cc +++ b/libsanitizer/asan/asan_fake_stack.cc @@ -26,9 +26,9 @@ static const u64 kAllocaRedzoneMask = 31UL; // For small size classes inline PoisonShadow for better performance. ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { - CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3. u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr)); - if (class_id <= 6) { + if (SHADOW_SCALE == 3 && class_id <= 6) { + // This code expects SHADOW_SCALE=3. for (uptr i = 0; i < (((uptr)1) << class_id); i++) { shadow[i] = magic; // Make sure this does not become memset. diff --git a/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cc index 39473bba64d..66398412ed0 100644 --- a/libsanitizer/asan/asan_flags.cc +++ b/libsanitizer/asan/asan_flags.cc @@ -13,6 +13,7 @@ #include "asan_activation.h" #include "asan_flags.h" #include "asan_interface_internal.h" +#include "asan_mapping.h" #include "asan_stack.h" #include "lsan/lsan_common.h" #include "sanitizer_common/sanitizer_common.h" @@ -133,6 +134,9 @@ void InitializeFlags() { SanitizerToolName); Die(); } + // Ensure that redzone is at least SHADOW_GRANULARITY. + if (f->redzone < (int)SHADOW_GRANULARITY) + f->redzone = SHADOW_GRANULARITY; // Make "strict_init_order" imply "check_initialization_order". // TODO(samsonov): Use a single runtime flag for an init-order checker. if (f->strict_init_order) { diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index b9fa5f79481..040cde68ae4 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -122,11 +122,16 @@ // || `[0x30000000, 0x35ffffff]` || LowShadow || // || `[0x00000000, 0x2fffffff]` || LowMem || +#if defined(ASAN_SHADOW_SCALE) +static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE; +#else static const u64 kDefaultShadowScale = 3; +#endif static const u64 kDefaultShadowSentinel = ~(uptr)0; static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000 static const u64 kDefaultShadowOffset64 = 1ULL << 44; -static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. +static const u64 kDefaultShort64bitShadowOffset = + 0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G. static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000 static const u64 kIosShadowOffset64 = 0x120200000; static const u64 kIosSimShadowOffset32 = 1ULL << 30; diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc index 5bafb9a78cf..9ff29001259 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cc @@ -469,6 +469,7 @@ static void AsanInitInternal() { MaybeReexec(); // Setup internal allocator callback. + SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY); SetLowLevelAllocateCallback(OnLowLevelAllocate); InitializeAsanInterceptors(); diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_allocator.cc index 5af4fba2bc7..d68c2072ff4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator.cc +++ b/libsanitizer/sanitizer_common/sanitizer_allocator.cc @@ -175,11 +175,13 @@ void InternalFree(void *addr, InternalAllocatorCache *cache) { } // LowLevelAllocator +constexpr uptr kLowLevelAllocatorDefaultAlignment = 8; +static uptr low_level_alloc_min_alignment = kLowLevelAllocatorDefaultAlignment; static LowLevelAllocateCallback low_level_alloc_callback; void *LowLevelAllocator::Allocate(uptr size) { // Align allocation size. - size = RoundUpTo(size, 8); + size = RoundUpTo(size, low_level_alloc_min_alignment); if (allocated_end_ - allocated_current_ < (sptr)size) { uptr size_to_allocate = Max(size, GetPageSizeCached()); allocated_current_ = @@ -196,6 +198,11 @@ void *LowLevelAllocator::Allocate(uptr size) { return res; } +void SetLowLevelAllocateMinAlignment(uptr alignment) { + CHECK(IsPowerOfTwo(alignment)); + low_level_alloc_min_alignment = Max(alignment, low_level_alloc_min_alignment); +} + void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) { low_level_alloc_callback = callback; } diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index fb06aa45109..79017ca591b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -174,6 +174,8 @@ class LowLevelAllocator { char *allocated_end_; char *allocated_current_; }; +// Set the min alignment of LowLevelAllocator to at least alignment. +void SetLowLevelAllocateMinAlignment(uptr alignment); typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size); // Allows to register tool-specific callbacks for LowLevelAllocator. // Passing NULL removes the callback. diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index 52a7c9d3fb4..25eaa9423e1 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then fi %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) } +%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})} %ifarch armv7l armv7hl aarch64 %undefine gcc_profiledbootstrap diff --git a/packaging/gcc-armv7hl.spec b/packaging/gcc-armv7hl.spec index 3540bfe1e27..b5a36ff0727 100644 --- a/packaging/gcc-armv7hl.spec +++ b/packaging/gcc-armv7hl.spec @@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then fi %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) } +%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})} %ifarch armv7l armv7hl aarch64 %undefine gcc_profiledbootstrap diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index f9a624167f2..fda85b88306 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then fi %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) } +%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})} %ifarch armv7l armv7hl aarch64 %undefine gcc_profiledbootstrap diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index 52a1b5f5f78..fde4e38354d 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -724,6 +724,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then fi %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) } +%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})} %ifarch armv7l armv7hl aarch64 %undefine gcc_profiledbootstrap |