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