Struct gimli::read::Evaluation

source ·
pub struct Evaluation<R: Reader, S: EvaluationStorage<R> = StoreOnHeap> { /* private fields */ }
Expand description

A DWARF expression evaluator.

Usage

A DWARF expression may require additional data to produce a final result, such as the value of a register or a memory location. Once initial setup is complete (i.e. set_initial_value(), set_object_address()) the consumer calls the evaluate() method. That returns an EvaluationResult, which is either EvaluationResult::Complete or a value indicating what data is needed to resume the Evaluation. The consumer is responsible for producing that data and resuming the computation with the correct method, as documented for EvaluationResult. Only once an EvaluationResult::Complete is returned can the consumer call result().

This design allows the consumer of Evaluation to decide how and when to produce the required data and resume the computation. The Evaluation can be driven synchronously (as shown below) or by some asynchronous mechanism such as futures.

Examples

use gimli::{EndianSlice, Evaluation, EvaluationResult, Format, LittleEndian, Value};

let mut eval = Evaluation::new(bytecode, encoding);
let mut result = eval.evaluate().unwrap();
while result != EvaluationResult::Complete {
  match result {
    EvaluationResult::RequiresRegister { register, base_type } => {
      let value = get_register_value(register, base_type);
      result = eval.resume_with_register(value).unwrap();
    },
    EvaluationResult::RequiresFrameBase => {
      let frame_base = get_frame_base();
      result = eval.resume_with_frame_base(frame_base).unwrap();
    },
    _ => unimplemented!(),
  };
}

let result = eval.result();
println!("{:?}", result);

Implementations§

source§

impl<R: Reader> Evaluation<R>

source

pub fn new(bytecode: R, encoding: Encoding) -> Self

Create a new DWARF expression evaluator.

The new evaluator is created without an initial value, without an object address, and without a maximum number of iterations.

source

pub fn result(self) -> Vec<Piece<R>>

Get the result of this Evaluation.

Panics

Panics if this Evaluation has not been driven to completion.

source§

impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S>

source

pub fn new_in(bytecode: R, encoding: Encoding) -> Self

Create a new DWARF expression evaluator.

The new evaluator is created without an initial value, without an object address, and without a maximum number of iterations.

source

pub fn set_initial_value(&mut self, value: u64)

Set an initial value to be pushed on the DWARF expression evaluator’s stack. This can be used in cases like DW_AT_vtable_elem_location, which require a value on the stack before evaluation commences. If no initial value is set, and the expression uses an opcode requiring the initial value, then evaluation will fail with an error.

Panics

Panics if set_initial_value() has already been called, or if evaluate() has already been called.

source

pub fn set_object_address(&mut self, value: u64)

Set the enclosing object’s address, as used by DW_OP_push_object_address. If no object address is set, and the expression uses an opcode requiring the object address, then evaluation will fail with an error.

source

pub fn set_max_iterations(&mut self, value: u32)

Set the maximum number of iterations to be allowed by the expression evaluator.

An iteration corresponds approximately to the evaluation of a single operation in an expression (“approximately” because the implementation may allow two such operations in some cases). The default is not to have a maximum; once set, it’s not possible to go back to this default state. This value can be set to avoid denial of service attacks by bad DWARF bytecode.

source

pub fn as_result(&self) -> &[Piece<R>]

Get the result of this Evaluation.

Panics

Panics if this Evaluation has not been driven to completion.

source

pub fn evaluate(&mut self) -> Result<EvaluationResult<R>>

Evaluate a DWARF expression. This method should only ever be called once. If the returned EvaluationResult is not EvaluationResult::Complete, the caller should provide the required value and resume the evaluation by calling the appropriate resume_with method on Evaluation.

source

pub fn resume_with_memory( &mut self, value: Value ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided memory value. This will apply the provided memory value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresMemory.

source

pub fn resume_with_register( &mut self, value: Value ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided register value. This will apply the provided register value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresRegister.

source

pub fn resume_with_frame_base( &mut self, frame_base: u64 ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided frame_base. This will apply the provided frame base value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresFrameBase.

source

pub fn resume_with_tls(&mut self, value: u64) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided value. This will apply the provided TLS value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresTls.

source

pub fn resume_with_call_frame_cfa( &mut self, cfa: u64 ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided cfa. This will apply the provided CFA value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresCallFrameCfa.

source

pub fn resume_with_at_location( &mut self, bytes: R ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided bytes. This will continue processing the evaluation with the new expression provided until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresAtLocation.

source

pub fn resume_with_entry_value( &mut self, entry_value: Value ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided entry_value. This will apply the provided entry value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresEntryValue.

source

pub fn resume_with_parameter_ref( &mut self, parameter_value: u64 ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided parameter_value. This will apply the provided parameter value to the evaluation and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresParameterRef.

source

pub fn resume_with_relocated_address( &mut self, address: u64 ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided relocated address. This will use the provided relocated address for the operation that required it, and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresRelocatedAddress.

source

pub fn resume_with_indexed_address( &mut self, address: u64 ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided indexed address. This will use the provided indexed address for the operation that required it, and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresIndexedAddress.

source

pub fn resume_with_base_type( &mut self, base_type: ValueType ) -> Result<EvaluationResult<R>>

Resume the Evaluation with the provided base_type. This will use the provided base type for the operation that required it, and continue evaluating opcodes until the evaluation is completed, reaches an error, or needs more information again.

Panics

Panics if this Evaluation did not previously stop with EvaluationResult::RequiresBaseType.

Trait Implementations§

source§

impl<R: Debug + Reader, S: Debug + EvaluationStorage<R>> Debug for Evaluation<R, S>where S::Stack: Debug, S::ExpressionStack: Debug, S::Result: Debug,

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<R, S> RefUnwindSafe for Evaluation<R, S>where R: RefUnwindSafe, <<S as EvaluationStorage<R>>::ExpressionStack as Sealed>::Storage: RefUnwindSafe, <<S as EvaluationStorage<R>>::Result as Sealed>::Storage: RefUnwindSafe, <<S as EvaluationStorage<R>>::Stack as Sealed>::Storage: RefUnwindSafe,

§

impl<R, S> Send for Evaluation<R, S>where R: Send, <<S as EvaluationStorage<R>>::ExpressionStack as Sealed>::Storage: Send, <<S as EvaluationStorage<R>>::Result as Sealed>::Storage: Send, <<S as EvaluationStorage<R>>::Stack as Sealed>::Storage: Send,

§

impl<R, S> Sync for Evaluation<R, S>where R: Sync, <<S as EvaluationStorage<R>>::ExpressionStack as Sealed>::Storage: Sync, <<S as EvaluationStorage<R>>::Result as Sealed>::Storage: Sync, <<S as EvaluationStorage<R>>::Stack as Sealed>::Storage: Sync,

§

impl<R, S> Unpin for Evaluation<R, S>where R: Unpin, <<S as EvaluationStorage<R>>::ExpressionStack as Sealed>::Storage: Unpin, <<S as EvaluationStorage<R>>::Result as Sealed>::Storage: Unpin, <<S as EvaluationStorage<R>>::Stack as Sealed>::Storage: Unpin,

§

impl<R, S> UnwindSafe for Evaluation<R, S>where R: UnwindSafe, <<S as EvaluationStorage<R>>::ExpressionStack as Sealed>::Storage: UnwindSafe, <<S as EvaluationStorage<R>>::Result as Sealed>::Storage: UnwindSafe, <<S as EvaluationStorage<R>>::Stack as Sealed>::Storage: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere 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, U> TryFrom<U> for Twhere 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 Twhere 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.