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