1use yaxpeax_arch::Arch;
2use data::ValueLocations;
3
4#[macro_use]
5pub mod control_flow;
6pub mod data_flow;
7pub mod function_signatures;
8pub mod memory_layout;
9pub mod static_single_assignment;
10pub mod xrefs;
11pub mod evaluators;
12pub mod value_range;
13
14pub enum CompletionStatus {
15 Incomplete,
16 Complete,
17}
18
19pub struct ValueRes<V> {
20 pub value: V,
21 pub carry: V,
22}
23
24#[allow(dead_code)]
25impl<V: Value> ValueRes<V> {
26 pub(crate) fn from_zero() -> Self {
27 ValueRes::literal(V::from_const(0))
28 }
29 pub(crate) fn literal(value: V) -> Self {
30 ValueRes {
31 value,
32 carry: V::from_const(0),
33 }
34 }
35 pub(crate) fn unknown() -> Self {
36 ValueRes {
37 value: V::unknown(),
38 carry: V::unknown(),
39 }
40 }
41 pub(crate) fn parts(self) -> (V, V) {
42 (self.value, self.carry)
43 }
44 pub(crate) fn value(self) -> V {
45 self.value
46 }
47 pub(crate) fn carry(self) -> V {
48 self.carry
49 }
50 pub(crate) fn zero(&self) -> V {
51 self.value.eq(&V::from_const(0))
52 }
53 pub(crate) fn sign(&self) -> V {
54 self.value.lt(&V::from_const(0))
55 }
56}
57
58pub trait DFG<V: Value, A: Arch + ValueLocations, When=<A as Arch>::Address> where When: Copy {
95 type Indirect: IndirectQuery<V>;
96
97 fn read_loc(&self, when: When, loc: A::Location) -> V;
98 fn read<T: ToDFGLoc<A::Location>>(&self, when: When, loc: &T) -> V {
99 self.read_loc(when, loc.convert())
100 }
101 fn write_loc(&mut self, when: When, loc: A::Location, value: V);
102 fn write<T: ToDFGLoc<A::Location>>(&mut self, when: When, loc: &T, value: V) {
103 self.write_loc(when, loc.convert(), value)
104 }
105 fn indirect_loc(&self, _when: When, _loc: A::Location) -> Self::Indirect;
114 fn indirect<T: ToDFGLoc<A::Location>>(&self, when: When, loc: &T) -> Self::Indirect {
115 self.indirect_loc(when, loc.convert())
116 }
117 fn query_at(&self, when: When) -> DFGLocationQueryCursor<When, V, A, Self> {
118 DFGLocationQueryCursor {
119 dfg: self,
120 addr: when,
121 _a: std::marker::PhantomData,
122 _v: std::marker::PhantomData,
123 }
124 }
125 fn query_at_mut(&mut self, when: When) -> DFGLocationQueryCursorMut<When, V, A, Self> {
126 DFGLocationQueryCursorMut {
127 dfg: self,
128 addr: when,
129 _a: std::marker::PhantomData,
130 _v: std::marker::PhantomData,
131 }
132 }
133}
134
135pub struct DFGLocationQueryCursor<'dfg, K: Copy + Sized, V: Value, A: Arch + ValueLocations, D: DFG<V, A, K> + ?Sized> {
136 dfg: &'dfg D,
137 addr: K,
138 _a: std::marker::PhantomData<A>,
139 _v: std::marker::PhantomData<V>,
140}
141
142pub struct DFGLocationQueryCursorMut<'dfg, K: Copy + Sized, V: Value, A: Arch + ValueLocations, D: DFG<V, A, K> + ?Sized> {
143 dfg: &'dfg mut D,
144 addr: K,
145 _a: std::marker::PhantomData<A>,
146 _v: std::marker::PhantomData<V>,
147}
148
149impl<'dfg, K: Copy, V: Value, A: Arch + ValueLocations, D: DFG<V, A, K> + ?Sized> DFGLocationQuery<V, A> for DFGLocationQueryCursor<'dfg, K, V, A, D> {
150 type Indirect = D::Indirect;
151
152 fn read_loc(&self, loc: A::Location) -> V {
153 self.dfg.read_loc(self.addr, loc)
154 }
155 fn read<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> V {
156 self.read_loc(loc.convert())
157 }
158 fn indirect_loc(&self, loc: A::Location) -> Self::Indirect {
159 self.dfg.indirect_loc(self.addr, loc)
160 }
161 fn indirect<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> Self::Indirect {
162 self.indirect_loc(loc.convert())
163 }
164}
165impl<'dfg, K: Copy, V: Value, A: Arch + ValueLocations, D: DFG<V, A, K> + ?Sized> DFGLocationQuery<V, A> for DFGLocationQueryCursorMut<'dfg, K, V, A, D> {
166 type Indirect = D::Indirect;
167
168 fn read_loc(&self, loc: A::Location) -> V {
169 self.dfg.read_loc(self.addr, loc)
170 }
171 fn read<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> V {
172 self.read_loc(loc.convert())
173 }
174 fn indirect_loc(&self, loc: A::Location) -> Self::Indirect {
175 self.dfg.indirect_loc(self.addr, loc)
176 }
177 fn indirect<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> Self::Indirect {
178 self.indirect_loc(loc.convert())
179 }
180}
181impl<'dfg, K: Copy, V: Value, A: Arch + ValueLocations, D: DFG<V, A, K> + ?Sized> DFGLocationQueryMut<V, A> for DFGLocationQueryCursorMut<'dfg, K, V, A, D> {
182 fn write_loc(&mut self, loc: A::Location, value: V) {
183 self.dfg.write_loc(self.addr, loc, value)
184 }
185 fn write<T: ToDFGLoc<A::Location>>(&mut self, loc: &T, value: V) {
186 self.write_loc(loc.convert(), value)
187 }
188}
189
190pub trait DFGLocationQuery<V: Value, A: Arch + ValueLocations> where Self: Sized {
194 type Indirect: IndirectQuery<V>;
195
196 fn read_loc(&self, loc: A::Location) -> V;
197 fn read<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> V {
198 self.read_loc(loc.convert())
199 }
200 fn indirect_loc(&self, loc: A::Location) -> Self::Indirect;
201 fn indirect<T: ToDFGLoc<A::Location>>(&self, loc: &T) -> Self::Indirect {
202 self.indirect_loc(loc.convert())
203 }
204}
205
206pub trait DFGLocationQueryMut<V: Value, A: Arch + ValueLocations> where Self: Sized + DFGLocationQuery<V, A> {
207 fn write_loc(&mut self, loc: A::Location, value: V);
208 fn write<T: ToDFGLoc<A::Location>>(&mut self, loc: &T, value: V) {
209 self.write_loc(loc.convert(), value)
210 }
211}
212
213pub trait ToDFGLoc<U> {
214 fn convert(&self) -> U;
215}
216
217impl<T: Clone> ToDFGLoc<T> for T {
218 fn convert(&self) -> T {
219 self.to_owned()
220 }
221}
222
223impl<'a, T: Clone> ToDFGLoc<T> for &'a T {
224 fn convert(&self) -> T {
225 self.to_owned().to_owned()
226 }
227}
228
229#[derive(Copy, Clone, Debug)]
230pub struct ValueIndex<'v, V: ?Sized> {
231 pub base: &'v V,
232 pub size: usize,
233}
234
235impl<'v, V: ?Sized + crate::analyses::static_single_assignment::DataDisplay<'v, 'static>> fmt::Display for ValueIndex<'v, V> {
236 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
237 write!(f, "[{}, width: {}]", self.base.display(false, None), self.size)
238 }
239}
240
241pub trait IntoValueIndex {
242 fn byte(&self) -> ValueIndex<Self> {
243 ValueIndex {
244 base: self,
245 size: 1,
246 }
247 }
248
249 fn word(&self) -> ValueIndex<Self> {
250 ValueIndex {
251 base: self,
252 size: 2,
253 }
254 }
255
256 fn dword(&self) -> ValueIndex<Self> {
257 ValueIndex {
258 base: self,
259 size: 4,
260 }
261 }
262
263 fn qword(&self) -> ValueIndex<Self> {
264 ValueIndex {
265 base: self,
266 size: 8,
267 }
268 }
269
270 fn width(&self, size: usize) -> ValueIndex<Self> {
271 ValueIndex {
272 base: self,
273 size,
274 }
275 }
276}
277
278impl <T: Value> IntoValueIndex for T {}
279
280pub trait IndirectQuery<V> {
281 fn load(&self, _address: ValueIndex<V>) -> V;
289
290 fn store(&self, _address: ValueIndex<V>, _value: &V);
298
299 fn try_get_load(&self, _address: ValueIndex<V>) -> Option<V>;
308
309 fn try_get_store(&self, _address: ValueIndex<V>) -> Option<()>;
317}
318
319pub struct OpaqueIndirection<V> {
320 _marker: std::marker::PhantomData<V>,
321}
322
323impl<V> OpaqueIndirection<V> {
324 pub fn inst() -> Self {
325 OpaqueIndirection {
326 _marker: std::marker::PhantomData
327 }
328 }
329}
330
331
332impl<V: Value> IndirectQuery<V> for OpaqueIndirection<V> {
333 fn load(&self, _: ValueIndex<V>) -> V {
334 V::unknown()
335 }
336
337 fn store(&self, _: ValueIndex<V>, _: &V) { }
338
339 fn try_get_load(&self, _: ValueIndex<V>) -> Option<V> {
340 None
341 }
342
343 fn try_get_store(&self, _: ValueIndex<V>) -> Option<()> {
344 None
345 }
346}
347
348pub trait Value: Sized {
349fn unknown() -> Self;
352
353 fn from_const(_c: i64) -> Self {
354 Self::unknown()
355 }
356
357 fn from_set(xs: &[Self]) -> Self;
358
359 fn to_const(&self) -> Option<i64>;
360
361 fn as_bool(&self) -> Option<bool> {
362 self.ne(&Value::from_const(0)).to_const().map(|x| x != 0)
363 }
364
365 fn add(&self, _other: &Self) -> ValueRes<Self> {
366 ValueRes::unknown()
367 }
368
369 fn sub(&self, _other: &Self) -> ValueRes<Self> {
370 ValueRes::unknown()
371 }
372
373 fn mul(&self, _other: &Self) -> ValueRes<Self> {
374 ValueRes::unknown()
375 }
376
377 fn or(&self, _other: &Self) -> ValueRes<Self> {
378 ValueRes::unknown()
379 }
380
381 fn and(&self, _other: &Self) -> ValueRes<Self> {
382 ValueRes::unknown()
383 }
384
385 fn xor(&self, _other: &Self) -> ValueRes<Self> {
386 ValueRes::unknown()
387 }
388
389 fn modulo(&self, other: &Self) -> Self {
390 match (self.to_const(), other.to_const()) {
391 (Some(x), Some(y)) => {
392 Value::from_const(x % y)
393 }
394 _ => {
395 Self::unknown()
396 }
397 }
398 }
399
400 fn ne(&self, _other: &Self) -> Self {
401 Self::unknown()
402 }
403
404 fn le(&self, _other: &Self) -> Self {
405 Self::unknown()
406 }
407
408 fn lt(&self, other: &Self) -> Self {
409 self.le(other).and(&self.eq(other).not()).value()
410 }
411
412 fn gte(&self, other: &Self) -> Self {
413 self.lt(other).not()
414 }
415
416 fn eq(&self, _other: &Self) -> Self {
417 Self::unknown()
418 }
419
420 fn not(&self) -> Self {
421 Self::unknown()
422 }
423
424 fn sxt(&self, _width: &Self) -> Self {
425 Self::unknown()
426 }
427
428 fn zxt(&self, _width: &Self) -> Self {
429 Self::unknown()
430 }
431
432 fn shr(&self, _amt: &Self) -> Self {
433 Self::unknown()
434 }
435
436 fn sar(&self, _width: &Self) -> Self {
437 Self::unknown()
438 }
439
440 fn shl(&self, _width: &Self) -> Self {
441 Self::unknown()
442 }
443
444 fn sal(&self, _width: &Self) -> Self {
445 Self::unknown()
446 }
447
448 fn rcl(&self, _width: &Self) -> Self {
449 Self::unknown()
450 }
451
452 fn rcr(&self, _width: &Self) -> Self {
453 Self::unknown()
454 }
455
456 fn rol(&self, _width: &Self) -> Self {
457 Self::unknown()
458 }
459
460 fn ror(&self, _width: &Self) -> Self {
461 Self::unknown()
462 }
463}
464
465use SSAValues;
466use std::rc::Rc;
467use analyses::static_single_assignment::{DataDisplay, DFGRef};
468use crate::ColorSettings;
469use data::types::TypeSpec;
470
471#[derive(Debug, Eq, Hash, PartialEq)]
472pub struct Item<Leaf> {
473 pub ty: Option<TypeSpec>,
474 pub value: Expression<Leaf>,
475}
476
477pub struct ItemDisplay<'data, 'colors, Leaf> where Leaf: DataDisplay<'data, 'colors> {
478 data: &'data Rc<Item<Leaf>>,
479 detailed: bool,
480 colors: Option<&'colors ColorSettings>,
481}
482
483impl<'data, 'colors, Leaf: 'data + DataDisplay<'data, 'colors>> DataDisplay<'data, 'colors> for Rc<Item<Leaf>> {
484 type Displayer = ItemDisplay<'data, 'colors, Leaf>;
485 fn display(&'data self, detailed: bool, colors: Option<&'colors ColorSettings>) -> Self::Displayer {
486 ItemDisplay {
487 data: self,
488 detailed,
489 colors
490 }
491 }
492}
493
494impl<'data, 'colors, Leaf: 'data + DataDisplay<'data, 'colors>> fmt::Display for ItemDisplay<'data, 'colors, Leaf> {
495 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496 if let Some(ty) = self.data.ty.as_ref() {
497 write!(f, "({}: {:?})", self.data.value.display(self.detailed, self.colors), ty)
498 } else {
499 write!(f, "{}", self.data.value.display(self.detailed, self.colors))
500 }
501 }
502}
503
504impl<Leaf: fmt::Display> fmt::Display for Item<Leaf> {
505 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
506 fmt::Display::fmt(&self.value, f)
507 }
508}
509
510impl<A: SSAValues> Item<ValueOrImmediate<A>> where A::Data: Eq + fmt::Display {
511 pub fn immediate(v: i64) -> Rc<Self> {
512 Self::untyped(Expression::value(ValueOrImmediate::Immediate(v)))
513 }
514}
515
516use analyses::memory_layout::Underlying;
517impl<A: SSAValues> Item<ValueOrImmediate<A>> where A::Data: Underlying<Arch=A> + Eq + fmt::Display {
518 pub fn dealiased(&self) -> Rc<Self> {
519 let ty = self.ty.clone();
520 let value = self.value.dealiased();
521 Rc::new(Item { ty, value })
522 }
523}
524
525impl<A: SSAValues> Item<ValueOrImmediate<A>> where A::Data: Eq + fmt::Display{
526}
527
528impl<Leaf> Item<Leaf> {
529 pub fn untyped(value: Expression<Leaf>) -> Rc<Self> {
530 Rc::new(Item {
531 ty: None,
532 value,
533 })
534 }
535
536 pub fn opaque(ty: TypeSpec) -> Rc<Self> {
537 Rc::new(Item {
538 ty: Some(ty),
539 value: Expression::unknown()
540 })
541 }
542
543 pub fn unknown() -> Rc<Self> {
544 Self::untyped(Expression::unknown())
545 }
546
547 pub fn value(leaf: Leaf) -> Rc<Self> {
548 Self::untyped(Expression::value(leaf))
549 }
550
551 pub fn loadb(self: &Rc<Self>) -> Rc<Self> {
552 self.load(1)
553 }
554
555 pub fn loadw(self: &Rc<Self>) -> Rc<Self> {
556 self.load(2)
557 }
558
559 pub fn loadd(self: &Rc<Self>) -> Rc<Self> {
560 self.load(4)
561 }
562
563 pub fn loadq(self: &Rc<Self>) -> Rc<Self> {
564 self.load(8)
565 }
566
567 pub fn load(self: &Rc<Self>, size: u8) -> Rc<Self> {
568 Self::untyped(Expression::Load { address: Rc::clone(self), size })
569 }
570
571 pub fn add(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
572 Self::untyped(Expression::Add { left: Rc::clone(self), right: Rc::clone(other) })
573 }
574
575 pub fn sub(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
576 Self::untyped(Expression::Sub { left: Rc::clone(self), right: Rc::clone(other) })
577 }
578
579 pub fn mul(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
580 Self::untyped(Expression::Mul { left: Rc::clone(self), right: Rc::clone(other) })
581 }
582
583 pub fn or(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
584 Self::untyped(Expression::Or { left: Rc::clone(self), right: Rc::clone(other) })
585 }
586
587 pub fn and(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
588 Self::untyped(Expression::And { left: Rc::clone(self), right: Rc::clone(other) })
589 }
590
591 pub fn xor(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
592 Self::untyped(Expression::Xor { left: Rc::clone(self), right: Rc::clone(other) })
593 }
594
595 pub fn shl(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
596 Self::untyped(Expression::Shl { value: Rc::clone(self), amount: Rc::clone(other) })
597 }
598
599 pub fn shr(self: &Rc<Self>, other: &Rc<Self>) -> Rc<Self> {
600 Self::untyped(Expression::Shr { value: Rc::clone(self), amount: Rc::clone(other) })
601 }
602}
603
604#[derive(Debug, Eq, Hash, PartialEq)]
609pub enum Expression<Leaf> {
610 Unknown,
611 Value(Leaf),
612 Load { address: Rc<Item<Leaf>>, size: u8 },
613 Add { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
616 Sub { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
617 Mul { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
618 Or { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
619 And { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
620 Xor { left: Rc<Item<Leaf>>, right: Rc<Item<Leaf>> },
621 Shl { value: Rc<Item<Leaf>>, amount: Rc<Item<Leaf>> },
622 Shr { value: Rc<Item<Leaf>>, amount: Rc<Item<Leaf>> },
623}
624
625pub struct ExpressionDisplay<'data, 'colors, Leaf: DataDisplay<'data, 'colors>> {
626 data: &'data Expression<Leaf>,
627 detailed: bool,
628 colors: Option<&'colors ColorSettings>,
629}
630
631impl<'data, 'colors, Leaf: 'data + DataDisplay<'data, 'colors>> DataDisplay<'data, 'colors> for Expression<Leaf> {
632 type Displayer = ExpressionDisplay<'data, 'colors, Leaf>;
633 fn display(&'data self, detailed: bool, colors: Option<&'colors ColorSettings>) -> Self::Displayer {
634 ExpressionDisplay {
635 data: self,
636 detailed,
637 colors
638 }
639 }
640}
641
642impl<'data, 'colors, Leaf: 'data + DataDisplay<'data, 'colors>> fmt::Display for ExpressionDisplay<'data, 'colors, Leaf> {
643 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
644 match self.data {
645 Expression::Unknown => {
646 write!(f, "<unknown>")
647 }
648 Expression::Value(l) => {
649 write!(f, "{}", l.display(self.detailed, self.colors))
650 }
651 Expression::Load { address, size } => {
652 write!(f, "[{}:{}]", address.display(self.detailed, self.colors), size)
653 }
654 Expression::Add { left, right } => {
655 write!(f, "({} + {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
656 }
657 Expression::Sub { left, right } => {
658 write!(f, "({} - {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
659 }
660 Expression::Mul { left, right } => {
661 write!(f, "({} * {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
662 }
663 Expression::Or { left, right } => {
664 write!(f, "({} | {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
665 }
666 Expression::And { left, right } => {
667 write!(f, "({} & {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
668 }
669 Expression::Xor { left, right } => {
670 write!(f, "({} ^ {})", left.display(self.detailed, self.colors), right.display(self.detailed, self.colors))
671 }
672 Expression::Shl { value, amount } => {
673 write!(f, "({} << {})", value.display(self.detailed, self.colors), amount.display(self.detailed, self.colors))
674 }
675 Expression::Shr { value, amount } => {
676 write!(f, "({} >> {})", value.display(self.detailed, self.colors), amount.display(self.detailed, self.colors))
677 }
678 }
679 }
680}
681
682impl<Leaf: fmt::Display> fmt::Display for Expression<Leaf> {
683 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
684 match self {
685 Expression::Unknown => {
686 write!(f, "<unknown>")
687 }
688 Expression::Value(l) => {
689 write!(f, "{}", l)
690 }
691 Expression::Load { address, size } => {
692 write!(f, "[{}:{}]", address, size)
693 }
694 Expression::Add { left, right } => {
695 write!(f, "({} + {})", left, right)
696 }
697 Expression::Sub { left, right } => {
698 write!(f, "({} - {})", left, right)
699 }
700 Expression::Mul { left, right } => {
701 write!(f, "({} * {})", left, right)
702 }
703 Expression::Or { left, right } => {
704 write!(f, "({} | {})", left, right)
705 }
706 Expression::And { left, right } => {
707 write!(f, "({} & {})", left, right)
708 }
709 Expression::Xor { left, right } => {
710 write!(f, "({} ^ {})", left, right)
711 }
712 Expression::Shl { value, amount } => {
713 write!(f, "({} << {})", value, amount)
714 }
715 Expression::Shr { value, amount } => {
716 write!(f, "({} >> {})", value, amount)
717 }
718 }
719 }
720}
721
722impl<T: SSAValues> Expression<ValueOrImmediate<T>> where T::Data: Eq + fmt::Display {
723 pub fn as_immediate(&self) -> Option<i64> {
724 if let Expression::Value(ValueOrImmediate::Immediate(i)) = self {
725 Some(*i)
726 } else {
727 None
728 }
729 }
730}
731
732impl<A: SSAValues> Expression<ValueOrImmediate<A>> where A::Data: Underlying<Arch=A> + Eq + fmt::Display {
733 pub fn dealiased(&self) -> Self {
734 match self {
735 Expression::Unknown => Expression::Unknown,
736 Expression::Value(ValueOrImmediate::Immediate(i)) => Expression::Value(ValueOrImmediate::Immediate(*i)),
737 Expression::Value(ValueOrImmediate::Value(v)) => {
738 if let Some(underlying) = v.borrow().data.as_ref().and_then(|x| x.underlying()) {
739 Expression::Value(ValueOrImmediate::Value(underlying))
740 } else {
741 Expression::Value(ValueOrImmediate::Value(Rc::clone(v)))
742 }
743 }
744 Expression::Load { address, size } => Expression::Load { address: address.dealiased(), size: *size },
745 Expression::Add { left, right } => Expression::Add {
746 left: left.dealiased(), right: right.dealiased(),
747 },
748 Expression::Sub { left, right } => Expression::Sub {
749 left: left.dealiased(), right: right.dealiased(),
750 },
751 Expression::Mul { left, right } => Expression::Mul {
752 left: left.dealiased(), right: right.dealiased(),
753 },
754 Expression::Or { left, right } => Expression::Or {
755 left: left.dealiased(), right: right.dealiased(),
756 },
757 Expression::And { left, right } => Expression::And {
758 left: left.dealiased(), right: right.dealiased(),
759 },
760 Expression::Xor { left, right } => Expression::Xor {
761 left: left.dealiased(), right: right.dealiased(),
762 },
763 Expression::Shl { value, amount } => Expression::Shl {
764 value: value.dealiased(), amount: amount.dealiased(),
765 },
766 Expression::Shr { value, amount } => Expression::Shr {
767 value: value.dealiased(), amount: amount.dealiased(),
768 },
769 }
770 }
771}
772
773impl<Leaf> Expression<Leaf> {
774 pub fn unknown() -> Self {
775 Self::Unknown
776 }
777
778 pub fn value(leaf: Leaf) -> Self {
779 Self::Value(leaf)
780 }
781
782 }
816
817use std::hash::Hash;
818use std::hash::Hasher;
819pub enum ValueOrImmediate<A: SSAValues> where A::Data: Eq + fmt::Display {
820 Immediate(i64),
821 Value(DFGRef<A>),
822}
823
824impl<A: SSAValues> ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
825 pub fn immediate(v: i64) -> Expression<Self> {
826 Expression::value(ValueOrImmediate::Immediate(v))
827 }
828
829 fn name(&self) -> String {
830 match self {
831 ValueOrImmediate::Immediate(v) => {
832 format!("{}", v)
833 }
834 ValueOrImmediate::Value(v) => {
835 let version_string = match v.borrow().version {
836 Some(v) => { v.to_string() },
837 None => "input".to_string()
838 };
839 if let Some(_data) = v.borrow().data.as_ref() {
840 format!("{:?}_{}", v.borrow().location, version_string)
841 } else {
842 format!("{:?}_{}", v.borrow().location, version_string)
843 }
844 }
845 }
846 }
847}
848
849use std::fmt;
850impl<A: SSAValues> fmt::Debug for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
851 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
852 match self {
853 ValueOrImmediate::Immediate(v) => {
854 write!(f, "Immediate({})", v)
855 }
856 ValueOrImmediate::Value(v) => {
857 write!(f, "Value({:?})", v)
858 }
859 }
860 }
861}
862
863impl<A: SSAValues> fmt::Display for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
864 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
865 match self {
866 ValueOrImmediate::Immediate(v) => {
867 write!(f, "{}", v)
868 }
869 ValueOrImmediate::Value(v) => {
870 let version_string = match v.borrow().version {
871 Some(v) => { v.to_string() },
872 None => "input".to_string()
873 };
874 if let Some(data) = v.borrow().data.as_ref() {
875 write!(f, "{} ({:?}_{})", data, v.borrow().location, version_string)
876 } else {
877 write!(f, "<unknown value> ({:?}_{})", v.borrow().location, version_string)
878 }
879 }
880 }
881 }
882}
883
884pub struct LeafDisplay<'data, 'colors, A: SSAValues> where A::Data: Eq + fmt::Display {
885 data: &'data ValueOrImmediate<A>,
886 detailed: bool,
887 colors: Option<&'colors ColorSettings>,
888}
889
890impl<'data, 'colors, A: 'data + SSAValues> DataDisplay<'data, 'colors> for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
891 type Displayer = LeafDisplay<'data, 'colors, A>;
892 fn display(&'data self, detailed: bool, colors: Option<&'colors ColorSettings>) -> Self::Displayer {
893 LeafDisplay {
894 data: self,
895 detailed,
896 colors
897 }
898 }
899}
900
901impl<'data, 'colors, A: SSAValues> fmt::Display for LeafDisplay<'data, 'colors, A> where A::Data: Eq + fmt::Display {
902 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
903 match &self.data {
904 ValueOrImmediate::Immediate(i) => {
905 write!(f, "{:#x}", i)
907 }
908 ValueOrImmediate::Value(v) => {
909 fmt::Display::fmt(&v.borrow().display(self.detailed, self.colors), f)
910 }
911 }
912 }
913}
914
915
916impl<A: SSAValues> Eq for ValueOrImmediate<A> where A::Data: Eq + fmt::Display { }
917impl<A: SSAValues> PartialEq for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
918 fn eq(&self, other: &Self) -> bool {
919 match (self, other) {
920 (ValueOrImmediate::Immediate(l), ValueOrImmediate::Immediate(r)) => {
921 l == r
922 }
923 (ValueOrImmediate::Value(l), ValueOrImmediate::Value(r)) => {
924 Rc::ptr_eq(l, r)
925 }
926 _ => {
927 false
928 }
929 }
930 }
931}
932
933impl<A: SSAValues> Clone for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
934 fn clone(&self) -> Self {
935 match self {
936 ValueOrImmediate::Immediate(v) => {
937 ValueOrImmediate::Immediate(*v)
938 }
939 ValueOrImmediate::Value(v) => {
940 ValueOrImmediate::Value(Rc::clone(v))
941 }
942 }
943 }
944}
945
946impl<A: SSAValues> Hash for ValueOrImmediate<A> where A::Data: Eq + fmt::Display {
947 fn hash<H: Hasher>(&self, state: &mut H) {
948 match self {
949 ValueOrImmediate::Immediate(v) => {
950 state.write_u8(1);
951 state.write_i64(*v);
952 }
953 ValueOrImmediate::Value(value) => {
954 state.write_u8(2);
955 (crate::analyses::static_single_assignment::HashedValue { value: Rc::clone(value) }).hash(state);
956 }
957 }
958 }
959}
960
961use analyses::static_single_assignment::{DFGRebase, DefSource, HashedValue, SSA};
962impl<A: SSAValues + Arch> DFGRebase<A> for Rc<Item<ValueOrImmediate<A>>> where A::Data: Hash + Eq + fmt::Display, A::Location: DFGRebase<A> {
963 fn rebase_references(&self, old_dfg: &SSA<A>, new_dfg: &SSA<A>) -> Self {
964 match &self.value {
965 Expression::Unknown => Item::unknown(),
966 Expression::Value(leaf) => {
967 match leaf {
968 ValueOrImmediate::Immediate(v) => {
969 Item::untyped(Expression::Value(ValueOrImmediate::Immediate(*v)))
970 }
971 ValueOrImmediate::Value(v) => {
972 if !new_dfg.defs.contains_key(&HashedValue { value: Rc::clone(v) }) {
973 let (old_def_addr, old_def_source) = old_dfg.get_def_site(Rc::clone(v));
974 let new_use = match old_def_source {
975 DefSource::Instruction => {
976 new_dfg.get_use(old_def_addr, v.borrow().location.rebase_references(old_dfg, new_dfg))
977 .value
978 },
979 DefSource::External => {
980 new_dfg.instruction_values.values()
981 .find_map(|values| {
982 values.iter().find_map(|((loc, dir), dfg_ref)| {
983 if dir == &crate::data::Direction::Read && loc == &v.borrow().location && v.borrow().version.is_none() {
984 Some(Rc::clone(dfg_ref))
985 } else {
986 None
987 }
988 })
989 })
990 .expect(&format!("corresponding external def exists for location {:?}", v.borrow().location))
991 }
992 DefSource::Between(addr) => {
993 Rc::clone(new_dfg.control_dependent_values
994 .get(&old_def_addr).expect("old def addr is valid")
995 .get(&addr).expect("between's prior addr is valid")
996 .get(&(v.borrow().location.rebase_references(old_dfg, new_dfg), crate::data::Direction::Write))
997 .expect("corresponding def exists in new dfg"))
998 }
999 other => {
1000 panic!("aaaa {}", other);
1001 }
1002 };
1003 Item::untyped(Expression::Value(ValueOrImmediate::Value(new_use)))
1004 } else {
1005 Item::untyped(Expression::Value(ValueOrImmediate::Value(Rc::clone(v))))
1006 }
1007 }
1008 }
1009 }
1010 Expression::Load { address, size } => {
1011 Item::load(&address.rebase_references(old_dfg, new_dfg), *size)
1012 },
1013 Expression::Add { left, right } => {
1014 Item::add(
1015 &left.rebase_references(old_dfg, new_dfg),
1016 &right.rebase_references(old_dfg, new_dfg),
1017 )
1018 },
1019 Expression::Sub { left, right } => {
1020 Item::sub(
1021 &left.rebase_references(old_dfg, new_dfg),
1022 &right.rebase_references(old_dfg, new_dfg),
1023 )
1024 },
1025 Expression::Mul { left, right } => {
1026 Item::mul(
1027 &left.rebase_references(old_dfg, new_dfg),
1028 &right.rebase_references(old_dfg, new_dfg),
1029 )
1030 },
1031 Expression::Or { left, right } => {
1032 Item::or(
1033 &left.rebase_references(old_dfg, new_dfg),
1034 &right.rebase_references(old_dfg, new_dfg),
1035 )
1036 },
1037 Expression::And { left, right } => {
1038 Item::and(
1039 &left.rebase_references(old_dfg, new_dfg),
1040 &right.rebase_references(old_dfg, new_dfg),
1041 )
1042 },
1043 Expression::Xor { left, right } => {
1044 Item::xor(
1045 &left.rebase_references(old_dfg, new_dfg),
1046 &right.rebase_references(old_dfg, new_dfg),
1047 )
1048 },
1049 Expression::Shl { value, amount } => {
1050 Item::shl(
1051 &value.rebase_references(old_dfg, new_dfg),
1052 &amount.rebase_references(old_dfg, new_dfg),
1053 )
1054 },
1055 Expression::Shr { value, amount } => {
1056 Item::shr(
1057 &value.rebase_references(old_dfg, new_dfg),
1058 &amount.rebase_references(old_dfg, new_dfg),
1059 )
1060 },
1061 }
1062 }
1063}
1064
1065impl<A: SSAValues> Value for Rc<Item<ValueOrImmediate<A>>> where A::Data: Hash + Eq + fmt::Display {
1066 fn unknown() -> Self {
1069 Item::untyped(Expression::Unknown)
1070 }
1071
1072 fn from_const(c: i64) -> Self {
1073 Item::untyped(Expression::Value(ValueOrImmediate::Immediate(c)))
1074 }
1075
1076 fn from_set(_xs: &[Self]) -> Self {
1077 Self::unknown()
1079 }
1080
1081 fn to_const(&self) -> Option<i64> {
1082 if let Expression::Value(ValueOrImmediate::Immediate(c)) = self.as_ref().value {
1083 Some(c)
1084 } else {
1085 None
1086 }
1087 }
1088
1089 fn as_bool(&self) -> Option<bool> {
1090 self.to_const().map(|x| x != 0)
1091 }
1092
1093 fn add(&self, other: &Self) -> ValueRes<Self> {
1094 ValueRes {
1095 value: Item::untyped(Expression::Add { left: Rc::clone(self), right: Rc::clone(other) }),
1096 carry: Self::unknown()
1097 }
1098 }
1099
1100 fn sub(&self, other: &Self) -> ValueRes<Self> {
1101 ValueRes {
1102 value: Item::untyped(Expression::Sub { left: Rc::clone(self), right: Rc::clone(other) }),
1103 carry: Self::unknown()
1104 }
1105 }
1106
1107 fn mul(&self, other: &Self) -> ValueRes<Self> {
1108 ValueRes {
1109 value: Item::untyped(Expression::Mul { left: Rc::clone(self), right: Rc::clone(other) }),
1110 carry: Self::unknown()
1111 }
1112 }
1113
1114 fn or(&self, other: &Self) -> ValueRes<Self> {
1115 ValueRes {
1116 value: Item::untyped(Expression::Or { left: Rc::clone(self), right: Rc::clone(other) }),
1117 carry: Self::unknown()
1118 }
1119 }
1120
1121 fn and(&self, other: &Self) -> ValueRes<Self> {
1122 ValueRes {
1123 value: Item::untyped(Expression::And { left: Rc::clone(self), right: Rc::clone(other) }),
1124 carry: Self::unknown()
1125 }
1126 }
1127
1128 fn xor(&self, other: &Self) -> ValueRes<Self> {
1129 ValueRes {
1130 value: Item::untyped(Expression::Xor { left: Rc::clone(self), right: Rc::clone(other) }),
1131 carry: Self::unknown()
1132 }
1133 }
1134
1135 fn sxt(&self, _width: &Self) -> Self {
1136 Self::unknown()
1137 }
1138
1139 fn zxt(&self, _width: &Self) -> Self {
1140 Self::unknown()
1141 }
1142
1143 fn shr(&self, amount: &Self) -> Self {
1144 Item::untyped(Expression::Shr { value: Rc::clone(self), amount: Rc::clone(amount) })
1145 }
1146
1147 fn shl(&self, amount: &Self) -> Self {
1148 Item::untyped(Expression::Shl { value: Rc::clone(self), amount: Rc::clone(amount) })
1149 }
1150}