sanitizer_procmaps.h revision 9ae2883d88dd28b9c5dc862107e6e6d12a35926e
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  MemoryMappingLayout() {}
26  bool GetObjectNameAndOffset(uptr addr, uptr *offset,
27                              char filename[], uptr filename_size,
28                              uptr *protection) {
29    UNIMPLEMENTED();
30  }
31};
32
33#else  // _WIN32
34#if SANITIZER_LINUX
35struct ProcSelfMapsBuff {
36  char *data;
37  uptr mmaped_size;
38  uptr len;
39};
40#endif  // SANITIZER_LINUX
41
42class MemoryMappingLayout {
43 public:
44  explicit MemoryMappingLayout(bool cache_enabled);
45  bool Next(uptr *start, uptr *end, uptr *offset,
46            char filename[], uptr filename_size, uptr *protection);
47  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,
51                              char filename[], uptr filename_size,
52                              uptr *protection);
53  // 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();
57  ~MemoryMappingLayout();
58
59  // 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
65 private:
66  void LoadFromCache();
67  // 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,
71                                     char filename[], uptr filename_size,
72                                     uptr *protection) {
73    Reset();
74    uptr start, end, file_offset;
75    for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size,
76                         protection);
77         i++) {
78      if (addr >= start && addr < end) {
79        // 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.
90        *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
99# if defined __linux__
100  ProcSelfMapsBuff proc_self_maps_;
101  char *current_;
102
103  // Static mappings cache.
104  static ProcSelfMapsBuff cached_proc_self_maps_;
105  static StaticSpinMutex cache_lock_;  // protects cached_proc_self_maps_.
106# elif defined __APPLE__
107  template<u32 kLCSegment, typename SegmentCommand>
108  bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,
109                       char filename[], uptr filename_size,
110                       uptr *protection);
111  int current_image_;
112  u32 current_magic_;
113  u32 current_filetype_;
114  int current_load_cmd_count_;
115  char *current_load_cmd_addr_;
116# endif
117};
118
119#endif  // _WIN32
120
121}  // namespace __sanitizer
122
123#endif  // SANITIZER_PROCMAPS_H
124