Skip to content

Commit 09c123b

Browse files
committed
[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.
1 parent 6728415 commit 09c123b

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

rust/src/low_level_il/function.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,38 @@ where
213213

214214
impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> {
215215
/// Retrieve the SSA form of the function.
216+
///
217+
/// If the function has not had the SSA form generated you may call `generate_ssa_form`.
216218
pub fn ssa_form(&self) -> Option<Ref<LowLevelILFunction<M, SSA>>> {
217219
let handle = unsafe { BNGetLowLevelILSSAForm(self.handle) };
218220
if handle.is_null() {
219221
return None;
220222
}
221223
Some(unsafe { LowLevelILFunction::ref_from_raw(handle) })
222224
}
225+
226+
/// Generates the SSA form of the function. Typically called **after** `finalize`.
227+
///
228+
/// If you created a freestanding [`LowLevelILFunction`] with no [`LowLevelILFunction::function`]
229+
/// than this function will **not** generate the SSA form, as it is currently impossible.
230+
///
231+
/// # Example
232+
///
233+
/// ```no_run
234+
/// use binaryninja::low_level_il::LowLevelILMutableFunction;
235+
/// use binaryninja::rc::Ref;
236+
/// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
237+
/// // ... modify the IL
238+
/// let finalized_llil = mutable_llil.finalized();
239+
/// finalized_llil.generate_ssa_form();
240+
/// ```
241+
pub fn generate_ssa_form(&self) {
242+
use binaryninjacore_sys::BNGenerateLowLevelILSSAForm;
243+
// SSA form may only be generated if there is an owning function, otherwise it will crash.
244+
if self.function().is_some() {
245+
unsafe { BNGenerateLowLevelILSSAForm(self.handle) };
246+
}
247+
}
223248
}
224249

225250
// Allow instantiating Lifted IL functions for querying Lifted IL from Architectures
@@ -242,14 +267,24 @@ impl LowLevelILFunction<Mutable, NonSSA> {
242267

243268
unsafe { Self::ref_from_raw_with_arch(handle, Some(arch)) }
244269
}
245-
246-
pub fn generate_ssa_form(&self) {
247-
use binaryninjacore_sys::BNGenerateLowLevelILSSAForm;
248-
unsafe { BNGenerateLowLevelILSSAForm(self.handle) };
249-
}
250270
}
251271

252272
impl Ref<LowLevelILFunction<Mutable, NonSSA>> {
273+
/// Finalize the mutated [`LowLevelILFunction`], returning a [`LowLevelILRegularFunction`].
274+
///
275+
/// This function **will not** correct the SSA related dataflow, to do that you must call
276+
/// the function [`LowLevelILMutableFunction::generate_ssa_form`].
277+
///
278+
/// # Example
279+
///
280+
/// ```no_run
281+
/// use binaryninja::low_level_il::LowLevelILMutableFunction;
282+
/// use binaryninja::rc::Ref;
283+
/// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
284+
/// // ... modify the IL
285+
/// let finalized_llil = mutable_llil.finalized();
286+
/// finalized_llil.generate_ssa_form();
287+
/// ```
253288
pub fn finalized(self) -> Ref<LowLevelILFunction<Finalized, NonSSA>> {
254289
unsafe {
255290
BNFinalizeLowLevelILFunction(self.handle);

0 commit comments

Comments
 (0)