use crate::file::FileHash;
use crate::{Address, Range, Size};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Register(pub u16);
impl Register {
pub fn name(self, hash: &FileHash) -> Option<&'static str> {
hash.file.get_register_name(self)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct FrameLocation {
pub offset: i64,
pub bit_size: Size,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Piece {
pub bit_offset: u64,
pub bit_size: Size,
pub location: Location,
pub location_offset: u64,
pub is_value: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Location {
Empty,
Literal {
value: u64,
},
Register {
register: Register,
},
RegisterOffset {
register: Register,
offset: i64,
},
FrameOffset {
offset: i64,
},
CfaOffset {
offset: i64,
},
Address {
address: Address,
},
TlsOffset {
offset: u64,
},
Other,
}
pub(crate) fn registers(
locations: &[(Range, Piece)],
) -> impl Iterator<Item = (Range, Register)> + '_ {
locations.iter().filter_map(|(range, piece)| {
if piece.is_value {
return None;
}
match piece.location {
Location::Register { register } => Some((*range, register)),
_ => None,
}
})
}
pub(crate) fn frame_locations(
locations: &[(Range, Piece)],
) -> impl Iterator<Item = (Range, FrameLocation)> + '_ {
locations.iter().filter_map(|(range, piece)| {
if piece.is_value {
return None;
}
match piece.location {
Location::FrameOffset { offset } | Location::CfaOffset { offset } => Some((
*range,
FrameLocation {
offset,
bit_size: piece.bit_size,
},
)),
_ => None,
}
})
}
pub(crate) fn register_offsets(
locations: &[(Range, Piece)],
) -> impl Iterator<Item = (Range, Register, i64)> + '_ {
locations.iter().filter_map(|(range, piece)| {
if piece.is_value {
return None;
}
match piece.location {
Location::RegisterOffset { register, offset } => Some((*range, register, offset)),
_ => None,
}
})
}