angr.go.optimization_passes.atomic_rewriter

Fold the atomic instruction sequences the Go compiler emits back into the sync/atomic calls they came from.

On arm64 below GOARM64=v8.1 every atomic intrinsic is a dispatch on runtime.arm64HasATOMICS between an LSE instruction and an LL/SC retry loop. libVEX lifts the LSE instruction as an alignment-fault exit, fences and a compare-and-swap with a retry exit, all of which the structurer keeps as gotos. This pass drops the LL/SC arm, folds the LSE sequence into one call and strips the fault exits and fences from atomic loads and stores. On x86 the lock xadd, xchg and lock cmpxchg forms lift to the same compare-and-swap shape without the dispatch.

class angr.go.optimization_passes.atomic_rewriter.GoAtomicRewriter

Bases: OptimizationPass, CFGTransformationMixin

See the module docstring. Runs on the raw AIL, where the lifted shape of every instruction is exact.

ARCHES = ['AARCH64', 'AMD64', 'X86']
PLATFORMS = None
STAGE: OptimizationPassStage = 1
NAME = 'Fold atomic instruction sequences into sync/atomic calls'
__init__(func, manager, **kwargs)
class angr.go.optimization_passes.atomic_rewriter.GoAtomicCasFolder

Bases: OptimizationPass

Turn atomic_compare_exchange(p, old, new) == old into atomic.CompareAndSwap*(p, old, new) once the comparison is explicit, and give every synthesized atomic call its prototype.

ARCHES = ['AARCH64', 'AMD64', 'X86']
PLATFORMS = None
STAGE: OptimizationPassStage = 7
NAME = 'Fold compare-and-swap results into their bool'
__init__(func, manager, **kwargs)
static cas_bool(call)
Return type:

Call

Parameters:

call (Call)

set_prototype(call)
Return type:

None

Parameters:

call (Call)