Skip to content

Commit d93ca79

Browse files
committed
feat: add many safe wrapper functions
1 parent bde72aa commit d93ca79

File tree

8 files changed

+240
-4
lines changed

8 files changed

+240
-4
lines changed

src/address.rs

+15
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,21 @@ impl SBAddress {
234234
pub fn line_entry(&self) -> Option<SBLineEntry> {
235235
SBLineEntry::maybe_wrap(unsafe { sys::SBAddressGetLineEntry(self.raw) })
236236
}
237+
238+
/// Returns offset of the address in the section
239+
///
240+
/// See also:
241+
/// - [`get_section`] for get the section corresponding to this address
242+
///
243+
/// [`get_section`]: Self::get_section
244+
pub fn get_offset(&self) -> lldb_addr_t {
245+
unsafe { sys::SBAddressGetOffset(self.raw) }
246+
}
247+
248+
/// Returns the corresponding section of this address.
249+
pub fn get_section(&self) -> Option<SBSection> {
250+
SBSection::maybe_wrap(unsafe { sys::SBAddressGetSection(self.raw) })
251+
}
237252
}
238253

239254
impl Clone for SBAddress {

src/data.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// option. This file may not be copied, modified, or distributed
55
// except according to those terms.
66

7-
use crate::sys;
7+
use crate::{sys, SBError};
88

99
/// A block of data.
1010
#[derive(Debug)]
@@ -32,6 +32,36 @@ impl SBData {
3232
pub fn is_valid(&self) -> bool {
3333
unsafe { sys::SBDataIsValid(self.raw) }
3434
}
35+
36+
/// Get address of the specified offset in this data region
37+
pub fn get_address(&self, offset: sys::lldb_offset_t) -> Result<sys::lldb_addr_t, SBError> {
38+
let error = SBError::default();
39+
let result = unsafe { sys::SBDataGetAddress(self.raw, error.raw, offset) };
40+
if error.is_success() {
41+
Ok(result)
42+
} else {
43+
Err(error)
44+
}
45+
}
46+
47+
/// Reads the data at specified offset to the buffer.
48+
fn read_raw_data(&self, offset: sys::lldb_offset_t, buffer: &mut [u8]) -> Result<(), SBError> {
49+
let error = SBError::default();
50+
unsafe {
51+
sys::SBDataReadRawData(
52+
self.raw,
53+
error.raw,
54+
offset,
55+
buffer.as_mut_ptr() as *mut _,
56+
buffer.len(),
57+
);
58+
}
59+
if error.is_success() {
60+
Ok(())
61+
} else {
62+
Err(error)
63+
}
64+
}
3565
}
3666

3767
impl Clone for SBData {

src/filespec.rs

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ impl SBFileSpec {
3333
}
3434
}
3535

36+
/// Create SBFileSpec from path
37+
pub fn from_path(path: &str, resolve: bool) -> Self {
38+
let path_cstring = std::ffi::CString::new(path).unwrap();
39+
Self::wrap(unsafe { sys::CreateSBFileSpec3(path_cstring.as_ptr(), resolve) })
40+
}
41+
3642
/// Check whether or not this is a valid `SBFileSpec` value.
3743
pub fn is_valid(&self) -> bool {
3844
unsafe { sys::SBFileSpecIsValid(self.raw) }

src/module.rs

+64-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
// except according to those terms.
66

77
use crate::{
8-
sys, SBFileSpec, SBSection, SBStream, SBSymbolContextList, SBTypeList, SymbolType, TypeClass,
8+
sys, SBFileSpec, SBSection, SBStream, SBSymbol, SBSymbolContextList, SBTypeList, SymbolType,
9+
TypeClass,
910
};
1011
use std::ffi::CString;
1112
use std::fmt;
@@ -99,6 +100,11 @@ impl SBModule {
99100
pub fn types(&self, type_mask: TypeClass) -> SBTypeList {
100101
SBTypeList::wrap(unsafe { sys::SBModuleGetTypes(self.raw, type_mask.bits()) })
101102
}
103+
104+
/// Get a list of all symbols in the module
105+
pub fn symbols(&self) -> ModuleSymbols {
106+
ModuleSymbols { module: self }
107+
}
102108
}
103109

104110
/// Iterate over the [sections] in a [module].
@@ -133,6 +139,63 @@ impl<'d> Iterator for SBModuleSectionIter<'d> {
133139

134140
impl<'d> ExactSizeIterator for SBModuleSectionIter<'d> {}
135141

142+
/// The list of symbols in the module
143+
pub struct ModuleSymbols<'d> {
144+
module: &'d SBModule,
145+
}
146+
147+
impl<'d> ModuleSymbols<'d> {
148+
pub fn len(&self) -> usize {
149+
unsafe { sys::SBModuleGetNumSymbols(self.module.raw) }
150+
}
151+
152+
pub fn get(&self, index: usize) -> Option<SBSymbol> {
153+
if index < self.len() {
154+
let symbol = unsafe { sys::SBModuleGetSymbolAtIndex(self.module.raw, index) };
155+
Some(SBSymbol { raw: symbol })
156+
} else {
157+
None
158+
}
159+
}
160+
}
161+
162+
impl<'a> IntoIterator for ModuleSymbols<'a> {
163+
type Item = SBSymbol;
164+
type IntoIter = ModuleSymbolsIter<'a>;
165+
166+
fn into_iter(self) -> Self::IntoIter {
167+
ModuleSymbolsIter {
168+
module: self,
169+
index: 0,
170+
}
171+
}
172+
}
173+
174+
pub struct ModuleSymbolsIter<'d> {
175+
module: ModuleSymbols<'d>,
176+
index: usize,
177+
}
178+
179+
impl<'d> Iterator for ModuleSymbolsIter<'d> {
180+
type Item = SBSymbol;
181+
182+
fn next(&mut self) -> Option<Self::Item> {
183+
if self.index < self.module.len() {
184+
self.index += 1;
185+
self.module.get(self.index - 1)
186+
} else {
187+
None
188+
}
189+
}
190+
191+
fn size_hint(&self) -> (usize, Option<usize>) {
192+
let len = self.module.len() - self.index;
193+
(len, Some(len))
194+
}
195+
}
196+
197+
impl<'d> ExactSizeIterator for ModuleSymbolsIter<'d> {}
198+
136199
impl Clone for SBModule {
137200
fn clone(&self) -> SBModule {
138201
SBModule {

src/modulespec.rs

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ pub struct SBModuleSpec {
1414
}
1515

1616
impl SBModuleSpec {
17+
/// Construct a new `SBModuleSpec`.
18+
pub(crate) fn wrap(raw: sys::SBModuleSpecRef) -> SBModuleSpec {
19+
SBModuleSpec { raw }
20+
}
21+
1722
/// Construct a new `Some(SBModuleSpec)` or `None`.
1823
#[allow(dead_code)]
1924
pub(crate) fn maybe_wrap(raw: sys::SBModuleSpecRef) -> Option<SBModuleSpec> {
@@ -29,6 +34,11 @@ impl SBModuleSpec {
2934
unsafe { sys::SBModuleSpecIsValid(self.raw) }
3035
}
3136

37+
/// Creates new empty SBModuleSpec
38+
pub fn new() -> Self {
39+
Self::wrap(unsafe { sys::CreateSBModuleSpec() })
40+
}
41+
3242
/// The file for the module on the host system that is running LLDB.
3343
///
3444
/// This can differ from the path on the platform since we might

src/process.rs

+81-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
use crate::{
88
lldb_addr_t, lldb_pid_t, lldb_tid_t, sys, Permissions, SBBroadcaster, SBError, SBEvent,
9-
SBMemoryRegionInfo, SBMemoryRegionInfoList, SBProcessInfo, SBQueue, SBStream, SBStructuredData,
10-
SBThread, StateType,
9+
SBFileSpec, SBMemoryRegionInfo, SBMemoryRegionInfoList, SBProcessInfo, SBQueue, SBStream,
10+
SBStructuredData, SBTarget, SBThread, StateType,
1111
};
1212
use std::ffi::{CStr, CString};
1313
use std::fmt;
@@ -559,6 +559,85 @@ impl SBProcess {
559559
pub fn get_memory_regions(&self) -> SBMemoryRegionInfoList {
560560
SBMemoryRegionInfoList::wrap(unsafe { sys::SBProcessGetMemoryRegions(self.raw) })
561561
}
562+
563+
/// Reads the memory at specified address in the process to the `buffer`
564+
pub fn read_memory(&self, addr: lldb_addr_t, buffer: &mut [u8]) -> Result<(), SBError> {
565+
// SBProcessReadMemory will return error the memory region is not allowed to read
566+
// and does not cause bad behavior so this method can be safe.
567+
let error = SBError::default();
568+
unsafe {
569+
sys::SBProcessReadMemory(
570+
self.raw,
571+
addr,
572+
buffer.as_mut_ptr() as *mut _,
573+
buffer.len(),
574+
error.raw,
575+
);
576+
}
577+
if error.is_success() {
578+
Ok(())
579+
} else {
580+
Err(error)
581+
}
582+
}
583+
584+
/// Writes the `buffer` data to the memory at specified address in the process
585+
pub fn write_memory(&self, addr: lldb_addr_t, buffer: &[u8]) -> Result<(), SBError> {
586+
let error = SBError::default();
587+
unsafe {
588+
sys::SBProcessWriteMemory(
589+
self.raw,
590+
addr,
591+
buffer.as_ptr() as *mut _,
592+
buffer.len(),
593+
error.raw,
594+
);
595+
}
596+
if error.is_success() {
597+
Ok(())
598+
} else {
599+
Err(error)
600+
}
601+
}
602+
603+
/// Returns the byte order of target process
604+
pub fn byte_order(&self) -> crate::ByteOrder {
605+
unsafe { sys::SBProcessGetByteOrder(self.raw) }
606+
}
607+
608+
/// Loads the specified image to the process
609+
pub fn load_image(&self, file: &SBFileSpec) -> Result<u32, SBError> {
610+
let error = SBError::default();
611+
let image_token = unsafe { sys::SBProcessLoadImage(self.raw, file.raw, error.raw) };
612+
if error.is_failure() {
613+
Err(error)
614+
} else {
615+
Ok(image_token)
616+
}
617+
}
618+
619+
/// Unloads the image loaded with [`load_image`]
620+
///
621+
/// [`load_image`]: Self::load_image
622+
pub fn unload_image(&self, image_token: u32) -> Result<(), SBError> {
623+
// the method returns error if image_token is not valid, instead of cause undefined behavior
624+
let error = SBError::wrap(unsafe { sys::SBProcessUnloadImage(self.raw, image_token) });
625+
if error.is_failure() {
626+
Err(error)
627+
} else {
628+
Ok(())
629+
}
630+
}
631+
632+
/// Returns the [`SBTarget`] corresponds to this SBProcess.
633+
///
634+
/// This never return None if `self` is [`valid`].
635+
///
636+
/// [`SBTarget`]: SBTarget
637+
/// [`valid`]: Self::is_valid
638+
pub fn target(&self) -> Option<SBTarget> {
639+
SBTarget::maybe_wrap(unsafe { sys::SBProcessGetTarget(self.raw) })
640+
}
562641
}
563642

564643
/// Iterate over the [threads] in a [process].

src/target.rs

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
SBModule, SBModuleSpec, SBPlatform, SBProcess, SBStream, SBSymbolContextList, SBValue,
1111
SBWatchpoint, SymbolType,
1212
};
13+
use lldb_sys::ByteOrder;
1314
use std::ffi::{CStr, CString};
1415
use std::fmt;
1516

@@ -386,6 +387,16 @@ impl SBTarget {
386387
pub fn set_launch_info(&self, launch_info: SBLaunchInfo) {
387388
unsafe { sys::SBTargetSetLaunchInfo(self.raw, launch_info.raw) };
388389
}
390+
391+
/// Returns the byte order of target
392+
pub fn byte_order(&self) -> ByteOrder {
393+
unsafe { sys::SBTargetGetByteOrder(self.raw) }
394+
}
395+
396+
/// Returns the size of address in bytes
397+
fn get_address_byte_size(&self) -> u32 {
398+
unsafe { sys::SBTargetGetAddressByteSize(self.raw) }
399+
}
389400
}
390401

391402
impl Clone for SBTarget {

src/value.rs

+22
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,28 @@ impl SBValue {
249249
None
250250
}
251251
}
252+
253+
/// Get the value as signed integer
254+
fn get_as_signed(&self) -> Result<i64, SBError> {
255+
let error = SBError::default();
256+
let result = unsafe { sys::SBValueGetValueAsSigned(self.raw, error.raw, 0) };
257+
if error.is_success() {
258+
Ok(result)
259+
} else {
260+
Err(error)
261+
}
262+
}
263+
264+
/// Get the value as unsigned integer
265+
pub fn get_as_unsigned(&self) -> Result<u64, SBError> {
266+
let error = SBError::default();
267+
let result = unsafe { sys::SBValueGetValueAsUnsigned(self.raw, error.raw, 0) };
268+
if error.is_success() {
269+
Ok(result)
270+
} else {
271+
Err(error)
272+
}
273+
}
252274
}
253275

254276
impl Clone for SBValue {

0 commit comments

Comments
 (0)