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(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(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("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 " ", load_addr,
170               load_addr + m_opaque_up->GetRange().size);
171   strm.Printf(m_opaque_up->GetReadable() ? "R" : "-");
172   strm.Printf(m_opaque_up->GetWritable() ? "W" : "-");
173   strm.Printf(m_opaque_up->GetExecutable() ? "X" : "-");
174   strm.Printf("]");
175 
176   return true;
177 }
178