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