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