1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Static Single Assignment (SSA) form for CIL methods.
//!
//! This module provides SSA transformation for .NET CIL bytecode, converting
//! stack-based operations into an explicit variable form where each variable
//! is assigned exactly once. This representation enables powerful optimizations
//! and analyses like constant propagation, dead code elimination, and type inference.
//!
//! # Architecture
//!
//! The SSA module is organized into focused sub-modules:
//!
//! - [`variable`] - SSA variable representation and identifiers
//! - [`phi`] - Phi node representation for control flow merges
//! - [`instruction`] - SSA-form instructions with explicit def/use chains
//! - [`block`] - SSA basic blocks containing phi nodes and instructions
//! - [`function`] - Complete SSA representation of a method
//! - [`builder`] - SSA construction algorithm (Cytron et al.)
//! - [`types`] - SSA type system for CIL types
//! - [`value`] - Value tracking for constant propagation and CSE
//! - [`ops`] - Decomposed SSA operations
//!
//! # CIL to SSA Transformation
//!
//! CIL is a stack-based instruction set, while SSA uses explicit variables.
//! The transformation involves several phases:
//!
//! 1. **Stack Simulation**: Convert implicit stack operations to explicit variables
//! 2. **Phi Placement**: Insert phi nodes at dominance frontiers
//! 3. **Variable Renaming**: Assign unique versions using dominator tree traversal
//!
//! ## Variable Origins
//!
//! SSA variables can originate from several sources:
//!
//! - **Arguments**: Method parameters (`ldarg`, `starg`)
//! - **Locals**: Local variables (`ldloc`, `stloc`)
//! - **Stack slots**: Temporary values from stack operations
//! - **Phi nodes**: Merged values at control flow joins
//!
//! ## Address-Taking Considerations
//!
//! Variables whose address is taken (`ldarga`, `ldloca`) require special handling
//! as they may be modified through pointers. These are tracked separately and
//! may be excluded from full SSA optimization.
//!
//! # Usage
//!
//! ```rust,ignore
//! use dotscope::analysis::{ControlFlowGraph, SsaConverter};
//! use dotscope::assembly::decode_blocks;
//!
//! // Build CFG from decoded blocks
//! let blocks = decode_blocks(data, offset, rva, Some(size))?;
//! let cfg = ControlFlowGraph::from_basic_blocks(blocks)?;
//!
//! // Construct SSA form
//! let ssa = SsaConverter::build(&cfg, num_args, num_locals, resolver)?;
//!
//! // Analyze phi nodes at merge points
//! for block in ssa.blocks() {
//! for phi in block.phi_nodes() {
//! println!("Phi: {:?} = phi({:?})", phi.result(), phi.operands());
//! }
//! }
//! ```
//!
//! # References
//!
//! - Cytron et al., "Efficiently Computing Static Single Assignment Form and the
//! Control Dependence Graph", ACM TOPLAS 1991
//! - Cooper & Torczon, "Engineering a Compiler", Chapter 9
// Re-export primary types at module level
pub use SsaBlock;
pub use ;
pub use SsaCfg;
pub use ;
pub use ConstEvaluator;
pub use SsaConverter;
pub use ;
pub use SsaExceptionHandler;
pub use ;
pub use SsaInstruction;
pub use ;
pub use ;
pub use ;
pub use ;
pub use PhiAnalyzer;
pub use ValueResolver;
pub use ;
pub use ;
// Z3Solver requires the z3 dependency (independent of deobfuscation)
pub use Z3Solver;
pub use ;
pub use ;
pub use ;