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(crate) 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(crate) 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<'a>(
locations: &'a [(Range, Piece)],
) -> impl Iterator<Item = (Range, Register)> + 'a {
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<'a>(
locations: &'a [(Range, Piece)],
) -> impl Iterator<Item = FrameLocation> + 'a {
locations.iter().filter_map(|(_, piece)| {
if piece.is_value {
return None;
}
match piece.location {
Location::FrameOffset { offset } | Location::CfaOffset { offset } => {
Some(FrameLocation {
offset,
bit_size: piece.bit_size,
})
}
_ => None,
}
})
}
pub(crate) fn register_offsets<'a>(
locations: &'a [(Range, Piece)],
) -> impl Iterator<Item = (Range, Register, i64)> + 'a {
locations.iter().filter_map(|(range, piece)| {
if piece.is_value {
return None;
}
match piece.location {
Location::RegisterOffset { register, offset } => Some((*range, register, offset)),
_ => None,
}
})
}