1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | #if defined(__arm__) |
6 | #define PAGE_SIZE sysconf(_SC_PAGESIZE) |
7 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
8 | #endif |
9 | |
10 | #ifdef BIT64 |
11 | #define PRIA "016" |
12 | #else |
13 | #define PRIA "08" |
14 | #endif |
15 | |
16 | enum MEMORY_REGION_FLAGS : uint32_t |
17 | { |
18 | // PF_X = 0x01, // Execute |
19 | // PF_W = 0x02, // Write |
20 | // PF_R = 0x04, // Read |
21 | MEMORY_REGION_FLAG_PERMISSIONS_MASK = 0x0f, |
22 | MEMORY_REGION_FLAG_SHARED = 0x10, |
23 | MEMORY_REGION_FLAG_PRIVATE = 0x20, |
24 | MEMORY_REGION_FLAG_MEMORY_BACKED = 0x40 |
25 | }; |
26 | |
27 | struct MemoryRegion |
28 | { |
29 | private: |
30 | uint32_t m_flags; |
31 | uint64_t m_startAddress; |
32 | uint64_t m_endAddress; |
33 | uint64_t m_offset; |
34 | |
35 | // The name used for NT_FILE output |
36 | const char* m_fileName; |
37 | |
38 | public: |
39 | MemoryRegion(uint32_t flags, uint64_t start, uint64_t end) : |
40 | m_flags(flags), |
41 | m_startAddress(start), |
42 | m_endAddress(end), |
43 | m_offset(0), |
44 | m_fileName(nullptr) |
45 | { |
46 | assert((start & ~PAGE_MASK) == 0); |
47 | assert((end & ~PAGE_MASK) == 0); |
48 | } |
49 | |
50 | MemoryRegion(uint32_t flags, uint64_t start, uint64_t end, uint64_t offset, const char* filename) : |
51 | m_flags(flags), |
52 | m_startAddress(start), |
53 | m_endAddress(end), |
54 | m_offset(offset), |
55 | m_fileName(filename) |
56 | { |
57 | assert((start & ~PAGE_MASK) == 0); |
58 | assert((end & ~PAGE_MASK) == 0); |
59 | } |
60 | |
61 | // This is a special constructor for the module base address |
62 | // set where the start/end are not page aligned and "offset" |
63 | // is reused as the module base address. |
64 | MemoryRegion(uint32_t flags, uint64_t start, uint64_t end, uint64_t baseAddress) : |
65 | m_flags(flags), |
66 | m_startAddress(start), |
67 | m_endAddress(end), |
68 | m_offset(baseAddress), |
69 | m_fileName(nullptr) |
70 | { |
71 | } |
72 | |
73 | // copy with new file name constructor |
74 | MemoryRegion(const MemoryRegion& region, const char* fileName) : |
75 | m_flags(region.m_flags), |
76 | m_startAddress(region.m_startAddress), |
77 | m_endAddress(region.m_endAddress), |
78 | m_offset(region.m_offset), |
79 | m_fileName(fileName) |
80 | { |
81 | } |
82 | |
83 | // copy with new flags constructor. The file name is not copied. |
84 | MemoryRegion(const MemoryRegion& region, uint32_t flags) : |
85 | m_flags(flags), |
86 | m_startAddress(region.m_startAddress), |
87 | m_endAddress(region.m_endAddress), |
88 | m_offset(region.m_offset), |
89 | m_fileName(nullptr) |
90 | { |
91 | } |
92 | |
93 | // copy constructor |
94 | MemoryRegion(const MemoryRegion& region) : |
95 | m_flags(region.m_flags), |
96 | m_startAddress(region.m_startAddress), |
97 | m_endAddress(region.m_endAddress), |
98 | m_offset(region.m_offset), |
99 | m_fileName(region.m_fileName) |
100 | { |
101 | } |
102 | |
103 | uint32_t Permissions() const { return m_flags & MEMORY_REGION_FLAG_PERMISSIONS_MASK; } |
104 | uint32_t Flags() const { return m_flags; } |
105 | bool IsBackedByMemory() const { return (m_flags & MEMORY_REGION_FLAG_MEMORY_BACKED) != 0; } |
106 | uint64_t StartAddress() const { return m_startAddress; } |
107 | uint64_t EndAddress() const { return m_endAddress; } |
108 | uint64_t Size() const { return m_endAddress - m_startAddress; } |
109 | uint64_t Offset() const { return m_offset; } |
110 | const char* FileName() const { return m_fileName; } |
111 | |
112 | bool operator<(const MemoryRegion& rhs) const |
113 | { |
114 | return (m_startAddress < rhs.m_startAddress) && (m_endAddress <= rhs.m_startAddress); |
115 | } |
116 | |
117 | // Returns true if "rhs" is wholly contained in this one |
118 | bool Contains(const MemoryRegion& rhs) const |
119 | { |
120 | return (m_startAddress <= rhs.m_startAddress) && (m_endAddress >= rhs.m_endAddress); |
121 | } |
122 | |
123 | // Free the file name memory |
124 | void Cleanup() |
125 | { |
126 | if (m_fileName != nullptr) |
127 | { |
128 | free((void*)m_fileName); |
129 | m_fileName = nullptr; |
130 | } |
131 | } |
132 | |
133 | void Trace() const |
134 | { |
135 | TRACE("%s%" PRIA PRIx64 " - %" PRIA PRIx64 " (%06" PRId64 ") %" PRIA PRIx64 " %02x %s\n" , IsBackedByMemory() ? "*" : " " , m_startAddress, m_endAddress, |
136 | Size() / PAGE_SIZE, m_offset, m_flags, m_fileName != nullptr ? m_fileName : "" ); |
137 | } |
138 | }; |
139 | |