Index: compiler-rt/lib/asan/asan_mapping.h =================================================================== --- compiler-rt/lib/asan/asan_mapping.h +++ compiler-rt/lib/asan/asan_mapping.h @@ -130,6 +130,19 @@ // || `[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 || + + +static const u64 kMyriadShadowScale = 5; +static const u64 kMyriadMemoryOffset32 = 0x80000000ULL; +static const u64 kMyriadMemoryEnd32 = 0xa0000000ULL; +static const u64 kMyriadShadowOffset32 = 0x9f000000ULL; +static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; #if defined(ASAN_SHADOW_SCALE) static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE; @@ -155,7 +168,8 @@ static const u64 kNetBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 -#define SHADOW_SCALE kDefaultShadowScale +#define SHADOW_SCALE \ + (SANITIZER_MYRIAD2 ? kMyriadShadowScale : kDefaultShadowScale) #if SANITIZER_FUCHSIA # define SHADOW_OFFSET (0) @@ -174,6 +188,8 @@ # else # define SHADOW_OFFSET kIosShadowOffset32 # endif +# elif SANITIZER_MYRIAD2 +# define SHADOW_OFFSET kMyriadShadowOffset32 # else # define SHADOW_OFFSET kDefaultShadowOffset32 # endif @@ -212,18 +228,19 @@ #endif #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE) -#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET)) +#define MEM_TO_SHADOW(mem) \ + (((__asan::RawAddr(mem) - kLowMemBeg) >> SHADOW_SCALE) + (SHADOW_OFFSET)) -#define kLowMemBeg 0 -#define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0) +#define kLowMemBeg (SANITIZER_MYRIAD2 ? kMyriadMemoryOffset32 : 0) +#define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0) -#define kLowShadowBeg SHADOW_OFFSET -#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) +#define kLowShadowBeg SHADOW_OFFSET +#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) -#define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1) +#define kHighMemBeg (SANITIZER_MYRIAD2 ? 0 : (MEM_TO_SHADOW(kHighMemEnd) + 1)) -#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg) -#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd) +#define kHighShadowBeg (SANITIZER_MYRIAD2 ? 0 : MEM_TO_SHADOW(kHighMemBeg)) +#define kHighShadowEnd (SANITIZER_MYRIAD2 ? 0 : MEM_TO_SHADOW(kHighMemEnd)) # define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg) # define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd) @@ -233,9 +250,10 @@ #define kZeroBaseShadowStart 0 #define kZeroBaseMaxShadowStart (1 << 18) -#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \ - : kZeroBaseShadowStart) -#define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1) +#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \ + : kZeroBaseShadowStart) +#define kShadowGapEnd (SANITIZER_MYRIAD2 ? (kMyriadMemoryEnd32 - 1) : \ + ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)) #define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0) #define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0) @@ -270,28 +288,37 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. #endif +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; @@ -319,11 +346,13 @@ static inline bool AddrIsInHighShadow(uptr a) { PROFILE_ASAN_MAPPING(); - return a >= kHighShadowBeg && a <= kHighMemEnd; + a = RawAddr(a); + return kHighMemBeg && a >= kHighShadowBeg && a <= kHighMemEnd; } static inline bool AddrIsInMidShadow(uptr a) { PROFILE_ASAN_MAPPING(); + a = RawAddr(a); return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd; } @@ -339,6 +368,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_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); \ @@ -306,7 +309,7 @@ } static void InitializeHighMemEnd() { -#if !ASAN_FIXED_MAPPING +#if !ASAN_FIXED_MAPPING && !SANITIZER_RTEMS kHighMemEnd = GetMaxUserVirtualAddress(); // Increase kHighMemEnd to make sure it's properly // aligned together with kHighMemBeg: @@ -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() {