16895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===// 26895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// 36895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// The LLVM Compiler Infrastructure 46895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// 56895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// This file is distributed under the University of Illinois Open Source 66895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// License. See LICENSE.TXT for details. 76895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// 86895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov//===----------------------------------------------------------------------===// 96895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// 106895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer. 116895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// 126895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// Information about the process mappings. 136895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov//===----------------------------------------------------------------------===// 146895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#ifndef SANITIZER_PROCMAPS_H 156895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#define SANITIZER_PROCMAPS_H 166895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 176895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_internal_defs.h" 1893da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko#include "sanitizer_mutex.h" 196895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 206895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonovnamespace __sanitizer { 216895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 2230e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_WINDOWS 23e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonovclass MemoryMappingLayout { 24985aaaaf208f43e4b47625e21e9ebc434c5462e3Alexey Samsonov public: 25b443a65bd65d5c2c6090ed0537382b1ade1dbbb9Dmitry Vyukov explicit MemoryMappingLayout(bool cache_enabled) { 2609a19b221bc60863bc10f1aad1d210ce9999990cAlexander Potapenko (void)cache_enabled; 2709a19b221bc60863bc10f1aad1d210ce9999990cAlexander Potapenko } 28f7fa68f5efbd32acd36987ab55305a3abc037636Alexey Samsonov bool GetObjectNameAndOffset(uptr addr, uptr *offset, 294a1a495f29b63d44e012f6edcee6307ddac253efAlexey Samsonov char filename[], uptr filename_size, 304a1a495f29b63d44e012f6edcee6307ddac253efAlexey Samsonov uptr *protection) { 31f7fa68f5efbd32acd36987ab55305a3abc037636Alexey Samsonov UNIMPLEMENTED(); 32f7fa68f5efbd32acd36987ab55305a3abc037636Alexey Samsonov } 33e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov}; 34e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov 35e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov#else // _WIN32 3624e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_LINUX 37ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenkostruct ProcSelfMapsBuff { 38ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko char *data; 39ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko uptr mmaped_size; 40ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko uptr len; 41ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko}; 4224e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#endif // SANITIZER_LINUX 43ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko 44e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonovclass MemoryMappingLayout { 456895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov public: 469ae2883d88dd28b9c5dc862107e6e6d12a35926eAlexander Potapenko explicit MemoryMappingLayout(bool cache_enabled); 476895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov bool Next(uptr *start, uptr *end, uptr *offset, 4845717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov char filename[], uptr filename_size, uptr *protection); 496895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov void Reset(); 506895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov // Gets the object file name and the offset in that object for a given 516895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov // address 'addr'. Returns true on success. 526895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov bool GetObjectNameAndOffset(uptr addr, uptr *offset, 5345717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov char filename[], uptr filename_size, 5445717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov uptr *protection); 5593da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko // In some cases, e.g. when running under a sandbox on Linux, ASan is unable 5693da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko // to obtain the memory mappings. It should fall back to pre-cached data 5793da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko // instead of aborting. 5893da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko static void CacheMemoryMappings(); 59e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov ~MemoryMappingLayout(); 606985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany 6145717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov // Memory protection masks. 6245717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov static const uptr kProtectionRead = 1; 6345717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov static const uptr kProtectionWrite = 2; 6445717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov static const uptr kProtectionExecute = 4; 6545717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov static const uptr kProtectionShared = 8; 6645717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov 676895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov private: 6893da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko void LoadFromCache(); 696895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov // Default implementation of GetObjectNameAndOffset. 706895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov // Quite slow, because it iterates through the whole process map for each 716895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov // lookup. 726895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov bool IterateForObjectNameAndOffset(uptr addr, uptr *offset, 7345717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov char filename[], uptr filename_size, 7445717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov uptr *protection) { 756895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov Reset(); 766895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov uptr start, end, file_offset; 7745717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size, 7845717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov protection); 796895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov i++) { 806895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov if (addr >= start && addr < end) { 81a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // Don't subtract 'start' for the first entry: 82a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // * If a binary is compiled w/o -pie, then the first entry in 83a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // process maps is likely the binary itself (all dynamic libs 84a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // are mapped higher in address space). For such a binary, 85a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // instruction offset in binary coincides with the actual 86a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // instruction address in virtual memory (as code section 87a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // is mapped to a fixed memory range). 88a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // * If a binary is compiled with -pie, all the modules are 89a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // mapped high at address space (in particular, higher than 90a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // shadow memory of the tool), so the module can't be the 91a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov // first entry. 926895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov *offset = (addr - (i ? start : 0)) + file_offset; 936895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov return true; 946895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov } 956895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov } 966895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov if (filename_size) 976895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov filename[0] = '\0'; 986895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov return false; 996895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov } 1006895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 10146f9395baf65e17f1a3f7a3a1deee72a1560ac53Alexey Samsonov# if SANITIZER_LINUX 102ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko ProcSelfMapsBuff proc_self_maps_; 1036895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov char *current_; 10493da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko 10593da8b6a5e0ed2ca621897504c5d06449b3d7077Alexander Potapenko // Static mappings cache. 106ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko static ProcSelfMapsBuff cached_proc_self_maps_; 107ad91267d45fef531c1082ab7974e4cc78aba5280Alexander Potapenko static StaticSpinMutex cache_lock_; // protects cached_proc_self_maps_. 10846f9395baf65e17f1a3f7a3a1deee72a1560ac53Alexey Samsonov# elif SANITIZER_MAC 1096895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov template<u32 kLCSegment, typename SegmentCommand> 1106895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset, 1114a1a495f29b63d44e012f6edcee6307ddac253efAlexey Samsonov char filename[], uptr filename_size, 1124a1a495f29b63d44e012f6edcee6307ddac253efAlexey Samsonov uptr *protection); 1136895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov int current_image_; 1146895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov u32 current_magic_; 1158bf8b7943848973398be0c3ad99855e20da6d6faAlexander Potapenko u32 current_filetype_; 1166895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov int current_load_cmd_count_; 1176895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov char *current_load_cmd_addr_; 118f7fa68f5efbd32acd36987ab55305a3abc037636Alexey Samsonov# endif 1196895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}; 1206895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 121e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov#endif // _WIN32 122e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov 1236895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov} // namespace __sanitizer 1246895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov 1256895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#endif // SANITIZER_PROCMAPS_H 126