536 lines
20 KiB
Diff
536 lines
20 KiB
Diff
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) \
|