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