/* 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
#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"
\f
/* 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);
}
\f
/* Argument support functions. */
#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 {
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);
// 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.
#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"
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) {
// || `[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;
MaybeReexec();
// Setup internal allocator callback.
+ SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY);
SetLowLevelAllocateCallback(OnLowLevelAllocate);
InitializeAsanInterceptors();
}
// 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_ =
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;
}
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.
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
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
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
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