summaryrefslogtreecommitdiff
path: root/rust/src/basicblock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/basicblock.rs')
-rw-r--r--rust/src/basicblock.rs310
1 files changed, 0 insertions, 310 deletions
diff --git a/rust/src/basicblock.rs b/rust/src/basicblock.rs
deleted file mode 100644
index a6ac8f74..00000000
--- a/rust/src/basicblock.rs
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2021-2024 Vector 35 Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::fmt;
-
-use crate::architecture::CoreArchitecture;
-use crate::function::Function;
-use binaryninjacore_sys::*;
-
-use crate::rc::*;
-
-enum EdgeDirection {
- Incoming,
- Outgoing,
-}
-
-pub struct Edge<'a, C: 'a + BlockContext> {
- branch: super::BranchType,
- back_edge: bool,
- source: Guard<'a, BasicBlock<C>>,
- target: Guard<'a, BasicBlock<C>>,
-}
-
-impl<'a, C: 'a + BlockContext> Edge<'a, C> {
- pub fn branch_type(&self) -> super::BranchType {
- self.branch
- }
-
- pub fn back_edge(&self) -> bool {
- self.back_edge
- }
-
- pub fn source(&self) -> &BasicBlock<C> {
- &self.source
- }
-
- pub fn target(&self) -> &BasicBlock<C> {
- &self.target
- }
-}
-
-impl<'a, C: 'a + fmt::Debug + BlockContext> fmt::Debug for Edge<'a, C> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "{:?} ({}) {:?} -> {:?}",
- self.branch, self.back_edge, &*self.source, &*self.target
- )
- }
-}
-
-pub struct EdgeContext<'a, C: 'a + BlockContext> {
- dir: EdgeDirection,
- orig_block: &'a BasicBlock<C>,
-}
-
-impl<'a, C: 'a + BlockContext> CoreArrayProvider for Edge<'a, C> {
- type Raw = BNBasicBlockEdge;
- type Context = EdgeContext<'a, C>;
- type Wrapped<'b> = Edge<'b, C> where 'a: 'b;
-}
-
-unsafe impl<'a, C: 'a + BlockContext> CoreArrayProviderInner for Edge<'a, C> {
- unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
- BNFreeBasicBlockEdgeList(raw, count);
- }
- unsafe fn wrap_raw<'b>(raw: &'b Self::Raw, context: &'b Self::Context) -> Self::Wrapped<'b> {
- let edge_target = Guard::new(
- BasicBlock::from_raw(raw.target, context.orig_block.context.clone()),
- raw,
- );
- let orig_block = Guard::new(
- BasicBlock::from_raw(
- context.orig_block.handle,
- context.orig_block.context.clone(),
- ),
- raw,
- );
-
- let (source, target) = match context.dir {
- EdgeDirection::Incoming => (edge_target, orig_block),
- EdgeDirection::Outgoing => (orig_block, edge_target),
- };
-
- Edge {
- branch: raw.type_,
- back_edge: raw.backEdge,
- source,
- target,
- }
- }
-}
-
-pub trait BlockContext: Clone + Sync + Send + Sized {
- type Instruction;
- type Iter: Iterator<Item = Self::Instruction>;
-
- fn start(&self, block: &BasicBlock<Self>) -> Self::Instruction;
- fn iter(&self, block: &BasicBlock<Self>) -> Self::Iter;
-}
-
-#[derive(PartialEq, Eq, Hash)]
-pub struct BasicBlock<C: BlockContext> {
- pub(crate) handle: *mut BNBasicBlock,
- context: C,
-}
-
-unsafe impl<C: BlockContext> Send for BasicBlock<C> {}
-unsafe impl<C: BlockContext> Sync for BasicBlock<C> {}
-
-impl<C: BlockContext> BasicBlock<C> {
- pub(crate) unsafe fn from_raw(handle: *mut BNBasicBlock, context: C) -> Self {
- Self { handle, context }
- }
-
- // TODO native bb vs il bbs
- pub fn function(&self) -> Ref<Function> {
- unsafe {
- let func = BNGetBasicBlockFunction(self.handle);
- Function::from_raw(func)
- }
- }
-
- pub fn arch(&self) -> CoreArchitecture {
- unsafe {
- let arch = BNGetBasicBlockArchitecture(self.handle);
- CoreArchitecture::from_raw(arch)
- }
- }
-
- pub fn iter(&self) -> C::Iter {
- self.context.iter(self)
- }
-
- pub fn raw_start(&self) -> u64 {
- unsafe { BNGetBasicBlockStart(self.handle) }
- }
-
- pub fn raw_end(&self) -> u64 {
- unsafe { BNGetBasicBlockEnd(self.handle) }
- }
-
- pub fn raw_length(&self) -> u64 {
- unsafe { BNGetBasicBlockLength(self.handle) }
- }
-
- pub fn incoming_edges(&self) -> Array<Edge<C>> {
- unsafe {
- let mut count = 0;
- let edges = BNGetBasicBlockIncomingEdges(self.handle, &mut count);
-
- Array::new(
- edges,
- count,
- EdgeContext {
- dir: EdgeDirection::Incoming,
- orig_block: self,
- },
- )
- }
- }
-
- pub fn outgoing_edges(&self) -> Array<Edge<C>> {
- unsafe {
- let mut count = 0;
- let edges = BNGetBasicBlockOutgoingEdges(self.handle, &mut count);
-
- Array::new(
- edges,
- count,
- EdgeContext {
- dir: EdgeDirection::Outgoing,
- orig_block: self,
- },
- )
- }
- }
-
- // is this valid for il blocks?
- pub fn has_undetermined_outgoing_edges(&self) -> bool {
- unsafe { BNBasicBlockHasUndeterminedOutgoingEdges(self.handle) }
- }
-
- pub fn can_exit(&self) -> bool {
- unsafe { BNBasicBlockCanExit(self.handle) }
- }
-
- pub fn index(&self) -> usize {
- unsafe { BNGetBasicBlockIndex(self.handle) }
- }
-
- pub fn immediate_dominator(&self) -> Option<Ref<Self>> {
- unsafe {
- let block = BNGetBasicBlockImmediateDominator(self.handle, false);
-
- if block.is_null() {
- return None;
- }
-
- Some(Ref::new(BasicBlock::from_raw(block, self.context.clone())))
- }
- }
-
- pub fn dominators(&self) -> Array<BasicBlock<C>> {
- unsafe {
- let mut count = 0;
- let blocks = BNGetBasicBlockDominators(self.handle, &mut count, false);
-
- Array::new(blocks, count, self.context.clone())
- }
- }
-
- pub fn strict_dominators(&self) -> Array<BasicBlock<C>> {
- unsafe {
- let mut count = 0;
- let blocks = BNGetBasicBlockStrictDominators(self.handle, &mut count, false);
-
- Array::new(blocks, count, self.context.clone())
- }
- }
-
- pub fn dominator_tree_children(&self) -> Array<BasicBlock<C>> {
- unsafe {
- let mut count = 0;
- let blocks = BNGetBasicBlockDominatorTreeChildren(self.handle, &mut count, false);
-
- Array::new(blocks, count, self.context.clone())
- }
- }
-
- pub fn dominance_frontier(&self) -> Array<BasicBlock<C>> {
- unsafe {
- let mut count = 0;
- let blocks = BNGetBasicBlockDominanceFrontier(self.handle, &mut count, false);
-
- Array::new(blocks, count, self.context.clone())
- }
- }
-
- // TODO iterated dominance frontier
-}
-
-impl<'a, C: BlockContext> IntoIterator for &'a BasicBlock<C> {
- type Item = C::Instruction;
- type IntoIter = C::Iter;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl<C: fmt::Debug + BlockContext> fmt::Debug for BasicBlock<C> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "<bb handle {:p} context {:?} contents: {} -> {}>",
- self.handle,
- &self.context,
- self.raw_start(),
- self.raw_end()
- )
- }
-}
-
-impl<C: BlockContext> ToOwned for BasicBlock<C> {
- type Owned = Ref<Self>;
-
- fn to_owned(&self) -> Self::Owned {
- unsafe { RefCountable::inc_ref(self) }
- }
-}
-
-unsafe impl<C: BlockContext> RefCountable for BasicBlock<C> {
- unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
- Ref::new(Self {
- handle: BNNewBasicBlockReference(handle.handle),
- context: handle.context.clone(),
- })
- }
-
- unsafe fn dec_ref(handle: &Self) {
- BNFreeBasicBlock(handle.handle);
- }
-}
-
-impl<C: BlockContext> CoreArrayProvider for BasicBlock<C> {
- type Raw = *mut BNBasicBlock;
- type Context = C;
- type Wrapped<'a> = Guard<'a, BasicBlock<C>> where C: 'a;
-}
-
-unsafe impl<C: BlockContext> CoreArrayProviderInner for BasicBlock<C> {
- unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
- BNFreeBasicBlockList(raw, count);
- }
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- Guard::new(BasicBlock::from_raw(*raw, context.clone()), context)
- }
-}