Skip to main content

gimli/read/
op.rs

1//! Functions for parsing and evaluating DWARF expressions.
2
3#[cfg(feature = "read")]
4use alloc::vec::Vec;
5use core::mem;
6
7use super::util::{ArrayLike, ArrayVec};
8use crate::common::{DebugAddrIndex, DebugInfoOffset, Encoding, Register};
9use crate::constants;
10use crate::read::{Error, Reader, ReaderOffset, Result, StoreOnHeap, UnitOffset, Value, ValueType};
11
12/// A reference to a DIE, either relative to the current CU or
13/// relative to the section.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DieReference<T = usize> {
16    /// A CU-relative reference.
17    UnitRef(UnitOffset<T>),
18    /// A section-relative reference.
19    DebugInfoRef(DebugInfoOffset<T>),
20}
21
22/// A single decoded DWARF expression operation.
23///
24/// DWARF expression evaluation is done in two parts: first the raw
25/// bytes of the next part of the expression are decoded; and then the
26/// decoded operation is evaluated.  This approach lets other
27/// consumers inspect the DWARF expression without reimplementing the
28/// decoding operation.
29///
30/// Multiple DWARF opcodes may decode into a single `Operation`.  For
31/// example, both `DW_OP_deref` and `DW_OP_xderef` are represented
32/// using `Operation::Deref`.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum Operation<R, Offset = <R as Reader>::Offset>
35where
36    R: Reader<Offset = Offset>,
37    Offset: ReaderOffset,
38{
39    /// Dereference the topmost value of the stack.
40    Deref {
41        /// The DIE of the base type or 0 to indicate the generic type
42        base_type: UnitOffset<Offset>,
43        /// The size of the data to dereference.
44        size: u8,
45        /// True if the dereference operation takes an address space
46        /// argument from the stack; false otherwise.
47        space: bool,
48    },
49    /// Drop an item from the stack.
50    Drop,
51    /// Pick an item from the stack and push it on top of the stack.
52    /// This operation handles `DW_OP_pick`, `DW_OP_dup`, and
53    /// `DW_OP_over`.
54    Pick {
55        /// The index, from the top of the stack, of the item to copy.
56        index: u8,
57    },
58    /// Swap the top two stack items.
59    Swap,
60    /// Rotate the top three stack items.
61    Rot,
62    /// Take the absolute value of the top of the stack.
63    Abs,
64    /// Bitwise `and` of the top two values on the stack.
65    And,
66    /// Divide the top two values on the stack.
67    Div,
68    /// Subtract the top two values on the stack.
69    Minus,
70    /// Modulus of the top two values on the stack.
71    Mod,
72    /// Multiply the top two values on the stack.
73    Mul,
74    /// Negate the top of the stack.
75    Neg,
76    /// Bitwise `not` of the top of the stack.
77    Not,
78    /// Bitwise `or` of the top two values on the stack.
79    Or,
80    /// Add the top two values on the stack.
81    Plus,
82    /// Add a constant to the topmost value on the stack.
83    PlusConstant {
84        /// The value to add.
85        value: u64,
86    },
87    /// Logical left shift of the 2nd value on the stack by the number
88    /// of bits given by the topmost value on the stack.
89    Shl,
90    /// Right shift of the 2nd value on the stack by the number of
91    /// bits given by the topmost value on the stack.
92    Shr,
93    /// Arithmetic left shift of the 2nd value on the stack by the
94    /// number of bits given by the topmost value on the stack.
95    Shra,
96    /// Bitwise `xor` of the top two values on the stack.
97    Xor,
98    /// Branch to the target location if the top of stack is nonzero.
99    Bra {
100        /// The relative offset to the target bytecode.
101        target: i16,
102    },
103    /// Compare the top two stack values for equality.
104    Eq,
105    /// Compare the top two stack values using `>=`.
106    Ge,
107    /// Compare the top two stack values using `>`.
108    Gt,
109    /// Compare the top two stack values using `<=`.
110    Le,
111    /// Compare the top two stack values using `<`.
112    Lt,
113    /// Compare the top two stack values using `!=`.
114    Ne,
115    /// Unconditional branch to the target location.
116    Skip {
117        /// The relative offset to the target bytecode.
118        target: i16,
119    },
120    /// Push an unsigned constant value on the stack.  This handles multiple
121    /// DWARF opcodes.
122    UnsignedConstant {
123        /// The value to push.
124        value: u64,
125    },
126    /// Push a signed constant value on the stack.  This handles multiple
127    /// DWARF opcodes.
128    SignedConstant {
129        /// The value to push.
130        value: i64,
131    },
132    /// Indicate that this piece's location is in the given register.
133    ///
134    /// Completes the piece or expression.
135    Register {
136        /// The register number.
137        register: Register,
138    },
139    /// Find the value of the given register, add the offset, and then
140    /// push the resulting sum on the stack.
141    RegisterOffset {
142        /// The register number.
143        register: Register,
144        /// The offset to add.
145        offset: i64,
146        /// The DIE of the base type or 0 to indicate the generic type
147        base_type: UnitOffset<Offset>,
148    },
149    /// Compute the frame base (using `DW_AT_frame_base`), add the
150    /// given offset, and then push the resulting sum on the stack.
151    FrameOffset {
152        /// The offset to add.
153        offset: i64,
154    },
155    /// No operation.
156    Nop,
157    /// Push the object address on the stack.
158    PushObjectAddress,
159    /// Evaluate a DWARF expression as a subroutine.  The expression
160    /// comes from the `DW_AT_location` attribute of the indicated
161    /// DIE.
162    Call {
163        /// The DIE to use.
164        offset: DieReference<Offset>,
165    },
166    /// Compute the value of a variable and push it on the stack.
167    ///
168    /// Represents `DW_OP_GNU_variable_value`.
169    VariableValue {
170        /// The `.debug_info` offset of the variable.
171        offset: DebugInfoOffset<Offset>,
172    },
173    /// Compute the address of a thread-local variable and push it on
174    /// the stack.
175    TLS,
176    /// Compute the call frame CFA and push it on the stack.
177    CallFrameCFA,
178    /// Terminate a piece.
179    Piece {
180        /// The size of this piece in bits.
181        size_in_bits: u64,
182        /// The bit offset of this piece.  If `None`, then this piece
183        /// was specified using `DW_OP_piece` and should start at the
184        /// next byte boundary.
185        bit_offset: Option<u64>,
186    },
187    /// The object has no location, but has a known constant value.
188    ///
189    /// Represents `DW_OP_implicit_value`.
190    /// Completes the piece or expression.
191    ImplicitValue {
192        /// The implicit value to use.
193        data: R,
194    },
195    /// The object has no location, but its value is at the top of the stack.
196    ///
197    /// Represents `DW_OP_stack_value`.
198    /// Completes the piece or expression.
199    StackValue,
200    /// The object is a pointer to a value which has no actual location,
201    /// such as an implicit value or a stack value.
202    ///
203    /// Represents `DW_OP_implicit_pointer`.
204    /// Completes the piece or expression.
205    ImplicitPointer {
206        /// The `.debug_info` offset of the value that this is an implicit pointer into.
207        value: DebugInfoOffset<Offset>,
208        /// The byte offset into the value that the implicit pointer points to.
209        byte_offset: i64,
210    },
211    /// Evaluate an expression at the entry to the current subprogram, and push it on the stack.
212    ///
213    /// Represents `DW_OP_entry_value`.
214    EntryValue {
215        /// The expression to be evaluated.
216        expression: R,
217    },
218    /// This represents a parameter that was optimized out.
219    ///
220    /// The offset points to the definition of the parameter, and is
221    /// matched to the `DW_TAG_GNU_call_site_parameter` in the caller that also
222    /// points to the same definition of the parameter.
223    ///
224    /// Represents `DW_OP_GNU_parameter_ref`.
225    ParameterRef {
226        /// The DIE to use.
227        offset: UnitOffset<Offset>,
228    },
229    /// Relocate the address if needed, and push it on the stack.
230    ///
231    /// Represents `DW_OP_addr`.
232    Address {
233        /// The offset to add.
234        address: u64,
235    },
236    /// Read the address at the given index in `.debug_addr, relocate the address if needed,
237    /// and push it on the stack.
238    ///
239    /// Represents `DW_OP_addrx`.
240    AddressIndex {
241        /// The index of the address in `.debug_addr`.
242        index: DebugAddrIndex<Offset>,
243    },
244    /// Read the address at the given index in `.debug_addr, and push it on the stack.
245    /// Do not relocate the address.
246    ///
247    /// Represents `DW_OP_constx`.
248    ConstantIndex {
249        /// The index of the address in `.debug_addr`.
250        index: DebugAddrIndex<Offset>,
251    },
252    /// Interpret the value bytes as a constant of a given type, and push it on the stack.
253    ///
254    /// Represents `DW_OP_const_type`.
255    TypedLiteral {
256        /// The DIE of the base type.
257        base_type: UnitOffset<Offset>,
258        /// The value bytes.
259        value: R,
260    },
261    /// Pop the top stack entry, convert it to a different type, and push it on the stack.
262    ///
263    /// Represents `DW_OP_convert`.
264    Convert {
265        /// The DIE of the base type.
266        base_type: UnitOffset<Offset>,
267    },
268    /// Pop the top stack entry, reinterpret the bits in its value as a different type,
269    /// and push it on the stack.
270    ///
271    /// Represents `DW_OP_reinterpret`.
272    Reinterpret {
273        /// The DIE of the base type.
274        base_type: UnitOffset<Offset>,
275    },
276    /// Indicates that the value in the computed location is uninitialized.
277    ///
278    /// Represents `DW_OP_GNU_uninit`.
279    Uninitialized,
280    /// The index of a local in the currently executing function.
281    ///
282    /// Represents `DW_OP_WASM_location 0x00`.
283    /// Completes the piece or expression.
284    WasmLocal {
285        /// The index of the local.
286        index: u32,
287    },
288    /// The index of a global.
289    ///
290    /// Represents `DW_OP_WASM_location 0x01` or `DW_OP_WASM_location 0x03`.
291    /// Completes the piece or expression.
292    WasmGlobal {
293        /// The index of the global.
294        index: u32,
295    },
296    /// The index of an item on the operand stack.
297    ///
298    /// Represents `DW_OP_WASM_location 0x02`.
299    /// Completes the piece or expression.
300    WasmStack {
301        /// The index of the stack item. 0 is the bottom of the operand stack.
302        index: u32,
303    },
304}
305
306#[derive(Debug)]
307enum OperationEvaluationResult<R: Reader> {
308    Piece,
309    Incomplete,
310    Complete { location: Location<R> },
311    Waiting(EvaluationWaiting<R>, EvaluationResult<R>),
312}
313
314/// A single location of a piece of the result of a DWARF expression.
315#[derive(Debug, Clone, Copy, PartialEq)]
316pub enum Location<R, Offset = <R as Reader>::Offset>
317where
318    R: Reader<Offset = Offset>,
319    Offset: ReaderOffset,
320{
321    /// The piece is empty.  Ordinarily this means the piece has been
322    /// optimized away.
323    Empty,
324    /// The piece is found in a register.
325    Register {
326        /// The register number.
327        register: Register,
328    },
329    /// The piece is found in memory.
330    Address {
331        /// The address.
332        address: u64,
333    },
334    /// The piece has no location but its value is known.
335    Value {
336        /// The value.
337        value: Value,
338    },
339    /// The piece is represented by some constant bytes.
340    Bytes {
341        /// The value.
342        value: R,
343    },
344    /// The piece is a pointer to a value which has no actual location.
345    ImplicitPointer {
346        /// The `.debug_info` offset of the value that this is an implicit pointer into.
347        value: DebugInfoOffset<Offset>,
348        /// The byte offset into the value that the implicit pointer points to.
349        byte_offset: i64,
350    },
351}
352
353impl<R, Offset> Location<R, Offset>
354where
355    R: Reader<Offset = Offset>,
356    Offset: ReaderOffset,
357{
358    /// Return true if the piece is empty.
359    pub fn is_empty(&self) -> bool {
360        matches!(*self, Location::Empty)
361    }
362}
363
364/// The description of a single piece of the result of a DWARF
365/// expression.
366#[derive(Debug, Clone, Copy, PartialEq)]
367pub struct Piece<R, Offset = <R as Reader>::Offset>
368where
369    R: Reader<Offset = Offset>,
370    Offset: ReaderOffset,
371{
372    /// If given, the size of the piece in bits.  If `None`, there
373    /// must be only one piece whose size is all of the object.
374    pub size_in_bits: Option<u64>,
375    /// If given, the bit offset of the piece within the location.
376    /// If the location is a `Location::Register` or `Location::Value`,
377    /// then this offset is from the least significant bit end of
378    /// the register or value.
379    /// If the location is a `Location::Address` then the offset uses
380    /// the bit numbering and direction conventions of the language
381    /// and target system.
382    ///
383    /// If `None`, the piece starts at the location. If the
384    /// location is a register whose size is larger than the piece,
385    /// then placement within the register is defined by the ABI.
386    pub bit_offset: Option<u64>,
387    /// Where this piece is to be found.
388    pub location: Location<R, Offset>,
389}
390
391// A helper function to handle branch offsets.
392fn compute_pc<R: Reader>(pc: &R, bytecode: &R, offset: i16) -> Result<R> {
393    let pc_offset = pc.offset_from(bytecode);
394    let new_pc_offset = pc_offset.wrapping_add(R::Offset::from_i16(offset));
395    if new_pc_offset > bytecode.len() {
396        Err(Error::BadBranchTarget(new_pc_offset.into_u64()))
397    } else {
398        let mut new_pc = bytecode.clone();
399        new_pc.skip(new_pc_offset)?;
400        Ok(new_pc)
401    }
402}
403
404fn generic_type<O: ReaderOffset>() -> UnitOffset<O> {
405    UnitOffset(O::from_u64(0).unwrap())
406}
407
408impl<R, Offset> Operation<R, Offset>
409where
410    R: Reader<Offset = Offset>,
411    Offset: ReaderOffset,
412{
413    /// Parse a single DWARF expression operation.
414    ///
415    /// This is useful when examining a DWARF expression for reasons other
416    /// than direct evaluation.
417    ///
418    /// `bytes` points to a the operation to decode.  It should point into
419    /// the same array as `bytecode`, which should be the entire
420    /// expression.
421    pub fn parse(bytes: &mut R, encoding: Encoding) -> Result<Operation<R, Offset>> {
422        let opcode = bytes.read_u8()?;
423        let name = constants::DwOp(opcode);
424        match name {
425            constants::DW_OP_addr => {
426                let address = bytes.read_address(encoding.address_size)?;
427                Ok(Operation::Address { address })
428            }
429            constants::DW_OP_deref => Ok(Operation::Deref {
430                base_type: generic_type(),
431                size: encoding.address_size,
432                space: false,
433            }),
434            constants::DW_OP_const1u => {
435                let value = bytes.read_u8()?;
436                Ok(Operation::UnsignedConstant {
437                    value: u64::from(value),
438                })
439            }
440            constants::DW_OP_const1s => {
441                let value = bytes.read_i8()?;
442                Ok(Operation::SignedConstant {
443                    value: i64::from(value),
444                })
445            }
446            constants::DW_OP_const2u => {
447                let value = bytes.read_u16()?;
448                Ok(Operation::UnsignedConstant {
449                    value: u64::from(value),
450                })
451            }
452            constants::DW_OP_const2s => {
453                let value = bytes.read_i16()?;
454                Ok(Operation::SignedConstant {
455                    value: i64::from(value),
456                })
457            }
458            constants::DW_OP_const4u => {
459                let value = bytes.read_u32()?;
460                Ok(Operation::UnsignedConstant {
461                    value: u64::from(value),
462                })
463            }
464            constants::DW_OP_const4s => {
465                let value = bytes.read_i32()?;
466                Ok(Operation::SignedConstant {
467                    value: i64::from(value),
468                })
469            }
470            constants::DW_OP_const8u => {
471                let value = bytes.read_u64()?;
472                Ok(Operation::UnsignedConstant { value })
473            }
474            constants::DW_OP_const8s => {
475                let value = bytes.read_i64()?;
476                Ok(Operation::SignedConstant { value })
477            }
478            constants::DW_OP_constu => {
479                let value = bytes.read_uleb128()?;
480                Ok(Operation::UnsignedConstant { value })
481            }
482            constants::DW_OP_consts => {
483                let value = bytes.read_sleb128()?;
484                Ok(Operation::SignedConstant { value })
485            }
486            constants::DW_OP_dup => Ok(Operation::Pick { index: 0 }),
487            constants::DW_OP_drop => Ok(Operation::Drop),
488            constants::DW_OP_over => Ok(Operation::Pick { index: 1 }),
489            constants::DW_OP_pick => {
490                let value = bytes.read_u8()?;
491                Ok(Operation::Pick { index: value })
492            }
493            constants::DW_OP_swap => Ok(Operation::Swap),
494            constants::DW_OP_rot => Ok(Operation::Rot),
495            constants::DW_OP_xderef => Ok(Operation::Deref {
496                base_type: generic_type(),
497                size: encoding.address_size,
498                space: true,
499            }),
500            constants::DW_OP_abs => Ok(Operation::Abs),
501            constants::DW_OP_and => Ok(Operation::And),
502            constants::DW_OP_div => Ok(Operation::Div),
503            constants::DW_OP_minus => Ok(Operation::Minus),
504            constants::DW_OP_mod => Ok(Operation::Mod),
505            constants::DW_OP_mul => Ok(Operation::Mul),
506            constants::DW_OP_neg => Ok(Operation::Neg),
507            constants::DW_OP_not => Ok(Operation::Not),
508            constants::DW_OP_or => Ok(Operation::Or),
509            constants::DW_OP_plus => Ok(Operation::Plus),
510            constants::DW_OP_plus_uconst => {
511                let value = bytes.read_uleb128()?;
512                Ok(Operation::PlusConstant { value })
513            }
514            constants::DW_OP_shl => Ok(Operation::Shl),
515            constants::DW_OP_shr => Ok(Operation::Shr),
516            constants::DW_OP_shra => Ok(Operation::Shra),
517            constants::DW_OP_xor => Ok(Operation::Xor),
518            constants::DW_OP_bra => {
519                let target = bytes.read_i16()?;
520                Ok(Operation::Bra { target })
521            }
522            constants::DW_OP_eq => Ok(Operation::Eq),
523            constants::DW_OP_ge => Ok(Operation::Ge),
524            constants::DW_OP_gt => Ok(Operation::Gt),
525            constants::DW_OP_le => Ok(Operation::Le),
526            constants::DW_OP_lt => Ok(Operation::Lt),
527            constants::DW_OP_ne => Ok(Operation::Ne),
528            constants::DW_OP_skip => {
529                let target = bytes.read_i16()?;
530                Ok(Operation::Skip { target })
531            }
532            constants::DW_OP_lit0
533            | constants::DW_OP_lit1
534            | constants::DW_OP_lit2
535            | constants::DW_OP_lit3
536            | constants::DW_OP_lit4
537            | constants::DW_OP_lit5
538            | constants::DW_OP_lit6
539            | constants::DW_OP_lit7
540            | constants::DW_OP_lit8
541            | constants::DW_OP_lit9
542            | constants::DW_OP_lit10
543            | constants::DW_OP_lit11
544            | constants::DW_OP_lit12
545            | constants::DW_OP_lit13
546            | constants::DW_OP_lit14
547            | constants::DW_OP_lit15
548            | constants::DW_OP_lit16
549            | constants::DW_OP_lit17
550            | constants::DW_OP_lit18
551            | constants::DW_OP_lit19
552            | constants::DW_OP_lit20
553            | constants::DW_OP_lit21
554            | constants::DW_OP_lit22
555            | constants::DW_OP_lit23
556            | constants::DW_OP_lit24
557            | constants::DW_OP_lit25
558            | constants::DW_OP_lit26
559            | constants::DW_OP_lit27
560            | constants::DW_OP_lit28
561            | constants::DW_OP_lit29
562            | constants::DW_OP_lit30
563            | constants::DW_OP_lit31 => Ok(Operation::UnsignedConstant {
564                value: (opcode - constants::DW_OP_lit0.0).into(),
565            }),
566            constants::DW_OP_reg0
567            | constants::DW_OP_reg1
568            | constants::DW_OP_reg2
569            | constants::DW_OP_reg3
570            | constants::DW_OP_reg4
571            | constants::DW_OP_reg5
572            | constants::DW_OP_reg6
573            | constants::DW_OP_reg7
574            | constants::DW_OP_reg8
575            | constants::DW_OP_reg9
576            | constants::DW_OP_reg10
577            | constants::DW_OP_reg11
578            | constants::DW_OP_reg12
579            | constants::DW_OP_reg13
580            | constants::DW_OP_reg14
581            | constants::DW_OP_reg15
582            | constants::DW_OP_reg16
583            | constants::DW_OP_reg17
584            | constants::DW_OP_reg18
585            | constants::DW_OP_reg19
586            | constants::DW_OP_reg20
587            | constants::DW_OP_reg21
588            | constants::DW_OP_reg22
589            | constants::DW_OP_reg23
590            | constants::DW_OP_reg24
591            | constants::DW_OP_reg25
592            | constants::DW_OP_reg26
593            | constants::DW_OP_reg27
594            | constants::DW_OP_reg28
595            | constants::DW_OP_reg29
596            | constants::DW_OP_reg30
597            | constants::DW_OP_reg31 => Ok(Operation::Register {
598                register: Register((opcode - constants::DW_OP_reg0.0).into()),
599            }),
600            constants::DW_OP_breg0
601            | constants::DW_OP_breg1
602            | constants::DW_OP_breg2
603            | constants::DW_OP_breg3
604            | constants::DW_OP_breg4
605            | constants::DW_OP_breg5
606            | constants::DW_OP_breg6
607            | constants::DW_OP_breg7
608            | constants::DW_OP_breg8
609            | constants::DW_OP_breg9
610            | constants::DW_OP_breg10
611            | constants::DW_OP_breg11
612            | constants::DW_OP_breg12
613            | constants::DW_OP_breg13
614            | constants::DW_OP_breg14
615            | constants::DW_OP_breg15
616            | constants::DW_OP_breg16
617            | constants::DW_OP_breg17
618            | constants::DW_OP_breg18
619            | constants::DW_OP_breg19
620            | constants::DW_OP_breg20
621            | constants::DW_OP_breg21
622            | constants::DW_OP_breg22
623            | constants::DW_OP_breg23
624            | constants::DW_OP_breg24
625            | constants::DW_OP_breg25
626            | constants::DW_OP_breg26
627            | constants::DW_OP_breg27
628            | constants::DW_OP_breg28
629            | constants::DW_OP_breg29
630            | constants::DW_OP_breg30
631            | constants::DW_OP_breg31 => {
632                let value = bytes.read_sleb128()?;
633                Ok(Operation::RegisterOffset {
634                    register: Register((opcode - constants::DW_OP_breg0.0).into()),
635                    offset: value,
636                    base_type: generic_type(),
637                })
638            }
639            constants::DW_OP_regx => {
640                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
641                Ok(Operation::Register { register })
642            }
643            constants::DW_OP_fbreg => {
644                let value = bytes.read_sleb128()?;
645                Ok(Operation::FrameOffset { offset: value })
646            }
647            constants::DW_OP_bregx => {
648                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
649                let offset = bytes.read_sleb128()?;
650                Ok(Operation::RegisterOffset {
651                    register,
652                    offset,
653                    base_type: generic_type(),
654                })
655            }
656            constants::DW_OP_piece => {
657                let size = bytes.read_uleb128()?;
658                Ok(Operation::Piece {
659                    size_in_bits: 8 * size,
660                    bit_offset: None,
661                })
662            }
663            constants::DW_OP_deref_size => {
664                let size = bytes.read_u8()?;
665                Ok(Operation::Deref {
666                    base_type: generic_type(),
667                    size,
668                    space: false,
669                })
670            }
671            constants::DW_OP_xderef_size => {
672                let size = bytes.read_u8()?;
673                Ok(Operation::Deref {
674                    base_type: generic_type(),
675                    size,
676                    space: true,
677                })
678            }
679            constants::DW_OP_nop => Ok(Operation::Nop),
680            constants::DW_OP_push_object_address => Ok(Operation::PushObjectAddress),
681            constants::DW_OP_call2 => {
682                let value = bytes.read_u16().map(R::Offset::from_u16)?;
683                Ok(Operation::Call {
684                    offset: DieReference::UnitRef(UnitOffset(value)),
685                })
686            }
687            constants::DW_OP_call4 => {
688                let value = bytes.read_u32().map(R::Offset::from_u32)?;
689                Ok(Operation::Call {
690                    offset: DieReference::UnitRef(UnitOffset(value)),
691                })
692            }
693            constants::DW_OP_call_ref => {
694                let value = bytes.read_offset(encoding.format)?;
695                Ok(Operation::Call {
696                    offset: DieReference::DebugInfoRef(DebugInfoOffset(value)),
697                })
698            }
699            constants::DW_OP_GNU_variable_value => {
700                let value = bytes.read_offset(encoding.format)?;
701                Ok(Operation::VariableValue {
702                    offset: DebugInfoOffset(value),
703                })
704            }
705            constants::DW_OP_form_tls_address | constants::DW_OP_GNU_push_tls_address => {
706                Ok(Operation::TLS)
707            }
708            constants::DW_OP_call_frame_cfa => Ok(Operation::CallFrameCFA),
709            constants::DW_OP_bit_piece => {
710                let size = bytes.read_uleb128()?;
711                let offset = bytes.read_uleb128()?;
712                Ok(Operation::Piece {
713                    size_in_bits: size,
714                    bit_offset: Some(offset),
715                })
716            }
717            constants::DW_OP_implicit_value => {
718                let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
719                let data = bytes.split(len)?;
720                Ok(Operation::ImplicitValue { data })
721            }
722            constants::DW_OP_stack_value => Ok(Operation::StackValue),
723            constants::DW_OP_implicit_pointer | constants::DW_OP_GNU_implicit_pointer => {
724                let value = if encoding.version == 2 {
725                    bytes
726                        .read_address(encoding.address_size)
727                        .and_then(Offset::from_u64)?
728                } else {
729                    bytes.read_offset(encoding.format)?
730                };
731                let byte_offset = bytes.read_sleb128()?;
732                Ok(Operation::ImplicitPointer {
733                    value: DebugInfoOffset(value),
734                    byte_offset,
735                })
736            }
737            constants::DW_OP_addrx | constants::DW_OP_GNU_addr_index => {
738                let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
739                Ok(Operation::AddressIndex {
740                    index: DebugAddrIndex(index),
741                })
742            }
743            constants::DW_OP_constx | constants::DW_OP_GNU_const_index => {
744                let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
745                Ok(Operation::ConstantIndex {
746                    index: DebugAddrIndex(index),
747                })
748            }
749            constants::DW_OP_entry_value | constants::DW_OP_GNU_entry_value => {
750                let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
751                let expression = bytes.split(len)?;
752                Ok(Operation::EntryValue { expression })
753            }
754            constants::DW_OP_GNU_parameter_ref => {
755                let value = bytes.read_u32().map(R::Offset::from_u32)?;
756                Ok(Operation::ParameterRef {
757                    offset: UnitOffset(value),
758                })
759            }
760            constants::DW_OP_const_type | constants::DW_OP_GNU_const_type => {
761                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
762                let len = bytes.read_u8()?;
763                let value = bytes.split(R::Offset::from_u8(len))?;
764                Ok(Operation::TypedLiteral {
765                    base_type: UnitOffset(base_type),
766                    value,
767                })
768            }
769            constants::DW_OP_regval_type | constants::DW_OP_GNU_regval_type => {
770                let register = bytes.read_uleb128().and_then(Register::from_u64)?;
771                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
772                Ok(Operation::RegisterOffset {
773                    register,
774                    offset: 0,
775                    base_type: UnitOffset(base_type),
776                })
777            }
778            constants::DW_OP_deref_type | constants::DW_OP_GNU_deref_type => {
779                let size = bytes.read_u8()?;
780                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
781                Ok(Operation::Deref {
782                    base_type: UnitOffset(base_type),
783                    size,
784                    space: false,
785                })
786            }
787            constants::DW_OP_xderef_type => {
788                let size = bytes.read_u8()?;
789                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
790                Ok(Operation::Deref {
791                    base_type: UnitOffset(base_type),
792                    size,
793                    space: true,
794                })
795            }
796            constants::DW_OP_convert | constants::DW_OP_GNU_convert => {
797                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
798                Ok(Operation::Convert {
799                    base_type: UnitOffset(base_type),
800                })
801            }
802            constants::DW_OP_reinterpret | constants::DW_OP_GNU_reinterpret => {
803                let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
804                Ok(Operation::Reinterpret {
805                    base_type: UnitOffset(base_type),
806                })
807            }
808            constants::DW_OP_GNU_uninit => Ok(Operation::Uninitialized),
809            constants::DW_OP_WASM_location => match bytes.read_u8()? {
810                0x0 => {
811                    let index = bytes.read_uleb128_u32()?;
812                    Ok(Operation::WasmLocal { index })
813                }
814                0x1 => {
815                    let index = bytes.read_uleb128_u32()?;
816                    Ok(Operation::WasmGlobal { index })
817                }
818                0x2 => {
819                    let index = bytes.read_uleb128_u32()?;
820                    Ok(Operation::WasmStack { index })
821                }
822                0x3 => {
823                    let index = bytes.read_u32()?;
824                    Ok(Operation::WasmGlobal { index })
825                }
826                _ => Err(Error::InvalidExpression(name)),
827            },
828            _ => Err(Error::InvalidExpression(name)),
829        }
830    }
831}
832
833#[derive(Debug)]
834enum EvaluationState<R: Reader> {
835    Start(Option<u64>),
836    Ready,
837    Error(Error),
838    Complete,
839    Waiting(EvaluationWaiting<R>),
840}
841
842#[derive(Debug)]
843enum EvaluationWaiting<R: Reader> {
844    Memory,
845    Register { offset: i64 },
846    FrameBase { offset: i64 },
847    Tls,
848    Cfa,
849    AtLocation,
850    EntryValue,
851    ParameterRef,
852    RelocatedAddress,
853    IndexedAddress,
854    TypedLiteral { value: R },
855    Convert,
856    Reinterpret,
857}
858
859/// The state of an `Evaluation` after evaluating a DWARF expression.
860/// The evaluation is either `Complete`, or it requires more data
861/// to continue, as described by the variant.
862#[derive(Debug, PartialEq)]
863pub enum EvaluationResult<R: Reader> {
864    /// The `Evaluation` is complete, and `Evaluation::result()` can be called.
865    Complete,
866    /// The `Evaluation` needs a value from memory to proceed further.  Once the
867    /// caller determines what value to provide it should resume the `Evaluation`
868    /// by calling `Evaluation::resume_with_memory`.
869    RequiresMemory {
870        /// The address of the value required.
871        address: u64,
872        /// The size of the value required. This is guaranteed to be at most the
873        /// word size of the target architecture.
874        size: u8,
875        /// If not `None`, a target-specific address space value.
876        space: Option<u64>,
877        /// The DIE of the base type or 0 to indicate the generic type
878        base_type: UnitOffset<R::Offset>,
879    },
880    /// The `Evaluation` needs a value from a register to proceed further.  Once
881    /// the caller determines what value to provide it should resume the
882    /// `Evaluation` by calling `Evaluation::resume_with_register`.
883    RequiresRegister {
884        /// The register number.
885        register: Register,
886        /// The DIE of the base type or 0 to indicate the generic type
887        base_type: UnitOffset<R::Offset>,
888    },
889    /// The `Evaluation` needs the frame base address to proceed further.  Once
890    /// the caller determines what value to provide it should resume the
891    /// `Evaluation` by calling `Evaluation::resume_with_frame_base`.  The frame
892    /// base address is the address produced by the location description in the
893    /// `DW_AT_frame_base` attribute of the current function.
894    RequiresFrameBase,
895    /// The `Evaluation` needs a value from TLS to proceed further.  Once the
896    /// caller determines what value to provide it should resume the
897    /// `Evaluation` by calling `Evaluation::resume_with_tls`.
898    RequiresTls(u64),
899    /// The `Evaluation` needs the CFA to proceed further.  Once the caller
900    /// determines what value to provide it should resume the `Evaluation` by
901    /// calling `Evaluation::resume_with_call_frame_cfa`.
902    RequiresCallFrameCfa,
903    /// The `Evaluation` needs the DWARF expression at the given location to
904    /// proceed further.  Once the caller determines what value to provide it
905    /// should resume the `Evaluation` by calling
906    /// `Evaluation::resume_with_at_location`.
907    RequiresAtLocation(DieReference<R::Offset>),
908    /// The `Evaluation` needs the value produced by evaluating a DWARF
909    /// expression at the entry point of the current subprogram.  Once the
910    /// caller determines what value to provide it should resume the
911    /// `Evaluation` by calling `Evaluation::resume_with_entry_value`.
912    RequiresEntryValue(Expression<R>),
913    /// The `Evaluation` needs the value of the parameter at the given location
914    /// in the current function's caller.  Once the caller determines what value
915    /// to provide it should resume the `Evaluation` by calling
916    /// `Evaluation::resume_with_parameter_ref`.
917    RequiresParameterRef(UnitOffset<R::Offset>),
918    /// The `Evaluation` needs an address to be relocated to proceed further.
919    /// Once the caller determines what value to provide it should resume the
920    /// `Evaluation` by calling `Evaluation::resume_with_relocated_address`.
921    RequiresRelocatedAddress(u64),
922    /// The `Evaluation` needs an address from the `.debug_addr` section.
923    /// This address may also need to be relocated.
924    /// Once the caller determines what value to provide it should resume the
925    /// `Evaluation` by calling `Evaluation::resume_with_indexed_address`.
926    RequiresIndexedAddress {
927        /// The index of the address in the `.debug_addr` section,
928        /// relative to the `DW_AT_addr_base` of the compilation unit.
929        index: DebugAddrIndex<R::Offset>,
930        /// Whether the address also needs to be relocated.
931        relocate: bool,
932    },
933    /// The `Evaluation` needs the `ValueType` for the base type DIE at
934    /// the give unit offset.  Once the caller determines what value to provide it
935    /// should resume the `Evaluation` by calling
936    /// `Evaluation::resume_with_base_type`.
937    RequiresBaseType(UnitOffset<R::Offset>),
938}
939
940/// The bytecode for a DWARF expression or location description.
941#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
942pub struct Expression<R: Reader>(pub R);
943
944impl<R: Reader> Expression<R> {
945    /// Create an evaluation for this expression.
946    ///
947    /// The `encoding` is determined by the
948    /// [`CompilationUnitHeader`](struct.CompilationUnitHeader.html) or
949    /// [`TypeUnitHeader`](struct.TypeUnitHeader.html) that this expression
950    /// relates to.
951    ///
952    /// # Examples
953    /// ```rust,no_run
954    /// use gimli::Expression;
955    /// # let endian = gimli::LittleEndian;
956    /// # let debug_info = gimli::DebugInfo::from(gimli::EndianSlice::new(&[], endian));
957    /// # let unit = debug_info.units().next().unwrap().unwrap();
958    /// # let bytecode = gimli::EndianSlice::new(&[], endian);
959    /// let expression = gimli::Expression(bytecode);
960    /// let mut eval = expression.evaluation(unit.encoding());
961    /// let mut result = eval.evaluate().unwrap();
962    /// ```
963    #[cfg(feature = "read")]
964    #[inline]
965    pub fn evaluation(self, encoding: Encoding) -> Evaluation<R> {
966        Evaluation::new(self.0, encoding)
967    }
968
969    /// Return an iterator for the operations in the expression.
970    pub fn operations(self, encoding: Encoding) -> OperationIter<R> {
971        OperationIter {
972            input: self.0,
973            encoding,
974        }
975    }
976}
977
978/// An iterator for the operations in an expression.
979#[derive(Debug, Clone, Copy)]
980pub struct OperationIter<R: Reader> {
981    input: R,
982    encoding: Encoding,
983}
984
985impl<R: Reader> OperationIter<R> {
986    /// Read the next operation in an expression.
987    pub fn next(&mut self) -> Result<Option<Operation<R>>> {
988        if self.input.is_empty() {
989            return Ok(None);
990        }
991        match Operation::parse(&mut self.input, self.encoding) {
992            Ok(op) => Ok(Some(op)),
993            Err(e) => {
994                self.input.empty();
995                Err(e)
996            }
997        }
998    }
999
1000    /// Return the current byte offset of the iterator.
1001    pub fn offset_from(&self, expression: &Expression<R>) -> R::Offset {
1002        self.input.offset_from(&expression.0)
1003    }
1004}
1005
1006#[cfg(feature = "fallible-iterator")]
1007impl<R: Reader> fallible_iterator::FallibleIterator for OperationIter<R> {
1008    type Item = Operation<R>;
1009    type Error = Error;
1010
1011    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
1012        OperationIter::next(self)
1013    }
1014}
1015
1016impl<R: Reader> Iterator for OperationIter<R> {
1017    type Item = Result<Operation<R>>;
1018
1019    fn next(&mut self) -> Option<Self::Item> {
1020        OperationIter::next(self).transpose()
1021    }
1022}
1023
1024/// Specification of what storage should be used for [`Evaluation`].
1025///
1026#[cfg_attr(
1027    feature = "read",
1028    doc = "
1029Normally you would only need to use [`StoreOnHeap`], which places the stacks and the results
1030on the heap using [`Vec`]. This is the default storage type parameter for [`Evaluation`].
1031"
1032)]
1033///
1034/// If you need to avoid [`Evaluation`] from allocating memory, e.g. for signal safety,
1035/// you can provide you own storage specification:
1036/// ```rust,no_run
1037/// # use gimli::*;
1038/// # let bytecode = EndianSlice::new(&[], LittleEndian);
1039/// # let encoding = unimplemented!();
1040/// # let get_register_value = |_, _| Value::Generic(42);
1041/// # let get_frame_base = || 0xdeadbeef;
1042/// #
1043/// struct StoreOnStack;
1044///
1045/// impl<R: Reader> EvaluationStorage<R> for StoreOnStack {
1046///     type Stack = [Value; 64];
1047///     type ExpressionStack = [(R, R); 4];
1048///     type Result = [Piece<R>; 1];
1049/// }
1050///
1051/// let mut eval = Evaluation::<_, StoreOnStack>::new_in(bytecode, encoding);
1052/// let mut result = eval.evaluate().unwrap();
1053/// while result != EvaluationResult::Complete {
1054///   match result {
1055///     EvaluationResult::RequiresRegister { register, base_type } => {
1056///       let value = get_register_value(register, base_type);
1057///       result = eval.resume_with_register(value).unwrap();
1058///     },
1059///     EvaluationResult::RequiresFrameBase => {
1060///       let frame_base = get_frame_base();
1061///       result = eval.resume_with_frame_base(frame_base).unwrap();
1062///     },
1063///     _ => unimplemented!(),
1064///   };
1065/// }
1066///
1067/// let result = eval.as_result();
1068/// println!("{:?}", result);
1069/// ```
1070pub trait EvaluationStorage<R: Reader> {
1071    /// The storage used for the evaluation stack.
1072    type Stack: ArrayLike<Item = Value>;
1073    /// The storage used for the expression stack.
1074    type ExpressionStack: ArrayLike<Item = (R, R)>;
1075    /// The storage used for the results.
1076    type Result: ArrayLike<Item = Piece<R>>;
1077}
1078
1079#[cfg(feature = "read")]
1080impl<R: Reader> EvaluationStorage<R> for StoreOnHeap {
1081    type Stack = Vec<Value>;
1082    type ExpressionStack = Vec<(R, R)>;
1083    type Result = Vec<Piece<R>>;
1084}
1085
1086/// A DWARF expression evaluator.
1087///
1088/// # Usage
1089/// A DWARF expression may require additional data to produce a final result,
1090/// such as the value of a register or a memory location.  Once initial setup
1091/// is complete (i.e. `set_initial_value()`, `set_object_address()`) the
1092/// consumer calls the `evaluate()` method.  That returns an `EvaluationResult`,
1093/// which is either `EvaluationResult::Complete` or a value indicating what
1094/// data is needed to resume the `Evaluation`.  The consumer is responsible for
1095/// producing that data and resuming the computation with the correct method,
1096/// as documented for `EvaluationResult`.  Only once an `EvaluationResult::Complete`
1097/// is returned can the consumer call `result()`.
1098///
1099/// This design allows the consumer of `Evaluation` to decide how and when to
1100/// produce the required data and resume the computation.  The `Evaluation` can
1101/// be driven synchronously (as shown below) or by some asynchronous mechanism
1102/// such as futures.
1103///
1104/// # Examples
1105/// ```rust,no_run
1106/// use gimli::{Evaluation, EvaluationResult, Expression};
1107/// # let bytecode = gimli::EndianSlice::new(&[], gimli::LittleEndian);
1108/// # let encoding = unimplemented!();
1109/// # let get_register_value = |_, _| gimli::Value::Generic(42);
1110/// # let get_frame_base = || 0xdeadbeef;
1111///
1112/// let mut eval = Evaluation::new(bytecode, encoding);
1113/// let mut result = eval.evaluate().unwrap();
1114/// while result != EvaluationResult::Complete {
1115///   match result {
1116///     EvaluationResult::RequiresRegister { register, base_type } => {
1117///       let value = get_register_value(register, base_type);
1118///       result = eval.resume_with_register(value).unwrap();
1119///     },
1120///     EvaluationResult::RequiresFrameBase => {
1121///       let frame_base = get_frame_base();
1122///       result = eval.resume_with_frame_base(frame_base).unwrap();
1123///     },
1124///     _ => unimplemented!(),
1125///   };
1126/// }
1127///
1128/// let result = eval.result();
1129/// println!("{:?}", result);
1130/// ```
1131#[derive(Debug)]
1132pub struct Evaluation<R: Reader, S: EvaluationStorage<R> = StoreOnHeap> {
1133    bytecode: R,
1134    encoding: Encoding,
1135    object_address: Option<u64>,
1136    max_iterations: Option<u32>,
1137    iteration: u32,
1138    state: EvaluationState<R>,
1139
1140    // Stack operations are done on word-sized values.  We do all
1141    // operations on 64-bit values, and then mask the results
1142    // appropriately when popping.
1143    addr_mask: u64,
1144
1145    // The stack.
1146    stack: ArrayVec<S::Stack>,
1147
1148    // The next operation to decode and evaluate.
1149    pc: R,
1150
1151    // If we see a DW_OP_call* operation, the previous PC and bytecode
1152    // is stored here while evaluating the subroutine.
1153    expression_stack: ArrayVec<S::ExpressionStack>,
1154
1155    value_result: Option<Value>,
1156    result: ArrayVec<S::Result>,
1157}
1158
1159#[cfg(feature = "read")]
1160impl<R: Reader> Evaluation<R> {
1161    /// Create a new DWARF expression evaluator.
1162    ///
1163    /// The new evaluator is created without an initial value, without
1164    /// an object address, and without a maximum number of iterations.
1165    pub fn new(bytecode: R, encoding: Encoding) -> Self {
1166        Self::new_in(bytecode, encoding)
1167    }
1168
1169    /// Get the result of this `Evaluation`.
1170    ///
1171    /// # Panics
1172    /// Panics if this `Evaluation` has not been driven to completion.
1173    pub fn result(self) -> Vec<Piece<R>> {
1174        match self.state {
1175            EvaluationState::Complete => self.result.into_vec(),
1176            _ => {
1177                panic!("Called `Evaluation::result` on an `Evaluation` that has not been completed")
1178            }
1179        }
1180    }
1181}
1182
1183impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S> {
1184    /// Create a new DWARF expression evaluator.
1185    ///
1186    /// The new evaluator is created without an initial value, without
1187    /// an object address, and without a maximum number of iterations.
1188    pub fn new_in(bytecode: R, encoding: Encoding) -> Self {
1189        let pc = bytecode.clone();
1190        Evaluation {
1191            bytecode,
1192            encoding,
1193            object_address: None,
1194            max_iterations: None,
1195            iteration: 0,
1196            state: EvaluationState::Start(None),
1197            addr_mask: if encoding.address_size == 8 {
1198                !0u64
1199            } else {
1200                (1 << (8 * u64::from(encoding.address_size))) - 1
1201            },
1202            stack: Default::default(),
1203            expression_stack: Default::default(),
1204            pc,
1205            value_result: None,
1206            result: Default::default(),
1207        }
1208    }
1209
1210    /// Set an initial value to be pushed on the DWARF expression
1211    /// evaluator's stack.  This can be used in cases like
1212    /// `DW_AT_vtable_elem_location`, which require a value on the
1213    /// stack before evaluation commences.  If no initial value is
1214    /// set, and the expression uses an opcode requiring the initial
1215    /// value, then evaluation will fail with an error.
1216    ///
1217    /// # Panics
1218    /// Panics if `set_initial_value()` has already been called, or if
1219    /// `evaluate()` has already been called.
1220    pub fn set_initial_value(&mut self, value: u64) {
1221        match self.state {
1222            EvaluationState::Start(None) => {
1223                self.state = EvaluationState::Start(Some(value));
1224            }
1225            _ => panic!(
1226                "`Evaluation::set_initial_value` was called twice, or after evaluation began."
1227            ),
1228        };
1229    }
1230
1231    /// Set the enclosing object's address, as used by
1232    /// `DW_OP_push_object_address`.  If no object address is set, and
1233    /// the expression uses an opcode requiring the object address,
1234    /// then evaluation will fail with an error.
1235    pub fn set_object_address(&mut self, value: u64) {
1236        self.object_address = Some(value);
1237    }
1238
1239    /// Set the maximum number of iterations to be allowed by the
1240    /// expression evaluator.
1241    ///
1242    /// An iteration corresponds approximately to the evaluation of a
1243    /// single operation in an expression ("approximately" because the
1244    /// implementation may allow two such operations in some cases).
1245    /// The default is not to have a maximum; once set, it's not
1246    /// possible to go back to this default state.  This value can be
1247    /// set to avoid denial of service attacks by bad DWARF bytecode.
1248    pub fn set_max_iterations(&mut self, value: u32) {
1249        self.max_iterations = Some(value);
1250    }
1251
1252    fn pop(&mut self) -> Result<Value> {
1253        match self.stack.pop() {
1254            Some(value) => Ok(value),
1255            None => Err(Error::NotEnoughStackItems),
1256        }
1257    }
1258
1259    fn push(&mut self, value: Value) -> Result<()> {
1260        self.stack.try_push(value).map_err(|_| Error::StackFull)
1261    }
1262
1263    fn evaluate_one_operation(&mut self) -> Result<OperationEvaluationResult<R>> {
1264        let operation = Operation::parse(&mut self.pc, self.encoding)?;
1265
1266        match operation {
1267            Operation::Deref {
1268                base_type,
1269                size,
1270                space,
1271            } => {
1272                if size > self.encoding.address_size {
1273                    return Err(Error::InvalidDerefSize(size));
1274                }
1275                let entry = self.pop()?;
1276                let addr = entry.to_u64(self.addr_mask)?;
1277                let addr_space = if space {
1278                    let entry = self.pop()?;
1279                    let value = entry.to_u64(self.addr_mask)?;
1280                    Some(value)
1281                } else {
1282                    None
1283                };
1284                return Ok(OperationEvaluationResult::Waiting(
1285                    EvaluationWaiting::Memory,
1286                    EvaluationResult::RequiresMemory {
1287                        address: addr,
1288                        size,
1289                        space: addr_space,
1290                        base_type,
1291                    },
1292                ));
1293            }
1294
1295            Operation::Drop => {
1296                self.pop()?;
1297            }
1298            Operation::Pick { index } => {
1299                let len = self.stack.len();
1300                let index = index as usize;
1301                if index >= len {
1302                    return Err(Error::NotEnoughStackItems);
1303                }
1304                let value = self.stack[len - index - 1];
1305                self.push(value)?;
1306            }
1307            Operation::Swap => {
1308                let top = self.pop()?;
1309                let next = self.pop()?;
1310                self.push(top)?;
1311                self.push(next)?;
1312            }
1313            Operation::Rot => {
1314                let one = self.pop()?;
1315                let two = self.pop()?;
1316                let three = self.pop()?;
1317                self.push(one)?;
1318                self.push(three)?;
1319                self.push(two)?;
1320            }
1321
1322            Operation::Abs => {
1323                let value = self.pop()?;
1324                let result = value.abs(self.addr_mask)?;
1325                self.push(result)?;
1326            }
1327            Operation::And => {
1328                let rhs = self.pop()?;
1329                let lhs = self.pop()?;
1330                let result = lhs.and(rhs, self.addr_mask)?;
1331                self.push(result)?;
1332            }
1333            Operation::Div => {
1334                let rhs = self.pop()?;
1335                let lhs = self.pop()?;
1336                let result = lhs.div(rhs, self.addr_mask)?;
1337                self.push(result)?;
1338            }
1339            Operation::Minus => {
1340                let rhs = self.pop()?;
1341                let lhs = self.pop()?;
1342                let result = lhs.sub(rhs, self.addr_mask)?;
1343                self.push(result)?;
1344            }
1345            Operation::Mod => {
1346                let rhs = self.pop()?;
1347                let lhs = self.pop()?;
1348                let result = lhs.rem(rhs, self.addr_mask)?;
1349                self.push(result)?;
1350            }
1351            Operation::Mul => {
1352                let rhs = self.pop()?;
1353                let lhs = self.pop()?;
1354                let result = lhs.mul(rhs, self.addr_mask)?;
1355                self.push(result)?;
1356            }
1357            Operation::Neg => {
1358                let v = self.pop()?;
1359                let result = v.neg(self.addr_mask)?;
1360                self.push(result)?;
1361            }
1362            Operation::Not => {
1363                let value = self.pop()?;
1364                let result = value.not(self.addr_mask)?;
1365                self.push(result)?;
1366            }
1367            Operation::Or => {
1368                let rhs = self.pop()?;
1369                let lhs = self.pop()?;
1370                let result = lhs.or(rhs, self.addr_mask)?;
1371                self.push(result)?;
1372            }
1373            Operation::Plus => {
1374                let rhs = self.pop()?;
1375                let lhs = self.pop()?;
1376                let result = lhs.add(rhs, self.addr_mask)?;
1377                self.push(result)?;
1378            }
1379            Operation::PlusConstant { value } => {
1380                let lhs = self.pop()?;
1381                let rhs = Value::from_u64(lhs.value_type(), value)?;
1382                let result = lhs.add(rhs, self.addr_mask)?;
1383                self.push(result)?;
1384            }
1385            Operation::Shl => {
1386                let rhs = self.pop()?;
1387                let lhs = self.pop()?;
1388                let result = lhs.shl(rhs, self.addr_mask)?;
1389                self.push(result)?;
1390            }
1391            Operation::Shr => {
1392                let rhs = self.pop()?;
1393                let lhs = self.pop()?;
1394                let result = lhs.shr(rhs, self.addr_mask)?;
1395                self.push(result)?;
1396            }
1397            Operation::Shra => {
1398                let rhs = self.pop()?;
1399                let lhs = self.pop()?;
1400                let result = lhs.shra(rhs, self.addr_mask)?;
1401                self.push(result)?;
1402            }
1403            Operation::Xor => {
1404                let rhs = self.pop()?;
1405                let lhs = self.pop()?;
1406                let result = lhs.xor(rhs, self.addr_mask)?;
1407                self.push(result)?;
1408            }
1409
1410            Operation::Bra { target } => {
1411                let entry = self.pop()?;
1412                let v = entry.to_u64(self.addr_mask)?;
1413                if v != 0 {
1414                    self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
1415                }
1416            }
1417
1418            Operation::Eq => {
1419                let rhs = self.pop()?;
1420                let lhs = self.pop()?;
1421                let result = lhs.eq(rhs, self.addr_mask)?;
1422                self.push(result)?;
1423            }
1424            Operation::Ge => {
1425                let rhs = self.pop()?;
1426                let lhs = self.pop()?;
1427                let result = lhs.ge(rhs, self.addr_mask)?;
1428                self.push(result)?;
1429            }
1430            Operation::Gt => {
1431                let rhs = self.pop()?;
1432                let lhs = self.pop()?;
1433                let result = lhs.gt(rhs, self.addr_mask)?;
1434                self.push(result)?;
1435            }
1436            Operation::Le => {
1437                let rhs = self.pop()?;
1438                let lhs = self.pop()?;
1439                let result = lhs.le(rhs, self.addr_mask)?;
1440                self.push(result)?;
1441            }
1442            Operation::Lt => {
1443                let rhs = self.pop()?;
1444                let lhs = self.pop()?;
1445                let result = lhs.lt(rhs, self.addr_mask)?;
1446                self.push(result)?;
1447            }
1448            Operation::Ne => {
1449                let rhs = self.pop()?;
1450                let lhs = self.pop()?;
1451                let result = lhs.ne(rhs, self.addr_mask)?;
1452                self.push(result)?;
1453            }
1454
1455            Operation::Skip { target } => {
1456                self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
1457            }
1458
1459            Operation::UnsignedConstant { value } => {
1460                self.push(Value::Generic(value))?;
1461            }
1462
1463            Operation::SignedConstant { value } => {
1464                self.push(Value::Generic(value as u64))?;
1465            }
1466
1467            Operation::RegisterOffset {
1468                register,
1469                offset,
1470                base_type,
1471            } => {
1472                return Ok(OperationEvaluationResult::Waiting(
1473                    EvaluationWaiting::Register { offset },
1474                    EvaluationResult::RequiresRegister {
1475                        register,
1476                        base_type,
1477                    },
1478                ));
1479            }
1480
1481            Operation::FrameOffset { offset } => {
1482                return Ok(OperationEvaluationResult::Waiting(
1483                    EvaluationWaiting::FrameBase { offset },
1484                    EvaluationResult::RequiresFrameBase,
1485                ));
1486            }
1487
1488            Operation::Nop => {}
1489
1490            Operation::PushObjectAddress => {
1491                if let Some(value) = self.object_address {
1492                    self.push(Value::Generic(value))?;
1493                } else {
1494                    return Err(Error::InvalidPushObjectAddress);
1495                }
1496            }
1497
1498            Operation::Call { offset } => {
1499                return Ok(OperationEvaluationResult::Waiting(
1500                    EvaluationWaiting::AtLocation,
1501                    EvaluationResult::RequiresAtLocation(offset),
1502                ));
1503            }
1504
1505            Operation::TLS => {
1506                let entry = self.pop()?;
1507                let index = entry.to_u64(self.addr_mask)?;
1508                return Ok(OperationEvaluationResult::Waiting(
1509                    EvaluationWaiting::Tls,
1510                    EvaluationResult::RequiresTls(index),
1511                ));
1512            }
1513
1514            Operation::CallFrameCFA => {
1515                return Ok(OperationEvaluationResult::Waiting(
1516                    EvaluationWaiting::Cfa,
1517                    EvaluationResult::RequiresCallFrameCfa,
1518                ));
1519            }
1520
1521            Operation::Register { register } => {
1522                let location = Location::Register { register };
1523                return Ok(OperationEvaluationResult::Complete { location });
1524            }
1525
1526            Operation::ImplicitValue { ref data } => {
1527                let location = Location::Bytes {
1528                    value: data.clone(),
1529                };
1530                return Ok(OperationEvaluationResult::Complete { location });
1531            }
1532
1533            Operation::StackValue => {
1534                let value = self.pop()?;
1535                let location = Location::Value { value };
1536                return Ok(OperationEvaluationResult::Complete { location });
1537            }
1538
1539            Operation::ImplicitPointer { value, byte_offset } => {
1540                let location = Location::ImplicitPointer { value, byte_offset };
1541                return Ok(OperationEvaluationResult::Complete { location });
1542            }
1543
1544            Operation::EntryValue { ref expression } => {
1545                return Ok(OperationEvaluationResult::Waiting(
1546                    EvaluationWaiting::EntryValue,
1547                    EvaluationResult::RequiresEntryValue(Expression(expression.clone())),
1548                ));
1549            }
1550
1551            Operation::ParameterRef { offset } => {
1552                return Ok(OperationEvaluationResult::Waiting(
1553                    EvaluationWaiting::ParameterRef,
1554                    EvaluationResult::RequiresParameterRef(offset),
1555                ));
1556            }
1557
1558            Operation::Address { address } => {
1559                return Ok(OperationEvaluationResult::Waiting(
1560                    EvaluationWaiting::RelocatedAddress,
1561                    EvaluationResult::RequiresRelocatedAddress(address),
1562                ));
1563            }
1564
1565            Operation::AddressIndex { index } => {
1566                return Ok(OperationEvaluationResult::Waiting(
1567                    EvaluationWaiting::IndexedAddress,
1568                    EvaluationResult::RequiresIndexedAddress {
1569                        index,
1570                        relocate: true,
1571                    },
1572                ));
1573            }
1574
1575            Operation::ConstantIndex { index } => {
1576                return Ok(OperationEvaluationResult::Waiting(
1577                    EvaluationWaiting::IndexedAddress,
1578                    EvaluationResult::RequiresIndexedAddress {
1579                        index,
1580                        relocate: false,
1581                    },
1582                ));
1583            }
1584
1585            Operation::Piece {
1586                size_in_bits,
1587                bit_offset,
1588            } => {
1589                let location = if self.stack.is_empty() {
1590                    Location::Empty
1591                } else {
1592                    let entry = self.pop()?;
1593                    let address = entry.to_u64(self.addr_mask)?;
1594                    Location::Address { address }
1595                };
1596                self.result
1597                    .try_push(Piece {
1598                        size_in_bits: Some(size_in_bits),
1599                        bit_offset,
1600                        location,
1601                    })
1602                    .map_err(|_| Error::StackFull)?;
1603                return Ok(OperationEvaluationResult::Piece);
1604            }
1605
1606            Operation::TypedLiteral { base_type, value } => {
1607                return Ok(OperationEvaluationResult::Waiting(
1608                    EvaluationWaiting::TypedLiteral { value },
1609                    EvaluationResult::RequiresBaseType(base_type),
1610                ));
1611            }
1612            Operation::Convert { base_type } => {
1613                return Ok(OperationEvaluationResult::Waiting(
1614                    EvaluationWaiting::Convert,
1615                    EvaluationResult::RequiresBaseType(base_type),
1616                ));
1617            }
1618            Operation::Reinterpret { base_type } => {
1619                return Ok(OperationEvaluationResult::Waiting(
1620                    EvaluationWaiting::Reinterpret,
1621                    EvaluationResult::RequiresBaseType(base_type),
1622                ));
1623            }
1624            Operation::VariableValue { .. }
1625            | Operation::Uninitialized
1626            | Operation::WasmLocal { .. }
1627            | Operation::WasmGlobal { .. }
1628            | Operation::WasmStack { .. } => {
1629                return Err(Error::UnsupportedEvaluation);
1630            }
1631        }
1632
1633        Ok(OperationEvaluationResult::Incomplete)
1634    }
1635
1636    /// Get the result if this is an evaluation for a value.
1637    ///
1638    /// Returns `None` if the evaluation contained operations that are only
1639    /// valid for location descriptions.
1640    ///
1641    /// # Panics
1642    /// Panics if this `Evaluation` has not been driven to completion.
1643    pub fn value_result(&self) -> Option<Value> {
1644        match self.state {
1645            EvaluationState::Complete => self.value_result,
1646            _ => {
1647                panic!(
1648                    "Called `Evaluation::value_result` on an `Evaluation` that has not been completed"
1649                )
1650            }
1651        }
1652    }
1653
1654    /// Get the result of this `Evaluation`.
1655    ///
1656    /// # Panics
1657    /// Panics if this `Evaluation` has not been driven to completion.
1658    pub fn as_result(&self) -> &[Piece<R>] {
1659        match self.state {
1660            EvaluationState::Complete => &self.result,
1661            _ => {
1662                panic!(
1663                    "Called `Evaluation::as_result` on an `Evaluation` that has not been completed"
1664                )
1665            }
1666        }
1667    }
1668
1669    /// Evaluate a DWARF expression.  This method should only ever be called
1670    /// once.  If the returned `EvaluationResult` is not
1671    /// `EvaluationResult::Complete`, the caller should provide the required
1672    /// value and resume the evaluation by calling the appropriate resume_with
1673    /// method on `Evaluation`.
1674    pub fn evaluate(&mut self) -> Result<EvaluationResult<R>> {
1675        match self.state {
1676            EvaluationState::Start(initial_value) => {
1677                if let Some(value) = initial_value {
1678                    self.push(Value::Generic(value))?;
1679                }
1680                self.state = EvaluationState::Ready;
1681            }
1682            EvaluationState::Ready => {}
1683            EvaluationState::Error(err) => return Err(err),
1684            EvaluationState::Complete => return Ok(EvaluationResult::Complete),
1685            EvaluationState::Waiting(_) => panic!(),
1686        };
1687
1688        match self.evaluate_internal() {
1689            Ok(r) => Ok(r),
1690            Err(e) => {
1691                self.state = EvaluationState::Error(e);
1692                Err(e)
1693            }
1694        }
1695    }
1696
1697    /// Resume the `Evaluation` with the provided memory `value`.  This will apply
1698    /// the provided memory value to the evaluation and continue evaluating
1699    /// opcodes until the evaluation is completed, reaches an error, or needs
1700    /// more information again.
1701    ///
1702    /// # Panics
1703    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresMemory`.
1704    pub fn resume_with_memory(&mut self, value: Value) -> Result<EvaluationResult<R>> {
1705        match self.state {
1706            EvaluationState::Error(err) => return Err(err),
1707            EvaluationState::Waiting(EvaluationWaiting::Memory) => {
1708                self.push(value)?;
1709            }
1710            _ => panic!(
1711                "Called `Evaluation::resume_with_memory` without a preceding `EvaluationResult::RequiresMemory`"
1712            ),
1713        };
1714
1715        self.evaluate_internal()
1716    }
1717
1718    /// Resume the `Evaluation` with the provided `register` value.  This will apply
1719    /// the provided register value to the evaluation and continue evaluating
1720    /// opcodes until the evaluation is completed, reaches an error, or needs
1721    /// more information again.
1722    ///
1723    /// # Panics
1724    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresRegister`.
1725    pub fn resume_with_register(&mut self, value: Value) -> Result<EvaluationResult<R>> {
1726        match self.state {
1727            EvaluationState::Error(err) => return Err(err),
1728            EvaluationState::Waiting(EvaluationWaiting::Register { offset }) => {
1729                let offset = Value::from_u64(value.value_type(), offset as u64)?;
1730                let value = value.add(offset, self.addr_mask)?;
1731                self.push(value)?;
1732            }
1733            _ => panic!(
1734                "Called `Evaluation::resume_with_register` without a preceding `EvaluationResult::RequiresRegister`"
1735            ),
1736        };
1737
1738        self.evaluate_internal()
1739    }
1740
1741    /// Resume the `Evaluation` with the provided `frame_base`.  This will
1742    /// apply the provided frame base value to the evaluation and continue
1743    /// evaluating opcodes until the evaluation is completed, reaches an error,
1744    /// or needs more information again.
1745    ///
1746    /// # Panics
1747    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresFrameBase`.
1748    pub fn resume_with_frame_base(&mut self, frame_base: u64) -> Result<EvaluationResult<R>> {
1749        match self.state {
1750            EvaluationState::Error(err) => return Err(err),
1751            EvaluationState::Waiting(EvaluationWaiting::FrameBase { offset }) => {
1752                self.push(Value::Generic(frame_base.wrapping_add(offset as u64)))?;
1753            }
1754            _ => panic!(
1755                "Called `Evaluation::resume_with_frame_base` without a preceding `EvaluationResult::RequiresFrameBase`"
1756            ),
1757        };
1758
1759        self.evaluate_internal()
1760    }
1761
1762    /// Resume the `Evaluation` with the provided `value`.  This will apply
1763    /// the provided TLS value to the evaluation and continue evaluating
1764    /// opcodes until the evaluation is completed, reaches an error, or needs
1765    /// more information again.
1766    ///
1767    /// # Panics
1768    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresTls`.
1769    pub fn resume_with_tls(&mut self, value: u64) -> Result<EvaluationResult<R>> {
1770        match self.state {
1771            EvaluationState::Error(err) => return Err(err),
1772            EvaluationState::Waiting(EvaluationWaiting::Tls) => {
1773                self.push(Value::Generic(value))?;
1774            }
1775            _ => panic!(
1776                "Called `Evaluation::resume_with_tls` without a preceding `EvaluationResult::RequiresTls`"
1777            ),
1778        };
1779
1780        self.evaluate_internal()
1781    }
1782
1783    /// Resume the `Evaluation` with the provided `cfa`.  This will
1784    /// apply the provided CFA value to the evaluation and continue evaluating
1785    /// opcodes until the evaluation is completed, reaches an error, or needs
1786    /// more information again.
1787    ///
1788    /// # Panics
1789    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresCallFrameCfa`.
1790    pub fn resume_with_call_frame_cfa(&mut self, cfa: u64) -> Result<EvaluationResult<R>> {
1791        match self.state {
1792            EvaluationState::Error(err) => return Err(err),
1793            EvaluationState::Waiting(EvaluationWaiting::Cfa) => {
1794                self.push(Value::Generic(cfa))?;
1795            }
1796            _ => panic!(
1797                "Called `Evaluation::resume_with_call_frame_cfa` without a preceding `EvaluationResult::RequiresCallFrameCfa`"
1798            ),
1799        };
1800
1801        self.evaluate_internal()
1802    }
1803
1804    /// Resume the `Evaluation` with the provided `bytes`.  This will
1805    /// continue processing the evaluation with the new expression provided
1806    /// until the evaluation is completed, reaches an error, or needs more
1807    /// information again.
1808    ///
1809    /// # Panics
1810    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresAtLocation`.
1811    pub fn resume_with_at_location(&mut self, mut bytes: R) -> Result<EvaluationResult<R>> {
1812        match self.state {
1813            EvaluationState::Error(err) => return Err(err),
1814            EvaluationState::Waiting(EvaluationWaiting::AtLocation) => {
1815                if !bytes.is_empty() {
1816                    let mut pc = bytes.clone();
1817                    mem::swap(&mut pc, &mut self.pc);
1818                    mem::swap(&mut bytes, &mut self.bytecode);
1819                    self.expression_stack
1820                        .try_push((pc, bytes))
1821                        .map_err(|_| Error::StackFull)?;
1822                }
1823            }
1824            _ => panic!(
1825                "Called `Evaluation::resume_with_at_location` without a precedeing `EvaluationResult::RequiresAtLocation`"
1826            ),
1827        };
1828
1829        self.evaluate_internal()
1830    }
1831
1832    /// Resume the `Evaluation` with the provided `entry_value`.  This will
1833    /// apply the provided entry value to the evaluation and continue evaluating
1834    /// opcodes until the evaluation is completed, reaches an error, or needs
1835    /// more information again.
1836    ///
1837    /// # Panics
1838    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresEntryValue`.
1839    pub fn resume_with_entry_value(&mut self, entry_value: Value) -> Result<EvaluationResult<R>> {
1840        match self.state {
1841            EvaluationState::Error(err) => return Err(err),
1842            EvaluationState::Waiting(EvaluationWaiting::EntryValue) => {
1843                self.push(entry_value)?;
1844            }
1845            _ => panic!(
1846                "Called `Evaluation::resume_with_entry_value` without a preceding `EvaluationResult::RequiresEntryValue`"
1847            ),
1848        };
1849
1850        self.evaluate_internal()
1851    }
1852
1853    /// Resume the `Evaluation` with the provided `parameter_value`.  This will
1854    /// apply the provided parameter value to the evaluation and continue evaluating
1855    /// opcodes until the evaluation is completed, reaches an error, or needs
1856    /// more information again.
1857    ///
1858    /// # Panics
1859    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresParameterRef`.
1860    pub fn resume_with_parameter_ref(
1861        &mut self,
1862        parameter_value: u64,
1863    ) -> Result<EvaluationResult<R>> {
1864        match self.state {
1865            EvaluationState::Error(err) => return Err(err),
1866            EvaluationState::Waiting(EvaluationWaiting::ParameterRef) => {
1867                self.push(Value::Generic(parameter_value))?;
1868            }
1869            _ => panic!(
1870                "Called `Evaluation::resume_with_parameter_ref` without a preceding `EvaluationResult::RequiresParameterRef`"
1871            ),
1872        };
1873
1874        self.evaluate_internal()
1875    }
1876
1877    /// Resume the `Evaluation` with the provided relocated `address`.  This will use the
1878    /// provided relocated address for the operation that required it, and continue evaluating
1879    /// opcodes until the evaluation is completed, reaches an error, or needs
1880    /// more information again.
1881    ///
1882    /// # Panics
1883    /// Panics if this `Evaluation` did not previously stop with
1884    /// `EvaluationResult::RequiresRelocatedAddress`.
1885    pub fn resume_with_relocated_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
1886        match self.state {
1887            EvaluationState::Error(err) => return Err(err),
1888            EvaluationState::Waiting(EvaluationWaiting::RelocatedAddress) => {
1889                self.push(Value::Generic(address))?;
1890            }
1891            _ => panic!(
1892                "Called `Evaluation::resume_with_relocated_address` without a preceding `EvaluationResult::RequiresRelocatedAddress`"
1893            ),
1894        };
1895
1896        self.evaluate_internal()
1897    }
1898
1899    /// Resume the `Evaluation` with the provided indexed `address`.  This will use the
1900    /// provided indexed address for the operation that required it, and continue evaluating
1901    /// opcodes until the evaluation is completed, reaches an error, or needs
1902    /// more information again.
1903    ///
1904    /// # Panics
1905    /// Panics if this `Evaluation` did not previously stop with
1906    /// `EvaluationResult::RequiresIndexedAddress`.
1907    pub fn resume_with_indexed_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
1908        match self.state {
1909            EvaluationState::Error(err) => return Err(err),
1910            EvaluationState::Waiting(EvaluationWaiting::IndexedAddress) => {
1911                self.push(Value::Generic(address))?;
1912            }
1913            _ => panic!(
1914                "Called `Evaluation::resume_with_indexed_address` without a preceding `EvaluationResult::RequiresIndexedAddress`"
1915            ),
1916        };
1917
1918        self.evaluate_internal()
1919    }
1920
1921    /// Resume the `Evaluation` with the provided `base_type`.  This will use the
1922    /// provided base type for the operation that required it, and continue evaluating
1923    /// opcodes until the evaluation is completed, reaches an error, or needs
1924    /// more information again.
1925    ///
1926    /// # Panics
1927    /// Panics if this `Evaluation` did not previously stop with `EvaluationResult::RequiresBaseType`.
1928    pub fn resume_with_base_type(&mut self, base_type: ValueType) -> Result<EvaluationResult<R>> {
1929        let value = match self.state {
1930            EvaluationState::Error(err) => return Err(err),
1931            EvaluationState::Waiting(EvaluationWaiting::TypedLiteral { ref value }) => {
1932                Value::parse(base_type, value.clone())?
1933            }
1934            EvaluationState::Waiting(EvaluationWaiting::Convert) => {
1935                let entry = self.pop()?;
1936                entry.convert(base_type, self.addr_mask)?
1937            }
1938            EvaluationState::Waiting(EvaluationWaiting::Reinterpret) => {
1939                let entry = self.pop()?;
1940                entry.reinterpret(base_type, self.addr_mask)?
1941            }
1942            _ => panic!(
1943                "Called `Evaluation::resume_with_base_type` without a preceding `EvaluationResult::RequiresBaseType`"
1944            ),
1945        };
1946        self.push(value)?;
1947        self.evaluate_internal()
1948    }
1949
1950    fn end_of_expression(&mut self) -> bool {
1951        while self.pc.is_empty() {
1952            match self.expression_stack.pop() {
1953                Some((newpc, newbytes)) => {
1954                    self.pc = newpc;
1955                    self.bytecode = newbytes;
1956                }
1957                None => return true,
1958            }
1959        }
1960        false
1961    }
1962
1963    fn evaluate_internal(&mut self) -> Result<EvaluationResult<R>> {
1964        while !self.end_of_expression() {
1965            self.iteration += 1;
1966            if let Some(max_iterations) = self.max_iterations
1967                && self.iteration > max_iterations
1968            {
1969                return Err(Error::TooManyIterations);
1970            }
1971
1972            let op_result = self.evaluate_one_operation()?;
1973            match op_result {
1974                OperationEvaluationResult::Piece => {}
1975                OperationEvaluationResult::Incomplete => {
1976                    if self.end_of_expression() && !self.result.is_empty() {
1977                        // We saw a piece earlier and then some
1978                        // unterminated piece.  It's not clear this is
1979                        // well-defined.
1980                        return Err(Error::InvalidPiece);
1981                    }
1982                }
1983                OperationEvaluationResult::Complete { location } => {
1984                    if self.end_of_expression() {
1985                        if !self.result.is_empty() {
1986                            // We saw a piece earlier and then some
1987                            // unterminated piece.  It's not clear this is
1988                            // well-defined.
1989                            return Err(Error::InvalidPiece);
1990                        }
1991                        self.result
1992                            .try_push(Piece {
1993                                size_in_bits: None,
1994                                bit_offset: None,
1995                                location,
1996                            })
1997                            .map_err(|_| Error::StackFull)?;
1998                    } else {
1999                        // If there are more operations, then the next operation must
2000                        // be a Piece.
2001                        match Operation::parse(&mut self.pc, self.encoding)? {
2002                            Operation::Piece {
2003                                size_in_bits,
2004                                bit_offset,
2005                            } => {
2006                                self.result
2007                                    .try_push(Piece {
2008                                        size_in_bits: Some(size_in_bits),
2009                                        bit_offset,
2010                                        location,
2011                                    })
2012                                    .map_err(|_| Error::StackFull)?;
2013                            }
2014                            _ => {
2015                                let value =
2016                                    self.bytecode.len().into_u64() - self.pc.len().into_u64() - 1;
2017                                return Err(Error::InvalidExpressionTerminator(value));
2018                            }
2019                        }
2020                    }
2021                }
2022                OperationEvaluationResult::Waiting(waiting, result) => {
2023                    self.state = EvaluationState::Waiting(waiting);
2024                    return Ok(result);
2025                }
2026            }
2027        }
2028
2029        // If no pieces have been seen, use the stack top as the
2030        // result.
2031        if self.result.is_empty() {
2032            let entry = self.pop()?;
2033            self.value_result = Some(entry);
2034            let addr = entry.to_u64(self.addr_mask)?;
2035            self.result
2036                .try_push(Piece {
2037                    size_in_bits: None,
2038                    bit_offset: None,
2039                    location: Location::Address { address: addr },
2040                })
2041                .map_err(|_| Error::StackFull)?;
2042        }
2043
2044        self.state = EvaluationState::Complete;
2045        Ok(EvaluationResult::Complete)
2046    }
2047}
2048
2049#[cfg(test)]
2050// Tests require leb128::write.
2051#[cfg(feature = "write")]
2052mod tests {
2053    use super::*;
2054    use crate::common::Format;
2055    use crate::constants;
2056    use crate::endianity::LittleEndian;
2057    use crate::leb128;
2058    use crate::read::{EndianSlice, Error, Result, UnitOffset};
2059    use crate::test_util::GimliSectionMethods;
2060    use test_assembler::{Endian, Section};
2061
2062    fn encoding4() -> Encoding {
2063        Encoding {
2064            format: Format::Dwarf32,
2065            version: 4,
2066            address_size: 4,
2067        }
2068    }
2069
2070    fn encoding8() -> Encoding {
2071        Encoding {
2072            format: Format::Dwarf64,
2073            version: 4,
2074            address_size: 8,
2075        }
2076    }
2077
2078    #[test]
2079    fn test_compute_pc() {
2080        // Contents don't matter for this test, just length.
2081        let bytes = [0, 1, 2, 3, 4];
2082        let bytecode = &bytes[..];
2083        let ebuf = &EndianSlice::new(bytecode, LittleEndian);
2084
2085        assert_eq!(compute_pc(ebuf, ebuf, 0), Ok(*ebuf));
2086        assert_eq!(
2087            compute_pc(ebuf, ebuf, -1),
2088            Err(Error::BadBranchTarget(usize::MAX as u64))
2089        );
2090        assert_eq!(compute_pc(ebuf, ebuf, 5), Ok(ebuf.range_from(5..)));
2091        assert_eq!(
2092            compute_pc(&ebuf.range_from(3..), ebuf, -2),
2093            Ok(ebuf.range_from(1..))
2094        );
2095        assert_eq!(
2096            compute_pc(&ebuf.range_from(2..), ebuf, 2),
2097            Ok(ebuf.range_from(4..))
2098        );
2099    }
2100
2101    fn check_op_parse_simple<'input>(
2102        input: &'input [u8],
2103        expect: &Operation<EndianSlice<'input, LittleEndian>>,
2104        encoding: Encoding,
2105    ) {
2106        let buf = EndianSlice::new(input, LittleEndian);
2107        let mut pc = buf;
2108        let value = Operation::parse(&mut pc, encoding);
2109        match value {
2110            Ok(val) => {
2111                assert_eq!(val, *expect);
2112                assert_eq!(pc.len(), 0);
2113            }
2114            _ => panic!("Unexpected result"),
2115        }
2116    }
2117
2118    fn check_op_parse_eof(input: &[u8], encoding: Encoding) {
2119        let buf = EndianSlice::new(input, LittleEndian);
2120        let mut pc = buf;
2121        match Operation::parse(&mut pc, encoding) {
2122            Err(Error::UnexpectedEof(id)) => {
2123                assert!(buf.lookup_offset_id(id).is_some());
2124            }
2125
2126            _ => panic!("Unexpected result"),
2127        }
2128    }
2129
2130    fn check_op_parse<F>(
2131        input: F,
2132        expect: &Operation<EndianSlice<'_, LittleEndian>>,
2133        encoding: Encoding,
2134    ) where
2135        F: Fn(Section) -> Section,
2136    {
2137        let input = input(Section::with_endian(Endian::Little))
2138            .get_contents()
2139            .unwrap();
2140        for i in 1..input.len() {
2141            check_op_parse_eof(&input[..i], encoding);
2142        }
2143        check_op_parse_simple(&input, expect, encoding);
2144    }
2145
2146    #[test]
2147    fn test_op_parse_onebyte() {
2148        // Doesn't matter for this test.
2149        let encoding = encoding4();
2150
2151        // Test all single-byte opcodes.
2152        #[rustfmt::skip]
2153        let inputs = [
2154            (
2155                constants::DW_OP_deref,
2156                Operation::Deref {
2157                    base_type: generic_type(),
2158                    size: encoding.address_size,
2159                    space: false,
2160                },
2161            ),
2162            (constants::DW_OP_dup, Operation::Pick { index: 0 }),
2163            (constants::DW_OP_drop, Operation::Drop),
2164            (constants::DW_OP_over, Operation::Pick { index: 1 }),
2165            (constants::DW_OP_swap, Operation::Swap),
2166            (constants::DW_OP_rot, Operation::Rot),
2167            (
2168                constants::DW_OP_xderef,
2169                Operation::Deref {
2170                    base_type: generic_type(),
2171                    size: encoding.address_size,
2172                    space: true,
2173                },
2174            ),
2175            (constants::DW_OP_abs, Operation::Abs),
2176            (constants::DW_OP_and, Operation::And),
2177            (constants::DW_OP_div, Operation::Div),
2178            (constants::DW_OP_minus, Operation::Minus),
2179            (constants::DW_OP_mod, Operation::Mod),
2180            (constants::DW_OP_mul, Operation::Mul),
2181            (constants::DW_OP_neg, Operation::Neg),
2182            (constants::DW_OP_not, Operation::Not),
2183            (constants::DW_OP_or, Operation::Or),
2184            (constants::DW_OP_plus, Operation::Plus),
2185            (constants::DW_OP_shl, Operation::Shl),
2186            (constants::DW_OP_shr, Operation::Shr),
2187            (constants::DW_OP_shra, Operation::Shra),
2188            (constants::DW_OP_xor, Operation::Xor),
2189            (constants::DW_OP_eq, Operation::Eq),
2190            (constants::DW_OP_ge, Operation::Ge),
2191            (constants::DW_OP_gt, Operation::Gt),
2192            (constants::DW_OP_le, Operation::Le),
2193            (constants::DW_OP_lt, Operation::Lt),
2194            (constants::DW_OP_ne, Operation::Ne),
2195            (constants::DW_OP_lit0, Operation::UnsignedConstant { value: 0 }),
2196            (constants::DW_OP_lit1, Operation::UnsignedConstant { value: 1 }),
2197            (constants::DW_OP_lit2, Operation::UnsignedConstant { value: 2 }),
2198            (constants::DW_OP_lit3, Operation::UnsignedConstant { value: 3 }),
2199            (constants::DW_OP_lit4, Operation::UnsignedConstant { value: 4 }),
2200            (constants::DW_OP_lit5, Operation::UnsignedConstant { value: 5 }),
2201            (constants::DW_OP_lit6, Operation::UnsignedConstant { value: 6 }),
2202            (constants::DW_OP_lit7, Operation::UnsignedConstant { value: 7 }),
2203            (constants::DW_OP_lit8, Operation::UnsignedConstant { value: 8 }),
2204            (constants::DW_OP_lit9, Operation::UnsignedConstant { value: 9 }),
2205            (constants::DW_OP_lit10, Operation::UnsignedConstant { value: 10 }),
2206            (constants::DW_OP_lit11, Operation::UnsignedConstant { value: 11 }),
2207            (constants::DW_OP_lit12, Operation::UnsignedConstant { value: 12 }),
2208            (constants::DW_OP_lit13, Operation::UnsignedConstant { value: 13 }),
2209            (constants::DW_OP_lit14, Operation::UnsignedConstant { value: 14 }),
2210            (constants::DW_OP_lit15, Operation::UnsignedConstant { value: 15 }),
2211            (constants::DW_OP_lit16, Operation::UnsignedConstant { value: 16 }),
2212            (constants::DW_OP_lit17, Operation::UnsignedConstant { value: 17 }),
2213            (constants::DW_OP_lit18, Operation::UnsignedConstant { value: 18 }),
2214            (constants::DW_OP_lit19, Operation::UnsignedConstant { value: 19 }),
2215            (constants::DW_OP_lit20, Operation::UnsignedConstant { value: 20 }),
2216            (constants::DW_OP_lit21, Operation::UnsignedConstant { value: 21 }),
2217            (constants::DW_OP_lit22, Operation::UnsignedConstant { value: 22 }),
2218            (constants::DW_OP_lit23, Operation::UnsignedConstant { value: 23 }),
2219            (constants::DW_OP_lit24, Operation::UnsignedConstant { value: 24 }),
2220            (constants::DW_OP_lit25, Operation::UnsignedConstant { value: 25 }),
2221            (constants::DW_OP_lit26, Operation::UnsignedConstant { value: 26 }),
2222            (constants::DW_OP_lit27, Operation::UnsignedConstant { value: 27 }),
2223            (constants::DW_OP_lit28, Operation::UnsignedConstant { value: 28 }),
2224            (constants::DW_OP_lit29, Operation::UnsignedConstant { value: 29 }),
2225            (constants::DW_OP_lit30, Operation::UnsignedConstant { value: 30 }),
2226            (constants::DW_OP_lit31, Operation::UnsignedConstant { value: 31 }),
2227            (constants::DW_OP_reg0, Operation::Register { register: Register(0) }),
2228            (constants::DW_OP_reg1, Operation::Register { register: Register(1) }),
2229            (constants::DW_OP_reg2, Operation::Register { register: Register(2) }),
2230            (constants::DW_OP_reg3, Operation::Register { register: Register(3) }),
2231            (constants::DW_OP_reg4, Operation::Register { register: Register(4) }),
2232            (constants::DW_OP_reg5, Operation::Register { register: Register(5) }),
2233            (constants::DW_OP_reg6, Operation::Register { register: Register(6) }),
2234            (constants::DW_OP_reg7, Operation::Register { register: Register(7) }),
2235            (constants::DW_OP_reg8, Operation::Register { register: Register(8) }),
2236            (constants::DW_OP_reg9, Operation::Register { register: Register(9) }),
2237            (constants::DW_OP_reg10, Operation::Register { register: Register(10) }),
2238            (constants::DW_OP_reg11, Operation::Register { register: Register(11) }),
2239            (constants::DW_OP_reg12, Operation::Register { register: Register(12) }),
2240            (constants::DW_OP_reg13, Operation::Register { register: Register(13) }),
2241            (constants::DW_OP_reg14, Operation::Register { register: Register(14) }),
2242            (constants::DW_OP_reg15, Operation::Register { register: Register(15) }),
2243            (constants::DW_OP_reg16, Operation::Register { register: Register(16) }),
2244            (constants::DW_OP_reg17, Operation::Register { register: Register(17) }),
2245            (constants::DW_OP_reg18, Operation::Register { register: Register(18) }),
2246            (constants::DW_OP_reg19, Operation::Register { register: Register(19) }),
2247            (constants::DW_OP_reg20, Operation::Register { register: Register(20) }),
2248            (constants::DW_OP_reg21, Operation::Register { register: Register(21) }),
2249            (constants::DW_OP_reg22, Operation::Register { register: Register(22) }),
2250            (constants::DW_OP_reg23, Operation::Register { register: Register(23) }),
2251            (constants::DW_OP_reg24, Operation::Register { register: Register(24) }),
2252            (constants::DW_OP_reg25, Operation::Register { register: Register(25) }),
2253            (constants::DW_OP_reg26, Operation::Register { register: Register(26) }),
2254            (constants::DW_OP_reg27, Operation::Register { register: Register(27) }),
2255            (constants::DW_OP_reg28, Operation::Register { register: Register(28) }),
2256            (constants::DW_OP_reg29, Operation::Register { register: Register(29) }),
2257            (constants::DW_OP_reg30, Operation::Register { register: Register(30) }),
2258            (constants::DW_OP_reg31, Operation::Register { register: Register(31) }),
2259            (constants::DW_OP_nop, Operation::Nop),
2260            (constants::DW_OP_push_object_address, Operation::PushObjectAddress),
2261            (constants::DW_OP_form_tls_address, Operation::TLS),
2262            (constants::DW_OP_GNU_push_tls_address, Operation::TLS),
2263            (constants::DW_OP_call_frame_cfa, Operation::CallFrameCFA),
2264            (constants::DW_OP_stack_value, Operation::StackValue),
2265            (constants::DW_OP_GNU_uninit, Operation::Uninitialized),
2266        ];
2267
2268        let input = [];
2269        check_op_parse_eof(&input[..], encoding);
2270
2271        for item in inputs.iter() {
2272            let (opcode, ref result) = *item;
2273            check_op_parse(|s| s.D8(opcode.0), result, encoding);
2274        }
2275    }
2276
2277    #[test]
2278    fn test_op_parse_twobyte() {
2279        // Doesn't matter for this test.
2280        let encoding = encoding4();
2281
2282        let inputs = [
2283            (
2284                constants::DW_OP_const1u,
2285                23,
2286                Operation::UnsignedConstant { value: 23 },
2287            ),
2288            (
2289                constants::DW_OP_const1s,
2290                (-23i8) as u8,
2291                Operation::SignedConstant { value: -23 },
2292            ),
2293            (constants::DW_OP_pick, 7, Operation::Pick { index: 7 }),
2294            (
2295                constants::DW_OP_deref_size,
2296                19,
2297                Operation::Deref {
2298                    base_type: generic_type(),
2299                    size: 19,
2300                    space: false,
2301                },
2302            ),
2303            (
2304                constants::DW_OP_xderef_size,
2305                19,
2306                Operation::Deref {
2307                    base_type: generic_type(),
2308                    size: 19,
2309                    space: true,
2310                },
2311            ),
2312        ];
2313
2314        for item in inputs.iter() {
2315            let (opcode, arg, ref result) = *item;
2316            check_op_parse(|s| s.D8(opcode.0).D8(arg), result, encoding);
2317        }
2318    }
2319
2320    #[test]
2321    fn test_op_parse_threebyte() {
2322        // Doesn't matter for this test.
2323        let encoding = encoding4();
2324
2325        // While bra and skip are 3-byte opcodes, they aren't tested here,
2326        // but rather specially in their own function.
2327        let inputs = [
2328            (
2329                constants::DW_OP_const2u,
2330                23,
2331                Operation::UnsignedConstant { value: 23 },
2332            ),
2333            (
2334                constants::DW_OP_const2s,
2335                (-23i16) as u16,
2336                Operation::SignedConstant { value: -23 },
2337            ),
2338            (
2339                constants::DW_OP_call2,
2340                1138,
2341                Operation::Call {
2342                    offset: DieReference::UnitRef(UnitOffset(1138)),
2343                },
2344            ),
2345            (
2346                constants::DW_OP_bra,
2347                (-23i16) as u16,
2348                Operation::Bra { target: -23 },
2349            ),
2350            (
2351                constants::DW_OP_skip,
2352                (-23i16) as u16,
2353                Operation::Skip { target: -23 },
2354            ),
2355        ];
2356
2357        for item in inputs.iter() {
2358            let (opcode, arg, ref result) = *item;
2359            check_op_parse(|s| s.D8(opcode.0).L16(arg), result, encoding);
2360        }
2361    }
2362
2363    #[test]
2364    fn test_op_parse_fivebyte() {
2365        // There are some tests here that depend on address size.
2366        let encoding = encoding4();
2367
2368        let inputs = [
2369            (
2370                constants::DW_OP_addr,
2371                0x1234_5678,
2372                Operation::Address {
2373                    address: 0x1234_5678,
2374                },
2375            ),
2376            (
2377                constants::DW_OP_const4u,
2378                0x1234_5678,
2379                Operation::UnsignedConstant { value: 0x1234_5678 },
2380            ),
2381            (
2382                constants::DW_OP_const4s,
2383                (-23i32) as u32,
2384                Operation::SignedConstant { value: -23 },
2385            ),
2386            (
2387                constants::DW_OP_call4,
2388                0x1234_5678,
2389                Operation::Call {
2390                    offset: DieReference::UnitRef(UnitOffset(0x1234_5678)),
2391                },
2392            ),
2393            (
2394                constants::DW_OP_call_ref,
2395                0x1234_5678,
2396                Operation::Call {
2397                    offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678)),
2398                },
2399            ),
2400            (
2401                constants::DW_OP_GNU_variable_value,
2402                0x1234_5678,
2403                Operation::VariableValue {
2404                    offset: DebugInfoOffset(0x1234_5678),
2405                },
2406            ),
2407        ];
2408
2409        for item in inputs.iter() {
2410            let (op, arg, ref expect) = *item;
2411            check_op_parse(|s| s.D8(op.0).L32(arg), expect, encoding);
2412        }
2413    }
2414
2415    #[test]
2416    #[cfg(target_pointer_width = "64")]
2417    fn test_op_parse_ninebyte() {
2418        // There are some tests here that depend on address size.
2419        let encoding = encoding8();
2420
2421        let inputs = [
2422            (
2423                constants::DW_OP_addr,
2424                0x1234_5678_1234_5678,
2425                Operation::Address {
2426                    address: 0x1234_5678_1234_5678,
2427                },
2428            ),
2429            (
2430                constants::DW_OP_const8u,
2431                0x1234_5678_1234_5678,
2432                Operation::UnsignedConstant {
2433                    value: 0x1234_5678_1234_5678,
2434                },
2435            ),
2436            (
2437                constants::DW_OP_const8s,
2438                (-23i64) as u64,
2439                Operation::SignedConstant { value: -23 },
2440            ),
2441            (
2442                constants::DW_OP_call_ref,
2443                0x1234_5678_1234_5678,
2444                Operation::Call {
2445                    offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678_1234_5678)),
2446                },
2447            ),
2448            (
2449                constants::DW_OP_GNU_variable_value,
2450                0x1234_5678_1234_5678,
2451                Operation::VariableValue {
2452                    offset: DebugInfoOffset(0x1234_5678_1234_5678),
2453                },
2454            ),
2455        ];
2456
2457        for item in inputs.iter() {
2458            let (op, arg, ref expect) = *item;
2459            check_op_parse(|s| s.D8(op.0).L64(arg), expect, encoding);
2460        }
2461    }
2462
2463    #[test]
2464    fn test_op_parse_sleb() {
2465        // Doesn't matter for this test.
2466        let encoding = encoding4();
2467
2468        let values = [
2469            -1i64,
2470            0,
2471            1,
2472            0x100,
2473            0x1eee_eeee,
2474            0x7fff_ffff_ffff_ffff,
2475            -0x100,
2476            -0x1eee_eeee,
2477            -0x7fff_ffff_ffff_ffff,
2478        ];
2479        for value in values.iter() {
2480            let mut inputs = vec![
2481                (
2482                    constants::DW_OP_consts.0,
2483                    Operation::SignedConstant { value: *value },
2484                ),
2485                (
2486                    constants::DW_OP_fbreg.0,
2487                    Operation::FrameOffset { offset: *value },
2488                ),
2489            ];
2490
2491            for i in 0..32 {
2492                inputs.push((
2493                    constants::DW_OP_breg0.0 + i,
2494                    Operation::RegisterOffset {
2495                        register: Register(i.into()),
2496                        offset: *value,
2497                        base_type: UnitOffset(0),
2498                    },
2499                ));
2500            }
2501
2502            for item in inputs.iter() {
2503                let (op, ref expect) = *item;
2504                check_op_parse(|s| s.D8(op).sleb(*value), expect, encoding);
2505            }
2506        }
2507    }
2508
2509    #[test]
2510    fn test_op_parse_uleb() {
2511        // Doesn't matter for this test.
2512        let encoding = encoding4();
2513
2514        let values = [
2515            0,
2516            1,
2517            0x100,
2518            (!0u16).into(),
2519            0x1eee_eeee,
2520            0x7fff_ffff_ffff_ffff,
2521            !0u64,
2522        ];
2523        for value in values.iter() {
2524            let mut inputs = vec![
2525                (
2526                    constants::DW_OP_constu,
2527                    Operation::UnsignedConstant { value: *value },
2528                ),
2529                (
2530                    constants::DW_OP_plus_uconst,
2531                    Operation::PlusConstant { value: *value },
2532                ),
2533            ];
2534
2535            if *value <= (!0u16).into() {
2536                inputs.push((
2537                    constants::DW_OP_regx,
2538                    Operation::Register {
2539                        register: Register::from_u64(*value).unwrap(),
2540                    },
2541                ));
2542            }
2543
2544            if *value <= (!0u32).into() {
2545                inputs.extend(&[
2546                    (
2547                        constants::DW_OP_addrx,
2548                        Operation::AddressIndex {
2549                            index: DebugAddrIndex(*value as usize),
2550                        },
2551                    ),
2552                    (
2553                        constants::DW_OP_constx,
2554                        Operation::ConstantIndex {
2555                            index: DebugAddrIndex(*value as usize),
2556                        },
2557                    ),
2558                ]);
2559            }
2560
2561            // FIXME
2562            if *value < !0u64 / 8 {
2563                inputs.push((
2564                    constants::DW_OP_piece,
2565                    Operation::Piece {
2566                        size_in_bits: 8 * value,
2567                        bit_offset: None,
2568                    },
2569                ));
2570            }
2571
2572            for item in inputs.iter() {
2573                let (op, ref expect) = *item;
2574                let input = Section::with_endian(Endian::Little)
2575                    .D8(op.0)
2576                    .uleb(*value)
2577                    .get_contents()
2578                    .unwrap();
2579                check_op_parse_simple(&input, expect, encoding);
2580            }
2581        }
2582    }
2583
2584    #[test]
2585    fn test_op_parse_bregx() {
2586        // Doesn't matter for this test.
2587        let encoding = encoding4();
2588
2589        let uvalues = [0, 1, 0x100, !0u16];
2590        let svalues = [
2591            -1i64,
2592            0,
2593            1,
2594            0x100,
2595            0x1eee_eeee,
2596            0x7fff_ffff_ffff_ffff,
2597            -0x100,
2598            -0x1eee_eeee,
2599            -0x7fff_ffff_ffff_ffff,
2600        ];
2601
2602        for v1 in uvalues.iter() {
2603            for v2 in svalues.iter() {
2604                check_op_parse(
2605                    |s| s.D8(constants::DW_OP_bregx.0).uleb((*v1).into()).sleb(*v2),
2606                    &Operation::RegisterOffset {
2607                        register: Register(*v1),
2608                        offset: *v2,
2609                        base_type: UnitOffset(0),
2610                    },
2611                    encoding,
2612                );
2613            }
2614        }
2615    }
2616
2617    #[test]
2618    fn test_op_parse_bit_piece() {
2619        // Doesn't matter for this test.
2620        let encoding = encoding4();
2621
2622        let values = [0, 1, 0x100, 0x1eee_eeee, 0x7fff_ffff_ffff_ffff, !0u64];
2623
2624        for v1 in values.iter() {
2625            for v2 in values.iter() {
2626                let input = Section::with_endian(Endian::Little)
2627                    .D8(constants::DW_OP_bit_piece.0)
2628                    .uleb(*v1)
2629                    .uleb(*v2)
2630                    .get_contents()
2631                    .unwrap();
2632                check_op_parse_simple(
2633                    &input,
2634                    &Operation::Piece {
2635                        size_in_bits: *v1,
2636                        bit_offset: Some(*v2),
2637                    },
2638                    encoding,
2639                );
2640            }
2641        }
2642    }
2643
2644    #[test]
2645    fn test_op_parse_implicit_value() {
2646        // Doesn't matter for this test.
2647        let encoding = encoding4();
2648
2649        let data = b"hello";
2650
2651        check_op_parse(
2652            |s| {
2653                s.D8(constants::DW_OP_implicit_value.0)
2654                    .uleb(data.len() as u64)
2655                    .append_bytes(&data[..])
2656            },
2657            &Operation::ImplicitValue {
2658                data: EndianSlice::new(&data[..], LittleEndian),
2659            },
2660            encoding,
2661        );
2662    }
2663
2664    #[test]
2665    fn test_op_parse_const_type() {
2666        // Doesn't matter for this test.
2667        let encoding = encoding4();
2668
2669        let data = b"hello";
2670
2671        check_op_parse(
2672            |s| {
2673                s.D8(constants::DW_OP_const_type.0)
2674                    .uleb(100)
2675                    .D8(data.len() as u8)
2676                    .append_bytes(&data[..])
2677            },
2678            &Operation::TypedLiteral {
2679                base_type: UnitOffset(100),
2680                value: EndianSlice::new(&data[..], LittleEndian),
2681            },
2682            encoding,
2683        );
2684        check_op_parse(
2685            |s| {
2686                s.D8(constants::DW_OP_GNU_const_type.0)
2687                    .uleb(100)
2688                    .D8(data.len() as u8)
2689                    .append_bytes(&data[..])
2690            },
2691            &Operation::TypedLiteral {
2692                base_type: UnitOffset(100),
2693                value: EndianSlice::new(&data[..], LittleEndian),
2694            },
2695            encoding,
2696        );
2697    }
2698
2699    #[test]
2700    fn test_op_parse_regval_type() {
2701        // Doesn't matter for this test.
2702        let encoding = encoding4();
2703
2704        check_op_parse(
2705            |s| s.D8(constants::DW_OP_regval_type.0).uleb(1).uleb(100),
2706            &Operation::RegisterOffset {
2707                register: Register(1),
2708                offset: 0,
2709                base_type: UnitOffset(100),
2710            },
2711            encoding,
2712        );
2713        check_op_parse(
2714            |s| s.D8(constants::DW_OP_GNU_regval_type.0).uleb(1).uleb(100),
2715            &Operation::RegisterOffset {
2716                register: Register(1),
2717                offset: 0,
2718                base_type: UnitOffset(100),
2719            },
2720            encoding,
2721        );
2722    }
2723
2724    #[test]
2725    fn test_op_parse_deref_type() {
2726        // Doesn't matter for this test.
2727        let encoding = encoding4();
2728
2729        check_op_parse(
2730            |s| s.D8(constants::DW_OP_deref_type.0).D8(8).uleb(100),
2731            &Operation::Deref {
2732                base_type: UnitOffset(100),
2733                size: 8,
2734                space: false,
2735            },
2736            encoding,
2737        );
2738        check_op_parse(
2739            |s| s.D8(constants::DW_OP_GNU_deref_type.0).D8(8).uleb(100),
2740            &Operation::Deref {
2741                base_type: UnitOffset(100),
2742                size: 8,
2743                space: false,
2744            },
2745            encoding,
2746        );
2747        check_op_parse(
2748            |s| s.D8(constants::DW_OP_xderef_type.0).D8(8).uleb(100),
2749            &Operation::Deref {
2750                base_type: UnitOffset(100),
2751                size: 8,
2752                space: true,
2753            },
2754            encoding,
2755        );
2756    }
2757
2758    #[test]
2759    fn test_op_convert() {
2760        // Doesn't matter for this test.
2761        let encoding = encoding4();
2762
2763        check_op_parse(
2764            |s| s.D8(constants::DW_OP_convert.0).uleb(100),
2765            &Operation::Convert {
2766                base_type: UnitOffset(100),
2767            },
2768            encoding,
2769        );
2770        check_op_parse(
2771            |s| s.D8(constants::DW_OP_GNU_convert.0).uleb(100),
2772            &Operation::Convert {
2773                base_type: UnitOffset(100),
2774            },
2775            encoding,
2776        );
2777    }
2778
2779    #[test]
2780    fn test_op_reinterpret() {
2781        // Doesn't matter for this test.
2782        let encoding = encoding4();
2783
2784        check_op_parse(
2785            |s| s.D8(constants::DW_OP_reinterpret.0).uleb(100),
2786            &Operation::Reinterpret {
2787                base_type: UnitOffset(100),
2788            },
2789            encoding,
2790        );
2791        check_op_parse(
2792            |s| s.D8(constants::DW_OP_GNU_reinterpret.0).uleb(100),
2793            &Operation::Reinterpret {
2794                base_type: UnitOffset(100),
2795            },
2796            encoding,
2797        );
2798    }
2799
2800    #[test]
2801    fn test_op_parse_implicit_pointer() {
2802        for op in &[
2803            constants::DW_OP_implicit_pointer,
2804            constants::DW_OP_GNU_implicit_pointer,
2805        ] {
2806            check_op_parse(
2807                |s| s.D8(op.0).D32(0x1234_5678).sleb(0x123),
2808                &Operation::ImplicitPointer {
2809                    value: DebugInfoOffset(0x1234_5678),
2810                    byte_offset: 0x123,
2811                },
2812                encoding4(),
2813            );
2814
2815            check_op_parse(
2816                |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
2817                &Operation::ImplicitPointer {
2818                    value: DebugInfoOffset(0x1234_5678),
2819                    byte_offset: 0x123,
2820                },
2821                encoding8(),
2822            );
2823
2824            check_op_parse(
2825                |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
2826                &Operation::ImplicitPointer {
2827                    value: DebugInfoOffset(0x1234_5678),
2828                    byte_offset: 0x123,
2829                },
2830                Encoding {
2831                    format: Format::Dwarf32,
2832                    version: 2,
2833                    address_size: 8,
2834                },
2835            )
2836        }
2837    }
2838
2839    #[test]
2840    fn test_op_parse_entry_value() {
2841        for op in &[
2842            constants::DW_OP_entry_value,
2843            constants::DW_OP_GNU_entry_value,
2844        ] {
2845            let data = b"hello";
2846            check_op_parse(
2847                |s| s.D8(op.0).uleb(data.len() as u64).append_bytes(&data[..]),
2848                &Operation::EntryValue {
2849                    expression: EndianSlice::new(&data[..], LittleEndian),
2850                },
2851                encoding4(),
2852            );
2853        }
2854    }
2855
2856    #[test]
2857    fn test_op_parse_gnu_parameter_ref() {
2858        check_op_parse(
2859            |s| s.D8(constants::DW_OP_GNU_parameter_ref.0).D32(0x1234_5678),
2860            &Operation::ParameterRef {
2861                offset: UnitOffset(0x1234_5678),
2862            },
2863            encoding4(),
2864        )
2865    }
2866
2867    #[test]
2868    fn test_op_wasm() {
2869        // Doesn't matter for this test.
2870        let encoding = encoding4();
2871
2872        check_op_parse(
2873            |s| s.D8(constants::DW_OP_WASM_location.0).D8(0).uleb(1000),
2874            &Operation::WasmLocal { index: 1000 },
2875            encoding,
2876        );
2877        check_op_parse(
2878            |s| s.D8(constants::DW_OP_WASM_location.0).D8(1).uleb(1000),
2879            &Operation::WasmGlobal { index: 1000 },
2880            encoding,
2881        );
2882        check_op_parse(
2883            |s| s.D8(constants::DW_OP_WASM_location.0).D8(2).uleb(1000),
2884            &Operation::WasmStack { index: 1000 },
2885            encoding,
2886        );
2887        check_op_parse(
2888            |s| s.D8(constants::DW_OP_WASM_location.0).D8(3).D32(1000),
2889            &Operation::WasmGlobal { index: 1000 },
2890            encoding,
2891        );
2892    }
2893
2894    enum AssemblerEntry {
2895        Op(constants::DwOp),
2896        Mark(u8),
2897        Branch(u8),
2898        U8(u8),
2899        U16(u16),
2900        U32(u32),
2901        U64(u64),
2902        Uleb(u64),
2903        Sleb(u64),
2904    }
2905
2906    fn assemble(entries: &[AssemblerEntry]) -> Vec<u8> {
2907        let mut result = Vec::new();
2908
2909        struct Marker(Option<usize>, Vec<usize>);
2910
2911        let mut markers = Vec::new();
2912        for _ in 0..256 {
2913            markers.push(Marker(None, Vec::new()));
2914        }
2915
2916        fn write(stack: &mut [u8], index: usize, mut num: u64, nbytes: u8) {
2917            for i in 0..nbytes as usize {
2918                stack[index + i] = (num & 0xff) as u8;
2919                num >>= 8;
2920            }
2921        }
2922
2923        fn push(stack: &mut Vec<u8>, num: u64, nbytes: u8) {
2924            let index = stack.len();
2925            for _ in 0..nbytes {
2926                stack.push(0);
2927            }
2928            write(stack, index, num, nbytes);
2929        }
2930
2931        for item in entries {
2932            match *item {
2933                AssemblerEntry::Op(op) => result.push(op.0),
2934                AssemblerEntry::Mark(num) => {
2935                    assert!(markers[num as usize].0.is_none());
2936                    markers[num as usize].0 = Some(result.len());
2937                }
2938                AssemblerEntry::Branch(num) => {
2939                    markers[num as usize].1.push(result.len());
2940                    push(&mut result, 0, 2);
2941                }
2942                AssemblerEntry::U8(num) => result.push(num),
2943                AssemblerEntry::U16(num) => push(&mut result, u64::from(num), 2),
2944                AssemblerEntry::U32(num) => push(&mut result, u64::from(num), 4),
2945                AssemblerEntry::U64(num) => push(&mut result, num, 8),
2946                AssemblerEntry::Uleb(num) => {
2947                    result.extend(leb128::write::Leb128::unsigned(num).bytes());
2948                }
2949                AssemblerEntry::Sleb(num) => {
2950                    result.extend(leb128::write::Leb128::signed(num as i64).bytes());
2951                }
2952            }
2953        }
2954
2955        // Update all the branches.
2956        for marker in markers {
2957            if let Some(offset) = marker.0 {
2958                for branch_offset in marker.1 {
2959                    let delta = offset.wrapping_sub(branch_offset + 2) as u64;
2960                    write(&mut result, branch_offset, delta, 2);
2961                }
2962            }
2963        }
2964
2965        result
2966    }
2967
2968    fn check_eval_with_args<F>(
2969        program: &[AssemblerEntry],
2970        expect: Result<&[Piece<EndianSlice<'_, LittleEndian>>]>,
2971        encoding: Encoding,
2972        object_address: Option<u64>,
2973        initial_value: Option<u64>,
2974        max_iterations: Option<u32>,
2975        f: F,
2976    ) where
2977        for<'a> F: Fn(
2978            &mut Evaluation<EndianSlice<'a, LittleEndian>>,
2979            EvaluationResult<EndianSlice<'a, LittleEndian>>,
2980        ) -> Result<EvaluationResult<EndianSlice<'a, LittleEndian>>>,
2981    {
2982        let bytes = assemble(program);
2983        let bytes = EndianSlice::new(&bytes, LittleEndian);
2984
2985        let mut eval = Evaluation::new(bytes, encoding);
2986
2987        if let Some(val) = object_address {
2988            eval.set_object_address(val);
2989        }
2990        if let Some(val) = initial_value {
2991            eval.set_initial_value(val);
2992        }
2993        if let Some(val) = max_iterations {
2994            eval.set_max_iterations(val);
2995        }
2996
2997        let result = match eval.evaluate() {
2998            Err(e) => Err(e),
2999            Ok(r) => f(&mut eval, r),
3000        };
3001
3002        match (result, expect) {
3003            (Ok(EvaluationResult::Complete), Ok(pieces)) => {
3004                let vec = eval.result();
3005                assert_eq!(vec.len(), pieces.len());
3006                for i in 0..pieces.len() {
3007                    assert_eq!(vec[i], pieces[i]);
3008                }
3009            }
3010            (Err(f1), Err(f2)) => {
3011                assert_eq!(f1, f2);
3012            }
3013            otherwise => panic!("Unexpected result: {:?}", otherwise),
3014        }
3015    }
3016
3017    fn check_eval(
3018        program: &[AssemblerEntry],
3019        expect: Result<&[Piece<EndianSlice<'_, LittleEndian>>]>,
3020        encoding: Encoding,
3021    ) {
3022        check_eval_with_args(program, expect, encoding, None, None, None, |_, result| {
3023            Ok(result)
3024        });
3025    }
3026
3027    #[test]
3028    fn test_eval_arith() {
3029        // It's nice if an operation and its arguments can fit on a single
3030        // line in the test program.
3031        use self::AssemblerEntry::*;
3032        use crate::constants::*;
3033
3034        // Indices of marks in the assembly.
3035        let done = 0;
3036        let fail = 1;
3037
3038        #[rustfmt::skip]
3039        let program = [
3040            Op(DW_OP_const1u), U8(23),
3041            Op(DW_OP_const1s), U8((-23i8) as u8),
3042            Op(DW_OP_plus),
3043            Op(DW_OP_bra), Branch(fail),
3044
3045            Op(DW_OP_const2u), U16(23),
3046            Op(DW_OP_const2s), U16((-23i16) as u16),
3047            Op(DW_OP_plus),
3048            Op(DW_OP_bra), Branch(fail),
3049
3050            Op(DW_OP_const4u), U32(0x1111_2222),
3051            Op(DW_OP_const4s), U32((-0x1111_2222i32) as u32),
3052            Op(DW_OP_plus),
3053            Op(DW_OP_bra), Branch(fail),
3054
3055            // Plus should overflow.
3056            Op(DW_OP_const1s), U8(0xff),
3057            Op(DW_OP_const1u), U8(1),
3058            Op(DW_OP_plus),
3059            Op(DW_OP_bra), Branch(fail),
3060
3061            Op(DW_OP_const1s), U8(0xff),
3062            Op(DW_OP_plus_uconst), Uleb(1),
3063            Op(DW_OP_bra), Branch(fail),
3064
3065            // Minus should underflow.
3066            Op(DW_OP_const1s), U8(0),
3067            Op(DW_OP_const1u), U8(1),
3068            Op(DW_OP_minus),
3069            Op(DW_OP_const1s), U8(0xff),
3070            Op(DW_OP_ne),
3071            Op(DW_OP_bra), Branch(fail),
3072
3073            Op(DW_OP_const1s), U8(0xff),
3074            Op(DW_OP_abs),
3075            Op(DW_OP_const1u), U8(1),
3076            Op(DW_OP_minus),
3077            Op(DW_OP_bra), Branch(fail),
3078
3079            Op(DW_OP_const4u), U32(0xf078_fffe),
3080            Op(DW_OP_const4u), U32(0x0f87_0001),
3081            Op(DW_OP_and),
3082            Op(DW_OP_bra), Branch(fail),
3083
3084            Op(DW_OP_const4u), U32(0xf078_fffe),
3085            Op(DW_OP_const4u), U32(0xf000_00fe),
3086            Op(DW_OP_and),
3087            Op(DW_OP_const4u), U32(0xf000_00fe),
3088            Op(DW_OP_ne),
3089            Op(DW_OP_bra), Branch(fail),
3090
3091            // Division is signed.
3092            Op(DW_OP_const1s), U8(0xfe),
3093            Op(DW_OP_const1s), U8(2),
3094            Op(DW_OP_div),
3095            Op(DW_OP_plus_uconst), Uleb(1),
3096            Op(DW_OP_bra), Branch(fail),
3097
3098            // Mod is unsigned.
3099            Op(DW_OP_const1s), U8(0xfd),
3100            Op(DW_OP_const1s), U8(2),
3101            Op(DW_OP_mod),
3102            Op(DW_OP_neg),
3103            Op(DW_OP_plus_uconst), Uleb(1),
3104            Op(DW_OP_bra), Branch(fail),
3105
3106            // Overflow is defined for multiplication.
3107            Op(DW_OP_const4u), U32(0x8000_0001),
3108            Op(DW_OP_lit2),
3109            Op(DW_OP_mul),
3110            Op(DW_OP_lit2),
3111            Op(DW_OP_ne),
3112            Op(DW_OP_bra), Branch(fail),
3113
3114            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3115            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3116            Op(DW_OP_xor),
3117            Op(DW_OP_bra), Branch(fail),
3118
3119            Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3120            Op(DW_OP_const4u), U32(0x0f0f_0f0f),
3121            Op(DW_OP_or),
3122            Op(DW_OP_not),
3123            Op(DW_OP_bra), Branch(fail),
3124
3125            // In 32 bit mode, values are truncated.
3126            Op(DW_OP_const8u), U64(0xffff_ffff_0000_0000),
3127            Op(DW_OP_lit2),
3128            Op(DW_OP_div),
3129            Op(DW_OP_bra), Branch(fail),
3130
3131            Op(DW_OP_const1u), U8(0xff),
3132            Op(DW_OP_lit1),
3133            Op(DW_OP_shl),
3134            Op(DW_OP_const2u), U16(0x1fe),
3135            Op(DW_OP_ne),
3136            Op(DW_OP_bra), Branch(fail),
3137
3138            Op(DW_OP_const1u), U8(0xff),
3139            Op(DW_OP_const1u), U8(50),
3140            Op(DW_OP_shl),
3141            Op(DW_OP_bra), Branch(fail),
3142
3143            // Absurd shift.
3144            Op(DW_OP_const1u), U8(0xff),
3145            Op(DW_OP_const1s), U8(0xff),
3146            Op(DW_OP_shl),
3147            Op(DW_OP_bra), Branch(fail),
3148
3149            Op(DW_OP_const1s), U8(0xff),
3150            Op(DW_OP_lit1),
3151            Op(DW_OP_shr),
3152            Op(DW_OP_const4u), U32(0x7fff_ffff),
3153            Op(DW_OP_ne),
3154            Op(DW_OP_bra), Branch(fail),
3155
3156            Op(DW_OP_const1s), U8(0xff),
3157            Op(DW_OP_const1u), U8(0xff),
3158            Op(DW_OP_shr),
3159            Op(DW_OP_bra), Branch(fail),
3160
3161            Op(DW_OP_const1s), U8(0xff),
3162            Op(DW_OP_lit1),
3163            Op(DW_OP_shra),
3164            Op(DW_OP_const1s), U8(0xff),
3165            Op(DW_OP_ne),
3166            Op(DW_OP_bra), Branch(fail),
3167
3168            Op(DW_OP_const1s), U8(0xff),
3169            Op(DW_OP_const1u), U8(0xff),
3170            Op(DW_OP_shra),
3171            Op(DW_OP_const1s), U8(0xff),
3172            Op(DW_OP_ne),
3173            Op(DW_OP_bra), Branch(fail),
3174
3175            // Success.
3176            Op(DW_OP_lit0),
3177            Op(DW_OP_nop),
3178            Op(DW_OP_skip), Branch(done),
3179
3180            Mark(fail),
3181            Op(DW_OP_lit1),
3182
3183            Mark(done),
3184            Op(DW_OP_stack_value),
3185        ];
3186
3187        let result = [Piece {
3188            size_in_bits: None,
3189            bit_offset: None,
3190            location: Location::Value {
3191                value: Value::Generic(0),
3192            },
3193        }];
3194
3195        check_eval(&program, Ok(&result), encoding4());
3196    }
3197
3198    #[test]
3199    fn test_eval_arith64() {
3200        // It's nice if an operation and its arguments can fit on a single
3201        // line in the test program.
3202        use self::AssemblerEntry::*;
3203        use crate::constants::*;
3204
3205        // Indices of marks in the assembly.
3206        let done = 0;
3207        let fail = 1;
3208
3209        #[rustfmt::skip]
3210        let program = [
3211            Op(DW_OP_const8u), U64(0x1111_2222_3333_4444),
3212            Op(DW_OP_const8s), U64((-0x1111_2222_3333_4444i64) as u64),
3213            Op(DW_OP_plus),
3214            Op(DW_OP_bra), Branch(fail),
3215
3216            Op(DW_OP_constu), Uleb(0x1111_2222_3333_4444),
3217            Op(DW_OP_consts), Sleb((-0x1111_2222_3333_4444i64) as u64),
3218            Op(DW_OP_plus),
3219            Op(DW_OP_bra), Branch(fail),
3220
3221            Op(DW_OP_lit1),
3222            Op(DW_OP_plus_uconst), Uleb(!0u64),
3223            Op(DW_OP_bra), Branch(fail),
3224
3225            Op(DW_OP_lit1),
3226            Op(DW_OP_neg),
3227            Op(DW_OP_not),
3228            Op(DW_OP_bra), Branch(fail),
3229
3230            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3231            Op(DW_OP_const1u), U8(63),
3232            Op(DW_OP_shr),
3233            Op(DW_OP_lit1),
3234            Op(DW_OP_ne),
3235            Op(DW_OP_bra), Branch(fail),
3236
3237            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3238            Op(DW_OP_const1u), U8(62),
3239            Op(DW_OP_shra),
3240            Op(DW_OP_plus_uconst), Uleb(2),
3241            Op(DW_OP_bra), Branch(fail),
3242
3243            Op(DW_OP_lit1),
3244            Op(DW_OP_const1u), U8(63),
3245            Op(DW_OP_shl),
3246            Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3247            Op(DW_OP_ne),
3248            Op(DW_OP_bra), Branch(fail),
3249
3250            // Success.
3251            Op(DW_OP_lit0),
3252            Op(DW_OP_nop),
3253            Op(DW_OP_skip), Branch(done),
3254
3255            Mark(fail),
3256            Op(DW_OP_lit1),
3257
3258            Mark(done),
3259            Op(DW_OP_stack_value),
3260        ];
3261
3262        let result = [Piece {
3263            size_in_bits: None,
3264            bit_offset: None,
3265            location: Location::Value {
3266                value: Value::Generic(0),
3267            },
3268        }];
3269
3270        check_eval(&program, Ok(&result), encoding8());
3271    }
3272
3273    #[test]
3274    fn test_eval_compare() {
3275        // It's nice if an operation and its arguments can fit on a single
3276        // line in the test program.
3277        use self::AssemblerEntry::*;
3278        use crate::constants::*;
3279
3280        // Indices of marks in the assembly.
3281        let done = 0;
3282        let fail = 1;
3283
3284        #[rustfmt::skip]
3285        let program = [
3286            // Comparisons are signed.
3287            Op(DW_OP_const1s), U8(1),
3288            Op(DW_OP_const1s), U8(0xff),
3289            Op(DW_OP_lt),
3290            Op(DW_OP_bra), Branch(fail),
3291
3292            Op(DW_OP_const1s), U8(0xff),
3293            Op(DW_OP_const1s), U8(1),
3294            Op(DW_OP_gt),
3295            Op(DW_OP_bra), Branch(fail),
3296
3297            Op(DW_OP_const1s), U8(1),
3298            Op(DW_OP_const1s), U8(0xff),
3299            Op(DW_OP_le),
3300            Op(DW_OP_bra), Branch(fail),
3301
3302            Op(DW_OP_const1s), U8(0xff),
3303            Op(DW_OP_const1s), U8(1),
3304            Op(DW_OP_ge),
3305            Op(DW_OP_bra), Branch(fail),
3306
3307            Op(DW_OP_const1s), U8(0xff),
3308            Op(DW_OP_const1s), U8(1),
3309            Op(DW_OP_eq),
3310            Op(DW_OP_bra), Branch(fail),
3311
3312            Op(DW_OP_const4s), U32(1),
3313            Op(DW_OP_const1s), U8(1),
3314            Op(DW_OP_ne),
3315            Op(DW_OP_bra), Branch(fail),
3316
3317            // Success.
3318            Op(DW_OP_lit0),
3319            Op(DW_OP_nop),
3320            Op(DW_OP_skip), Branch(done),
3321
3322            Mark(fail),
3323            Op(DW_OP_lit1),
3324
3325            Mark(done),
3326            Op(DW_OP_stack_value),
3327        ];
3328
3329        let result = [Piece {
3330            size_in_bits: None,
3331            bit_offset: None,
3332            location: Location::Value {
3333                value: Value::Generic(0),
3334            },
3335        }];
3336
3337        check_eval(&program, Ok(&result), encoding4());
3338    }
3339
3340    #[test]
3341    fn test_eval_stack() {
3342        // It's nice if an operation and its arguments can fit on a single
3343        // line in the test program.
3344        use self::AssemblerEntry::*;
3345        use crate::constants::*;
3346
3347        #[rustfmt::skip]
3348        let program = [
3349            Op(DW_OP_lit17),                // -- 17
3350            Op(DW_OP_dup),                  // -- 17 17
3351            Op(DW_OP_over),                 // -- 17 17 17
3352            Op(DW_OP_minus),                // -- 17 0
3353            Op(DW_OP_swap),                 // -- 0 17
3354            Op(DW_OP_dup),                  // -- 0 17 17
3355            Op(DW_OP_plus_uconst), Uleb(1), // -- 0 17 18
3356            Op(DW_OP_rot),                  // -- 18 0 17
3357            Op(DW_OP_pick), U8(2),          // -- 18 0 17 18
3358            Op(DW_OP_pick), U8(3),          // -- 18 0 17 18 18
3359            Op(DW_OP_minus),                // -- 18 0 17 0
3360            Op(DW_OP_drop),                 // -- 18 0 17
3361            Op(DW_OP_swap),                 // -- 18 17 0
3362            Op(DW_OP_drop),                 // -- 18 17
3363            Op(DW_OP_minus),                // -- 1
3364            Op(DW_OP_stack_value),
3365        ];
3366
3367        let result = [Piece {
3368            size_in_bits: None,
3369            bit_offset: None,
3370            location: Location::Value {
3371                value: Value::Generic(1),
3372            },
3373        }];
3374
3375        check_eval(&program, Ok(&result), encoding4());
3376    }
3377
3378    #[test]
3379    fn test_eval_lit_and_reg() {
3380        // It's nice if an operation and its arguments can fit on a single
3381        // line in the test program.
3382        use self::AssemblerEntry::*;
3383        use crate::constants::*;
3384
3385        let mut program = Vec::new();
3386        program.push(Op(DW_OP_lit0));
3387        for i in 0..32 {
3388            program.push(Op(DwOp(DW_OP_lit0.0 + i)));
3389            program.push(Op(DwOp(DW_OP_breg0.0 + i)));
3390            program.push(Sleb(u64::from(i)));
3391            program.push(Op(DW_OP_plus));
3392            program.push(Op(DW_OP_plus));
3393        }
3394
3395        program.push(Op(DW_OP_bregx));
3396        program.push(Uleb(0x1234));
3397        program.push(Sleb(0x1234));
3398        program.push(Op(DW_OP_plus));
3399
3400        program.push(Op(DW_OP_stack_value));
3401
3402        let result = [Piece {
3403            size_in_bits: None,
3404            bit_offset: None,
3405            location: Location::Value {
3406                value: Value::Generic(496),
3407            },
3408        }];
3409
3410        check_eval_with_args(
3411            &program,
3412            Ok(&result),
3413            encoding4(),
3414            None,
3415            None,
3416            None,
3417            |eval, mut result| {
3418                while result != EvaluationResult::Complete {
3419                    result = eval.resume_with_register(match result {
3420                        EvaluationResult::RequiresRegister {
3421                            register,
3422                            base_type,
3423                        } => {
3424                            assert_eq!(base_type, UnitOffset(0));
3425                            Value::Generic(u64::from(register.0).wrapping_neg())
3426                        }
3427                        _ => panic!(),
3428                    })?;
3429                }
3430                Ok(result)
3431            },
3432        );
3433    }
3434
3435    #[test]
3436    fn test_eval_memory() {
3437        // It's nice if an operation and its arguments can fit on a single
3438        // line in the test program.
3439        use self::AssemblerEntry::*;
3440        use crate::constants::*;
3441
3442        // Indices of marks in the assembly.
3443        let done = 0;
3444        let fail = 1;
3445
3446        #[rustfmt::skip]
3447        let program = [
3448            Op(DW_OP_addr), U32(0x7fff_ffff),
3449            Op(DW_OP_deref),
3450            Op(DW_OP_const4u), U32(0xffff_fffc),
3451            Op(DW_OP_ne),
3452            Op(DW_OP_bra), Branch(fail),
3453
3454            Op(DW_OP_addr), U32(0x7fff_ffff),
3455            Op(DW_OP_deref_size), U8(2),
3456            Op(DW_OP_const4u), U32(0xfffc),
3457            Op(DW_OP_ne),
3458            Op(DW_OP_bra), Branch(fail),
3459
3460            Op(DW_OP_lit1),
3461            Op(DW_OP_addr), U32(0x7fff_ffff),
3462            Op(DW_OP_xderef),
3463            Op(DW_OP_const4u), U32(0xffff_fffd),
3464            Op(DW_OP_ne),
3465            Op(DW_OP_bra), Branch(fail),
3466
3467            Op(DW_OP_lit1),
3468            Op(DW_OP_addr), U32(0x7fff_ffff),
3469            Op(DW_OP_xderef_size), U8(2),
3470            Op(DW_OP_const4u), U32(0xfffd),
3471            Op(DW_OP_ne),
3472            Op(DW_OP_bra), Branch(fail),
3473
3474            Op(DW_OP_lit17),
3475            Op(DW_OP_form_tls_address),
3476            Op(DW_OP_constu), Uleb(!17),
3477            Op(DW_OP_ne),
3478            Op(DW_OP_bra), Branch(fail),
3479
3480            Op(DW_OP_lit17),
3481            Op(DW_OP_GNU_push_tls_address),
3482            Op(DW_OP_constu), Uleb(!17),
3483            Op(DW_OP_ne),
3484            Op(DW_OP_bra), Branch(fail),
3485
3486            Op(DW_OP_addrx), Uleb(0x10),
3487            Op(DW_OP_deref),
3488            Op(DW_OP_const4u), U32(0x4040),
3489            Op(DW_OP_ne),
3490            Op(DW_OP_bra), Branch(fail),
3491
3492            Op(DW_OP_constx), Uleb(17),
3493            Op(DW_OP_form_tls_address),
3494            Op(DW_OP_constu), Uleb(!27),
3495            Op(DW_OP_ne),
3496            Op(DW_OP_bra), Branch(fail),
3497
3498            // Success.
3499            Op(DW_OP_lit0),
3500            Op(DW_OP_nop),
3501            Op(DW_OP_skip), Branch(done),
3502
3503            Mark(fail),
3504            Op(DW_OP_lit1),
3505
3506            Mark(done),
3507            Op(DW_OP_stack_value),
3508        ];
3509
3510        let result = [Piece {
3511            size_in_bits: None,
3512            bit_offset: None,
3513            location: Location::Value {
3514                value: Value::Generic(0),
3515            },
3516        }];
3517
3518        check_eval_with_args(
3519            &program,
3520            Ok(&result),
3521            encoding4(),
3522            None,
3523            None,
3524            None,
3525            |eval, mut result| {
3526                while result != EvaluationResult::Complete {
3527                    result = match result {
3528                        EvaluationResult::RequiresMemory {
3529                            address,
3530                            size,
3531                            space,
3532                            base_type,
3533                        } => {
3534                            assert_eq!(base_type, UnitOffset(0));
3535                            let mut v = address << 2;
3536                            if let Some(value) = space {
3537                                v += value;
3538                            }
3539                            v &= (1u64 << (8 * size)) - 1;
3540                            eval.resume_with_memory(Value::Generic(v))?
3541                        }
3542                        EvaluationResult::RequiresTls(slot) => eval.resume_with_tls(!slot)?,
3543                        EvaluationResult::RequiresRelocatedAddress(address) => {
3544                            eval.resume_with_relocated_address(address)?
3545                        }
3546                        EvaluationResult::RequiresIndexedAddress { index, relocate } => {
3547                            if relocate {
3548                                eval.resume_with_indexed_address(0x1000 + index.0 as u64)?
3549                            } else {
3550                                eval.resume_with_indexed_address(10 + index.0 as u64)?
3551                            }
3552                        }
3553                        _ => panic!(),
3554                    };
3555                }
3556
3557                Ok(result)
3558            },
3559        );
3560
3561        #[rustfmt::skip]
3562        let program = [
3563            Op(DW_OP_addr), U32(0x7fff_ffff),
3564            Op(DW_OP_deref_size), U8(8),
3565        ];
3566        check_eval_with_args(
3567            &program,
3568            Err(Error::InvalidDerefSize(8)),
3569            encoding4(),
3570            None,
3571            None,
3572            None,
3573            |eval, mut result| {
3574                while result != EvaluationResult::Complete {
3575                    result = match result {
3576                        EvaluationResult::RequiresMemory {
3577                            address,
3578                            size,
3579                            space,
3580                            base_type,
3581                        } => {
3582                            assert_eq!(base_type, UnitOffset(0));
3583                            let mut v = address << 2;
3584                            if let Some(value) = space {
3585                                v += value;
3586                            }
3587                            v &= (1u64 << (8 * size)) - 1;
3588                            eval.resume_with_memory(Value::Generic(v))?
3589                        }
3590                        EvaluationResult::RequiresRelocatedAddress(address) => {
3591                            eval.resume_with_relocated_address(address)?
3592                        }
3593                        _ => panic!("Unexpected result: {:?}", result),
3594                    };
3595                }
3596
3597                Ok(result)
3598            },
3599        );
3600    }
3601
3602    #[test]
3603    fn test_eval_register() {
3604        // It's nice if an operation and its arguments can fit on a single
3605        // line in the test program.
3606        use self::AssemblerEntry::*;
3607        use crate::constants::*;
3608
3609        for i in 0..32 {
3610            #[rustfmt::skip]
3611            let program = [
3612                Op(DwOp(DW_OP_reg0.0 + i)),
3613                // Included only in the "bad" run.
3614                Op(DW_OP_lit23),
3615            ];
3616            let ok_result = [Piece {
3617                size_in_bits: None,
3618                bit_offset: None,
3619                location: Location::Register {
3620                    register: Register(i.into()),
3621                },
3622            }];
3623
3624            check_eval(&program[..1], Ok(&ok_result), encoding4());
3625
3626            check_eval(
3627                &program,
3628                Err(Error::InvalidExpressionTerminator(1)),
3629                encoding4(),
3630            );
3631        }
3632
3633        #[rustfmt::skip]
3634        let program = [
3635            Op(DW_OP_regx), Uleb(0x1234)
3636        ];
3637
3638        let result = [Piece {
3639            size_in_bits: None,
3640            bit_offset: None,
3641            location: Location::Register {
3642                register: Register(0x1234),
3643            },
3644        }];
3645
3646        check_eval(&program, Ok(&result), encoding4());
3647    }
3648
3649    #[test]
3650    fn test_eval_context() {
3651        // It's nice if an operation and its arguments can fit on a single
3652        // line in the test program.
3653        use self::AssemblerEntry::*;
3654        use crate::constants::*;
3655
3656        // Test `frame_base` and `call_frame_cfa` callbacks.
3657        #[rustfmt::skip]
3658        let program = [
3659            Op(DW_OP_fbreg), Sleb((-8i8) as u64),
3660            Op(DW_OP_call_frame_cfa),
3661            Op(DW_OP_plus),
3662            Op(DW_OP_neg),
3663            Op(DW_OP_stack_value)
3664        ];
3665
3666        let result = [Piece {
3667            size_in_bits: None,
3668            bit_offset: None,
3669            location: Location::Value {
3670                value: Value::Generic(9),
3671            },
3672        }];
3673
3674        check_eval_with_args(
3675            &program,
3676            Ok(&result),
3677            encoding8(),
3678            None,
3679            None,
3680            None,
3681            |eval, result| {
3682                match result {
3683                    EvaluationResult::RequiresFrameBase => {}
3684                    _ => panic!(),
3685                };
3686                match eval.resume_with_frame_base(0x0123_4567_89ab_cdef)? {
3687                    EvaluationResult::RequiresCallFrameCfa => {}
3688                    _ => panic!(),
3689                };
3690                eval.resume_with_call_frame_cfa(0xfedc_ba98_7654_3210)
3691            },
3692        );
3693
3694        // Test `evaluate_entry_value` callback.
3695        #[rustfmt::skip]
3696        let program = [
3697            Op(DW_OP_entry_value), Uleb(8), U64(0x1234_5678),
3698            Op(DW_OP_stack_value)
3699        ];
3700
3701        let result = [Piece {
3702            size_in_bits: None,
3703            bit_offset: None,
3704            location: Location::Value {
3705                value: Value::Generic(0x1234_5678),
3706            },
3707        }];
3708
3709        check_eval_with_args(
3710            &program,
3711            Ok(&result),
3712            encoding8(),
3713            None,
3714            None,
3715            None,
3716            |eval, result| {
3717                let entry_value = match result {
3718                    EvaluationResult::RequiresEntryValue(mut expression) => {
3719                        expression.0.read_u64()?
3720                    }
3721                    _ => panic!(),
3722                };
3723                eval.resume_with_entry_value(Value::Generic(entry_value))
3724            },
3725        );
3726
3727        // Test missing `object_address` field.
3728        #[rustfmt::skip]
3729        let program = [
3730            Op(DW_OP_push_object_address),
3731        ];
3732
3733        check_eval_with_args(
3734            &program,
3735            Err(Error::InvalidPushObjectAddress),
3736            encoding4(),
3737            None,
3738            None,
3739            None,
3740            |_, _| panic!(),
3741        );
3742
3743        // Test `object_address` field.
3744        #[rustfmt::skip]
3745        let program = [
3746            Op(DW_OP_push_object_address),
3747            Op(DW_OP_stack_value),
3748        ];
3749
3750        let result = [Piece {
3751            size_in_bits: None,
3752            bit_offset: None,
3753            location: Location::Value {
3754                value: Value::Generic(0xff),
3755            },
3756        }];
3757
3758        check_eval_with_args(
3759            &program,
3760            Ok(&result),
3761            encoding8(),
3762            Some(0xff),
3763            None,
3764            None,
3765            |_, result| Ok(result),
3766        );
3767
3768        // Test `initial_value` field.
3769        #[rustfmt::skip]
3770        let program = [
3771        ];
3772
3773        let result = [Piece {
3774            size_in_bits: None,
3775            bit_offset: None,
3776            location: Location::Address {
3777                address: 0x1234_5678,
3778            },
3779        }];
3780
3781        check_eval_with_args(
3782            &program,
3783            Ok(&result),
3784            encoding8(),
3785            None,
3786            Some(0x1234_5678),
3787            None,
3788            |_, result| Ok(result),
3789        );
3790    }
3791
3792    #[test]
3793    fn test_eval_empty_stack() {
3794        // It's nice if an operation and its arguments can fit on a single
3795        // line in the test program.
3796        use self::AssemblerEntry::*;
3797        use crate::constants::*;
3798
3799        #[rustfmt::skip]
3800        let program = [
3801            Op(DW_OP_stack_value)
3802        ];
3803
3804        check_eval(&program, Err(Error::NotEnoughStackItems), encoding4());
3805    }
3806
3807    #[test]
3808    fn test_eval_call() {
3809        // It's nice if an operation and its arguments can fit on a single
3810        // line in the test program.
3811        use self::AssemblerEntry::*;
3812        use crate::constants::*;
3813
3814        #[rustfmt::skip]
3815        let program = [
3816            Op(DW_OP_lit23),
3817            Op(DW_OP_call2), U16(0x7755),
3818            Op(DW_OP_call4), U32(0x7755_aaee),
3819            Op(DW_OP_call_ref), U32(0x7755_aaee),
3820            Op(DW_OP_stack_value)
3821        ];
3822
3823        let result = [Piece {
3824            size_in_bits: None,
3825            bit_offset: None,
3826            location: Location::Value {
3827                value: Value::Generic(23),
3828            },
3829        }];
3830
3831        check_eval_with_args(
3832            &program,
3833            Ok(&result),
3834            encoding4(),
3835            None,
3836            None,
3837            None,
3838            |eval, result| {
3839                let buf = EndianSlice::new(&[], LittleEndian);
3840                match result {
3841                    EvaluationResult::RequiresAtLocation(_) => {}
3842                    _ => panic!(),
3843                };
3844
3845                eval.resume_with_at_location(buf)?;
3846
3847                match result {
3848                    EvaluationResult::RequiresAtLocation(_) => {}
3849                    _ => panic!(),
3850                };
3851
3852                eval.resume_with_at_location(buf)?;
3853
3854                match result {
3855                    EvaluationResult::RequiresAtLocation(_) => {}
3856                    _ => panic!(),
3857                };
3858
3859                eval.resume_with_at_location(buf)
3860            },
3861        );
3862
3863        // DW_OP_lit2 DW_OP_mul
3864        const SUBR: &[u8] = &[0x32, 0x1e];
3865
3866        let result = [Piece {
3867            size_in_bits: None,
3868            bit_offset: None,
3869            location: Location::Value {
3870                value: Value::Generic(184),
3871            },
3872        }];
3873
3874        check_eval_with_args(
3875            &program,
3876            Ok(&result),
3877            encoding4(),
3878            None,
3879            None,
3880            None,
3881            |eval, result| {
3882                let buf = EndianSlice::new(SUBR, LittleEndian);
3883                match result {
3884                    EvaluationResult::RequiresAtLocation(_) => {}
3885                    _ => panic!(),
3886                };
3887
3888                eval.resume_with_at_location(buf)?;
3889
3890                match result {
3891                    EvaluationResult::RequiresAtLocation(_) => {}
3892                    _ => panic!(),
3893                };
3894
3895                eval.resume_with_at_location(buf)?;
3896
3897                match result {
3898                    EvaluationResult::RequiresAtLocation(_) => {}
3899                    _ => panic!(),
3900                };
3901
3902                eval.resume_with_at_location(buf)
3903            },
3904        );
3905    }
3906
3907    #[test]
3908    fn test_eval_pieces() {
3909        // It's nice if an operation and its arguments can fit on a single
3910        // line in the test program.
3911        use self::AssemblerEntry::*;
3912        use crate::constants::*;
3913
3914        // Example from DWARF 2.6.1.3.
3915        #[rustfmt::skip]
3916        let program = [
3917            Op(DW_OP_reg3),
3918            Op(DW_OP_piece), Uleb(4),
3919            Op(DW_OP_reg4),
3920            Op(DW_OP_piece), Uleb(2),
3921        ];
3922
3923        let result = [
3924            Piece {
3925                size_in_bits: Some(32),
3926                bit_offset: None,
3927                location: Location::Register {
3928                    register: Register(3),
3929                },
3930            },
3931            Piece {
3932                size_in_bits: Some(16),
3933                bit_offset: None,
3934                location: Location::Register {
3935                    register: Register(4),
3936                },
3937            },
3938        ];
3939
3940        check_eval(&program, Ok(&result), encoding4());
3941
3942        // Example from DWARF 2.6.1.3 (but hacked since dealing with fbreg
3943        // in the tests is a pain).
3944        #[rustfmt::skip]
3945        let program = [
3946            Op(DW_OP_reg0),
3947            Op(DW_OP_piece), Uleb(4),
3948            Op(DW_OP_piece), Uleb(4),
3949            Op(DW_OP_addr), U32(0x7fff_ffff),
3950            Op(DW_OP_piece), Uleb(4),
3951        ];
3952
3953        let result = [
3954            Piece {
3955                size_in_bits: Some(32),
3956                bit_offset: None,
3957                location: Location::Register {
3958                    register: Register(0),
3959                },
3960            },
3961            Piece {
3962                size_in_bits: Some(32),
3963                bit_offset: None,
3964                location: Location::Empty,
3965            },
3966            Piece {
3967                size_in_bits: Some(32),
3968                bit_offset: None,
3969                location: Location::Address {
3970                    address: 0x7fff_ffff,
3971                },
3972            },
3973        ];
3974
3975        check_eval_with_args(
3976            &program,
3977            Ok(&result),
3978            encoding4(),
3979            None,
3980            None,
3981            None,
3982            |eval, mut result| {
3983                while result != EvaluationResult::Complete {
3984                    result = match result {
3985                        EvaluationResult::RequiresRelocatedAddress(address) => {
3986                            eval.resume_with_relocated_address(address)?
3987                        }
3988                        _ => panic!(),
3989                    };
3990                }
3991
3992                Ok(result)
3993            },
3994        );
3995
3996        #[rustfmt::skip]
3997        let program = [
3998            Op(DW_OP_implicit_value), Uleb(5),
3999            U8(23), U8(24), U8(25), U8(26), U8(0),
4000        ];
4001
4002        const BYTES: &[u8] = &[23, 24, 25, 26, 0];
4003
4004        let result = [Piece {
4005            size_in_bits: None,
4006            bit_offset: None,
4007            location: Location::Bytes {
4008                value: EndianSlice::new(BYTES, LittleEndian),
4009            },
4010        }];
4011
4012        check_eval(&program, Ok(&result), encoding4());
4013
4014        #[rustfmt::skip]
4015        let program = [
4016            Op(DW_OP_lit7),
4017            Op(DW_OP_stack_value),
4018            Op(DW_OP_bit_piece), Uleb(5), Uleb(0),
4019            Op(DW_OP_bit_piece), Uleb(3), Uleb(0),
4020        ];
4021
4022        let result = [
4023            Piece {
4024                size_in_bits: Some(5),
4025                bit_offset: Some(0),
4026                location: Location::Value {
4027                    value: Value::Generic(7),
4028                },
4029            },
4030            Piece {
4031                size_in_bits: Some(3),
4032                bit_offset: Some(0),
4033                location: Location::Empty,
4034            },
4035        ];
4036
4037        check_eval(&program, Ok(&result), encoding4());
4038
4039        #[rustfmt::skip]
4040        let program = [
4041            Op(DW_OP_lit7),
4042        ];
4043
4044        let result = [Piece {
4045            size_in_bits: None,
4046            bit_offset: None,
4047            location: Location::Address { address: 7 },
4048        }];
4049
4050        check_eval(&program, Ok(&result), encoding4());
4051
4052        #[rustfmt::skip]
4053        let program = [
4054            Op(DW_OP_implicit_pointer), U32(0x1234_5678), Sleb(0x123),
4055        ];
4056
4057        let result = [Piece {
4058            size_in_bits: None,
4059            bit_offset: None,
4060            location: Location::ImplicitPointer {
4061                value: DebugInfoOffset(0x1234_5678),
4062                byte_offset: 0x123,
4063            },
4064        }];
4065
4066        check_eval(&program, Ok(&result), encoding4());
4067
4068        #[rustfmt::skip]
4069        let program = [
4070            Op(DW_OP_reg3),
4071            Op(DW_OP_piece), Uleb(4),
4072            Op(DW_OP_reg4),
4073        ];
4074
4075        check_eval(&program, Err(Error::InvalidPiece), encoding4());
4076
4077        #[rustfmt::skip]
4078        let program = [
4079            Op(DW_OP_reg3),
4080            Op(DW_OP_piece), Uleb(4),
4081            Op(DW_OP_lit0),
4082        ];
4083
4084        check_eval(&program, Err(Error::InvalidPiece), encoding4());
4085    }
4086
4087    #[test]
4088    fn test_eval_max_iterations() {
4089        // It's nice if an operation and its arguments can fit on a single
4090        // line in the test program.
4091        use self::AssemblerEntry::*;
4092        use crate::constants::*;
4093
4094        #[rustfmt::skip]
4095        let program = [
4096            Mark(1),
4097            Op(DW_OP_skip), Branch(1),
4098        ];
4099
4100        check_eval_with_args(
4101            &program,
4102            Err(Error::TooManyIterations),
4103            encoding4(),
4104            None,
4105            None,
4106            Some(150),
4107            |_, _| panic!(),
4108        );
4109    }
4110
4111    #[test]
4112    fn test_eval_typed_stack() {
4113        use self::AssemblerEntry::*;
4114        use crate::constants::*;
4115
4116        let base_types = [
4117            ValueType::Generic,
4118            ValueType::U16,
4119            ValueType::U32,
4120            ValueType::F32,
4121        ];
4122
4123        // TODO: convert, reinterpret
4124        #[rustfmt::skip]
4125        let tests = [
4126            (
4127                &[
4128                    Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
4129                    Op(DW_OP_stack_value),
4130                ][..],
4131                Value::U16(0x1234),
4132            ),
4133            (
4134                &[
4135                    Op(DW_OP_regval_type), Uleb(0x1234), Uleb(1),
4136                    Op(DW_OP_stack_value),
4137                ][..],
4138                Value::U16(0x2340),
4139            ),
4140            (
4141                &[
4142                    Op(DW_OP_addr), U32(0x7fff_ffff),
4143                    Op(DW_OP_deref_type), U8(2), Uleb(1),
4144                    Op(DW_OP_stack_value),
4145                ][..],
4146                Value::U16(0xfff0),
4147            ),
4148            (
4149                &[
4150                    Op(DW_OP_lit1),
4151                    Op(DW_OP_addr), U32(0x7fff_ffff),
4152                    Op(DW_OP_xderef_type), U8(2), Uleb(1),
4153                    Op(DW_OP_stack_value),
4154                ][..],
4155                Value::U16(0xfff1),
4156            ),
4157            (
4158                &[
4159                    Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
4160                    Op(DW_OP_convert), Uleb(2),
4161                    Op(DW_OP_stack_value),
4162                ][..],
4163                Value::U32(0x1234),
4164            ),
4165            (
4166                &[
4167                    Op(DW_OP_const_type), Uleb(2), U8(4), U32(0x3f80_0000),
4168                    Op(DW_OP_reinterpret), Uleb(3),
4169                    Op(DW_OP_stack_value),
4170                ][..],
4171                Value::F32(1.0),
4172            ),
4173        ];
4174        for &(program, value) in &tests {
4175            let result = [Piece {
4176                size_in_bits: None,
4177                bit_offset: None,
4178                location: Location::Value { value },
4179            }];
4180
4181            check_eval_with_args(
4182                program,
4183                Ok(&result),
4184                encoding4(),
4185                None,
4186                None,
4187                None,
4188                |eval, mut result| {
4189                    while result != EvaluationResult::Complete {
4190                        result = match result {
4191                            EvaluationResult::RequiresMemory {
4192                                address,
4193                                size,
4194                                space,
4195                                base_type,
4196                            } => {
4197                                let mut v = address << 4;
4198                                if let Some(value) = space {
4199                                    v += value;
4200                                }
4201                                v &= (1u64 << (8 * size)) - 1;
4202                                let v = Value::from_u64(base_types[base_type.0], v)?;
4203                                eval.resume_with_memory(v)?
4204                            }
4205                            EvaluationResult::RequiresRegister {
4206                                register,
4207                                base_type,
4208                            } => {
4209                                let v = Value::from_u64(
4210                                    base_types[base_type.0],
4211                                    u64::from(register.0) << 4,
4212                                )?;
4213                                eval.resume_with_register(v)?
4214                            }
4215                            EvaluationResult::RequiresBaseType(offset) => {
4216                                eval.resume_with_base_type(base_types[offset.0])?
4217                            }
4218                            EvaluationResult::RequiresRelocatedAddress(address) => {
4219                                eval.resume_with_relocated_address(address)?
4220                            }
4221                            _ => panic!("Unexpected result {:?}", result),
4222                        }
4223                    }
4224                    Ok(result)
4225                },
4226            );
4227        }
4228    }
4229}