angr.analyses.decompiler.pattern_match.region

Turn a token interval into something Outliner accepts.

The Outliner takes a single entry location plus a frontier and lifts everything between them into a new function. A token interval discovered by align does not automatically satisfy that: it may start or end in the middle of a block, and the blocks it covers may be entered from outside.

snap() reports whether an interval can be outlined and why not when it cannot; materialize() performs the block splits and returns the final (src_loc, frontier).

class angr.analyses.decompiler.pattern_match.region.Region

Bases: object

An interval mapped onto AIL blocks, with its outlinability verdict.

interval: Interval
block_locs: list[tuple[int, int]]
src_loc: tuple[int, int]
frontier: set[tuple[int, int]]
head_split: int = 0
tail_split: int = 0
outlinable: bool = False
reason: str = ''
property needs_split: bool
__init__(interval, block_locs, src_loc, frontier=<factory>, head_split=0, tail_split=0, outlinable=False, reason='')
Parameters:
Return type:

None

angr.analyses.decompiler.pattern_match.region.snap(stream, graph, interval, *, allow_split=True, entry_loc=None)

Map interval onto blocks and decide whether the Outliner can take it.

Return type:

Region

Parameters:
angr.analyses.decompiler.pattern_match.region.largest_single_entry_subrun(stream, graph, interval, *, entry_loc=None, min_ratio=0.0)

The largest outlinable region inside interval, made of whole consecutive blocks of it, or None.

A run of tokens is not always a single-entry region: reverse post-order interleaves blocks from different parts of the CFG, so one copy of an idiom can still be jumped into from elsewhere. Some consecutive sub-run of its blocks usually is single-entry, and the largest one is what can be outlined under the pattern’s name. min_ratio is the smallest share of the interval’s tokens the sub-run must cover to count.

Return type:

Region | None

Parameters:
angr.analyses.decompiler.pattern_match.region.fallback_idx_alloc(graph)

An AIL index allocator for a caller without a Manager: seeded past every index already in graph, since a rebuilt statement must not reuse one an existing expression holds.

Return type:

Callable[[], int]

Parameters:

graph (networkx.DiGraph[Block])

angr.analyses.decompiler.pattern_match.region.materialize(graph, stream, region, block_addr_alloc, *, split_tail=True, idx_alloc=None)

Split the boundary blocks in place so region becomes block-aligned.

Returns the (src_loc, frontier) pair to hand to the Outliner. graph is mutated. With split_tail=False only the head is split, which is what the caller wants when it intends to let the Outliner derive its own frontier: the tail boundary is then chosen by liveness, not by the interval.

Return type:

tuple[tuple[int, int], set[tuple[int, int]]]

Parameters: