gcc/gcc48-asan-speedup.patch
Jakub Jelinek 225104138d 4.8.0-0.13
2013-02-15 20:17:57 +01:00

536 lines
20 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

2013-02-15 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c: Use 0x7fff8000 as asan_shadow_offset on x86_64
linux.
* All source files: Merge from upstream.
--- gcc/config/i386/i386.c.jj 2013-02-13 17:04:34.000000000 +0100
+++ gcc/config/i386/i386.c 2013-02-15 13:27:47.674832994 +0100
@@ -5436,7 +5436,8 @@ ix86_legitimate_combined_insn (rtx insn)
static unsigned HOST_WIDE_INT
ix86_asan_shadow_offset (void)
{
- return TARGET_LP64 ? (HOST_WIDE_INT_1 << 44)
+ return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
+ : HOST_WIDE_INT_C (0x7fff8000))
: (HOST_WIDE_INT_1 << 29);
}
--- libsanitizer/sanitizer_common/sanitizer_internal_defs.h.jj 2013-02-13 11:53:43.403336342 +0100
+++ libsanitizer/sanitizer_common/sanitizer_internal_defs.h 2013-02-15 13:24:17.410033137 +0100
@@ -29,7 +29,7 @@
# define SANITIZER_SUPPORTS_WEAK_HOOKS 0
#endif
-// __has_feature
+// GCC does not understand __has_feature
#if !defined(__has_feature)
# define __has_feature(x) 0
#endif
--- libsanitizer/sanitizer_common/sanitizer_linux.cc.jj 2013-02-13 11:53:43.402336347 +0100
+++ libsanitizer/sanitizer_common/sanitizer_linux.cc 2013-02-15 13:24:17.410033137 +0100
@@ -232,6 +232,21 @@ const char *GetEnv(const char *name) {
return 0; // Not found.
}
+#ifdef __GLIBC__
+
+extern "C" {
+ extern void *__libc_stack_end;
+}
+
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ uptr *stack_end = (uptr *)__libc_stack_end;
+ int argc = *stack_end;
+ *argv = (char**)(stack_end + 1);
+ *envp = (char**)(stack_end + argc + 2);
+}
+
+#else // __GLIBC__
+
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -251,11 +266,17 @@ static void ReadNullSepFileToArray(const
(*arr)[count] = 0;
}
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ static const int kMaxArgv = 2000, kMaxEnvp = 2000;
+ ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
+ ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
+}
+
+#endif // __GLIBC__
+
void ReExec() {
- static const int kMaxArgv = 100, kMaxEnvp = 1000;
char **argv, **envp;
- ReadNullSepFileToArray("/proc/self/cmdline", &argv, kMaxArgv);
- ReadNullSepFileToArray("/proc/self/environ", &envp, kMaxEnvp);
+ GetArgsAndEnv(&argv, &envp);
execve(argv[0], argv, envp);
}
--- libsanitizer/asan/asan_internal.h.jj 2013-02-13 11:53:44.377330938 +0100
+++ libsanitizer/asan/asan_internal.h 2013-02-15 13:24:17.412033319 +0100
@@ -52,7 +52,7 @@
#define ASAN_POSIX (ASAN_LINUX || ASAN_MAC)
-#if __has_feature(address_sanitizer)
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# error "The AddressSanitizer run-time should not be"
" instrumented by AddressSanitizer"
#endif
--- libsanitizer/asan/asan_mac.cc.jj 2013-02-13 11:53:44.397330832 +0100
+++ libsanitizer/asan/asan_mac.cc 2013-02-15 13:24:17.412033319 +0100
@@ -104,7 +104,24 @@ void MaybeReexec() {
_NSGetExecutablePath(program_name, &buf_size);
// Ok to use setenv() since the wrappers don't depend on the value of
// asan_inited.
- setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
+ if (dyld_insert_libraries) {
+ // Append the runtime dylib name to the existing value of
+ // DYLD_INSERT_LIBRARIES.
+ uptr old_env_len = internal_strlen(dyld_insert_libraries);
+ uptr fname_len = internal_strlen(info.dli_fname);
+ LowLevelAllocator allocator_for_env;
+ char *new_env =
+ (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
+ internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
+ new_env[old_env_len] = ':';
+ // Copy fname_len and add a trailing zero.
+ internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
+ fname_len + 1);
+ setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
+ } else {
+ // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
+ setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
+ }
if (flags()->verbosity >= 1) {
Report("exec()-ing the program with\n");
Report("%s=%s\n", kDyldInsertLibraries, info.dli_fname);
--- libsanitizer/asan/asan_mapping.h.jj 2013-02-13 17:04:34.680198753 +0100
+++ libsanitizer/asan/asan_mapping.h 2013-02-15 13:26:25.846301749 +0100
@@ -1,7 +1,5 @@
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
@@ -18,6 +16,37 @@
// The full explanation of the memory mapping could be found here:
// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
+//
+// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
+// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
+// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
+// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap ||
+// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
+// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
+//
+// When SHADOW_OFFSET is zero (-pie):
+// || `[0x100000000000, 0x7fffffffffff]` || HighMem ||
+// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
+// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap ||
+//
+// Special case when something is already mapped between
+// 0x003000000000 and 0x004000000000 (e.g. when prelink is installed):
+// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
+// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
+// || `[0x004000000000, 0x02008fff6fff]` || ShadowGap3 ||
+// || `[0x003000000000, 0x003fffffffff]` || MidMem ||
+// || `[0x00087fff8000, 0x002fffffffff]` || ShadowGap2 ||
+// || `[0x00067fff8000, 0x00087fff7fff]` || MidShadow ||
+// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap ||
+// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
+// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
+//
+// Default Linux/i386 mapping:
+// || `[0x40000000, 0xffffffff]` || HighMem ||
+// || `[0x28000000, 0x3fffffff]` || HighShadow ||
+// || `[0x24000000, 0x27ffffff]` || ShadowGap ||
+// || `[0x20000000, 0x23ffffff]` || LowShadow ||
+// || `[0x00000000, 0x1fffffff]` || LowMem ||
#if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1
extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale;
@@ -36,7 +65,11 @@ extern SANITIZER_INTERFACE_ATTRIBUTE upt
# if defined(__powerpc64__)
# define SHADOW_OFFSET (1ULL << 41)
# else
-# define SHADOW_OFFSET (1ULL << 44)
+# if ASAN_MAC
+# define SHADOW_OFFSET (1ULL << 44)
+# else
+# define SHADOW_OFFSET 0x7fff8000ULL
+# endif
# endif
# endif
# endif
@@ -57,49 +90,105 @@ extern SANITIZER_INTERFACE_ATTRIBUTE upt
#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
+# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
+# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
+
// With the zero shadow base we can not actually map pages starting from 0.
// This constant is somewhat arbitrary.
#define kZeroBaseShadowStart (1 << 18)
#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \
: kZeroBaseShadowStart)
-#define kShadowGapEnd (kHighShadowBeg - 1)
+#define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
+
+#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
+#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
+
+#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
+#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
+
+#define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below.
+
+#if DO_ASAN_MAPPING_PROFILE
+# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
+#else
+# define PROFILE_ASAN_MAPPING()
+#endif
+
+// If 1, all shadow boundaries are constants.
+// Don't set to 1 other than for testing.
+#define ASAN_FIXED_MAPPING 0
namespace __asan {
+extern uptr AsanMappingProfile[];
+
+#if ASAN_FIXED_MAPPING
+// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
+// with non-fixed mapping. As of r175253 (Feb 2013) the performance
+// difference between fixed and non-fixed mapping is below the noise level.
+static uptr kHighMemEnd = 0x7fffffffffffULL;
+static uptr kMidMemBeg = 0x3000000000ULL;
+static uptr kMidMemEnd = 0x3fffffffffULL;
+#else
SANITIZER_INTERFACE_ATTRIBUTE
-extern uptr kHighMemEnd; // Initialized in __asan_init.
+extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
+#endif
static inline bool AddrIsInLowMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a < kLowMemEnd;
}
static inline bool AddrIsInLowShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a >= kLowShadowBeg && a <= kLowShadowEnd;
}
static inline bool AddrIsInHighMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a >= kHighMemBeg && a <= kHighMemEnd;
}
+static inline bool AddrIsInMidMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
+}
+
static inline bool AddrIsInMem(uptr a) {
- return AddrIsInLowMem(a) || AddrIsInHighMem(a);
+ PROFILE_ASAN_MAPPING();
+ return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);
}
static inline uptr MemToShadow(uptr p) {
+ PROFILE_ASAN_MAPPING();
CHECK(AddrIsInMem(p));
return MEM_TO_SHADOW(p);
}
static inline bool AddrIsInHighShadow(uptr a) {
- return a >= kHighShadowBeg && a <= kHighMemEnd;
+ PROFILE_ASAN_MAPPING();
+ return a >= kHighShadowBeg && a <= kHighMemEnd;
+}
+
+static inline bool AddrIsInMidShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;
}
static inline bool AddrIsInShadow(uptr a) {
- return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);
+ PROFILE_ASAN_MAPPING();
+ return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
}
static inline bool AddrIsInShadowGap(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ if (kMidMemBeg) {
+ if (a <= kShadowGapEnd)
+ return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
+ return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
+ (a >= kShadowGap3Beg && a <= kShadowGap3End);
+ }
// In zero-based shadow mode we treat addresses near zero as addresses
// in shadow gap as well.
if (SHADOW_OFFSET == 0)
@@ -108,10 +197,12 @@ static inline bool AddrIsInShadowGap(upt
}
static inline bool AddrIsAlignedByGranularity(uptr a) {
+ PROFILE_ASAN_MAPPING();
return (a & (SHADOW_GRANULARITY - 1)) == 0;
}
static inline bool AddressIsPoisoned(uptr a) {
+ PROFILE_ASAN_MAPPING();
const uptr kAccessSize = 1;
u8 *shadow_address = (u8*)MemToShadow(a);
s8 shadow_value = *shadow_address;
@@ -123,6 +214,9 @@ static inline bool AddressIsPoisoned(upt
return false;
}
+// Must be after all calls to PROFILE_ASAN_MAPPING().
+static const uptr kAsanMappingProfileSize = __LINE__;
+
} // namespace __asan
#endif // ASAN_MAPPING_H
--- libsanitizer/asan/asan_rtl.cc.jj 2013-02-13 17:04:25.688240113 +0100
+++ libsanitizer/asan/asan_rtl.cc 2013-02-15 13:24:17.411033229 +0100
@@ -25,6 +25,8 @@
namespace __asan {
+uptr AsanMappingProfile[kAsanMappingProfileSize];
+
static void AsanDie() {
static atomic_uint32_t num_calls;
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
@@ -35,8 +37,14 @@ static void AsanDie() {
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
SleepForSeconds(flags()->sleep_before_dying);
}
- if (flags()->unmap_shadow_on_exit)
- UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+ if (flags()->unmap_shadow_on_exit) {
+ if (kMidMemBeg) {
+ UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
+ UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
+ } else {
+ UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+ }
+ }
if (death_callback)
death_callback();
if (flags()->abort_on_error)
@@ -161,7 +169,10 @@ void InitializeFlags(Flags *f, const cha
int asan_inited;
bool asan_init_is_running;
void (*death_callback)(void);
-uptr kHighMemEnd;
+
+#if !ASAN_FIXED_MAPPING
+uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
+#endif
// -------------------------- Misc ---------------- {{{1
void ShowStatsAndAbort() {
@@ -259,9 +270,15 @@ static NOINLINE void force_interface_sym
static void asan_atexit() {
Printf("AddressSanitizer exit stats:\n");
__asan_print_accumulated_stats();
+ // Print AsanMappingProfile.
+ for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
+ if (AsanMappingProfile[i] == 0) continue;
+ Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
+ }
}
static void InitializeHighMemEnd() {
+#if !ASAN_FIXED_MAPPING
#if SANITIZER_WORDSIZE == 64
# if defined(__powerpc64__)
// FIXME:
@@ -277,6 +294,58 @@ static void InitializeHighMemEnd() {
#else // SANITIZER_WORDSIZE == 32
kHighMemEnd = (1ULL << 32) - 1; // 0xffffffff;
#endif // SANITIZER_WORDSIZE
+#endif // !ASAN_FIXED_MAPPING
+}
+
+static void ProtectGap(uptr a, uptr size) {
+ CHECK_EQ(a, (uptr)Mprotect(a, size));
+}
+
+static void PrintAddressSpaceLayout() {
+ Printf("|| `[%p, %p]` || HighMem ||\n",
+ (void*)kHighMemBeg, (void*)kHighMemEnd);
+ Printf("|| `[%p, %p]` || HighShadow ||\n",
+ (void*)kHighShadowBeg, (void*)kHighShadowEnd);
+ if (kMidMemBeg) {
+ Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
+ (void*)kShadowGap3Beg, (void*)kShadowGap3End);
+ Printf("|| `[%p, %p]` || MidMem ||\n",
+ (void*)kMidMemBeg, (void*)kMidMemEnd);
+ Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
+ (void*)kShadowGap2Beg, (void*)kShadowGap2End);
+ Printf("|| `[%p, %p]` || MidShadow ||\n",
+ (void*)kMidShadowBeg, (void*)kMidShadowEnd);
+ }
+ Printf("|| `[%p, %p]` || ShadowGap ||\n",
+ (void*)kShadowGapBeg, (void*)kShadowGapEnd);
+ if (kLowShadowBeg) {
+ Printf("|| `[%p, %p]` || LowShadow ||\n",
+ (void*)kLowShadowBeg, (void*)kLowShadowEnd);
+ Printf("|| `[%p, %p]` || LowMem ||\n",
+ (void*)kLowMemBeg, (void*)kLowMemEnd);
+ }
+ Printf("MemToShadow(shadow): %p %p %p %p",
+ (void*)MEM_TO_SHADOW(kLowShadowBeg),
+ (void*)MEM_TO_SHADOW(kLowShadowEnd),
+ (void*)MEM_TO_SHADOW(kHighShadowBeg),
+ (void*)MEM_TO_SHADOW(kHighShadowEnd));
+ if (kMidMemBeg) {
+ Printf(" %p %p",
+ (void*)MEM_TO_SHADOW(kMidShadowBeg),
+ (void*)MEM_TO_SHADOW(kMidShadowEnd));
+ }
+ Printf("\n");
+ Printf("red_zone=%zu\n", (uptr)flags()->redzone);
+ Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
+
+ Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
+ Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
+ Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
+ CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
+ if (kMidMemBeg)
+ CHECK(kMidShadowBeg > kLowShadowEnd &&
+ kMidMemBeg > kMidShadowEnd &&
+ kHighShadowBeg > kMidMemEnd);
}
} // namespace __asan
@@ -352,49 +421,48 @@ void __asan_init() {
ReplaceSystemMalloc();
ReplaceOperatorsNewAndDelete();
- if (flags()->verbosity) {
- Printf("|| `[%p, %p]` || HighMem ||\n",
- (void*)kHighMemBeg, (void*)kHighMemEnd);
- Printf("|| `[%p, %p]` || HighShadow ||\n",
- (void*)kHighShadowBeg, (void*)kHighShadowEnd);
- Printf("|| `[%p, %p]` || ShadowGap ||\n",
- (void*)kShadowGapBeg, (void*)kShadowGapEnd);
- Printf("|| `[%p, %p]` || LowShadow ||\n",
- (void*)kLowShadowBeg, (void*)kLowShadowEnd);
- Printf("|| `[%p, %p]` || LowMem ||\n",
- (void*)kLowMemBeg, (void*)kLowMemEnd);
- Printf("MemToShadow(shadow): %p %p %p %p\n",
- (void*)MEM_TO_SHADOW(kLowShadowBeg),
- (void*)MEM_TO_SHADOW(kLowShadowEnd),
- (void*)MEM_TO_SHADOW(kHighShadowBeg),
- (void*)MEM_TO_SHADOW(kHighShadowEnd));
- Printf("red_zone=%zu\n", (uptr)flags()->redzone);
- Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
-
- Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
- Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
- Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
- CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
+ uptr shadow_start = kLowShadowBeg;
+ if (kLowShadowBeg) shadow_start -= GetMmapGranularity();
+ uptr shadow_end = kHighShadowEnd;
+ bool full_shadow_is_available =
+ MemoryRangeIsAvailable(shadow_start, shadow_end);
+
+#if ASAN_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING
+ if (!full_shadow_is_available) {
+ kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
+ kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x3fffffffffULL : 0;
}
+#endif
+
+ if (flags()->verbosity)
+ PrintAddressSpaceLayout();
if (flags()->disable_core) {
DisableCoreDumper();
}
- uptr shadow_start = kLowShadowBeg;
- if (kLowShadowBeg > 0) shadow_start -= GetMmapGranularity();
- uptr shadow_end = kHighShadowEnd;
- if (MemoryRangeIsAvailable(shadow_start, shadow_end)) {
- if (kLowShadowBeg != kLowShadowEnd) {
- // mmap the low shadow plus at least one page.
- ReserveShadowMemoryRange(kLowShadowBeg - GetMmapGranularity(),
- kLowShadowEnd);
- }
+ if (full_shadow_is_available) {
+ // mmap the low shadow plus at least one page at the left.
+ if (kLowShadowBeg)
+ ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+ // mmap the high shadow.
+ ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
+ // protect the gap.
+ ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+ } else if (kMidMemBeg &&
+ MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
+ MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) {
+ CHECK(kLowShadowBeg != kLowShadowEnd);
+ // mmap the low shadow plus at least one page at the left.
+ ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+ // mmap the mid shadow.
+ ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
// mmap the high shadow.
ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
- // protect the gap
- void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
- CHECK(prot == (void*)kShadowGapBeg);
+ // protect the gaps.
+ ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+ ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
+ ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
} else {
Report("Shadow memory range interleaves with an existing memory mapping. "
"ASan cannot proceed correctly. ABORTING.\n");
--- libsanitizer/include/sanitizer/common_interface_defs.h.jj 2013-02-13 11:53:44.531330044 +0100
+++ libsanitizer/include/sanitizer/common_interface_defs.h 2013-02-15 13:24:17.403032450 +0100
@@ -14,6 +14,11 @@
#include <stddef.h>
#include <stdint.h>
+// GCC does not understand __has_feature.
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
--- libsanitizer/include/sanitizer/asan_interface.h.jj 2013-02-13 11:53:44.531330044 +0100
+++ libsanitizer/include/sanitizer/asan_interface.h 2013-02-15 13:24:17.403032450 +0100
@@ -35,8 +35,8 @@ extern "C" {
// (un)poison memory in the same memory region simultaneously.
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
- // User code should use macro instead of functions.
-#if __has_feature(address_sanitizer)
+// User code should use macros instead of functions.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
#define ASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \