1//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between AddressSanitizer and ThreadSanitizer.
10//
11// Information about the process mappings.
12//===----------------------------------------------------------------------===//
13#ifndef SANITIZER_PROCMAPS_H
14#define SANITIZER_PROCMAPS_H
15
16#include "sanitizer_platform.h"
17
18#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
19 SANITIZER_APPLE || SANITIZER_SOLARIS || SANITIZER_HAIKU || \
20 SANITIZER_FUCHSIA || SANITIZER_AIX
21
22# include "sanitizer_aix.h"
23# include "sanitizer_common.h"
24# include "sanitizer_fuchsia.h"
25# include "sanitizer_internal_defs.h"
26# include "sanitizer_linux.h"
27# include "sanitizer_mac.h"
28# include "sanitizer_mutex.h"
29
30namespace __sanitizer {
31
32// Memory protection masks.
33static const uptr kProtectionRead = 1;
34static const uptr kProtectionWrite = 2;
35static const uptr kProtectionExecute = 4;
36static const uptr kProtectionShared = 8;
37
38struct MemoryMappedSegmentData;
39
40class MemoryMappedSegment {
41 public:
42 explicit MemoryMappedSegment(char *buff = nullptr, uptr size = 0)
43 : filename(buff), filename_size(size), data_(nullptr) {}
44 ~MemoryMappedSegment() {}
45
46 bool IsReadable() const { return protection & kProtectionRead; }
47 bool IsWritable() const { return protection & kProtectionWrite; }
48 bool IsExecutable() const { return protection & kProtectionExecute; }
49 bool IsShared() const { return protection & kProtectionShared; }
50
51 void AddAddressRanges(LoadedModule *module);
52
53 uptr start;
54 uptr end;
55 uptr offset;
56 char *filename; // owned by caller
57 uptr filename_size;
58 uptr protection;
59 ModuleArch arch;
60 u8 uuid[kModuleUUIDSize];
61
62 private:
63 friend class MemoryMappingLayout;
64
65 // This field is assigned and owned by MemoryMappingLayout if needed
66 MemoryMappedSegmentData *data_;
67};
68
69struct ImageHeader;
70
71class MemoryMappingLayoutBase {
72 public:
73 virtual bool Next(MemoryMappedSegment *segment) { UNIMPLEMENTED(); }
74 virtual bool Error() const { UNIMPLEMENTED(); };
75 virtual void Reset() { UNIMPLEMENTED(); }
76
77 protected:
78 ~MemoryMappingLayoutBase() {}
79};
80
81class MemoryMappingLayout : public MemoryMappingLayoutBase {
82 public:
83 explicit MemoryMappingLayout(bool cache_enabled);
84
85// This destructor cannot be virtual, as it would cause an operator new() linking
86// failures in hwasan test cases. However non-virtual destructors emit warnings
87// in macOS build, hence disabling those
88#ifdef __clang__
89#pragma clang diagnostic push
90#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
91#endif
92 ~MemoryMappingLayout();
93#ifdef __clang__
94#pragma clang diagnostic pop
95#endif
96
97 virtual bool Next(MemoryMappedSegment *segment) override;
98 virtual bool Error() const override;
99 virtual void Reset() override;
100 // In some cases, e.g. when running under a sandbox on Linux, ASan is unable
101 // to obtain the memory mappings. It should fall back to pre-cached data
102 // instead of aborting.
103 static void CacheMemoryMappings();
104
105 // Adds all mapped objects into a vector.
106 void DumpListOfModules(InternalMmapVectorNoCtor<LoadedModule> *modules);
107
108 protected:
109#if SANITIZER_APPLE
110 virtual const ImageHeader *CurrentImageHeader();
111#endif
112 MemoryMappingLayoutData data_;
113
114 private:
115 void LoadFromCache();
116};
117
118// Returns code range for the specified module.
119bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end);
120
121bool IsDecimal(char c);
122uptr ParseDecimal(const char **p);
123bool IsHex(char c);
124uptr ParseHex(const char **p);
125
126} // namespace __sanitizer
127
128#endif
129#endif // SANITIZER_PROCMAPS_H
130