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 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.index() == 0
762 }
763
764 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 }