• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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