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