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