1 | //===-- SBMemoryRegionInfo.cpp --------------------------------------------===// |
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 | #include "lldb/API/SBMemoryRegionInfo.h" |
10 | #include "Utils.h" |
11 | #include "lldb/API/SBDefines.h" |
12 | #include "lldb/API/SBError.h" |
13 | #include "lldb/API/SBStream.h" |
14 | #include "lldb/Target/MemoryRegionInfo.h" |
15 | #include "lldb/Utility/Instrumentation.h" |
16 | #include "lldb/Utility/StreamString.h" |
17 | #include <optional> |
18 | |
19 | using namespace lldb; |
20 | using namespace lldb_private; |
21 | |
22 | SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_up(new MemoryRegionInfo()) { |
23 | LLDB_INSTRUMENT_VA(this); |
24 | } |
25 | |
26 | SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin, |
27 | lldb::addr_t end, uint32_t permissions, |
28 | bool mapped, bool stack_memory) |
29 | : SBMemoryRegionInfo() { |
30 | LLDB_INSTRUMENT_VA(this, name, begin, end, permissions, mapped, stack_memory); |
31 | m_opaque_up->SetName(name); |
32 | m_opaque_up->GetRange().SetRangeBase(begin); |
33 | m_opaque_up->GetRange().SetRangeEnd(end); |
34 | m_opaque_up->SetLLDBPermissions(permissions); |
35 | m_opaque_up->SetMapped(mapped ? MemoryRegionInfo::eYes |
36 | : MemoryRegionInfo::eNo); |
37 | m_opaque_up->SetIsStackMemory(stack_memory ? MemoryRegionInfo::eYes |
38 | : MemoryRegionInfo::eNo); |
39 | } |
40 | |
41 | SBMemoryRegionInfo::SBMemoryRegionInfo(const MemoryRegionInfo *lldb_object_ptr) |
42 | : m_opaque_up(new MemoryRegionInfo()) { |
43 | if (lldb_object_ptr) |
44 | ref() = *lldb_object_ptr; |
45 | } |
46 | |
47 | SBMemoryRegionInfo::SBMemoryRegionInfo(const SBMemoryRegionInfo &rhs) { |
48 | LLDB_INSTRUMENT_VA(this, rhs); |
49 | m_opaque_up = clone(src: rhs.m_opaque_up); |
50 | } |
51 | |
52 | const SBMemoryRegionInfo &SBMemoryRegionInfo:: |
53 | operator=(const SBMemoryRegionInfo &rhs) { |
54 | LLDB_INSTRUMENT_VA(this, rhs); |
55 | |
56 | if (this != &rhs) |
57 | m_opaque_up = clone(src: rhs.m_opaque_up); |
58 | return *this; |
59 | } |
60 | |
61 | SBMemoryRegionInfo::~SBMemoryRegionInfo() = default; |
62 | |
63 | void SBMemoryRegionInfo::Clear() { |
64 | LLDB_INSTRUMENT_VA(this); |
65 | |
66 | m_opaque_up->Clear(); |
67 | } |
68 | |
69 | bool SBMemoryRegionInfo::operator==(const SBMemoryRegionInfo &rhs) const { |
70 | LLDB_INSTRUMENT_VA(this, rhs); |
71 | |
72 | return ref() == rhs.ref(); |
73 | } |
74 | |
75 | bool SBMemoryRegionInfo::operator!=(const SBMemoryRegionInfo &rhs) const { |
76 | LLDB_INSTRUMENT_VA(this, rhs); |
77 | |
78 | return ref() != rhs.ref(); |
79 | } |
80 | |
81 | MemoryRegionInfo &SBMemoryRegionInfo::ref() { return *m_opaque_up; } |
82 | |
83 | const MemoryRegionInfo &SBMemoryRegionInfo::ref() const { return *m_opaque_up; } |
84 | |
85 | lldb::addr_t SBMemoryRegionInfo::GetRegionBase() { |
86 | LLDB_INSTRUMENT_VA(this); |
87 | |
88 | return m_opaque_up->GetRange().GetRangeBase(); |
89 | } |
90 | |
91 | lldb::addr_t SBMemoryRegionInfo::GetRegionEnd() { |
92 | LLDB_INSTRUMENT_VA(this); |
93 | |
94 | return m_opaque_up->GetRange().GetRangeEnd(); |
95 | } |
96 | |
97 | bool SBMemoryRegionInfo::IsReadable() { |
98 | LLDB_INSTRUMENT_VA(this); |
99 | |
100 | return m_opaque_up->GetReadable() == MemoryRegionInfo::eYes; |
101 | } |
102 | |
103 | bool SBMemoryRegionInfo::IsWritable() { |
104 | LLDB_INSTRUMENT_VA(this); |
105 | |
106 | return m_opaque_up->GetWritable() == MemoryRegionInfo::eYes; |
107 | } |
108 | |
109 | bool SBMemoryRegionInfo::IsExecutable() { |
110 | LLDB_INSTRUMENT_VA(this); |
111 | |
112 | return m_opaque_up->GetExecutable() == MemoryRegionInfo::eYes; |
113 | } |
114 | |
115 | bool SBMemoryRegionInfo::IsMapped() { |
116 | LLDB_INSTRUMENT_VA(this); |
117 | |
118 | return m_opaque_up->GetMapped() == MemoryRegionInfo::eYes; |
119 | } |
120 | |
121 | const char *SBMemoryRegionInfo::GetName() { |
122 | LLDB_INSTRUMENT_VA(this); |
123 | |
124 | return m_opaque_up->GetName().AsCString(); |
125 | } |
126 | |
127 | bool SBMemoryRegionInfo::HasDirtyMemoryPageList() { |
128 | LLDB_INSTRUMENT_VA(this); |
129 | |
130 | return m_opaque_up->GetDirtyPageList().has_value(); |
131 | } |
132 | |
133 | uint32_t SBMemoryRegionInfo::GetNumDirtyPages() { |
134 | LLDB_INSTRUMENT_VA(this); |
135 | |
136 | uint32_t num_dirty_pages = 0; |
137 | const std::optional<std::vector<addr_t>> &dirty_page_list = |
138 | m_opaque_up->GetDirtyPageList(); |
139 | if (dirty_page_list) |
140 | num_dirty_pages = dirty_page_list->size(); |
141 | |
142 | return num_dirty_pages; |
143 | } |
144 | |
145 | addr_t SBMemoryRegionInfo::GetDirtyPageAddressAtIndex(uint32_t idx) { |
146 | LLDB_INSTRUMENT_VA(this, idx); |
147 | |
148 | addr_t dirty_page_addr = LLDB_INVALID_ADDRESS; |
149 | const std::optional<std::vector<addr_t>> &dirty_page_list = |
150 | m_opaque_up->GetDirtyPageList(); |
151 | if (dirty_page_list && idx < dirty_page_list->size()) |
152 | dirty_page_addr = (*dirty_page_list)[idx]; |
153 | |
154 | return dirty_page_addr; |
155 | } |
156 | |
157 | int SBMemoryRegionInfo::GetPageSize() { |
158 | LLDB_INSTRUMENT_VA(this); |
159 | |
160 | return m_opaque_up->GetPageSize(); |
161 | } |
162 | |
163 | bool SBMemoryRegionInfo::GetDescription(SBStream &description) { |
164 | LLDB_INSTRUMENT_VA(this, description); |
165 | |
166 | Stream &strm = description.ref(); |
167 | const addr_t load_addr = m_opaque_up->GetRange().base; |
168 | |
169 | strm.Printf(format: "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 " " , load_addr, |
170 | load_addr + m_opaque_up->GetRange().size); |
171 | strm.Printf(format: m_opaque_up->GetReadable() ? "R" : "-" ); |
172 | strm.Printf(format: m_opaque_up->GetWritable() ? "W" : "-" ); |
173 | strm.Printf(format: m_opaque_up->GetExecutable() ? "X" : "-" ); |
174 | strm.Printf(format: "]" ); |
175 | |
176 | return true; |
177 | } |
178 | |