summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-12-09 20:03:22 -0500
committerMason Reed <35282038+emesare@users.noreply.github.com>2025-12-10 16:37:14 -0500
commit0ec8e7d31dcd5c38498ac473db46e3b55883edd2 (patch)
tree21ff1ee1f27abf830139e4f3f5c388ce412943aa /rust
parent570a01aa6c9a3299ce30f04af89b3f01e96aebe4 (diff)
[Rust] Fix crash when calling `LowLevelILFunction::generate_ssa_form` without an owner
You cannot generate SSA form of an LLIL function without a backing function unfortunately.
Diffstat (limited to 'rust')
-rw-r--r--rust/src/low_level_il/function.rs45
1 files changed, 40 insertions, 5 deletions
diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs
index 15a83c19..837b45ef 100644
--- a/rust/src/low_level_il/function.rs
+++ b/rust/src/low_level_il/function.rs
@@ -213,6 +213,8 @@ where
impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> {
/// Retrieve the SSA form of the function.
+ ///
+ /// If the function has not had the SSA form generated you may call `generate_ssa_form`.
pub fn ssa_form(&self) -> Option<Ref<LowLevelILFunction<M, SSA>>> {
let handle = unsafe { BNGetLowLevelILSSAForm(self.handle) };
if handle.is_null() {
@@ -220,6 +222,29 @@ impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> {
}
Some(unsafe { LowLevelILFunction::ref_from_raw(handle) })
}
+
+ /// Generates the SSA form of the function. Typically called **after** `finalize`.
+ ///
+ /// If you created a freestanding [`LowLevelILFunction`] with no [`LowLevelILFunction::function`]
+ /// than this function will **not** generate the SSA form, as it is currently impossible.
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// use binaryninja::low_level_il::LowLevelILMutableFunction;
+ /// use binaryninja::rc::Ref;
+ /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
+ /// // ... modify the IL
+ /// let finalized_llil = mutable_llil.finalized();
+ /// finalized_llil.generate_ssa_form();
+ /// ```
+ pub fn generate_ssa_form(&self) {
+ use binaryninjacore_sys::BNGenerateLowLevelILSSAForm;
+ // SSA form may only be generated if there is an owning function, otherwise it will crash.
+ if self.function().is_some() {
+ unsafe { BNGenerateLowLevelILSSAForm(self.handle) };
+ }
+ }
}
// Allow instantiating Lifted IL functions for querying Lifted IL from Architectures
@@ -242,14 +267,24 @@ impl LowLevelILFunction<Mutable, NonSSA> {
unsafe { Self::ref_from_raw_with_arch(handle, Some(arch)) }
}
-
- pub fn generate_ssa_form(&self) {
- use binaryninjacore_sys::BNGenerateLowLevelILSSAForm;
- unsafe { BNGenerateLowLevelILSSAForm(self.handle) };
- }
}
impl Ref<LowLevelILFunction<Mutable, NonSSA>> {
+ /// Finalize the mutated [`LowLevelILFunction`], returning a [`LowLevelILRegularFunction`].
+ ///
+ /// This function **will not** correct the SSA related dataflow, to do that you must call
+ /// the function [`LowLevelILMutableFunction::generate_ssa_form`].
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// use binaryninja::low_level_il::LowLevelILMutableFunction;
+ /// use binaryninja::rc::Ref;
+ /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
+ /// // ... modify the IL
+ /// let finalized_llil = mutable_llil.finalized();
+ /// finalized_llil.generate_ssa_form();
+ /// ```
pub fn finalized(self) -> Ref<LowLevelILFunction<Finalized, NonSSA>> {
unsafe {
BNFinalizeLowLevelILFunction(self.handle);