|
6 | 6 |
|
7 | 7 | use crate::{
|
8 | 8 | 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, |
11 | 11 | };
|
12 | 12 | use std::ffi::{CStr, CString};
|
13 | 13 | use std::fmt;
|
@@ -559,6 +559,85 @@ impl SBProcess {
|
559 | 559 | pub fn get_memory_regions(&self) -> SBMemoryRegionInfoList {
|
560 | 560 | SBMemoryRegionInfoList::wrap(unsafe { sys::SBProcessGetMemoryRegions(self.raw) })
|
561 | 561 | }
|
| 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 | + } |
562 | 641 | }
|
563 | 642 |
|
564 | 643 | /// Iterate over the [threads] in a [process].
|
|
0 commit comments