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