Index: compiler-rt/lib/asan/asan_mapping.h =================================================================== --- compiler-rt/lib/asan/asan_mapping.h +++ compiler-rt/lib/asan/asan_mapping.h @@ -137,6 +137,12 @@ // || `[0x36000000, 0x39ffffff]` || ShadowGap || // || `[0x30000000, 0x35ffffff]` || LowShadow || // || `[0x00000000, 0x2fffffff]` || LowMem || +// +// Shadow mapping on Myriad2: +// || `[0x9ff80000, 0x9fffffff]` || ShadowGap || +// || `[0x9f000000, 0x9ff7ffff]` || LowShadow || +// || `[0x80000000, 0x9effffff]` || LowMem || +// || `[0x00000000, 0x7fffffff]` || Ignored || #if defined(ASAN_SHADOW_SCALE) static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE; @@ -163,7 +169,14 @@ static const u64 kNetBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 -#define SHADOW_SCALE kDefaultShadowScale +static const u64 kMyriadShadowScale = 5; +static const u64 kMyriadMemoryOffset32 = 0x80000000ULL; +static const u64 kMyriadMemoryEnd32 = 0x9fffffffULL; +static const u64 kMyriadShadowOffset32 = 0x9f000000ULL; +static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; + +#define SHADOW_SCALE \ + (SANITIZER_MYRIAD2 ? kMyriadShadowScale : kDefaultShadowScale) #if SANITIZER_FUCHSIA # define SHADOW_OFFSET (0) @@ -184,6 +197,8 @@ # else # define SHADOW_OFFSET kIosShadowOffset32 # endif +# elif SANITIZER_MYRIAD2 +# define SHADOW_OFFSET kMyriadShadowOffset32 # else # define SHADOW_OFFSET kDefaultShadowOffset32 # endif @@ -222,6 +237,10 @@ #endif #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE) + +#if SANITIZER_MYRIAD2 +#include "asan_mapping_myriad.h" +#else #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET)) #define kLowMemBeg 0 @@ -252,6 +271,7 @@ #define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0) #define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0) +#endif // SANITIZER_MYRIAD2 #define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below. @@ -262,46 +282,62 @@ #endif // If 1, all shadow boundaries are constants. -// Don't set to 1 other than for testing. -#define ASAN_FIXED_MAPPING 0 +// Myriad is fixed-mapping only; for others, don't set to 1 other than +// for testing. +#define ASAN_FIXED_MAPPING SANITIZER_MYRIAD2 namespace __asan { extern uptr AsanMappingProfile[]; #if ASAN_FIXED_MAPPING +#if SANITIZER_MYRIAD2 +static uptr kHighMemEnd = 0; +static uptr kMidMemBeg = 0; +static uptr kMidMemEnd = 0; +#else // SANITIZER_MYRIAD2 // 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 = 0x4fffffffffULL; -#else +#endif // SANITIZER_MYRIAD2 +#else // ASAN_FIXED_MAPPING extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. -#endif +#endif // ASAN_FIXED_MAPPING + +static inline uptr RawAddr(uptr a) { + return SANITIZER_MYRIAD2 ? (a & ~kMyriadCacheBitMask32) : a; +} static inline bool AddrIsInLowMem(uptr a) { PROFILE_ASAN_MAPPING(); - return a < kLowMemEnd; + a = RawAddr(a); + return a >= kLowMemBeg && a <= kLowMemEnd; } static inline bool AddrIsInLowShadow(uptr a) { PROFILE_ASAN_MAPPING(); + a = RawAddr(a); return a >= kLowShadowBeg && a <= kLowShadowEnd; } static inline bool AddrIsInHighMem(uptr a) { PROFILE_ASAN_MAPPING(); - return a >= kHighMemBeg && a <= kHighMemEnd; + a = RawAddr(a); + return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd; } static inline bool AddrIsInMidMem(uptr a) { PROFILE_ASAN_MAPPING(); + a = RawAddr(a); return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd; } static inline bool AddrIsInShadowGap(uptr a) { PROFILE_ASAN_MAPPING(); + a = RawAddr(a); if (kMidMemBeg) { if (a <= kShadowGapEnd) return SHADOW_OFFSET == 0 || a >= kShadowGapBeg; @@ -329,11 +365,13 @@ static inline bool AddrIsInHighShadow(uptr a) { PROFILE_ASAN_MAPPING(); - return a >= kHighShadowBeg && a <= kHighShadowEnd; + a = RawAddr(a); + return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd; } static inline bool AddrIsInMidShadow(uptr a) { PROFILE_ASAN_MAPPING(); + a = RawAddr(a); return kMidMemBeg && a >= kMidShadowBeg && a <= kMidShadowEnd; } @@ -349,6 +387,8 @@ static inline bool AddressIsPoisoned(uptr a) { PROFILE_ASAN_MAPPING(); + if (SANITIZER_MYRIAD2 && !AddrIsInMem(a) && !AddrIsInShadow(a)) + return false; const uptr kAccessSize = 1; u8 *shadow_address = (u8*)MEM_TO_SHADOW(a); s8 shadow_value = *shadow_address; Index: compiler-rt/lib/asan/asan_mapping_myriad.h =================================================================== --- /dev/null +++ compiler-rt/lib/asan/asan_mapping_myriad.h @@ -0,0 +1,43 @@ +//===-- asan_mapping_myriad.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Myriad-specific definitions for ASan memory mapping. +//===----------------------------------------------------------------------===// +#ifndef ASAN_MAPPING_MYRIAD_H +#define ASAN_MAPPING_MYRIAD_H + +#define MEM_TO_SHADOW(mem) \ + (((__asan::RawAddr(mem) - kLowMemBeg) >> SHADOW_SCALE) + (SHADOW_OFFSET)) + +#define kLowMemBeg kMyriadMemoryOffset32 +#define kLowMemEnd (SHADOW_OFFSET - 1) + +#define kLowShadowBeg SHADOW_OFFSET +#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) + +#define kHighMemBeg 0 + +#define kHighShadowBeg 0 +#define kHighShadowEnd 0 + +#define kMidShadowBeg 0 +#define kMidShadowEnd 0 + +#define kShadowGapBeg (kLowShadowEnd + 1) +#define kShadowGapEnd kMyriadMemoryEnd32 + +#define kShadowGap2Beg 0 +#define kShadowGap2End 0 + +#define kShadowGap3Beg 0 +#define kShadowGap3End 0 + +#endif // ASAN_MAPPING_MYRIAD_H Index: compiler-rt/lib/asan/asan_poisoning.cc =================================================================== --- compiler-rt/lib/asan/asan_poisoning.cc +++ compiler-rt/lib/asan/asan_poisoning.cc @@ -182,8 +182,15 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) { if (!size) return 0; uptr end = beg + size; - if (!AddrIsInMem(beg)) return beg; - if (!AddrIsInMem(end)) return end; + if (SANITIZER_MYRIAD2) { + // On Myriad, address not in DRAM range need to be treated as + // unpoisoned. + if (!AddrIsInMem(beg) && !AddrIsInShadow(beg)) return 0; + if (!AddrIsInMem(end) && !AddrIsInShadow(end)) return 0; + } else { + if (!AddrIsInMem(beg)) return beg; + if (!AddrIsInMem(end)) return end; + } CHECK_LT(beg, end); uptr aligned_b = RoundUpTo(beg, SHADOW_GRANULARITY); uptr aligned_e = RoundDownTo(end, SHADOW_GRANULARITY); @@ -452,4 +459,3 @@ return (__asan_region_is_poisoned(addr, sizeof(uptr)) != 0); } } - Index: compiler-rt/lib/asan/asan_rtl.cc =================================================================== --- compiler-rt/lib/asan/asan_rtl.cc +++ compiler-rt/lib/asan/asan_rtl.cc @@ -56,7 +56,8 @@ UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); } else { - UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); + if (kHighShadowEnd) + UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); } } } @@ -140,6 +141,8 @@ ASAN_REPORT_ERROR_N(store, true) #define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \ + if (SANITIZER_RTEMS && !AddrIsInMem(addr) && !AddrIsInShadow(addr)) \ + return; \ uptr sp = MEM_TO_SHADOW(addr); \ uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast(sp) \ : *reinterpret_cast(sp); \ @@ -316,10 +319,12 @@ } void PrintAddressSpaceLayout() { - Printf("|| `[%p, %p]` || HighMem ||\n", - (void*)kHighMemBeg, (void*)kHighMemEnd); - Printf("|| `[%p, %p]` || HighShadow ||\n", - (void*)kHighShadowBeg, (void*)kHighShadowEnd); + if (kHighMemBeg) { + 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); @@ -338,11 +343,14 @@ Printf("|| `[%p, %p]` || LowMem ||\n", (void*)kLowMemBeg, (void*)kLowMemEnd); } - Printf("MemToShadow(shadow): %p %p %p %p", + Printf("MemToShadow(shadow): %p %p", (void*)MEM_TO_SHADOW(kLowShadowBeg), - (void*)MEM_TO_SHADOW(kLowShadowEnd), - (void*)MEM_TO_SHADOW(kHighShadowBeg), - (void*)MEM_TO_SHADOW(kHighShadowEnd)); + (void*)MEM_TO_SHADOW(kLowShadowEnd)); + if (kHighMemBeg) { + Printf(" %p %p", + (void*)MEM_TO_SHADOW(kHighShadowBeg), + (void*)MEM_TO_SHADOW(kHighShadowEnd)); + } if (kMidMemBeg) { Printf(" %p %p", (void*)MEM_TO_SHADOW(kMidShadowBeg), @@ -364,7 +372,7 @@ if (kMidMemBeg) CHECK(kMidShadowBeg > kLowShadowEnd && kMidMemBeg > kMidShadowEnd && - kHighShadowBeg > kMidMemEnd); + (!kHighMemBeg || kHighShadowBeg > kMidMemEnd)); } static void AsanInitInternal() {