blob: 565901960c7e67b424c11cbdb3c64872d7774bf2 [file] [log] [blame]
Alexey Samsonov28a98952012-06-07 06:15:12 +00001//===-- 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"
Alexander Potapenko78114252012-12-01 02:39:45 +000018#include "sanitizer_mutex.h"
Alexey Samsonov28a98952012-06-07 06:15:12 +000019
20namespace __sanitizer {
21
Evgeniy Stepanov95eaa212013-03-19 14:54:17 +000022#if SANITIZER_WINDOWS
Alexey Samsonovcc622112012-08-27 13:48:48 +000023class MemoryMappingLayout {
Alexey Samsonov28d8be22012-08-27 14:08:53 +000024 public:
Alexey Samsonov384de7c2012-08-28 08:27:08 +000025 MemoryMappingLayout() {}
Alexey Samsonovcae486c2012-08-28 07:22:24 +000026 bool GetObjectNameAndOffset(uptr addr, uptr *offset,
Alexey Samsonov91f833a2013-03-13 07:39:25 +000027 char filename[], uptr filename_size,
28 uptr *protection) {
Alexey Samsonovcae486c2012-08-28 07:22:24 +000029 UNIMPLEMENTED();
Alexey Samsonovcae486c2012-08-28 07:22:24 +000030 }
Alexey Samsonovcc622112012-08-27 13:48:48 +000031};
32
33#else // _WIN32
Evgeniy Stepanov0af67232013-03-19 14:33:38 +000034#if SANITIZER_LINUX
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +000035struct ProcSelfMapsBuff {
36 char *data;
37 uptr mmaped_size;
38 uptr len;
39};
Evgeniy Stepanov0af67232013-03-19 14:33:38 +000040#endif // SANITIZER_LINUX
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +000041
Alexey Samsonovcc622112012-08-27 13:48:48 +000042class MemoryMappingLayout {
Alexey Samsonov28a98952012-06-07 06:15:12 +000043 public:
Alexander Potapenkof8109dd2013-03-26 10:34:37 +000044 explicit MemoryMappingLayout(bool cache_enabled);
Alexey Samsonov28a98952012-06-07 06:15:12 +000045 bool Next(uptr *start, uptr *end, uptr *offset,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000046 char filename[], uptr filename_size, uptr *protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +000047 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,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000051 char filename[], uptr filename_size,
52 uptr *protection);
Alexander Potapenko78114252012-12-01 02:39:45 +000053 // 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();
Alexey Samsonovcc622112012-08-27 13:48:48 +000057 ~MemoryMappingLayout();
Kostya Serebryany98390d02012-06-20 15:19:17 +000058
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000059 // 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
Alexey Samsonov28a98952012-06-07 06:15:12 +000065 private:
Alexander Potapenko78114252012-12-01 02:39:45 +000066 void LoadFromCache();
Alexey Samsonov28a98952012-06-07 06:15:12 +000067 // 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,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000071 char filename[], uptr filename_size,
72 uptr *protection) {
Alexey Samsonov28a98952012-06-07 06:15:12 +000073 Reset();
74 uptr start, end, file_offset;
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000075 for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size,
76 protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +000077 i++) {
78 if (addr >= start && addr < end) {
Alexey Samsonov961276a2012-07-03 08:24:14 +000079 // 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.
Alexey Samsonov28a98952012-06-07 06:15:12 +000090 *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
Alexey Samsonovcae486c2012-08-28 07:22:24 +000099# if defined __linux__
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +0000100 ProcSelfMapsBuff proc_self_maps_;
Alexey Samsonov28a98952012-06-07 06:15:12 +0000101 char *current_;
Alexander Potapenko78114252012-12-01 02:39:45 +0000102
103 // Static mappings cache.
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +0000104 static ProcSelfMapsBuff cached_proc_self_maps_;
105 static StaticSpinMutex cache_lock_; // protects cached_proc_self_maps_.
Alexey Samsonovcae486c2012-08-28 07:22:24 +0000106# elif defined __APPLE__
Alexey Samsonov28a98952012-06-07 06:15:12 +0000107 template<u32 kLCSegment, typename SegmentCommand>
108 bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,
Alexey Samsonov91f833a2013-03-13 07:39:25 +0000109 char filename[], uptr filename_size,
110 uptr *protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +0000111 int current_image_;
112 u32 current_magic_;
Alexander Potapenko77c0ac22012-10-02 15:42:24 +0000113 u32 current_filetype_;
Alexey Samsonov28a98952012-06-07 06:15:12 +0000114 int current_load_cmd_count_;
115 char *current_load_cmd_addr_;
Alexey Samsonovcae486c2012-08-28 07:22:24 +0000116# endif
Alexey Samsonov28a98952012-06-07 06:15:12 +0000117};
118
Alexey Samsonovcc622112012-08-27 13:48:48 +0000119#endif // _WIN32
120
Alexey Samsonov28a98952012-06-07 06:15:12 +0000121} // namespace __sanitizer
122
123#endif // SANITIZER_PROCMAPS_H