diff options
| author | iximeow <me@iximeow.net> | 2021-06-14 17:51:58 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2021-06-14 17:51:58 -0700 | 
| commit | 7c53435a1c346fb224e9f5ef08304016e240be62 (patch) | |
| tree | e3084c970b01e2d62a0e46e7716e0d14d84aa31d /src | |
| parent | 354940536d4f700e7f441090435362e8f6ca219d (diff) | |
address diff is an u64 thingy that can be added to addressesnonbyte-words
Diffstat (limited to 'src')
| -rw-r--r-- | src/address/mod.rs | 91 | 
1 files changed, 73 insertions, 18 deletions
| diff --git a/src/address/mod.rs b/src/address/mod.rs index d3f5113..e44ca13 100644 --- a/src/address/mod.rs +++ b/src/address/mod.rs @@ -5,7 +5,7 @@ use core::fmt;  use core::ops::{Add, Sub, AddAssign, SubAssign};  use num_traits::identities; -use num_traits::{Bounded, WrappingAdd, WrappingSub, CheckedAdd, CheckedSub}; +use num_traits::{Bounded, WrappingAdd, WrappingSub, CheckedAdd, Zero, One};  #[cfg(feature="use-serde")]  use serde::{Deserialize, Serialize}; @@ -37,11 +37,11 @@ impl AddressDiffAmount for usize {}  /// which is to say, `yaxpeax` assumes associativity holds when `diff` yields a `Some`.  #[cfg(feature="use-serde")]  #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)] -pub struct AddressDiff<T: AddressDiffAmount> { +pub struct AddressDiff<T: AddressBase> {      // the AddressDiffAmount trait fools `Deserialize`'s proc macro, so we have to explicitly write      // the bound serde should use. -    #[serde(bound(deserialize = "T: AddressDiffAmount"))] -    amount: T, +    #[serde(bound(deserialize = "T::Diff: AddressDiffAmount"))] +    amount: T::Diff,  }  /// a struct describing the differece between some pair of `A: Address`. this is primarily useful  /// in describing the size of an instruction, or the relative offset of a branch. @@ -60,32 +60,32 @@ pub struct AddressDiff<T: AddressDiffAmount> {  /// which is to say, `yaxpeax` assumes associativity holds when `diff` yields a `Some`.  #[cfg(not(feature="use-serde"))]  #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] -pub struct AddressDiff<T: AddressDiffAmount> { -    amount: T, +pub struct AddressDiff<T: AddressBase> { +    amount: T::Diff,  } -impl<T: AddressDiffAmount> AddressDiff<T> { -    pub fn from_const(amount: T) -> Self { +impl<T: Address> AddressDiff<T> { +    pub fn from_const(amount: T::Diff) -> Self {          AddressDiff { amount }      }  } -impl<T: AddressDiffAmount + fmt::Debug> fmt::Debug for AddressDiff<T> { +impl<T: Address> fmt::Debug for AddressDiff<T> where T::Diff: fmt::Debug {      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {          write!(f, "AddressDiff({:?})", self.amount)      }  } -impl<T: AddressDiffAmount> AddressDiff<T> { +impl<T: Address> AddressDiff<T> {      pub fn one() -> Self {          AddressDiff { -            amount: T::one(), +            amount: <T as AddressBase>::Diff::one(),          }      }      pub fn zero() -> Self {          AddressDiff { -            amount: T::zero(), +            amount: <T as AddressBase>::Diff::zero(),          }      }  } @@ -208,11 +208,9 @@ pub trait AddressBase where Self:      Ord + Eq + PartialEq + Bounded +      Add<AddressDiff<Self>, Output=Self> + Sub<AddressDiff<Self>, Output=Self> +      AddAssign<AddressDiff<Self>> + SubAssign<AddressDiff<Self>> + -    WrappingAdd + WrappingSub + -    CheckedAdd + CheckedSub +      identities::Zero + -    AddressDiffAmount +      Hash { +    type Diff: AddressDiffAmount;      fn to_linear(&self) -> usize;      /// compute the `AddressDiff` beetween `self` and `other`. @@ -220,17 +218,26 @@ pub trait AddressBase where Self:      /// may return `None` if the two addresses aren't comparable. for example, if a pair of      /// addresses are a data-space address and code-space address, there may be no scalar that can      /// describe the difference between them. -    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>> { +    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>>; +    /* +    {          Some(AddressDiff { amount: self.wrapping_sub(other) })      } +    */ -    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self { +    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self; +    /* +    {          self.wrapping_add(&other.amount)      } +    */ -    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self> { +    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self>; +    /* +    {          self.checked_add(&other.amount)      } +    */  }  #[cfg(all(feature="use-serde", feature="address-parse"))] @@ -255,25 +262,73 @@ pub trait Address where Self:  pub trait Address where Self: AddressBase { }  impl AddressBase for u16 { +    type Diff = Self;      fn to_linear(&self) -> usize { *self as usize } + +    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>> { +        Some(AddressDiff { amount: self.wrapping_sub(other) }) +    } +    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self { +        self.wrapping_add(&other.amount) +    } + +    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self> { +        self.checked_add(&other.amount) +    }  }  impl Address for u16 {}  impl AddressBase for u32 { +    type Diff = Self;      fn to_linear(&self) -> usize { *self as usize } + +    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>> { +        Some(AddressDiff { amount: self.wrapping_sub(other) }) +    } +    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self { +        self.wrapping_add(&other.amount) +    } + +    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self> { +        self.checked_add(&other.amount) +    }  }  impl Address for u32 {}  impl AddressBase for u64 { +    type Diff = Self;      fn to_linear(&self) -> usize { *self as usize } + +    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>> { +        Some(AddressDiff { amount: self.wrapping_sub(other) }) +    } +    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self { +        self.wrapping_add(&other.amount) +    } + +    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self> { +        self.checked_add(&other.amount) +    }  }  impl Address for u64 {}  impl AddressBase for usize { +    type Diff = Self;      fn to_linear(&self) -> usize { *self } + +    fn diff(&self, other: &Self) -> Option<AddressDiff<Self>> { +        Some(AddressDiff { amount: self.wrapping_sub(other) }) +    } +    fn wrapping_offset(&self, other: AddressDiff<Self>) -> Self { +        self.wrapping_add(&other.amount) +    } + +    fn checked_offset(&self, other: AddressDiff<Self>) -> Option<Self> { +        self.checked_add(&other.amount) +    }  }  impl Address for usize {} | 
