Skip to main content

FunctionBody

Struct FunctionBody 

Source
pub struct FunctionBody<'str> {
    pub instruction_addrs: BTreeSet<u64>,
    /* private fields */
}
Expand description

A function body: arenas, roster, root, reverse use-def, local names. The caller-reasoning surface lives separately in FunctionInterface, stored in Context::interfaces under the same FunctionId.

Fields§

§instruction_addrs: BTreeSet<u64>

Addresses of every machine instruction lifted into this function, in ascending order. Recorded during recursive disassembly and preserved across optimization (which merges blocks and rewrites the IR), so the raw disassembly view can be reconstructed regardless of CFG changes.

Implementations§

Source§

impl<'str> FunctionBody<'str>

Source

pub fn arena_stats(&self) -> BodyArenaStats

Reports the current arena footprint and logical liveness.

Source

pub fn shrink_to_fit(&mut self)

Releases structural capacity retained from peak analysis churn.

Covers the four body arenas plus the block-owned instruction/parameter/ edge collections, the roster, and the reverse-use map. IDs, liveness, ordering, and every semantic invariant are unchanged — this is an allocator hint for explicit end-of-mutation boundaries, never a correctness barrier.

Source

pub fn install_id(&mut self, id: FunctionId)

Install a registry ID onto a freshly detached body at the mint barrier. Panics if the body already carries an id.

Source

pub fn resolve_minted_callee(&mut self, slot: u32, real: FunctionId) -> usize

Resolve one pass-local callee slot throughout this detached or installed body. Returns the number of call-like instructions patched.

Source

pub fn resolve_minted_callees( &mut self, installed: &[FunctionId], ) -> Result<usize, u32>

Resolve every pass-local callee slot in this body against the installed mapping (installed[k] is the real function for slot k) in one arena walk. Returns the number of call-like instructions patched, or the first slot with no installed function.

Source

pub fn empty_with_id(id: FunctionId) -> Self

An empty function body carrying the identity id. Used for bodies installed under a known registry key at creation (make-family constructors). Pass-minted bodies instead use detached + install_id.

Source

pub fn detached() -> Self

An empty detached function body: no root, empty arenas, and no registry identity yet (id panics until install_id runs at the mint barrier). The interface lives separately in Context::interfaces. This is how a pass mints a function; the id is stamped by install_id at the mint barrier.

Source

pub fn id(&self) -> FunctionId

This body’s immutable function identity. Panics on a detached body (one minted but not yet installed) — the loud, release-active tripwire against laundering an owner ID through an uninstalled body.

Source

pub fn try_id(&self) -> Option<FunctionId>

This body’s registry identity, or None while detached. The honest accessor for the install barrier and verifiers.

Source

pub fn has_users(&self, value: ValueId) -> bool

Whether any instruction in this body uses value.

The question users_of(v).is_empty() asks, without the allocation it takes to answer it that way. Dead-code elimination asks it once per instruction per round, which made building those vectors the single largest cost of lifting a block.

Source

pub fn users_of(&self, value: ValueId) -> Vec<InstructionId>

This body’s qualified instruction IDs that use value. A value owned by another function has no users in this body, even if its local index collides with one of this body’s values.

Source

pub fn user_map_entries( &self, ) -> impl Iterator<Item = (LocalValueId, &[LocalInsnId])>

Iterate this function’s recorded (value, users) reverse-use entries, with keys in their stored body-local form (qualify via the owning func at the FunctionRef wrapper). Read-only; used by the users-map consistency verifier.

Source

pub fn root_id(&self) -> Option<LocalBlockId>

This function’s body-local entry block id, if any (raw accessor).

Source

pub fn set_root_id(&mut self, root: Option<LocalBlockId>)

Sets this function’s body-local entry block id directly, without rostering / address bookkeeping of FunctionMutRef::set_root. Routing target for the raw .root = … field writes whose callers have already rostered the block (stage 6a §11).

