Struct gimli::read::Evaluation
source · pub struct Evaluation<R: Reader, S: EvaluationStorage<R> = StoreOnHeap> {
bytecode: R,
encoding: Encoding,
object_address: Option<u64>,
max_iterations: Option<u32>,
iteration: u32,
state: EvaluationState<R>,
addr_mask: u64,
stack: ArrayVec<S::Stack>,
pc: R,
expression_stack: ArrayVec<S::ExpressionStack>,
value_result: Option<Value>,
result: ArrayVec<S::Result>,
}
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::{Evaluation, EvaluationResult, Expression};
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);
Fields§
§bytecode: R
§encoding: Encoding
§object_address: Option<u64>
§max_iterations: Option<u32>
§iteration: u32
§state: EvaluationState<R>
§addr_mask: u64
§stack: ArrayVec<S::Stack>
§pc: R
§expression_stack: ArrayVec<S::ExpressionStack>
§value_result: Option<Value>
§result: ArrayVec<S::Result>
Implementations§
source§impl<R: Reader> Evaluation<R>
impl<R: Reader> Evaluation<R>
source§impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S>
impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S>
sourcepub fn new_in(bytecode: R, encoding: Encoding) -> Self
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.
sourcepub fn set_initial_value(&mut self, value: u64)
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.
sourcepub fn set_object_address(&mut self, value: u64)
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.
sourcepub fn set_max_iterations(&mut self, value: u32)
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.
fn pop(&mut self) -> Result<Value>
fn push(&mut self, value: Value) -> Result<()>
fn evaluate_one_operation(&mut self) -> Result<OperationEvaluationResult<R>>
sourcepub fn value_result(&self) -> Option<Value>
pub fn value_result(&self) -> Option<Value>
Get the result if this is an evaluation for a value.
Returns None
if the evaluation contained operations that are only
valid for location descriptions.
§Panics
Panics if this Evaluation
has not been driven to completion.
sourcepub fn as_result(&self) -> &[Piece<R>]
pub fn as_result(&self) -> &[Piece<R>]
Get the result of this Evaluation
.
§Panics
Panics if this Evaluation
has not been driven to completion.
sourcepub fn evaluate(&mut self) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_memory(
&mut self,
value: Value,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_register(
&mut self,
value: Value,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_frame_base(
&mut self,
frame_base: u64,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_tls(&mut self, value: u64) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_call_frame_cfa(
&mut self,
cfa: u64,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_at_location(
&mut self,
bytes: R,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_entry_value(
&mut self,
entry_value: Value,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_parameter_ref(
&mut self,
parameter_value: u64,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_relocated_address(
&mut self,
address: u64,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_indexed_address(
&mut self,
address: u64,
) -> Result<EvaluationResult<R>>
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
.
sourcepub fn resume_with_base_type(
&mut self,
base_type: ValueType,
) -> Result<EvaluationResult<R>>
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
.