summaryrefslogtreecommitdiff
path: root/rust/src/workflow.rs
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2025-11-23 16:18:34 -0500
committerBrian Potchik <brian@vector35.com>2025-11-23 16:18:34 -0500
commit56ce6d3d63d6a5cf30ea1f326a91104db59555be (patch)
tree175fd417c6084a40823fb7aa5d38ffd7e7406308 /rust/src/workflow.rs
parent5880769cbac1362aad46a34faec4c553fa9fcac6 (diff)
Unify SettingsCache and MemoryMap access under immutable snapshots for consistent, lock-free AnalysisContext queries.
Diffstat (limited to 'rust/src/workflow.rs')
-rw-r--r--rust/src/workflow.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/rust/src/workflow.rs b/rust/src/workflow.rs
index 49c5760e..618a290c 100644
--- a/rust/src/workflow.rs
+++ b/rust/src/workflow.rs
@@ -8,6 +8,7 @@ use crate::high_level_il::HighLevelILFunction;
use crate::low_level_il::{LowLevelILMutableFunction, LowLevelILRegularFunction};
use crate::medium_level_il::MediumLevelILFunction;
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
+use crate::segment::Segment;
use crate::string::{BnString, IntoCStr};
use std::ffi::c_char;
use std::ptr;
@@ -125,6 +126,152 @@ impl AnalysisContext {
blocks.iter().map(|block| block.handle).collect();
unsafe { BNSetBasicBlockList(self.handle.as_ptr(), blocks_raw.as_mut_ptr(), blocks.len()) }
}
+
+ // Settings cache access - lock-free access to cached settings
+
+ /// Get a boolean setting from the cached settings
+ pub fn get_setting_bool(&self, key: &str) -> bool {
+ let key = key.to_cstr();
+ unsafe { BNAnalysisContextGetSettingBool(self.handle.as_ptr(), key.as_ptr()) }
+ }
+
+ /// Get a double setting from the cached settings
+ pub fn get_setting_double(&self, key: &str) -> f64 {
+ let key = key.to_cstr();
+ unsafe { BNAnalysisContextGetSettingDouble(self.handle.as_ptr(), key.as_ptr()) }
+ }
+
+ /// Get a signed 64-bit integer setting from the cached settings
+ pub fn get_setting_int64(&self, key: &str) -> i64 {
+ let key = key.to_cstr();
+ unsafe { BNAnalysisContextGetSettingInt64(self.handle.as_ptr(), key.as_ptr()) }
+ }
+
+ /// Get an unsigned 64-bit integer setting from the cached settings
+ pub fn get_setting_uint64(&self, key: &str) -> u64 {
+ let key = key.to_cstr();
+ unsafe { BNAnalysisContextGetSettingUInt64(self.handle.as_ptr(), key.as_ptr()) }
+ }
+
+ /// Get a string setting from the cached settings
+ pub fn get_setting_string(&self, key: &str) -> BnString {
+ let key = key.to_cstr();
+ unsafe {
+ let result = BNAnalysisContextGetSettingString(self.handle.as_ptr(), key.as_ptr());
+ BnString::from_raw(result)
+ }
+ }
+
+ /// Get a string list setting from the cached settings
+ pub fn get_setting_string_list(&self, key: &str) -> Array<BnString> {
+ let key = key.to_cstr();
+ unsafe {
+ let mut count = 0;
+ let result = BNAnalysisContextGetSettingStringList(self.handle.as_ptr(), key.as_ptr(), &mut count);
+ Array::new(result, count, ())
+ }
+ }
+
+ // Memory map access - lock-free access to cached MemoryMap
+
+ /// Check if an offset is mapped in the cached memory map
+ pub fn is_valid_offset(&self, offset: u64) -> bool {
+ unsafe { BNAnalysisContextIsValidOffset(self.handle.as_ptr(), offset) }
+ }
+
+ /// Check if an offset is readable in the cached memory map
+ pub fn is_offset_readable(&self, offset: u64) -> bool {
+ unsafe { BNAnalysisContextIsOffsetReadable(self.handle.as_ptr(), offset) }
+ }
+
+ /// Check if an offset is writable in the cached memory map
+ pub fn is_offset_writable(&self, offset: u64) -> bool {
+ unsafe { BNAnalysisContextIsOffsetWritable(self.handle.as_ptr(), offset) }
+ }
+
+ /// Check if an offset is executable in the cached memory map
+ pub fn is_offset_executable(&self, offset: u64) -> bool {
+ unsafe { BNAnalysisContextIsOffsetExecutable(self.handle.as_ptr(), offset) }
+ }
+
+ /// Check if an offset is backed by file in the cached memory map
+ pub fn is_offset_backed_by_file(&self, offset: u64) -> bool {
+ unsafe { BNAnalysisContextIsOffsetBackedByFile(self.handle.as_ptr(), offset) }
+ }
+
+ /// Get the start address from the cached memory map
+ pub fn get_start(&self) -> u64 {
+ unsafe { BNAnalysisContextGetStart(self.handle.as_ptr()) }
+ }
+
+ /// Get the end address from the cached memory map
+ pub fn get_end(&self) -> u64 {
+ unsafe { BNAnalysisContextGetEnd(self.handle.as_ptr()) }
+ }
+
+ /// Get the length of the cached memory map
+ pub fn get_length(&self) -> u64 {
+ unsafe { BNAnalysisContextGetLength(self.handle.as_ptr()) }
+ }
+
+ /// Get the next valid offset after the given offset from the cached memory map
+ pub fn get_next_valid_offset(&self, offset: u64) -> u64 {
+ unsafe { BNAnalysisContextGetNextValidOffset(self.handle.as_ptr(), offset) }
+ }
+
+ /// Get the next mapped address after the given address from the cached memory map
+ pub fn get_next_mapped_address(&self, addr: u64, flags: u32) -> u64 {
+ unsafe { BNAnalysisContextGetNextMappedAddress(self.handle.as_ptr(), addr, flags) }
+ }
+
+ /// Get the next backed address after the given address from the cached memory map
+ pub fn get_next_backed_address(&self, addr: u64, flags: u32) -> u64 {
+ unsafe { BNAnalysisContextGetNextBackedAddress(self.handle.as_ptr(), addr, flags) }
+ }
+
+ /// Get the segment containing the given address from the cached memory map
+ pub fn get_segment_at(&self, addr: u64) -> Option<Ref<Segment>> {
+ unsafe {
+ let result = BNAnalysisContextGetSegmentAt(self.handle.as_ptr(), addr);
+ if result.is_null() {
+ None
+ } else {
+ Some(Segment::ref_from_raw(result))
+ }
+ }
+ }
+
+ /// Get all mapped address ranges from the cached memory map
+ pub fn get_mapped_address_ranges(&self) -> Vec<(u64, u64)> {
+ unsafe {
+ let mut count = 0;
+ let ranges = BNAnalysisContextGetMappedAddressRanges(self.handle.as_ptr(), &mut count);
+ let result = (0..count)
+ .map(|i| {
+ let range = *ranges.add(i);
+ (range.start, range.end)
+ })
+ .collect();
+ BNFreeAddressRanges(ranges);
+ result
+ }
+ }
+
+ /// Get all backed address ranges from the cached memory map
+ pub fn get_backed_address_ranges(&self) -> Vec<(u64, u64)> {
+ unsafe {
+ let mut count = 0;
+ let ranges = BNAnalysisContextGetBackedAddressRanges(self.handle.as_ptr(), &mut count);
+ let result = (0..count)
+ .map(|i| {
+ let range = *ranges.add(i);
+ (range.start, range.end)
+ })
+ .collect();
+ BNFreeAddressRanges(ranges);
+ result
+ }
+ }
}
impl ToOwned for AnalysisContext {