Source

pub fn block(&self, id: BlockId) -> &BasicBlock<'str>

The block id, by its function-local index (see the note above).

Source

pub fn block_mut(&mut self, id: BlockId) -> &mut BasicBlock<'str>

The block id, mutably.

Source

pub fn contains_block(&self, id: BlockId) -> bool

Whether id currently names a live block payload in this body.

Source

pub fn insn(&self, id: InstructionId) -> &Instruction<'str>

The instruction id, by its function-local index.

Source

pub fn insn_mut(&mut self, id: InstructionId) -> &mut Instruction<'str>

The instruction id, mutably.

Source

pub fn contains_instruction(&self, id: InstructionId) -> bool

Whether id currently names a live instruction payload in this body.

Source

pub fn block_param(&self, id: BlockParamId) -> &BlockParam<'str>

The block parameter id, by its function-local index.

Source

pub fn block_param_mut(&mut self, id: BlockParamId) -> &mut BlockParam<'str>

The block parameter id, mutably.

Source

pub fn contains_block_param(&self, id: BlockParamId) -> bool

Whether id currently names a live block-parameter payload in this body.

Source

pub fn local_type_of(&self, shared: &Shared<'str>, id: LocalValueId) -> TypeId

The result type of a body-local operand, resolved without a registry identity. The shared arms (Literal/Bytes/Varnode/Function) route through shared; the arena arms (Instruction/BlockParam/Temp/ BasicBlock) index this body’s own arenas by their bare local index. This is the id-less twin of QCodeView::type_of — usable on a detached body.

Source

pub fn local_stored_type_of( &self, shared: &Shared<'str>, id: LocalValueId, ) -> Option<TypeId>

The stored type of a body-local operand, or None where the operand carries no stored type (untyped varnode, temp, block, function). The id-less twin of QCodeView::stored_type_of.

Source

pub fn push_temp_space(&mut self, space: TempSpace) -> TempSpaceId

Appends a body-local temporary space and returns its qualified ID.

Source

pub fn push_temp(&mut self, temp: Temp<'str>) -> TempId

Appends a body-local temporary value and returns its qualified ID.

Source

pub fn temp_space(&self, id: TempSpaceId) -> &TempSpace

Resolves a qualified temporary-space ID against this body.

Source

pub fn temp_spaces( &self, ) -> impl Iterator<Item = (TempSpaceId, &TempSpace)> + '_

Iterates over every temporary space owned by this body, in id order.

Source

pub fn contains_temp_space(&self, id: TempSpaceId) -> bool

Whether id names a temporary space in this body.

Source

pub fn temp(&self, id: TempId) -> &Temp<'str>

Resolves a qualified temporary-value ID against this body.

Source

pub fn contains_temp(&self, id: TempId) -> bool

Whether id names a temporary value in this body.

Source

pub fn remove_block_param(&mut self, id: BlockParamId)

Physically removes a block parameter and its local bookkeeping. Positional block and edge-argument rewrites belong to the caller. Those rewrites may occur later in the same transformation, so outstanding uses are allowed while the transformation is in progress.

Source

pub fn edge(&self, id: EdgeId) -> &EdgeData

The CFG edge id, by its function-local index.

Source

pub fn push_insn(&mut self, insn: Instruction<'str>) -> InstructionId

Push a fresh instruction into this body’s arena, recording each operand’s use in the reverse-use map.

Source

pub fn push_insn_local(&mut self, insn: Instruction<'str>) -> LocalInsnId

Push a fresh instruction into this body’s arena, recording each operand’s use in the reverse-use map, and return its body-local id. The id-less twin of push_insn, usable on a detached body.

Source

pub fn push_block(&mut self, block: BasicBlock<'str>) -> BlockId

Push a fresh block into this body’s arena and onto its ownership roster. Ownership is derived from the storing arena: the returned id’s func is this body’s own id.

Source

pub fn push_block_local(&mut self, block: BasicBlock<'str>) -> LocalBlockId

Push a fresh block into this body’s arena and roster, returning its body-local id. The id-less twin of push_block, usable on a detached (uninstalled) body.

Source

pub fn make_block(&mut self) -> BlockId

Mint a fresh empty block, owned by this function (arena membership) and rostered.

Source

pub fn make_block_local(&mut self) -> LocalBlockId

Mint a fresh empty block, returning its body-local id. The id-less twin of make_block, usable on a detached body.

Source

pub fn block_local(&self, block: LocalBlockId) -> &BasicBlock<'str>

This body’s block block, by its function-local index (id-free read, usable on a detached body).

Source

pub fn mnemonic_local(&self, insn: LocalInsnId) -> &Mnemonic

This body’s instruction mnemonic, by its function-local index (id-free read, usable on a detached body).

Source

pub fn push_block_param(&mut self, param: BlockParam<'str>) -> BlockParamId

Push a fresh block parameter into this body’s arena.

Source

pub fn push_block_param_local( &mut self, block: LocalBlockId, param: BlockParam<'str>, ) -> LocalParamId

Push a fresh block parameter into this body’s arena and wire it into block’s parameter list, returning its body-local id. The id-less twin of push_block_param, usable on a detached body.

Source

pub fn append_insn_local(&mut self, block: LocalBlockId, insn: LocalInsnId)

Append an already-created instruction to the end of block, setting its parent (id-free; the mutation twin of BaseRef::push_insn, usable on a detached body).

Source

pub fn push_mnemonic( &mut self, shared: &Shared<'str>, mnemonic: Mnemonic, size: usize, ) -> InstructionId

Mint an Int(size)-typed instruction with mnemonic (the type is minted in shared’s interner through its &self path).

Source

pub fn push_mnemonic_with_type( &mut self, mnemonic: Mnemonic, type_id: TypeId, ) -> InstructionId

Mint an instruction with mnemonic and an explicit result type_id.

Source

pub fn push_mnemonic_with_type_local( &mut self, mnemonic: Mnemonic, type_id: TypeId, ) -> LocalInsnId

Mint an instruction with mnemonic and an explicit result type_id, returning its body-local id. The id-less twin of push_mnemonic_with_type.

Source

pub fn insert_insn_before( &mut self, block: BlockId, before: InstructionId, insn: InstructionId, )

Insert insn immediately before before in block. Panics if before is not in block.

Source

pub fn move_insn_before(&mut self, insn: InstructionId, before: InstructionId)

Move the live, non-terminator instruction insn immediately before the live instruction before, inferring the destination block from before. The moved instruction keeps its ID, payload, name, and use-map entries. Supports both cross-block motion and reordering within one block.

Source

pub fn add_cfg_edge(&mut self, from: BlockId, to: BlockId) -> EdgeId

Add a directed CFG edge from -> to, stored in this body’s edge arena and linked into both incident blocks’ edge sets.

Source

pub fn add_cfg_edge_local( &mut self, from: LocalBlockId, to: LocalBlockId, ) -> EdgeId

Add a directed CFG edge from -> to over body-local block ids (id-free; the twin of add_cfg_edge, usable on a detached body).

Source

pub fn remove_cfg_edge(&mut self, edge_id: EdgeId)

Remove CFG edge edge_id, unlinking it from both incident blocks and physically dropping its payload.

Source

pub fn replace_all_uses_with(&mut self, old: ValueId, new: ValueId)

Replace every use of old with new across this body’s instructions and update the reverse use-map (SSA defs only; old is intra-function).

Source

pub fn replace_instruction(&mut self, id: InstructionId, new: ValueId)

Replace every use of instruction id with new, then remove id — the standard “rewrite to a cheaper value” epilogue (replace_all_uses_with + remove_instruction).

Source

pub fn remove_instructions(&mut self, dead: &FxHashSet<LocalInsnId>)

Physically removes a set of instructions after pruning their operands from the reverse-use map. Call after removing them from their parent blocks and unlinking any CFG edges owned by terminators.

Source

pub fn remove_instruction(&mut self, id: InstructionId)

Remove instruction id from its block, unlink its outgoing CFG edges if a terminator, clear its name, prune its operand use-lists, and physically drop its payload.

Source

pub fn remove_block_instructions( &mut self, block_id: BlockId, dead: &FxHashSet<LocalInsnId>, )

Removes several non-terminator instructions of one block at once.

remove_instruction walks the block’s instruction list to unlink each one, so removing n of them costs n × block. Lifting an absorbed guest basic block deletes hundreds of instructions from a block hundreds long, and that product was a real share of translation time. Here the list is walked once however many go.

Terminators are rejected rather than handled: removing one has to tear down CFG edges too, and no caller of this deletes one — dead-code elimination will not touch a terminator, and store forwarding removes only loads and stores.

Source

pub fn split_block_before( &mut self, block: BlockId, insn: InstructionId, ) -> BlockId

Rehome remove’s outgoing CFG edges onto keep. The direct edge and keep’s forwarding terminator have already been removed by the caller. Moves insn and everything after it in its block — the terminator included — into a fresh block, and returns that block.

The original block keeps its identity, its address, its parameters and its incoming edges, and is left unterminated: the caller ends it, typically with a branch to the new block or a conditional branch that reaches the new block one way or another. The outgoing edges follow the terminator to the new block. Values defined before the split stay visible to the instructions after it, as SSA allows across blocks.

Unlike an address split this moves code rather than discarding it, so it is for rewriting a block in place — inserting a conditional detour — not for establishing a new branch target in the guest.

Source

pub fn rehome_outgoing_edges(&mut self, keep: BlockId, remove: BlockId)

Source

pub fn replace_instruction_mnemonic( &mut self, id: InstructionId, mnemonic: Mnemonic, )

Replace an instruction’s mnemonic in place, keeping the reverse use-map in sync.

Source

pub fn replace_instruction_mnemonic_local( &mut self, id: LocalInsnId, mnemonic: Mnemonic, )

Replace an instruction’s mnemonic in place, keeping the reverse use-map in sync, over a body-local instruction id (id-free; the twin of replace_instruction_mnemonic, usable on a detached body).

Source

pub fn rename_block_local( &mut self, block: LocalBlockId, name: Cow<'str, str>, ) -> Result<()>

Set block’s name and register it in this body’s local name table, over a body-local block id (id-free; the twin of BaseRef::rename_local restricted to the id-free local parts, usable on a detached body). Errors only on a duplicate name.

Source

pub fn unroster_block(&mut self, block: BlockId)

Drop block from this body’s ownership roster. Ownership is derived from the storing arena (block.func).

Source

pub fn clear_block_instructions(&mut self, block: BlockId)

Remove block from this body: unlink every incident CFG edge, remove its instructions and params, clear ownership metadata, then drop its payload. Empties block of code, keeping the block itself.

Only the outgoing edges go, because those are owned by the terminator being removed; the incoming ones belong to other blocks’ terminators, which still name this block and must keep resolving to it. That is the point of clearing rather than deleting: every branch already targeting this block stays valid while its contents are rebuilt.

Source

pub fn delete_block(&mut self, block: BlockId)

Source

pub fn absorb_block(&mut self, keep: BlockId, other: BlockId, edge_ab: EdgeId)

Absorb other into keep: drop keep’s terminal branch, append other’s instructions, rehome its outgoing edges, and remove it. edge_ab is the direct edge keep -> other.

Source

pub fn register_local_name( &mut self, shared: &Shared<'str>, id: ValueId, name: Cow<'str, str>, old_name: Option<&str>, ) -> Result<()>

Register name for id in this body’s local name table (block/instruction/ param). A global-scoped id reads shared for the duplicate check but cannot be registered through a body (its shared table is read-only here); no body verb reaches that arm.

Source

pub fn register_body_name( &mut self, id: ValueId, name: Cow<'str, str>, old_name: Option<&str>, ) -> Result<()>

Register name for the function-scoped id (block/instruction/param/Temp) in this body’s local name table. The shared-arm-free canon behind register_local_name; panics on a global-scoped id. Errors only on a duplicate name.

Source

pub fn from_id<'ctx>( ctx: &'ctx Context<'str>, id: FunctionId, ) -> FunctionRef<'str, 'ctx>

Gets a reference to a function from its ID

Source

pub fn from_id_mut<'ctx>( ctx: &'ctx mut Context<'str>, id: FunctionId, ) -> FunctionMutRef<'str, 'ctx>

Gets a mutable reference to a function from its ID

Source

pub fn from_name<'ctx>( ctx: &'ctx Context<'str>, name: &str, ) -> Option<FunctionRef<'str, 'ctx>>

Gets a reference to a function by name

Source

pub fn make<'ctx>( ctx: &'ctx mut Context<'str>, name: Cow<'str, str>, ) -> Result<FunctionMutRef<'str, 'ctx>>

Create a new function

Source

pub fn make_lambda<'ctx>( ctx: &'ctx mut Context<'str>, name: Cow<'str, str>, ) -> Result<FunctionMutRef<'str, 'ctx>>

Create a new pure value-level lambda function.

Source

pub fn make_at_addr<'ctx>( ctx: &'ctx mut Context<'str>, address: u64, name: Option<Cow<'str, str>>, ) -> FunctionMutRef<'str, 'ctx>

Create a new function at a given address, generating a name if necessary.

Source

pub fn make_at_addr_indexed<'ctx>( ctx: &'ctx mut Context<'str>, addresses: &mut AddressIndex, address: u64, name: Option<Cow<'str, str>>, ) -> FunctionMutRef<'str, 'ctx>

Indexed construction variant of make_at_addr.

Source

pub fn make_external<'ctx>( ctx: &'ctx mut Context<'str>, address: u64, name: Option<Cow<'str, str>>, ) -> FunctionMutRef<'str, 'ctx>

Like FunctionBody::make_at_addr but marks the result as external.

External functions have no lifted body; the recursive disassembler will not try to explore them.

Source

pub fn make_external_indexed<'ctx>( ctx: &'ctx mut Context<'str>, addresses: &mut AddressIndex, address: u64, name: Option<Cow<'str, str>>, ) -> FunctionMutRef<'str, 'ctx>

Indexed construction variant of make_external.

Source

pub fn from_addr_or_create<'ctx>( ctx: &'ctx mut Context<'str>, address: u64, ) -> FunctionMutRef<'str, 'ctx>

Returns the FunctionId for addr, creating a named stub if absent.

Source

pub fn from_addr_or_create_indexed<'ctx>( ctx: &'ctx mut Context<'str>, addresses: &mut AddressIndex, address: u64, ) -> FunctionMutRef<'str, 'ctx>

Indexed construction variant of from_addr_or_create.

Trait Implementations§

Source§

impl<'str> Clone for FunctionBody<'str>

Source§

fn clone(&self) -> FunctionBody<'str>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'de, 'str> Deserialize<'de> for FunctionBody<'str>

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'str> Serialize for FunctionBody<'str>

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<'str> Freeze for FunctionBody<'str>

§

impl<'str> RefUnwindSafe for FunctionBody<'str>

§

impl<'str> Send for FunctionBody<'str>

§

impl<'str> Sync for FunctionBody<'str>

§

impl<'str> Unpin for FunctionBody<'str>

§

impl<'str> UnsafeUnpin for FunctionBody<'str>

§

impl<'str> UnwindSafe for FunctionBody<'str>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.