1c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===-- esan_shadow.h -------------------------------------------*- C++ -*-===// 2c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 3c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 5c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 8c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 10c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// This file is a part of EfficiencySanitizer, a family of performance tuners. 11c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 12c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Shadow memory mappings for the esan run-time. 13c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 14c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 15c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifndef ESAN_SHADOW_H 16c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define ESAN_SHADOW_H 17c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 18c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sanitizer_common/sanitizer_platform.h> 19c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 20c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_WORDSIZE != 64 21c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#error Only 64-bit is supported 22c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 23c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 24c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarnamespace __esan { 25c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_LINUX && defined(__x86_64__) 27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Linux x86_64 28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Application memory falls into these 5 regions (ignoring the corner case 30c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// of PIE with a non-zero PT_LOAD base): 31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 32c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00000000'00000000, 0x00000100'00000000) non-PIE + heap 33c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00005500'00000000, 0x00005700'00000000) PIE 34c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00007e00'00000000, 0x00007fff'ff600000) libraries + stack, part 1 35c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00007fff'ff601000, 0x00008000'00000000) libraries + stack, part 2 36c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0xffffffff'ff600000, 0xffffffff'ff601000) vsyscall 37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 38c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Although we can ignore the vsyscall for the most part as there are few data 39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// references there (other sanitizers ignore it), we enforce a gap inside the 40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// library region to distinguish the vsyscall's shadow, considering this gap to 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// be an invalid app region. 42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We disallow application memory outside of those 5 regions. 43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Our regions assume that the stack rlimit is less than a terabyte (otherwise 44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// the Linux kernel's default mmap region drops below 0x7e00'), which we enforce 45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// at init time (we can support larger and unlimited sizes for shadow 46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scaledowns, but it is difficult for 1:1 mappings). 47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Our shadow memory is scaled from a 1:1 mapping and supports a scale 49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// specified at library initialization time that can be any power-of-2 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scaledown (1x, 2x, 4x, 8x, 16x, etc.). 51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We model our shadow memory after Umbra, a library used by the Dr. Memory 53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// tool: https://github.com/DynamoRIO/drmemory/blob/master/umbra/umbra_x64.c. 54c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We use Umbra's scheme as it was designed to support different 55c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// offsets, it supports two different shadow mappings (which we may want to 56c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// use for future tools), and it ensures that the shadow of a shadow will 57c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// not overlap either shadow memory or application memory. 58c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 59c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// This formula translates from application memory to shadow memory: 60c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 61c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// shadow(app) = ((app & 0x00000fff'ffffffff) + offset) >> scale 62c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 63c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Where the offset for 1:1 is 0x00001300'00000000. For other scales, the 64c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// offset is shifted left by the scale, except for scales of 1 and 2 where 65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// it must be tweaked in order to pass the double-shadow test 66c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// (see the "shadow(shadow)" comments below): 67c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scale == 0: 0x00001300'000000000 68c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scale == 1: 0x00002200'000000000 69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scale == 2: 0x00004400'000000000 70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// scale >= 3: (0x00001300'000000000 << scale) 71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Do not pass in the open-ended end value to the formula as it will fail. 73c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// The resulting shadow memory regions for a 0 scaling are: 75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 76c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00001300'00000000, 0x00001400'00000000) 77c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00001800'00000000, 0x00001a00'00000000) 78c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00002100'00000000, 0x000022ff'ff600000) 79c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x000022ff'ff601000, 0x00002300'00000000) 80c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x000022ff'ff600000, 0x000022ff'ff601000] 81c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 82c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We also want to ensure that a wild access by the application into the shadow 83c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// regions will not corrupt our own shadow memory. shadow(shadow) ends up 84c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// disjoint from shadow(app): 85c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 86c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00001600'00000000, 0x00001700'00000000) 87c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00001b00'00000000, 0x00001d00'00000000) 88c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x00001400'00000000, 0x000015ff'ff600000] 89c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x000015ff'ff601000, 0x00001600'00000000] 90c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// [0x000015ff'ff600000, 0x000015ff'ff601000] 91c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 92c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstruct ApplicationRegion { 93c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr Start; 94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr End; 95c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar bool ShadowMergedWithPrev; 96c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}; 97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 98c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic const struct ApplicationRegion AppRegions[] = { 99c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar {0x0000000000000000ull, 0x0000010000000000u, false}, 100c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar {0x0000550000000000u, 0x0000570000000000u, false}, 101c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // We make one shadow mapping to hold the shadow regions for all 3 of these 102c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // app regions, as the mappings interleave, and the gap between the 3rd and 103c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // 4th scales down below a page. 104c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar {0x00007e0000000000u, 0x00007fffff600000u, false}, 105c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar {0x00007fffff601000u, 0x0000800000000000u, true}, 106c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar {0xffffffffff600000u, 0xffffffffff601000u, true}, 107c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}; 108c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic const u32 NumAppRegions = sizeof(AppRegions)/sizeof(AppRegions[0]); 109c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 110c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// See the comment above: we do not currently support a stack size rlimit 111c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// equal to or larger than 1TB. 112c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic const uptr MaxStackSize = (1ULL << 40) - 4096; 113c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 114c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarclass ShadowMapping { 115c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarpublic: 116c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar static const uptr Mask = 0x00000fffffffffffu; 117c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // The scale and offset vary by tool. 118c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr Scale; 119c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr Offset; 120c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar void initialize(uptr ShadowScale) { 121c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar static const uptr OffsetArray[3] = { 122c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 0x0000130000000000u, 123c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 0x0000220000000000u, 124c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 0x0000440000000000u, 125c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar }; 126c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Scale = ShadowScale; 127c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Scale <= 2) 128c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Offset = OffsetArray[Scale]; 129c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar else 130c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Offset = OffsetArray[0] << Scale; 131c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 132c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}; 133c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarextern ShadowMapping Mapping; 134c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 135c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We'll want to use templatized functions over the ShadowMapping once 136c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// we support more platforms. 137c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#error Platform not supported 138c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 139c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 140c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic inline bool getAppRegion(u32 i, uptr *Start, uptr *End) { 141c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (i >= NumAppRegions) 142c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 143c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *Start = AppRegions[i].Start; 144c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *End = AppRegions[i].End; 145c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 146c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 147c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 148c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarALWAYS_INLINE 149c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarbool isAppMem(uptr Mem) { 150c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar for (u32 i = 0; i < NumAppRegions; ++i) { 151c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Mem >= AppRegions[i].Start && Mem < AppRegions[i].End) 152c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 153c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 154c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 155c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 156c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 157c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarALWAYS_INLINE 158c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainaruptr appToShadow(uptr App) { 159c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return (((App & ShadowMapping::Mask) + Mapping.Offset) >> Mapping.Scale); 160c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 161c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 162c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic inline bool getShadowRegion(u32 i, uptr *Start, uptr *End) { 163c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (i >= NumAppRegions) 164c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 165c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar u32 UnmergedShadowCount = 0; 166c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar u32 AppIdx; 167c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar for (AppIdx = 0; AppIdx < NumAppRegions; ++AppIdx) { 168c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (!AppRegions[AppIdx].ShadowMergedWithPrev) { 169c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (UnmergedShadowCount == i) 170c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar break; 171c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar UnmergedShadowCount++; 172c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 173c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 174c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (AppIdx >= NumAppRegions || UnmergedShadowCount != i) 175c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 176c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *Start = appToShadow(AppRegions[AppIdx].Start); 177c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // The formula fails for the end itself. 178c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *End = appToShadow(AppRegions[AppIdx].End - 1) + 1; 179c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Merge with adjacent shadow regions: 180c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar for (++AppIdx; AppIdx < NumAppRegions; ++AppIdx) { 181c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (!AppRegions[AppIdx].ShadowMergedWithPrev) 182c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar break; 183c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *Start = Min(*Start, appToShadow(AppRegions[AppIdx].Start)); 184c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *End = Max(*End, appToShadow(AppRegions[AppIdx].End - 1) + 1); 185c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 186c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 187c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 188c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 189c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarALWAYS_INLINE 190c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarbool isShadowMem(uptr Mem) { 191c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // We assume this is not used on any critical performance path and so there's 192c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // no need to hardcode the mapping results. 193c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar for (uptr i = 0; i < NumAppRegions; ++i) { 194c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Mem >= appToShadow(AppRegions[i].Start) && 195c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Mem < appToShadow(AppRegions[i].End - 1) + 1) 196c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 197c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 198c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 199c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 200c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 201c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} // namespace __esan 202c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 203c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif /* ESAN_SHADOW_H */ 204