summaryrefslogtreecommitdiff
path: root/rust/src/symbol.rs
diff options
context:
space:
mode:
authorRyan Snyder <ryan@vector35.com>2021-01-21 18:27:48 +0000
committerKyleMiles <krm504@nyu.edu>2021-01-21 19:06:55 +0000
commitd3140edec185f47235b9e4642bdd56d6c585a341 (patch)
treea61859c29e4e3539daea2b761bb1439d942beaf4 /rust/src/symbol.rs
parentc0ddbf0c76d3f1bb7a2b2024f749afc8b9482575 (diff)
This is a combination of 23 commits, the work of Ryan Snyder:
Initial fresh repo Add support for recent calling convention API updates and folds the binaryninjacore-sys crate directly into this one. Add support for auto function analysis suppression Finish moving binaryninjacore-sys back into this crate Update for Symbol/Segment core API changes Update for Symbol API cleanup api: advance submodule reference, support Token changes arch/lifting: support for flags in custom architectures arch/lifting: support default flag write behaviors, handle more ops build: enable headless binary support on MacOS via evil hack bv: add BinaryView wrapper support, remove wrong comment api: update to latest binja dev branch support deps: bump dep versions rust: bump to 2018 edition api: bump to avoid cargo submodule brokenness build: improve binaryninja path detection; enable linux linkhack bv: stub for bv load settings arch: fix flag related crash, minor llil update api: update for recent changes macos: disable linkhack briefly
Diffstat (limited to 'rust/src/symbol.rs')
-rw-r--r--rust/src/symbol.rs241
1 files changed, 241 insertions, 0 deletions
diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs
new file mode 100644
index 00000000..44021426
--- /dev/null
+++ b/rust/src/symbol.rs
@@ -0,0 +1,241 @@
+use std::fmt;
+use std::ptr;
+
+use binaryninjacore_sys::*;
+use crate::string::*;
+use crate::rc::*;
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum SymType {
+ Function,
+ LibraryFunction,
+ ImportAddress,
+ ImportedFunction,
+ Data,
+ ImportedData,
+ External,
+}
+
+impl From<BNSymbolType> for SymType {
+ fn from(bn: BNSymbolType) -> SymType {
+ use self::BNSymbolType::*;
+
+ match bn {
+ FunctionSymbol => SymType::Function,
+ LibraryFunctionSymbol => SymType::LibraryFunction,
+ ImportAddressSymbol => SymType::ImportAddress,
+ ImportedFunctionSymbol => SymType::ImportedFunction,
+ DataSymbol => SymType::Data,
+ ImportedDataSymbol => SymType::ImportedData,
+ ExternalSymbol => SymType::External,
+ }
+ }
+}
+
+impl Into<BNSymbolType> for SymType {
+ fn into(self) -> BNSymbolType {
+ use self::BNSymbolType::*;
+
+ match self {
+ SymType::Function => FunctionSymbol,
+ SymType::LibraryFunction => LibraryFunctionSymbol,
+ SymType::ImportAddress => ImportAddressSymbol,
+ SymType::ImportedFunction => ImportedFunctionSymbol,
+ SymType::Data => DataSymbol,
+ SymType::ImportedData => ImportedDataSymbol,
+ SymType::External => ExternalSymbol,
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum Binding {
+ None,
+ Local,
+ Global,
+ Weak,
+}
+
+impl From<BNSymbolBinding> for Binding {
+ fn from(bn: BNSymbolBinding) -> Binding {
+ use self::BNSymbolBinding::*;
+
+ match bn {
+ NoBinding => Binding::None,
+ LocalBinding => Binding::Local,
+ GlobalBinding => Binding::Global,
+ WeakBinding => Binding::Weak,
+ }
+ }
+}
+
+impl Into<BNSymbolBinding> for Binding {
+ fn into(self) -> BNSymbolBinding {
+ use self::BNSymbolBinding::*;
+
+ match self {
+ Binding::None => NoBinding,
+ Binding::Local => LocalBinding,
+ Binding::Global => GlobalBinding,
+ Binding::Weak => WeakBinding,
+ }
+ }
+}
+
+#[must_use]
+pub struct SymbolBuilder<S: BnStrCompatible> {
+ ty: SymType,
+ binding: Binding,
+ addr: u64,
+ raw_name: S,
+ short_name: Option<S>,
+ full_name: Option<S>,
+ ordinal: u64,
+}
+
+impl<S: BnStrCompatible> SymbolBuilder<S> {
+ pub fn binding(mut self, binding: Binding) -> Self {
+ self.binding = binding;
+ self
+ }
+
+ pub fn short_name(mut self, short_name: S) -> Self {
+ self.short_name = Some(short_name);
+ self
+ }
+
+ pub fn full_name(mut self, full_name: S) -> Self {
+ self.full_name = Some(full_name);
+ self
+ }
+
+ pub fn ordinal(mut self, ordinal: u64) -> Self {
+ self.ordinal = ordinal;
+ self
+ }
+
+ pub fn create(self) -> Ref<Symbol> {
+ let raw_name = self.raw_name.as_bytes_with_nul();
+ let short_name = self.short_name.map(|s| s.as_bytes_with_nul());
+ let full_name = self.full_name.map(|s| s.as_bytes_with_nul());
+
+ unsafe {
+ let raw_name = raw_name.as_ref().as_ptr() as *mut _;
+ let short_name = short_name.as_ref().map_or(raw_name, |s| s.as_ref().as_ptr() as *mut _);
+ let full_name = full_name.as_ref().map_or(raw_name, |s| s.as_ref().as_ptr() as *mut _);
+
+ let res = BNCreateSymbol(self.ty.into(),
+ short_name, full_name, raw_name,
+ self.addr, self.binding.into(), ptr::null_mut(),
+ self.ordinal);
+
+ Ref::new(Symbol::from_raw(res))
+ }
+ }
+}
+
+#[derive(PartialEq, Eq, Hash)]
+pub struct Symbol {
+ pub(crate) handle: *mut BNSymbol,
+}
+
+unsafe impl Send for Symbol {}
+unsafe impl Sync for Symbol {}
+
+impl Symbol {
+ pub(crate) unsafe fn from_raw(raw: *mut BNSymbol) -> Self {
+ Self { handle: raw }
+ }
+
+ pub fn new<S: BnStrCompatible>(ty: SymType, raw_name: S, addr: u64) -> SymbolBuilder<S> {
+ SymbolBuilder {
+ ty: ty,
+ binding: Binding::None,
+ addr: addr,
+ raw_name: raw_name,
+ short_name: None,
+ full_name: None,
+ ordinal: 0,
+ }
+ }
+
+ pub fn sym_type(&self) -> SymType {
+ unsafe { BNGetSymbolType(self.handle).into() }
+ }
+
+ pub fn binding(&self) -> Binding {
+ unsafe { BNGetSymbolBinding(self.handle).into() }
+ }
+
+ pub fn name(&self) -> BnString {
+ unsafe {
+ let name = BNGetSymbolFullName(self.handle);
+ BnString::from_raw(name)
+ }
+ }
+
+ pub fn short_name(&self) -> BnString {
+ unsafe {
+ let name = BNGetSymbolShortName(self.handle);
+ BnString::from_raw(name)
+ }
+ }
+
+ pub fn raw_name(&self) -> BnString {
+ unsafe {
+ let name = BNGetSymbolRawName(self.handle);
+ BnString::from_raw(name)
+ }
+ }
+
+ pub fn address(&self) -> u64 {
+ unsafe { BNGetSymbolAddress(self.handle) }
+ }
+
+ pub fn auto_defined(&self) -> bool {
+ unsafe { BNIsSymbolAutoDefined(self.handle) }
+ }
+}
+
+impl fmt::Debug for Symbol {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "<sym {:?} '{}' @ {:x} (handle: {:?})>", self.sym_type(), self.name(), self.address(), self.handle)
+ }
+}
+
+impl ToOwned for Symbol {
+ type Owned = Ref<Self>;
+
+ fn to_owned(&self) -> Self::Owned {
+ unsafe { RefCountable::inc_ref(self) }
+ }
+}
+
+unsafe impl RefCountable for Symbol {
+ unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
+ Ref::new(Self {
+ handle: BNNewSymbolReference(handle.handle),
+ })
+ }
+
+ unsafe fn dec_ref(handle: &Self) {
+ BNFreeSymbol(handle.handle);
+ }
+}
+
+unsafe impl CoreOwnedArrayProvider for Symbol {
+ type Raw = *mut BNSymbol;
+ type Context = ();
+
+ unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
+ BNFreeSymbolList(raw, count);
+ }
+}
+
+unsafe impl<'a> CoreOwnedArrayWrapper<'a> for Symbol {
+ type Wrapped = Guard<'a, Symbol>;
+
+ unsafe fn wrap_raw(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped {
+ Guard::new(Symbol::from_raw(*raw), context)
+ }
+}