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