1 //===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is shared between AddressSanitizer and ThreadSanitizer. 11 // 12 // Information about the process mappings. 13 //===----------------------------------------------------------------------===// 14 #ifndef SANITIZER_PROCMAPS_H 15 #define SANITIZER_PROCMAPS_H 16 17 #include "sanitizer_internal_defs.h" 18 #include "sanitizer_mutex.h" 19 20 namespace __sanitizer { 21 22 #if SANITIZER_WINDOWS 23 class MemoryMappingLayout { 24 public: MemoryMappingLayout(bool cache_enabled)25 explicit MemoryMappingLayout(bool cache_enabled) { 26 (void)cache_enabled; 27 } GetObjectNameAndOffset(uptr addr,uptr * offset,char filename[],uptr filename_size,uptr * protection)28 bool GetObjectNameAndOffset(uptr addr, uptr *offset, 29 char filename[], uptr filename_size, 30 uptr *protection) { 31 UNIMPLEMENTED(); 32 } 33 }; 34 35 #else // _WIN32 36 #if SANITIZER_LINUX 37 struct ProcSelfMapsBuff { 38 char *data; 39 uptr mmaped_size; 40 uptr len; 41 }; 42 #endif // SANITIZER_LINUX 43 44 class MemoryMappingLayout { 45 public: 46 explicit MemoryMappingLayout(bool cache_enabled); 47 bool Next(uptr *start, uptr *end, uptr *offset, 48 char filename[], uptr filename_size, uptr *protection); 49 void Reset(); 50 // Gets the object file name and the offset in that object for a given 51 // address 'addr'. Returns true on success. 52 bool GetObjectNameAndOffset(uptr addr, uptr *offset, 53 char filename[], uptr filename_size, 54 uptr *protection); 55 // In some cases, e.g. when running under a sandbox on Linux, ASan is unable 56 // to obtain the memory mappings. It should fall back to pre-cached data 57 // instead of aborting. 58 static void CacheMemoryMappings(); 59 ~MemoryMappingLayout(); 60 61 // Memory protection masks. 62 static const uptr kProtectionRead = 1; 63 static const uptr kProtectionWrite = 2; 64 static const uptr kProtectionExecute = 4; 65 static const uptr kProtectionShared = 8; 66 67 private: 68 void LoadFromCache(); 69 // Default implementation of GetObjectNameAndOffset. 70 // Quite slow, because it iterates through the whole process map for each 71 // lookup. 72 bool IterateForObjectNameAndOffset(uptr addr, uptr *offset, 73 char filename[], uptr filename_size, 74 uptr *protection) { 75 Reset(); 76 uptr start, end, file_offset; 77 for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size, 78 protection); 79 i++) { 80 if (addr >= start && addr < end) { 81 // Don't subtract 'start' for the first entry: 82 // * If a binary is compiled w/o -pie, then the first entry in 83 // process maps is likely the binary itself (all dynamic libs 84 // are mapped higher in address space). For such a binary, 85 // instruction offset in binary coincides with the actual 86 // instruction address in virtual memory (as code section 87 // is mapped to a fixed memory range). 88 // * If a binary is compiled with -pie, all the modules are 89 // mapped high at address space (in particular, higher than 90 // shadow memory of the tool), so the module can't be the 91 // first entry. 92 *offset = (addr - (i ? start : 0)) + file_offset; 93 return true; 94 } 95 } 96 if (filename_size) 97 filename[0] = '\0'; 98 return false; 99 } 100 101 # if SANITIZER_LINUX 102 ProcSelfMapsBuff proc_self_maps_; 103 char *current_; 104 105 // Static mappings cache. 106 static ProcSelfMapsBuff cached_proc_self_maps_; 107 static StaticSpinMutex cache_lock_; // protects cached_proc_self_maps_. 108 # elif SANITIZER_MAC 109 template<u32 kLCSegment, typename SegmentCommand> 110 bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset, 111 char filename[], uptr filename_size, 112 uptr *protection); 113 int current_image_; 114 u32 current_magic_; 115 u32 current_filetype_; 116 int current_load_cmd_count_; 117 char *current_load_cmd_addr_; 118 # endif 119 }; 120 121 #endif // _WIN32 122 123 } // namespace __sanitizer 124 125 #endif // SANITIZER_PROCMAPS_H 126