sanitizer_procmaps.h revision 2e13ca86c9ce926e6fefd528892592326478ac6c
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 20namespace __sanitizer { 21 22#if SANITIZER_WINDOWS 23class MemoryMappingLayout { 24 public: 25 explicit MemoryMappingLayout(bool cache_enabled) { 26 (void)cache_enabled; 27 } 28 bool GetObjectNameAndOffset(uptr addr, uptr *offset, 29 char filename[], uptr filename_size, 30 uptr *protection) { 31 UNIMPLEMENTED(); 32 } 33}; 34 35#else // SANITIZER_WINDOWS 36#if SANITIZER_LINUX 37struct ProcSelfMapsBuff { 38 char *data; 39 uptr mmaped_size; 40 uptr len; 41}; 42#endif // SANITIZER_LINUX 43 44class 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 121typedef void (*fill_profile_f)(uptr start, uptr rss, bool file, 122 /*out*/uptr *stats, uptr stats_size); 123 124// Parse the contents of /proc/self/smaps and generate a memory profile. 125// |cb| is a tool-specific callback that fills the |stats| array containing 126// |stats_size| elements. 127void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size); 128 129#endif // SANITIZER_WINDOWS 130 131} // namespace __sanitizer 132 133#endif // SANITIZER_PROCMAPS_H 134