11use crate :: analysis:: cpa:: lattice:: JoinSemiLattice ;
22use crate :: analysis:: cpa:: state:: { AbstractState , LocationState , MergeOutcome , Successor } ;
3+ use crate :: analysis:: valuation:: SimpleValue ;
34use crate :: display:: JingleDisplay ;
45use crate :: modeling:: machine:: cpu:: concrete:: ConcretePcodeAddress ;
56use jingle_sleigh:: { IndirectVarNode , PcodeOperation } ;
@@ -13,12 +14,14 @@ use std::iter::{empty, once};
1314///
1415/// Variants:
1516/// - `Const(addr)` — a concrete pcode address (like `FlatLattice::Value`)
16- /// - `Computed(indirect)` — a location that may be computed from an indirect varnode
17+ /// - `Indirect(ivn)` — raw output of the transfer function for indirect branches
18+ /// - `Computed(sv)` — resolved by valuation strengthening
1719/// - `Top` — unknown / multiple locations
1820#[ derive( Clone , PartialEq , Eq , Hash ) ]
1921pub enum PcodeAddressLattice {
2022 Const ( ConcretePcodeAddress ) ,
21- Computed ( IndirectVarNode ) ,
23+ Indirect ( IndirectVarNode ) ,
24+ Computed ( SimpleValue ) ,
2225 Top ,
2326}
2427
@@ -30,9 +33,8 @@ impl JingleDisplay for PcodeAddressLattice {
3033 ) -> std:: fmt:: Result {
3134 match self {
3235 PcodeAddressLattice :: Const ( addr) => write ! ( f, "{:x}" , addr) ,
33- PcodeAddressLattice :: Computed ( indirect_var_node) => {
34- indirect_var_node. fmt_jingle ( f, info)
35- }
36+ PcodeAddressLattice :: Indirect ( ivn) => ivn. fmt_jingle ( f, info) ,
37+ PcodeAddressLattice :: Computed ( sv) => sv. fmt_jingle ( f, info) ,
3638 PcodeAddressLattice :: Top => write ! ( f, "Top" ) ,
3739 }
3840 }
@@ -45,6 +47,10 @@ impl Debug for PcodeAddressLattice {
4547 . debug_tuple ( "PcodeAddressLattice::Const" )
4648 . field ( & format_args ! ( "{:x}" , a) )
4749 . finish ( ) ,
50+ PcodeAddressLattice :: Indirect ( ivn) => f
51+ . debug_tuple ( "PcodeAddressLattice::Indirect" )
52+ . field ( & format_args ! ( "{:?}" , ivn) )
53+ . finish ( ) ,
4854 PcodeAddressLattice :: Computed ( c) => f
4955 . debug_tuple ( "PcodeAddressLattice::Computed" )
5056 . field ( & format_args ! ( "{:?}" , c) )
@@ -60,9 +66,11 @@ impl LowerHex for PcodeAddressLattice {
6066 // Delegate to the inner `ConcretePcodeAddress` LowerHex implementation
6167 // so `{:#x}` / `{:x}` on `PcodeAddressLattice::Const` prints the expected hex form.
6268 PcodeAddressLattice :: Const ( a) => write ! ( f, "PcodeAddressLattice::Const({:x})" , a) ,
63- // Computed values don't have a natural hex representation; fall back to debug.
64- PcodeAddressLattice :: Computed ( c) => {
65- write ! ( f, "PcodeAddressLattice::Computed({:?})" , c)
69+ PcodeAddressLattice :: Indirect ( ivn) => {
70+ write ! ( f, "PcodeAddressLattice::Indirect({:x})" , ivn)
71+ }
72+ PcodeAddressLattice :: Computed ( sv) => {
73+ write ! ( f, "PcodeAddressLattice::Computed({:x})" , sv)
6674 }
6775 PcodeAddressLattice :: Top => write ! ( f, "PcodeAddressLattice::Top" ) ,
6876 }
@@ -103,14 +111,21 @@ impl PartialOrd for PcodeAddressLattice {
103111 None
104112 }
105113 }
114+ ( Self :: Indirect ( x) , Self :: Indirect ( y) ) => {
115+ if x == y {
116+ Some ( Ordering :: Equal )
117+ } else {
118+ None
119+ }
120+ }
106121 ( Self :: Computed ( x) , Self :: Computed ( y) ) => {
107122 if x == y {
108123 Some ( Ordering :: Equal )
109124 } else {
110125 None
111126 }
112127 }
113- // Different kinds (Const vs Computed) are incomparable
128+ // Different kinds are incomparable
114129 _ => None ,
115130 }
116131 }
@@ -120,26 +135,24 @@ impl JoinSemiLattice for PcodeAddressLattice {
120135 fn join ( & mut self , other : & Self ) {
121136 // Match on references to avoid moving out of `self` while inspecting it.
122137 match ( & * self , other) {
123- ( Self :: Top , _) => * self = Self :: Top ,
124- ( _, Self :: Top ) => * self = Self :: Top ,
138+ ( Self :: Top , _) | ( _, Self :: Top ) => * self = Self :: Top ,
125139 ( Self :: Const ( a) , Self :: Const ( b) ) => {
126- if a == b {
127- // keep the same concrete value
128- } else {
140+ if a != b {
129141 * self = Self :: Top ;
130142 }
131143 }
132- ( Self :: Computed ( x) , Self :: Computed ( y) ) => {
133- if x == y {
134- // keep the same computed descriptor
135- } else {
144+ ( Self :: Indirect ( x) , Self :: Indirect ( y) ) => {
145+ if x != y {
136146 * self = Self :: Top ;
137147 }
138148 }
139- // Mixing Const and Computed -> unknown
140- _ => {
141- * self = Self :: Top ;
149+ ( Self :: Computed ( x) , Self :: Computed ( y) ) => {
150+ if x != y {
151+ * self = Self :: Top ;
152+ }
142153 }
154+ // Mixing different kinds -> unknown
155+ _ => * self = Self :: Top ,
143156 } ;
144157 }
145158}
@@ -161,15 +174,16 @@ impl AbstractState for PcodeAddressLattice {
161174 PcodeOperation :: BranchInd { input }
162175 | PcodeOperation :: CallInd { input }
163176 | PcodeOperation :: Return { input } => {
164- return once ( PcodeAddressLattice :: Computed ( input. clone ( ) ) ) . into ( ) ;
177+ return once ( PcodeAddressLattice :: Indirect ( input. clone ( ) ) ) . into ( ) ;
165178 }
166179 _ => { }
167180 }
168181
169182 match self {
170183 PcodeAddressLattice :: Const ( a) => a. transfer ( op) . into_iter ( ) . map ( Self :: Const ) . into ( ) ,
171- PcodeAddressLattice :: Computed ( _) => empty ( ) . into ( ) ,
172- PcodeAddressLattice :: Top => empty ( ) . into ( ) ,
184+ PcodeAddressLattice :: Indirect ( _)
185+ | PcodeAddressLattice :: Computed ( _)
186+ | PcodeAddressLattice :: Top => empty ( ) . into ( ) ,
173187 }
174188 }
175189}
@@ -181,9 +195,9 @@ impl LocationState for PcodeAddressLattice {
181195 ) -> Option < crate :: analysis:: pcode_store:: PcodeOpRef < ' a > > {
182196 match self {
183197 PcodeAddressLattice :: Const ( a) => t. get_pcode_op_at ( a) ,
184- // If the location is computed or top, we cannot directly get a concrete op
185- PcodeAddressLattice :: Computed ( _) => None ,
186- PcodeAddressLattice :: Top => None ,
198+ PcodeAddressLattice :: Indirect ( _ )
199+ | PcodeAddressLattice :: Computed ( _)
200+ | PcodeAddressLattice :: Top => None ,
187201 }
188202 }
189203
@@ -198,9 +212,8 @@ impl Display for PcodeAddressLattice {
198212 PcodeAddressLattice :: Const ( concrete_pcode_address) => {
199213 write ! ( f, "{:x}" , concrete_pcode_address)
200214 }
201- PcodeAddressLattice :: Computed ( indirect_var_node) => {
202- write ! ( f, "{:x}" , indirect_var_node)
203- }
215+ PcodeAddressLattice :: Indirect ( ivn) => write ! ( f, "{}" , ivn) ,
216+ PcodeAddressLattice :: Computed ( sv) => write ! ( f, "{}" , sv) ,
204217 PcodeAddressLattice :: Top => write ! ( f, "Top" ) ,
205218 }
206219 }
0 commit comments