1use crate::{lldb_addr_t, sys, SBStream};
2use std::ffi::CStr;
3use std::fmt;
4
5pub struct SBMemoryRegionInfo {
11 pub raw: sys::SBMemoryRegionInfoRef,
13}
14
15impl SBMemoryRegionInfo {
16 #[allow(missing_docs)]
17 pub(crate) fn new() -> Self {
18 SBMemoryRegionInfo::wrap(unsafe { sys::CreateSBMemoryRegionInfo() })
19 }
20
21 pub(crate) fn wrap(raw: sys::SBMemoryRegionInfoRef) -> SBMemoryRegionInfo {
23 SBMemoryRegionInfo { raw }
24 }
25
26 #[allow(missing_docs)]
27 pub fn clear(&self) {
28 unsafe { sys::SBMemoryRegionInfoClear(self.raw) };
29 }
30
31 pub fn get_region_base(&self) -> lldb_addr_t {
37 unsafe { sys::SBMemoryRegionInfoGetRegionBase(self.raw) }
38 }
39
40 pub fn get_region_end(&self) -> lldb_addr_t {
46 unsafe { sys::SBMemoryRegionInfoGetRegionEnd(self.raw) }
47 }
48
49 pub fn is_readable(&self) -> bool {
56 unsafe { sys::SBMemoryRegionInfoIsReadable(self.raw) }
57 }
58
59 pub fn is_writable(&self) -> bool {
66 unsafe { sys::SBMemoryRegionInfoIsWritable(self.raw) }
67 }
68
69 pub fn is_executable(&self) -> bool {
76 unsafe { sys::SBMemoryRegionInfoIsExecutable(self.raw) }
77 }
78
79 pub fn is_mapped(&self) -> bool {
82 unsafe { sys::SBMemoryRegionInfoIsMapped(self.raw) }
83 }
84
85 pub fn get_name(&self) -> Option<String> {
92 unsafe {
93 let ptr = sys::SBMemoryRegionInfoGetName(self.raw);
94
95 if !ptr.is_null() {
96 match CStr::from_ptr(ptr).to_str() {
97 Ok(s) => Some(s.to_owned()),
98 _ => panic!("No MemoryRegionInfo name string?"),
99 }
100 } else {
101 None
102 }
103 }
104 }
105
106 pub fn has_dirty_memory_page_list(&self) -> bool {
115 unsafe { sys::SBMemoryRegionInfoHasDirtyMemoryPageList(self.raw) }
116 }
117
118 pub fn dirty_pages(&self) -> SBMemoryRegionInfoDirtyPageIter {
124 SBMemoryRegionInfoDirtyPageIter { info: self, idx: 0 }
125 }
126
127 pub fn get_page_size(&self) -> i32 {
130 unsafe { sys::SBMemoryRegionInfoGetPageSize(self.raw) }
131 }
132}
133
134impl Clone for SBMemoryRegionInfo {
135 fn clone(&self) -> Self {
136 Self {
137 raw: unsafe { sys::CloneSBMemoryRegionInfo(self.raw) },
138 }
139 }
140}
141
142impl fmt::Debug for SBMemoryRegionInfo {
143 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
144 let stream = SBStream::new();
145 unsafe { sys::SBMemoryRegionInfoGetDescription(self.raw, stream.raw) };
146 write!(fmt, "SBMemoryRegionInfo {{ {} }}", stream.data())
147 }
148}
149
150impl Default for SBMemoryRegionInfo {
151 fn default() -> Self {
152 Self::new()
153 }
154}
155
156impl Drop for SBMemoryRegionInfo {
157 fn drop(&mut self) {
158 unsafe { sys::DisposeSBMemoryRegionInfo(self.raw) };
159 }
160}
161
162unsafe impl Send for SBMemoryRegionInfo {}
163unsafe impl Sync for SBMemoryRegionInfo {}
164
165pub struct SBMemoryRegionInfoDirtyPageIter<'d> {
169 info: &'d SBMemoryRegionInfo,
170 idx: u32,
171}
172
173impl Iterator for SBMemoryRegionInfoDirtyPageIter<'_> {
174 type Item = lldb_addr_t;
175
176 fn next(&mut self) -> Option<Self::Item> {
177 if self.idx < unsafe { sys::SBMemoryRegionInfoGetNumDirtyPages(self.info.raw) } {
178 let r = Some(unsafe {
179 sys::SBMemoryRegionInfoGetDirtyPageAddressAtIndex(self.info.raw, self.idx)
180 });
181 self.idx += 1;
182 r
183 } else {
184 None
185 }
186 }
187
188 fn size_hint(&self) -> (usize, Option<usize>) {
189 let sz = unsafe { sys::SBMemoryRegionInfoGetNumDirtyPages(self.info.raw) } as usize;
190 (sz - self.idx as usize, Some(sz))
191 }
192}
193
194#[cfg(feature = "graphql")]
195#[juniper::graphql_object]
196impl SBMemoryRegionInfo {
197 fn region_base() -> i32 {
199 self.get_region_base() as i32
200 }
201
202 fn region_end() -> i32 {
204 self.get_region_end() as i32
205 }
206
207 fn is_readable() -> bool {
208 self.is_readable()
209 }
210
211 fn is_writable() -> bool {
212 self.is_writable()
213 }
214
215 fn is_executable() -> bool {
216 self.is_executable()
217 }
218
219 fn is_mapped() -> bool {
220 self.is_mapped()
221 }
222
223 fn name() -> Option<String> {
224 self.get_name()
225 }
226
227 fn page_size() -> i32 {
228 self.get_page_size()
229 }
230}