|
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | 15 | use binaryninjacore_sys::{ |
16 | | - BNGetLowLevelILByIndex, BNLowLevelILFreeOperandList, BNLowLevelILGetOperandList, |
17 | | - BNLowLevelILInstruction, |
| 16 | + BNGetCachedLowLevelILPossibleValueSet, BNGetLowLevelILByIndex, BNLowLevelILFreeOperandList, |
| 17 | + BNLowLevelILGetOperandList, BNLowLevelILInstruction, |
18 | 18 | }; |
19 | 19 |
|
20 | 20 | use super::*; |
21 | 21 | use crate::architecture::{ |
22 | 22 | CoreFlag, CoreFlagGroup, CoreFlagWrite, CoreIntrinsic, CoreRegister, CoreRegisterStack, |
23 | 23 | FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId, |
24 | 24 | }; |
| 25 | +use crate::variable::PossibleValueSet; |
25 | 26 | use std::collections::BTreeMap; |
26 | 27 | use std::fmt::{Debug, Formatter}; |
27 | 28 | use std::marker::PhantomData; |
|
62 | 63 | self.op.address |
63 | 64 | } |
64 | 65 |
|
65 | | - pub fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> { |
| 66 | + fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> { |
66 | 67 | let mut count = 0; |
67 | 68 | let raw_list_ptr = unsafe { |
68 | 69 | BNLowLevelILGetOperandList( |
|
77 | 78 | unsafe { BNLowLevelILFreeOperandList(raw_list_ptr) }; |
78 | 79 | list |
79 | 80 | } |
| 81 | + |
| 82 | + fn get_constraint(&self, operand_idx: usize) -> PossibleValueSet { |
| 83 | + let raw_pvs = unsafe { |
| 84 | + BNGetCachedLowLevelILPossibleValueSet( |
| 85 | + self.function.handle, |
| 86 | + self.op.operands[operand_idx] as usize, |
| 87 | + ) |
| 88 | + }; |
| 89 | + PossibleValueSet::from_owned_raw(raw_pvs) |
| 90 | + } |
80 | 91 | } |
81 | 92 |
|
82 | 93 | impl<M, O> Operation<'_, M, NonSSA<LiftedNonSSA>, O> |
@@ -1870,6 +1881,155 @@ where |
1870 | 1881 | } |
1871 | 1882 | } |
1872 | 1883 |
|
| 1884 | +// LLIL_ASSERT |
| 1885 | +pub struct Assert; |
| 1886 | + |
| 1887 | +impl<M, F> Operation<'_, M, F, Assert> |
| 1888 | +where |
| 1889 | + M: FunctionMutability, |
| 1890 | + F: FunctionForm, |
| 1891 | +{ |
| 1892 | + pub fn size(&self) -> usize { |
| 1893 | + self.op.size |
| 1894 | + } |
| 1895 | + |
| 1896 | + pub fn source_reg(&self) -> LowLevelILRegisterKind<CoreRegister> { |
| 1897 | + let raw_id = RegisterId(self.op.operands[0] as u32); |
| 1898 | + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") |
| 1899 | + } |
| 1900 | + |
| 1901 | + pub fn constraint(&self) -> PossibleValueSet { |
| 1902 | + self.get_constraint(1) |
| 1903 | + } |
| 1904 | +} |
| 1905 | + |
| 1906 | +impl<M, F> Debug for Operation<'_, M, F, Assert> |
| 1907 | +where |
| 1908 | + M: FunctionMutability, |
| 1909 | + F: FunctionForm, |
| 1910 | +{ |
| 1911 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 1912 | + f.debug_struct("Assert") |
| 1913 | + .field("size", &self.size()) |
| 1914 | + .field("source_reg", &self.source_reg()) |
| 1915 | + .field("constraint", &self.constraint()) |
| 1916 | + .finish() |
| 1917 | + } |
| 1918 | +} |
| 1919 | + |
| 1920 | +// LLIL_ASSERT_SSA |
| 1921 | +pub struct AssertSsa; |
| 1922 | + |
| 1923 | +impl<M, F> Operation<'_, M, F, AssertSsa> |
| 1924 | +where |
| 1925 | + M: FunctionMutability, |
| 1926 | + F: FunctionForm, |
| 1927 | +{ |
| 1928 | + pub fn size(&self) -> usize { |
| 1929 | + self.op.size |
| 1930 | + } |
| 1931 | + |
| 1932 | + pub fn source_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> { |
| 1933 | + let raw_id = RegisterId(self.op.operands[0] as u32); |
| 1934 | + let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id) |
| 1935 | + .expect("Bad register ID"); |
| 1936 | + let version = self.op.operands[1] as u32; |
| 1937 | + LowLevelILSSARegisterKind::new_full(reg_kind, version) |
| 1938 | + } |
| 1939 | + |
| 1940 | + pub fn constraint(&self) -> PossibleValueSet { |
| 1941 | + self.get_constraint(2) |
| 1942 | + } |
| 1943 | +} |
| 1944 | + |
| 1945 | +impl<M, F> Debug for Operation<'_, M, F, AssertSsa> |
| 1946 | +where |
| 1947 | + M: FunctionMutability, |
| 1948 | + F: FunctionForm, |
| 1949 | +{ |
| 1950 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 1951 | + f.debug_struct("AssertSsa") |
| 1952 | + .field("size", &self.size()) |
| 1953 | + .field("source_reg", &self.source_reg()) |
| 1954 | + .field("constraint", &self.constraint()) |
| 1955 | + .finish() |
| 1956 | + } |
| 1957 | +} |
| 1958 | + |
| 1959 | +// LLIL_FORCE_VER |
| 1960 | +pub struct ForceVersion; |
| 1961 | + |
| 1962 | +impl<M, F> Operation<'_, M, F, ForceVersion> |
| 1963 | +where |
| 1964 | + M: FunctionMutability, |
| 1965 | + F: FunctionForm, |
| 1966 | +{ |
| 1967 | + pub fn size(&self) -> usize { |
| 1968 | + self.op.size |
| 1969 | + } |
| 1970 | + |
| 1971 | + pub fn dest_reg(&self) -> LowLevelILRegisterKind<CoreRegister> { |
| 1972 | + let raw_id = RegisterId(self.op.operands[0] as u32); |
| 1973 | + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") |
| 1974 | + } |
| 1975 | +} |
| 1976 | + |
| 1977 | +impl<M, F> Debug for Operation<'_, M, F, ForceVersion> |
| 1978 | +where |
| 1979 | + M: FunctionMutability, |
| 1980 | + F: FunctionForm, |
| 1981 | +{ |
| 1982 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 1983 | + f.debug_struct("ForceVersion") |
| 1984 | + .field("size", &self.size()) |
| 1985 | + .field("dest_reg", &self.dest_reg()) |
| 1986 | + .finish() |
| 1987 | + } |
| 1988 | +} |
| 1989 | + |
| 1990 | +// LLIL_FORCE_VER_SSA |
| 1991 | +pub struct ForceVersionSsa; |
| 1992 | + |
| 1993 | +impl<M, F> Operation<'_, M, F, ForceVersionSsa> |
| 1994 | +where |
| 1995 | + M: FunctionMutability, |
| 1996 | + F: FunctionForm, |
| 1997 | +{ |
| 1998 | + pub fn size(&self) -> usize { |
| 1999 | + self.op.size |
| 2000 | + } |
| 2001 | + |
| 2002 | + pub fn dest_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> { |
| 2003 | + let raw_id = RegisterId(self.op.operands[0] as u32); |
| 2004 | + let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id) |
| 2005 | + .expect("Bad register ID"); |
| 2006 | + let version = self.op.operands[1] as u32; |
| 2007 | + LowLevelILSSARegisterKind::new_full(reg_kind, version) |
| 2008 | + } |
| 2009 | + |
| 2010 | + pub fn source_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> { |
| 2011 | + let raw_id = RegisterId(self.op.operands[2] as u32); |
| 2012 | + let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id) |
| 2013 | + .expect("Bad register ID"); |
| 2014 | + let version = self.op.operands[3] as u32; |
| 2015 | + LowLevelILSSARegisterKind::new_full(reg_kind, version) |
| 2016 | + } |
| 2017 | +} |
| 2018 | + |
| 2019 | +impl<M, F> Debug for Operation<'_, M, F, ForceVersionSsa> |
| 2020 | +where |
| 2021 | + M: FunctionMutability, |
| 2022 | + F: FunctionForm, |
| 2023 | +{ |
| 2024 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 2025 | + f.debug_struct("ForceVersionSsa") |
| 2026 | + .field("size", &self.size()) |
| 2027 | + .field("dest_reg", &self.dest_reg()) |
| 2028 | + .field("source_reg", &self.source_reg()) |
| 2029 | + .finish() |
| 2030 | + } |
| 2031 | +} |
| 2032 | + |
1873 | 2033 | // TODO TEST_BIT |
1874 | 2034 |
|
1875 | 2035 | pub trait OperationArguments: 'static {} |
@@ -1923,3 +2083,7 @@ impl OperationArguments for DoublePrecDivOp {} |
1923 | 2083 | impl OperationArguments for UnaryOp {} |
1924 | 2084 | impl OperationArguments for Condition {} |
1925 | 2085 | impl OperationArguments for UnimplMem {} |
| 2086 | +impl OperationArguments for Assert {} |
| 2087 | +impl OperationArguments for AssertSsa {} |
| 2088 | +impl OperationArguments for ForceVersion {} |
| 2089 | +impl OperationArguments for ForceVersionSsa {} |
0 commit comments