pub enum Expression {
    Var(Variable),
    Const(Bitvector),
    BinOp {
        op: BinOpType,
        lhs: Box<Expression>,
        rhs: Box<Expression>,
    },
    UnOp {
        op: UnOpType,
        arg: Box<Expression>,
    },
    Cast {
        op: CastOpType,
        size: ByteSize,
        arg: Box<Expression>,
    },
    Unknown {
        description: String,
        size: ByteSize,
    },
    Subpiece {
        low_byte: ByteSize,
        size: ByteSize,
        arg: Box<Expression>,
    },
}
Expand description

An expression is a calculation rule on how to compute a certain value given some variables (register values) as input.

The basic building blocks of expressions are the same as for Ghidra P-Code. However, expressions can be nested, unlike original P-Code.

Computing the value of an expression is a side-effect-free operation.

Expressions are typed in the sense that each expression has a ByteSize indicating the size of the result when evaluating the expression. Some expressions impose restrictions on the sizes of their inputs for the expression to be well-typed.

All operations are defined the same as the corresponding P-Code operation. Further information about specific operations can be obtained by looking up the P-Code mnemonics in the P-Code Reference Manual.

Variants§

§

Var(Variable)

A variable representing a register or temporary value of known size.

§

Const(Bitvector)

A constant value represented by a bitvector.

§

BinOp

Fields

§op: BinOpType

The opcode/type of the operation

§lhs: Box<Expression>

The left hand side expression

§rhs: Box<Expression>

The right hand side expression

A binary operation. Note that most (but not all) operations require the left hand side (lhs) and right hand side (rhs) to be of equal size.

§

UnOp

Fields

§op: UnOpType

The opcode/type of the operation

§arg: Box<Expression>

The argument expression

A unary operation

§

Cast

Fields

§op: CastOpType

The opcode/type of the cast operation

§size: ByteSize

The byte size of the result value of the expresion

§arg: Box<Expression>

The argument of the expression

A cast operation for type cast between integer and floating point types of different byte lengths.

§

Unknown

Fields

§description: String

A description of the operation

§size: ByteSize

The byte size of the result of the unknown expression

An unknown value but with known size. This may be generated for e.g. unsupported assembly instructions. Note that computation of an unknown value is still required to be side-effect-free!

§

Subpiece

Fields

§low_byte: ByteSize

The lowest byte (i.e. least significant byte if interpreted as integer) of the sub-bitvector to extract.

§size: ByteSize

The size of the resulting sub-bitvector

§arg: Box<Expression>

The argument from which to extract the bitvector from.

Extracting a sub-bitvector from the argument expression.

Implementations§

source§

impl Expression

source

pub fn plus(self, rhs: Expression) -> Expression

Shortcut for creating an IntAdd-expression

source

pub fn plus_const(self, value: i64) -> Expression

Construct an expression that adds a constant value to the given expression.

The bytesize of the value is automatically adjusted to the bytesize of the given expression.

source§

impl Expression

source

pub fn substitute_trivial_operations(&mut self)

Substitute some trivial expressions with their result. E.g. substitute a XOR a with zero or substitute a OR a with a.

source§

impl Expression

source

pub fn bytesize(&self) -> ByteSize

Return the size (in bytes) of the result value of the expression.

source

pub fn input_vars(&self) -> Vec<&Variable>

Return an array of all input variables of the given expression. The array may contain duplicates.

source

pub fn substitute_input_var( &mut self, input_var: &Variable, replace_with_expression: &Expression )

Substitute every occurrence of input_var in self with the given replace_with_expression.

source

pub fn recursion_depth(&self) -> u64

Compute a recursion depth for the expression.

Because of the recursive nature of the Expression type, overly complex expressions are very costly to clone, which in turn can negatively affect some analyses. The recursion depth measure can be used to detect and handle such cases.

Trait Implementations§

source§

impl Clone for Expression

source§

fn clone(&self) -> Expression

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Expression

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for Expression

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Display for Expression

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Expression> for Expression

source§

fn from(expr: Expression) -> IrExpression

Translates a P-Code expression into an expression of the internally used IR if possible. Panics if translation is not possible.

Cases where translation is not possible:

  • LOAD and STORE, since these are not expressions (they have side effects).
  • Expressions which store the size of their output in the output variable (to which we do not have access here). These include SUBPIECE, INT_ZEXT, INT_SEXT, INT2FLOAT, FLOAT2FLOAT, TRUNC, LZCOUNT and POPCOUNT. Translation of these expressions is handled explicitly during translation of Def.
source§

impl From<Variable> for Expression

source§

fn from(pcode_var: Variable) -> IrExpression

Translate a P-Code variable into a Varor Const expression of the internally used IR. Panics if the translation fails.

source§

impl Hash for Expression

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Expression

source§

fn eq(&self, other: &Expression) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Serialize for Expression

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for Expression

source§

impl StructuralEq for Expression

source§

impl StructuralPartialEq for Expression

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,