fugue_ir/
address.rs

1use std::borrow::Borrow;
2use std::fmt;
3use std::ops::{Add, AddAssign, Sub, SubAssign};
4
5use fugue_bv::BitVec;
6
7use crate::disassembly::IRBuilderArena;
8use crate::space::{AddressSpace, AddressSpaceId};
9use crate::space_manager::{FromSpace, SpaceManager};
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[derive(serde::Deserialize, serde::Serialize)]
13pub struct AddressValue {
14    space: AddressSpaceId,
15    word_size: u32,
16    highest: u64,
17    offset: u64,
18}
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
21#[derive(serde::Deserialize, serde::Serialize)]
22#[repr(transparent)]
23pub struct Address(u64);
24
25impl Address {
26    pub fn new(space: &AddressSpace, offset: u64) -> Self {
27        Self(space.wrap_offset(offset))
28    }
29
30    pub fn from_value<V: Into<Address>>(value: V) -> Self {
31        value.into()
32    }
33
34    pub fn offset(&self) -> u64 {
35        self.0
36    }
37}
38
39impl PartialEq<u8> for Address {
40     fn eq(&self, other: &u8) -> bool {
41         self.0 == *other as u64
42     }
43}
44
45impl PartialEq<u16> for Address {
46     fn eq(&self, other: &u16) -> bool {
47         self.0 == *other as u64
48     }
49}
50
51impl PartialEq<u32> for Address {
52     fn eq(&self, other: &u32) -> bool {
53         self.0 == *other as u64
54     }
55}
56
57impl PartialEq<u64> for Address {
58    fn eq(&self, other: &u64) -> bool {
59        self.0 == *other
60    }
61}
62
63impl PartialEq<Address> for u8 {
64    fn eq(&self, other: &Address) -> bool {
65        *self as u64 == other.0
66    }
67}
68
69impl PartialEq<Address> for u16 {
70    fn eq(&self, other: &Address) -> bool {
71        *self as u64 == other.0
72    }
73}
74
75impl PartialEq<Address> for u32 {
76    fn eq(&self, other: &Address) -> bool {
77        *self as u64 == other.0
78    }
79}
80
81impl PartialEq<Address> for u64 {
82    fn eq(&self, other: &Address) -> bool {
83        *self == other.0
84    }
85}
86
87impl From<u64> for Address {
88    fn from(v: u64) -> Self {
89        Self(v)
90    }
91}
92
93impl From<u32> for Address {
94    fn from(v: u32) -> Self {
95        Self(v as u64)
96    }
97}
98
99impl From<u16> for Address {
100    fn from(v: u16) -> Self {
101        Self(v as u64)
102    }
103}
104
105impl From<u8> for Address {
106    fn from(v: u8) -> Self {
107        Self(v as u64)
108    }
109}
110
111impl From<AddressValue> for Address {
112    fn from(v: AddressValue) -> Self {
113        Self(v.offset())
114    }
115}
116
117impl From<&'_ AddressValue> for Address {
118    fn from(v: &AddressValue) -> Self {
119        Self(v.offset())
120    }
121}
122
123impl<'z> FromSpace<'z, Address> for AddressValue {
124    fn from_space(t: Address, manager: &SpaceManager) -> Self {
125        AddressValue::new(manager.default_space_ref(), t.offset())
126    }
127
128    fn from_space_with(t: Address, _arena: &'z IRBuilderArena, manager: &SpaceManager) -> Self {
129        AddressValue::new(manager.default_space_ref(), t.offset())
130    }
131}
132
133pub trait IntoAddress {
134    fn into_address(self, space: &AddressSpace) -> Address;
135    fn into_address_value(self, space: &AddressSpace) -> AddressValue;
136}
137
138impl IntoAddress for Address {
139    fn into_address(self, space: &AddressSpace) -> Address {
140        Address::new(space, self.0)
141    }
142
143    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
144        AddressValue::new(space, self.0)
145    }
146}
147
148impl IntoAddress for &'_ Address {
149    fn into_address(self, space: &AddressSpace) -> Address {
150        Address::new(space, self.0)
151    }
152
153    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
154        AddressValue::new(space, self.0)
155    }
156}
157
158impl IntoAddress for AddressValue {
159    fn into_address(self, space: &AddressSpace) -> Address {
160        Address::new(space, self.offset)
161    }
162
163    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
164        AddressValue::new(space, self.offset)
165    }
166}
167
168impl IntoAddress for &'_ AddressValue {
169    fn into_address(self, space: &AddressSpace) -> Address {
170        Address::new(space, self.offset)
171    }
172
173    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
174        AddressValue::new(space, self.offset)
175    }
176}
177
178impl IntoAddress for usize {
179    fn into_address(self, space: &AddressSpace) -> Address {
180        Address::new(space, self as u64)
181    }
182
183    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
184        AddressValue::new(space, self as u64)
185    }
186}
187
188impl IntoAddress for &'_ usize {
189    fn into_address(self, space: &AddressSpace) -> Address {
190        Address::new(space, *self as u64)
191    }
192
193    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
194        AddressValue::new(space, *self as u64)
195    }
196}
197
198impl IntoAddress for u8 {
199    fn into_address(self, space: &AddressSpace) -> Address {
200        Address::new(space, self as u64)
201    }
202
203    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
204        AddressValue::new(space, self as u64)
205    }
206}
207
208impl IntoAddress for &'_ u8 {
209    fn into_address(self, space: &AddressSpace) -> Address {
210        Address::new(space, *self as u64)
211    }
212
213    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
214        AddressValue::new(space, *self as u64)
215    }
216}
217
218impl IntoAddress for u16 {
219    fn into_address(self, space: &AddressSpace) -> Address {
220        Address::new(space, self as u64)
221    }
222
223    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
224        AddressValue::new(space, self as u64)
225    }
226}
227
228impl IntoAddress for &'_ u16 {
229    fn into_address(self, space: &AddressSpace) -> Address {
230        Address::new(space, *self as u64)
231    }
232
233    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
234        AddressValue::new(space, *self as u64)
235    }
236}
237
238impl IntoAddress for u32 {
239    fn into_address(self, space: &AddressSpace) -> Address {
240        Address::new(space, self as u64)
241    }
242
243    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
244        AddressValue::new(space, self as u64)
245    }
246}
247
248impl IntoAddress for &'_ u32 {
249    fn into_address(self, space: &AddressSpace) -> Address {
250        Address::new(space, *self as u64)
251    }
252
253    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
254        AddressValue::new(space, *self as u64)
255    }
256}
257
258impl IntoAddress for u64 {
259    fn into_address(self, space: &AddressSpace) -> Address {
260        Address::new(space, self)
261    }
262
263    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
264        AddressValue::new(space, self)
265    }
266}
267
268impl IntoAddress for &'_ u64 {
269    fn into_address(self, space: &AddressSpace) -> Address {
270        Address::new(space, *self)
271    }
272
273    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
274        AddressValue::new(space, *self)
275    }
276}
277
278impl IntoAddress for BitVec {
279    fn into_address(self, space: &AddressSpace) -> Address {
280        Address::new(space, self.to_u64().expect("64-bit address limit"))
281    }
282
283    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
284        AddressValue::new(space, self.to_u64().expect("64-bit address limit"))
285    }
286}
287
288impl IntoAddress for &'_ BitVec {
289    fn into_address(self, space: &AddressSpace) -> Address {
290        Address::new(space, self.to_u64().expect("64-bit address limit"))
291    }
292
293    fn into_address_value(self, space: &AddressSpace) -> AddressValue {
294        AddressValue::new(space, self.to_u64().expect("64-bit address limit"))
295    }
296}
297
298impl From<Address> for usize {
299    fn from(t: Address) -> Self {
300        t.0 as _
301    }
302}
303
304impl From<&'_ Address> for usize {
305    fn from(t: &'_ Address) -> Self {
306        t.0 as _
307    }
308}
309
310impl From<Address> for u64 {
311    fn from(t: Address) -> Self {
312        t.0 as _
313    }
314}
315
316impl From<&'_ Address> for u64 {
317    fn from(t: &'_ Address) -> Self {
318        t.0 as _
319    }
320}
321
322impl From<Address> for u32 {
323    fn from(t: Address) -> Self {
324        t.0 as _
325    }
326}
327
328impl From<&'_ Address> for u32 {
329    fn from(t: &'_ Address) -> Self {
330        t.0 as _
331    }
332}
333
334impl From<Address> for u16 {
335    fn from(t: Address) -> Self {
336        t.0 as _
337    }
338}
339
340impl From<&'_ Address> for u16 {
341    fn from(t: &'_ Address) -> Self {
342        t.0 as _
343    }
344}
345
346impl From<Address> for u8 {
347    fn from(t: Address) -> Self {
348        t.0 as _
349    }
350}
351
352impl From<&'_ Address> for u8 {
353    fn from(t: &'_ Address) -> Self {
354        t.0 as _
355    }
356}
357
358impl From<AddressValue> for usize {
359    fn from(t: AddressValue) -> Self {
360        t.offset as _
361    }
362}
363
364impl From<&'_ AddressValue> for usize {
365    fn from(t: &'_ AddressValue) -> Self {
366        t.offset as _
367    }
368}
369
370impl From<AddressValue> for u64 {
371    fn from(t: AddressValue) -> Self {
372        t.offset as _
373    }
374}
375
376impl From<&'_ AddressValue> for u64 {
377    fn from(t: &'_ AddressValue) -> Self {
378        t.offset as _
379    }
380}
381
382impl From<AddressValue> for u32 {
383    fn from(t: AddressValue) -> Self {
384        t.offset as _
385    }
386}
387
388impl From<&'_ AddressValue> for u32 {
389    fn from(t: &'_ AddressValue) -> Self {
390        t.offset as _
391    }
392}
393
394impl From<AddressValue> for u16 {
395    fn from(t: AddressValue) -> Self {
396        t.offset as _
397    }
398}
399
400impl From<&'_ AddressValue> for u16 {
401    fn from(t: &'_ AddressValue) -> Self {
402        t.offset as _
403    }
404}
405
406impl From<AddressValue> for u8 {
407    fn from(t: AddressValue) -> Self {
408        t.offset as _
409    }
410}
411
412impl From<&'_ AddressValue> for u8 {
413    fn from(t: &'_ AddressValue) -> Self {
414        t.offset as _
415    }
416}
417
418impl fmt::Display for Address {
419    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
420        write!(f, "{:#x}", self.0)
421    }
422}
423
424impl Add<Address> for Address {
425    type Output = Self;
426
427    fn add(self, rhs: Address) -> Self {
428        Self(self.0.wrapping_add(rhs.0))
429    }
430}
431
432impl Sub<Address> for Address {
433    type Output = Self;
434
435    fn sub(self, rhs: Address) -> Self {
436        Self(self.0.wrapping_sub(rhs.0))
437    }
438}
439
440impl Add<&'_ Address> for Address {
441    type Output = Self;
442
443    fn add(self, rhs: &Address) -> Self {
444        Self(self.0.wrapping_add(rhs.0))
445    }
446}
447
448impl Sub<&'_ Address> for Address {
449    type Output = Self;
450
451    fn sub(self, rhs: &Address) -> Self {
452        Self(self.0.wrapping_sub(rhs.0))
453    }
454}
455
456impl Add<usize> for Address {
457    type Output = Self;
458
459    fn add(self, rhs: usize) -> Self {
460        Self(self.0.wrapping_add(rhs as u64))
461    }
462}
463
464impl Sub<usize> for Address {
465    type Output = Self;
466
467    fn sub(self, rhs: usize) -> Self {
468        Self(self.0.wrapping_sub(rhs as u64))
469    }
470}
471
472impl Add<u64> for Address {
473    type Output = Self;
474
475    fn add(self, rhs: u64) -> Self {
476        Self(self.0.wrapping_add(rhs))
477    }
478}
479
480impl Sub<u64> for Address {
481    type Output = Self;
482
483    fn sub(self, rhs: u64) -> Self {
484        Self(self.0.wrapping_sub(rhs))
485    }
486}
487
488impl Add<u32> for Address {
489    type Output = Self;
490
491    fn add(self, rhs: u32) -> Self {
492        Self(self.0.wrapping_add(rhs as u64))
493    }
494}
495
496impl Sub<u32> for Address {
497    type Output = Self;
498
499    fn sub(self, rhs: u32) -> Self {
500        Self(self.0.wrapping_sub(rhs as u64))
501    }
502}
503
504impl AddAssign<Address> for Address {
505    fn add_assign(&mut self, rhs: Address) {
506        self.0 = self.0.wrapping_add(rhs.0)
507    }
508}
509
510impl SubAssign<Address> for Address {
511    fn sub_assign(&mut self, rhs: Address) {
512        self.0 = self.0.wrapping_sub(rhs.0)
513    }
514}
515
516impl AddAssign<&'_ Address> for Address {
517    fn add_assign(&mut self, rhs: &'_ Address) {
518        self.0 = self.0.wrapping_add(rhs.0)
519    }
520}
521
522impl SubAssign<&'_ Address> for Address {
523    fn sub_assign(&mut self, rhs: &'_ Address) {
524        self.0 = self.0.wrapping_sub(rhs.0)
525    }
526}
527
528impl AddAssign<usize> for Address {
529    fn add_assign(&mut self, rhs: usize) {
530        self.0 = self.0.wrapping_add(rhs as u64)
531    }
532}
533
534impl SubAssign<usize> for Address {
535    fn sub_assign(&mut self, rhs: usize) {
536        self.0 = self.0.wrapping_sub(rhs as u64)
537    }
538}
539
540impl AddAssign<u64> for Address {
541    fn add_assign(&mut self, rhs: u64) {
542        self.0 = self.0.wrapping_add(rhs)
543    }
544}
545
546impl SubAssign<u64> for Address {
547    fn sub_assign(&mut self, rhs: u64) {
548        self.0 = self.0.wrapping_sub(rhs)
549    }
550}
551
552impl AddAssign<u32> for Address {
553    fn add_assign(&mut self, rhs: u32) {
554        self.0 = self.0.wrapping_add(rhs as u64)
555    }
556}
557
558impl SubAssign<u32> for Address {
559    fn sub_assign(&mut self, rhs: u32) {
560        self.0 = self.0.wrapping_sub(rhs as u64)
561    }
562}
563
564impl fmt::Display for AddressValue {
565    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
566        write!(f, "{:#x}", self.offset * self.word_size as u64)
567    }
568}
569
570impl Add<AddressValue> for AddressValue {
571    type Output = Self;
572
573    fn add(self, rhs: AddressValue) -> Self {
574        debug_assert_eq!(self.space, rhs.space);
575        Self {
576            offset: self.wrap_offset(self.offset.wrapping_add(rhs.offset)),
577            ..self
578        }
579    }
580}
581
582impl Sub<AddressValue> for AddressValue {
583    type Output = Self;
584
585    fn sub(self, rhs: AddressValue) -> Self {
586        debug_assert_eq!(self.space, rhs.space);
587        Self {
588            offset: self.wrap_offset(self.offset.wrapping_sub(rhs.offset)),
589            ..self
590        }
591    }
592}
593
594impl Add<&'_ AddressValue> for AddressValue {
595    type Output = Self;
596
597    fn add(self, rhs: &AddressValue) -> Self {
598        debug_assert_eq!(self.space, rhs.space);
599        Self {
600            offset: self.wrap_offset(self.offset.wrapping_add(rhs.offset)),
601            ..self
602        }
603    }
604}
605
606impl Sub<&'_ AddressValue> for AddressValue {
607    type Output = Self;
608
609    fn sub(self, rhs: &AddressValue) -> Self {
610        debug_assert_eq!(self.space, rhs.space);
611        Self {
612            offset: self.wrap_offset(self.offset.wrapping_sub(rhs.offset)),
613            ..self
614        }
615    }
616}
617
618impl Add<Address> for AddressValue {
619    type Output = Self;
620
621    fn add(self, rhs: Address) -> Self {
622        Self {
623            offset: self.wrap_offset(self.offset.wrapping_add(rhs.0)),
624            ..self
625        }
626    }
627}
628
629impl Sub<Address> for AddressValue {
630    type Output = Self;
631
632    fn sub(self, rhs: Address) -> Self {
633        Self {
634            offset: self.wrap_offset(self.offset.wrapping_sub(rhs.0)),
635            ..self
636        }
637    }
638}
639
640impl Add<&'_ Address> for AddressValue {
641    type Output = Self;
642
643    fn add(self, rhs: &Address) -> Self {
644        Self {
645            offset: self.wrap_offset(self.offset.wrapping_add(rhs.0)),
646            ..self
647        }
648    }
649}
650
651impl Sub<&'_ Address> for AddressValue {
652    type Output = Self;
653
654    fn sub(self, rhs: &Address) -> Self {
655        Self {
656            offset: self.wrap_offset(self.offset.wrapping_sub(rhs.0)),
657            ..self
658        }
659    }
660}
661
662impl Add<usize> for AddressValue {
663    type Output = Self;
664
665    fn add(self, rhs: usize) -> Self {
666        Self {
667            offset: self.wrap_offset(self.offset.wrapping_add(rhs as u64)),
668            ..self
669        }
670    }
671}
672
673impl Sub<usize> for AddressValue {
674    type Output = Self;
675
676    fn sub(self, rhs: usize) -> Self {
677        Self {
678            offset: self.wrap_offset(self.offset.wrapping_sub(rhs as u64)),
679            ..self
680        }
681    }
682}
683
684impl Add<u64> for AddressValue {
685    type Output = Self;
686
687    fn add(self, rhs: u64) -> Self {
688        Self {
689            offset: self.wrap_offset(self.offset.wrapping_add(rhs)),
690            ..self
691        }
692    }
693}
694
695impl Sub<u64> for AddressValue {
696    type Output = Self;
697
698    fn sub(self, rhs: u64) -> Self {
699        Self {
700            offset: self.wrap_offset(self.offset.wrapping_sub(rhs)),
701            ..self
702        }
703    }
704}
705
706impl AddressValue {
707    pub fn new<S: Borrow<AddressSpace>>(space: S, offset: u64) -> Self {
708        let space = space.borrow();
709        let offset = space.wrap_offset(offset);
710        Self {
711            space: space.id(),
712            highest: space.highest_offset(),
713            word_size: space.word_size() as u32,
714            offset,
715        }
716    }
717
718    pub fn space(&self) -> AddressSpaceId {
719        self.space
720    }
721
722    pub fn offset(&self) -> u64 {
723        self.offset
724    }
725
726    pub fn difference(&self, other: &AddressValue) -> AddressValue {
727        // reinterpret other as if it were in `self's` space
728        Self {
729            offset: self.offset.wrapping_sub(self.wrap_offset(other.offset())),
730            space: self.space,
731            word_size: self.word_size,
732            highest: self.highest,
733        }
734    }
735
736    pub fn wrap<V: Into<u64>>(&self, offset: V) -> AddressValue {
737        Self {
738            offset: self.wrap_offset(offset.into()),
739            space: self.space,
740            word_size: self.word_size,
741            highest: self.highest,
742        }
743    }
744
745    pub fn wrap_offset(&self, offset: u64) -> u64 {
746        if offset <= self.highest {
747            offset
748        } else {
749            let m = (self.highest + 1) as i64;
750            let r = (offset as i64) % m;
751            (if r < 0 { r + m } else { r }) as u64
752        }
753    }
754
755    pub fn highest_offset(&self) -> u64 {
756        self.highest
757    }
758
759    pub fn is_constant(&self) -> bool {
760        //self.space.kind() == SpaceKind::Constant
761        self.space.index() == 0
762    }
763
764    /*
765    pub fn is_contiguous(&self, size: usize, other: &Self, other_size: usize) -> bool {
766        if self.space != other.space {
767            false
768        } else if self.is_big_endian() {
769            self.space
770                .wrap_offset(self.offset.wrapping_add(size as u64))
771                == other.offset
772        } else {
773            self.space
774                .wrap_offset(other.offset.wrapping_add(other_size as u64))
775                == self.offset
776        }
777    }
778    */
779
780    pub fn contained_by(&self, size: usize, other: &Self, other_size: usize) -> bool {
781        self.space == other.space
782            && other.offset <= self.offset
783            && other.offset.wrapping_add((other_size - 1) as u64)
784                >= self.offset.wrapping_add((size - 1) as u64)
785    }
786
787    /*
788    pub fn justified_contain(
789        &self,
790        size: usize,
791        other: &Self,
792        other_size: usize,
793        force_left: bool,
794    ) -> Option<u64> {
795        if self.space != other.space || other.offset < self.offset {
796            None
797        } else {
798            let off1 = self.offset.wrapping_add((size - 1) as u64);
799            let off2 = other.offset.wrapping_add((other_size - 1) as u64);
800            if off2 > off1 {
801                None
802            } else if self.is_big_endian() && !force_left {
803                Some(off1 - off2)
804            } else {
805                Some(other.offset - self.offset)
806            }
807        }
808    }
809
810    pub fn overlap(&self, skip: usize, other: &Self, other_size: usize) -> Option<u64> {
811        if self.space != other.space || self.is_constant() {
812            None
813        } else {
814            let dist = self.space.wrap_offset(
815                self.offset
816                    .wrapping_add(skip as u64)
817                    .wrapping_sub(other.offset),
818            );
819            if dist >= other_size as u64 {
820                None
821            } else {
822                Some(dist)
823            }
824        }
825    }
826    */
827}