|
12 | 12 | // See the License for the specific language governing permissions and |
13 | 13 | // limitations under the License. |
14 | 14 |
|
| 15 | +use binaryninjacore_sys::BNLowLevelILInstruction; |
15 | 16 | use std::borrow::Cow; |
16 | 17 | use std::fmt; |
17 | | - |
| 18 | +use std::fmt::{Display, Formatter}; |
18 | 19 | // TODO : provide some way to forbid emitting register reads for certain registers |
19 | 20 | // also writing for certain registers (e.g. zero register must prohibit il.set_reg and il.reg |
20 | 21 | // (replace with nop or const(0) respectively) |
@@ -157,6 +158,30 @@ impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> { |
157 | 158 | } |
158 | 159 | } |
159 | 160 |
|
| 161 | +impl From<CoreRegister> for LowLevelILRegisterKind<CoreRegister> { |
| 162 | + fn from(reg: CoreRegister) -> Self { |
| 163 | + LowLevelILRegisterKind::Arch(reg) |
| 164 | + } |
| 165 | +} |
| 166 | + |
| 167 | +impl PartialEq<CoreRegister> for LowLevelILRegisterKind<CoreRegister> { |
| 168 | + fn eq(&self, other: &CoreRegister) -> bool { |
| 169 | + match *self { |
| 170 | + LowLevelILRegisterKind::Arch(ref r) => r == other, |
| 171 | + LowLevelILRegisterKind::Temp(_) => false, |
| 172 | + } |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +impl PartialEq<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> { |
| 177 | + fn eq(&self, other: &LowLevelILTempRegister) -> bool { |
| 178 | + match *self { |
| 179 | + LowLevelILRegisterKind::Arch(_) => false, |
| 180 | + LowLevelILRegisterKind::Temp(ref r) => r == other, |
| 181 | + } |
| 182 | + } |
| 183 | +} |
| 184 | + |
160 | 185 | #[derive(Copy, Clone, Debug)] |
161 | 186 | pub enum LowLevelILSSARegisterKind<R: ArchReg> { |
162 | 187 | Full { |
@@ -209,3 +234,52 @@ pub enum VisitorAction { |
209 | 234 | Sibling, |
210 | 235 | Halt, |
211 | 236 | } |
| 237 | + |
| 238 | +#[repr(transparent)] |
| 239 | +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 240 | +pub struct LowLevelILOperandIndex(pub u32); |
| 241 | + |
| 242 | +impl LowLevelILOperandIndex { |
| 243 | + pub fn next(&self) -> Self { |
| 244 | + Self(self.0 + 1) |
| 245 | + } |
| 246 | +} |
| 247 | + |
| 248 | +impl TryFrom<u32> for LowLevelILOperandIndex { |
| 249 | + type Error = (); |
| 250 | + |
| 251 | + fn try_from(value: u32) -> Result<Self, Self::Error> { |
| 252 | + match value { |
| 253 | + 7 => Err(()), |
| 254 | + value => Ok(Self(value)), |
| 255 | + } |
| 256 | + } |
| 257 | +} |
| 258 | + |
| 259 | +impl Display for LowLevelILOperandIndex { |
| 260 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 261 | + f.write_fmt(format_args!("{}", self.0)) |
| 262 | + } |
| 263 | +} |
| 264 | + |
| 265 | +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 266 | +pub struct LowLevelILSourceLocation { |
| 267 | + pub address: u64, |
| 268 | + /// The referenced source operand. |
| 269 | + pub source_operand: Option<LowLevelILOperandIndex>, |
| 270 | +} |
| 271 | + |
| 272 | +impl LowLevelILSourceLocation { |
| 273 | + pub fn raw_source_operand(&self) -> u32 { |
| 274 | + self.source_operand.unwrap_or(LowLevelILOperandIndex(7)).0 |
| 275 | + } |
| 276 | +} |
| 277 | + |
| 278 | +impl From<&BNLowLevelILInstruction> for LowLevelILSourceLocation { |
| 279 | + fn from(value: &BNLowLevelILInstruction) -> Self { |
| 280 | + Self { |
| 281 | + address: value.address, |
| 282 | + source_operand: value.sourceOperand.try_into().ok(), |
| 283 | + } |
| 284 | + } |
| 285 | +} |
0 commit comments