sanitizer_procmaps.h revision 821acfaccc7d11b987e2882b022e8d167b0c8a54
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// Returns code range for the specified module.
130bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end);
131
132#endif  // SANITIZER_WINDOWS
133
134}  // namespace __sanitizer
135
136#endif  // SANITIZER_PROCMAPS_H
137