1#[cfg(feature = "read")]
4use alloc::vec::Vec;
5use core::mem;
6
7use super::util::{ArrayLike, ArrayVec};
8use crate::common::{DebugAddrIndex, DebugInfoOffset, Encoding, Register};
9use crate::constants;
10use crate::read::{Error, Reader, ReaderOffset, Result, StoreOnHeap, UnitOffset, Value, ValueType};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DieReference<T = usize> {
16 UnitRef(UnitOffset<T>),
18 DebugInfoRef(DebugInfoOffset<T>),
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum Operation<R, Offset = <R as Reader>::Offset>
35where
36 R: Reader<Offset = Offset>,
37 Offset: ReaderOffset,
38{
39 Deref {
41 base_type: UnitOffset<Offset>,
43 size: u8,
45 space: bool,
48 },
49 Drop,
51 Pick {
55 index: u8,
57 },
58 Swap,
60 Rot,
62 Abs,
64 And,
66 Div,
68 Minus,
70 Mod,
72 Mul,
74 Neg,
76 Not,
78 Or,
80 Plus,
82 PlusConstant {
84 value: u64,
86 },
87 Shl,
90 Shr,
93 Shra,
96 Xor,
98 Bra {
100 target: i16,
102 },
103 Eq,
105 Ge,
107 Gt,
109 Le,
111 Lt,
113 Ne,
115 Skip {
117 target: i16,
119 },
120 UnsignedConstant {
123 value: u64,
125 },
126 SignedConstant {
129 value: i64,
131 },
132 Register {
136 register: Register,
138 },
139 RegisterOffset {
142 register: Register,
144 offset: i64,
146 base_type: UnitOffset<Offset>,
148 },
149 FrameOffset {
152 offset: i64,
154 },
155 Nop,
157 PushObjectAddress,
159 Call {
163 offset: DieReference<Offset>,
165 },
166 VariableValue {
170 offset: DebugInfoOffset<Offset>,
172 },
173 TLS,
176 CallFrameCFA,
178 Piece {
180 size_in_bits: u64,
182 bit_offset: Option<u64>,
186 },
187 ImplicitValue {
192 data: R,
194 },
195 StackValue,
200 ImplicitPointer {
206 value: DebugInfoOffset<Offset>,
208 byte_offset: i64,
210 },
211 EntryValue {
215 expression: R,
217 },
218 ParameterRef {
226 offset: UnitOffset<Offset>,
228 },
229 Address {
233 address: u64,
235 },
236 AddressIndex {
241 index: DebugAddrIndex<Offset>,
243 },
244 ConstantIndex {
249 index: DebugAddrIndex<Offset>,
251 },
252 TypedLiteral {
256 base_type: UnitOffset<Offset>,
258 value: R,
260 },
261 Convert {
265 base_type: UnitOffset<Offset>,
267 },
268 Reinterpret {
273 base_type: UnitOffset<Offset>,
275 },
276 Uninitialized,
280 WasmLocal {
285 index: u32,
287 },
288 WasmGlobal {
293 index: u32,
295 },
296 WasmStack {
301 index: u32,
303 },
304}
305
306#[derive(Debug)]
307enum OperationEvaluationResult<R: Reader> {
308 Piece,
309 Incomplete,
310 Complete { location: Location<R> },
311 Waiting(EvaluationWaiting<R>, EvaluationResult<R>),
312}
313
314#[derive(Debug, Clone, Copy, PartialEq)]
316pub enum Location<R, Offset = <R as Reader>::Offset>
317where
318 R: Reader<Offset = Offset>,
319 Offset: ReaderOffset,
320{
321 Empty,
324 Register {
326 register: Register,
328 },
329 Address {
331 address: u64,
333 },
334 Value {
336 value: Value,
338 },
339 Bytes {
341 value: R,
343 },
344 ImplicitPointer {
346 value: DebugInfoOffset<Offset>,
348 byte_offset: i64,
350 },
351}
352
353impl<R, Offset> Location<R, Offset>
354where
355 R: Reader<Offset = Offset>,
356 Offset: ReaderOffset,
357{
358 pub fn is_empty(&self) -> bool {
360 matches!(*self, Location::Empty)
361 }
362}
363
364#[derive(Debug, Clone, Copy, PartialEq)]
367pub struct Piece<R, Offset = <R as Reader>::Offset>
368where
369 R: Reader<Offset = Offset>,
370 Offset: ReaderOffset,
371{
372 pub size_in_bits: Option<u64>,
375 pub bit_offset: Option<u64>,
387 pub location: Location<R, Offset>,
389}
390
391fn compute_pc<R: Reader>(pc: &R, bytecode: &R, offset: i16) -> Result<R> {
393 let pc_offset = pc.offset_from(bytecode);
394 let new_pc_offset = pc_offset.wrapping_add(R::Offset::from_i16(offset));
395 if new_pc_offset > bytecode.len() {
396 Err(Error::BadBranchTarget(new_pc_offset.into_u64()))
397 } else {
398 let mut new_pc = bytecode.clone();
399 new_pc.skip(new_pc_offset)?;
400 Ok(new_pc)
401 }
402}
403
404fn generic_type<O: ReaderOffset>() -> UnitOffset<O> {
405 UnitOffset(O::from_u64(0).unwrap())
406}
407
408impl<R, Offset> Operation<R, Offset>
409where
410 R: Reader<Offset = Offset>,
411 Offset: ReaderOffset,
412{
413 pub fn parse(bytes: &mut R, encoding: Encoding) -> Result<Operation<R, Offset>> {
422 let opcode = bytes.read_u8()?;
423 let name = constants::DwOp(opcode);
424 match name {
425 constants::DW_OP_addr => {
426 let address = bytes.read_address(encoding.address_size)?;
427 Ok(Operation::Address { address })
428 }
429 constants::DW_OP_deref => Ok(Operation::Deref {
430 base_type: generic_type(),
431 size: encoding.address_size,
432 space: false,
433 }),
434 constants::DW_OP_const1u => {
435 let value = bytes.read_u8()?;
436 Ok(Operation::UnsignedConstant {
437 value: u64::from(value),
438 })
439 }
440 constants::DW_OP_const1s => {
441 let value = bytes.read_i8()?;
442 Ok(Operation::SignedConstant {
443 value: i64::from(value),
444 })
445 }
446 constants::DW_OP_const2u => {
447 let value = bytes.read_u16()?;
448 Ok(Operation::UnsignedConstant {
449 value: u64::from(value),
450 })
451 }
452 constants::DW_OP_const2s => {
453 let value = bytes.read_i16()?;
454 Ok(Operation::SignedConstant {
455 value: i64::from(value),
456 })
457 }
458 constants::DW_OP_const4u => {
459 let value = bytes.read_u32()?;
460 Ok(Operation::UnsignedConstant {
461 value: u64::from(value),
462 })
463 }
464 constants::DW_OP_const4s => {
465 let value = bytes.read_i32()?;
466 Ok(Operation::SignedConstant {
467 value: i64::from(value),
468 })
469 }
470 constants::DW_OP_const8u => {
471 let value = bytes.read_u64()?;
472 Ok(Operation::UnsignedConstant { value })
473 }
474 constants::DW_OP_const8s => {
475 let value = bytes.read_i64()?;
476 Ok(Operation::SignedConstant { value })
477 }
478 constants::DW_OP_constu => {
479 let value = bytes.read_uleb128()?;
480 Ok(Operation::UnsignedConstant { value })
481 }
482 constants::DW_OP_consts => {
483 let value = bytes.read_sleb128()?;
484 Ok(Operation::SignedConstant { value })
485 }
486 constants::DW_OP_dup => Ok(Operation::Pick { index: 0 }),
487 constants::DW_OP_drop => Ok(Operation::Drop),
488 constants::DW_OP_over => Ok(Operation::Pick { index: 1 }),
489 constants::DW_OP_pick => {
490 let value = bytes.read_u8()?;
491 Ok(Operation::Pick { index: value })
492 }
493 constants::DW_OP_swap => Ok(Operation::Swap),
494 constants::DW_OP_rot => Ok(Operation::Rot),
495 constants::DW_OP_xderef => Ok(Operation::Deref {
496 base_type: generic_type(),
497 size: encoding.address_size,
498 space: true,
499 }),
500 constants::DW_OP_abs => Ok(Operation::Abs),
501 constants::DW_OP_and => Ok(Operation::And),
502 constants::DW_OP_div => Ok(Operation::Div),
503 constants::DW_OP_minus => Ok(Operation::Minus),
504 constants::DW_OP_mod => Ok(Operation::Mod),
505 constants::DW_OP_mul => Ok(Operation::Mul),
506 constants::DW_OP_neg => Ok(Operation::Neg),
507 constants::DW_OP_not => Ok(Operation::Not),
508 constants::DW_OP_or => Ok(Operation::Or),
509 constants::DW_OP_plus => Ok(Operation::Plus),
510 constants::DW_OP_plus_uconst => {
511 let value = bytes.read_uleb128()?;
512 Ok(Operation::PlusConstant { value })
513 }
514 constants::DW_OP_shl => Ok(Operation::Shl),
515 constants::DW_OP_shr => Ok(Operation::Shr),
516 constants::DW_OP_shra => Ok(Operation::Shra),
517 constants::DW_OP_xor => Ok(Operation::Xor),
518 constants::DW_OP_bra => {
519 let target = bytes.read_i16()?;
520 Ok(Operation::Bra { target })
521 }
522 constants::DW_OP_eq => Ok(Operation::Eq),
523 constants::DW_OP_ge => Ok(Operation::Ge),
524 constants::DW_OP_gt => Ok(Operation::Gt),
525 constants::DW_OP_le => Ok(Operation::Le),
526 constants::DW_OP_lt => Ok(Operation::Lt),
527 constants::DW_OP_ne => Ok(Operation::Ne),
528 constants::DW_OP_skip => {
529 let target = bytes.read_i16()?;
530 Ok(Operation::Skip { target })
531 }
532 constants::DW_OP_lit0
533 | constants::DW_OP_lit1
534 | constants::DW_OP_lit2
535 | constants::DW_OP_lit3
536 | constants::DW_OP_lit4
537 | constants::DW_OP_lit5
538 | constants::DW_OP_lit6
539 | constants::DW_OP_lit7
540 | constants::DW_OP_lit8
541 | constants::DW_OP_lit9
542 | constants::DW_OP_lit10
543 | constants::DW_OP_lit11
544 | constants::DW_OP_lit12
545 | constants::DW_OP_lit13
546 | constants::DW_OP_lit14
547 | constants::DW_OP_lit15
548 | constants::DW_OP_lit16
549 | constants::DW_OP_lit17
550 | constants::DW_OP_lit18
551 | constants::DW_OP_lit19
552 | constants::DW_OP_lit20
553 | constants::DW_OP_lit21
554 | constants::DW_OP_lit22
555 | constants::DW_OP_lit23
556 | constants::DW_OP_lit24
557 | constants::DW_OP_lit25
558 | constants::DW_OP_lit26
559 | constants::DW_OP_lit27
560 | constants::DW_OP_lit28
561 | constants::DW_OP_lit29
562 | constants::DW_OP_lit30
563 | constants::DW_OP_lit31 => Ok(Operation::UnsignedConstant {
564 value: (opcode - constants::DW_OP_lit0.0).into(),
565 }),
566 constants::DW_OP_reg0
567 | constants::DW_OP_reg1
568 | constants::DW_OP_reg2
569 | constants::DW_OP_reg3
570 | constants::DW_OP_reg4
571 | constants::DW_OP_reg5
572 | constants::DW_OP_reg6
573 | constants::DW_OP_reg7
574 | constants::DW_OP_reg8
575 | constants::DW_OP_reg9
576 | constants::DW_OP_reg10
577 | constants::DW_OP_reg11
578 | constants::DW_OP_reg12
579 | constants::DW_OP_reg13
580 | constants::DW_OP_reg14
581 | constants::DW_OP_reg15
582 | constants::DW_OP_reg16
583 | constants::DW_OP_reg17
584 | constants::DW_OP_reg18
585 | constants::DW_OP_reg19
586 | constants::DW_OP_reg20
587 | constants::DW_OP_reg21
588 | constants::DW_OP_reg22
589 | constants::DW_OP_reg23
590 | constants::DW_OP_reg24
591 | constants::DW_OP_reg25
592 | constants::DW_OP_reg26
593 | constants::DW_OP_reg27
594 | constants::DW_OP_reg28
595 | constants::DW_OP_reg29
596 | constants::DW_OP_reg30
597 | constants::DW_OP_reg31 => Ok(Operation::Register {
598 register: Register((opcode - constants::DW_OP_reg0.0).into()),
599 }),
600 constants::DW_OP_breg0
601 | constants::DW_OP_breg1
602 | constants::DW_OP_breg2
603 | constants::DW_OP_breg3
604 | constants::DW_OP_breg4
605 | constants::DW_OP_breg5
606 | constants::DW_OP_breg6
607 | constants::DW_OP_breg7
608 | constants::DW_OP_breg8
609 | constants::DW_OP_breg9
610 | constants::DW_OP_breg10
611 | constants::DW_OP_breg11
612 | constants::DW_OP_breg12
613 | constants::DW_OP_breg13
614 | constants::DW_OP_breg14
615 | constants::DW_OP_breg15
616 | constants::DW_OP_breg16
617 | constants::DW_OP_breg17
618 | constants::DW_OP_breg18
619 | constants::DW_OP_breg19
620 | constants::DW_OP_breg20
621 | constants::DW_OP_breg21
622 | constants::DW_OP_breg22
623 | constants::DW_OP_breg23
624 | constants::DW_OP_breg24
625 | constants::DW_OP_breg25
626 | constants::DW_OP_breg26
627 | constants::DW_OP_breg27
628 | constants::DW_OP_breg28
629 | constants::DW_OP_breg29
630 | constants::DW_OP_breg30
631 | constants::DW_OP_breg31 => {
632 let value = bytes.read_sleb128()?;
633 Ok(Operation::RegisterOffset {
634 register: Register((opcode - constants::DW_OP_breg0.0).into()),
635 offset: value,
636 base_type: generic_type(),
637 })
638 }
639 constants::DW_OP_regx => {
640 let register = bytes.read_uleb128().and_then(Register::from_u64)?;
641 Ok(Operation::Register { register })
642 }
643 constants::DW_OP_fbreg => {
644 let value = bytes.read_sleb128()?;
645 Ok(Operation::FrameOffset { offset: value })
646 }
647 constants::DW_OP_bregx => {
648 let register = bytes.read_uleb128().and_then(Register::from_u64)?;
649 let offset = bytes.read_sleb128()?;
650 Ok(Operation::RegisterOffset {
651 register,
652 offset,
653 base_type: generic_type(),
654 })
655 }
656 constants::DW_OP_piece => {
657 let size = bytes.read_uleb128()?;
658 Ok(Operation::Piece {
659 size_in_bits: 8 * size,
660 bit_offset: None,
661 })
662 }
663 constants::DW_OP_deref_size => {
664 let size = bytes.read_u8()?;
665 Ok(Operation::Deref {
666 base_type: generic_type(),
667 size,
668 space: false,
669 })
670 }
671 constants::DW_OP_xderef_size => {
672 let size = bytes.read_u8()?;
673 Ok(Operation::Deref {
674 base_type: generic_type(),
675 size,
676 space: true,
677 })
678 }
679 constants::DW_OP_nop => Ok(Operation::Nop),
680 constants::DW_OP_push_object_address => Ok(Operation::PushObjectAddress),
681 constants::DW_OP_call2 => {
682 let value = bytes.read_u16().map(R::Offset::from_u16)?;
683 Ok(Operation::Call {
684 offset: DieReference::UnitRef(UnitOffset(value)),
685 })
686 }
687 constants::DW_OP_call4 => {
688 let value = bytes.read_u32().map(R::Offset::from_u32)?;
689 Ok(Operation::Call {
690 offset: DieReference::UnitRef(UnitOffset(value)),
691 })
692 }
693 constants::DW_OP_call_ref => {
694 let value = bytes.read_offset(encoding.format)?;
695 Ok(Operation::Call {
696 offset: DieReference::DebugInfoRef(DebugInfoOffset(value)),
697 })
698 }
699 constants::DW_OP_GNU_variable_value => {
700 let value = bytes.read_offset(encoding.format)?;
701 Ok(Operation::VariableValue {
702 offset: DebugInfoOffset(value),
703 })
704 }
705 constants::DW_OP_form_tls_address | constants::DW_OP_GNU_push_tls_address => {
706 Ok(Operation::TLS)
707 }
708 constants::DW_OP_call_frame_cfa => Ok(Operation::CallFrameCFA),
709 constants::DW_OP_bit_piece => {
710 let size = bytes.read_uleb128()?;
711 let offset = bytes.read_uleb128()?;
712 Ok(Operation::Piece {
713 size_in_bits: size,
714 bit_offset: Some(offset),
715 })
716 }
717 constants::DW_OP_implicit_value => {
718 let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
719 let data = bytes.split(len)?;
720 Ok(Operation::ImplicitValue { data })
721 }
722 constants::DW_OP_stack_value => Ok(Operation::StackValue),
723 constants::DW_OP_implicit_pointer | constants::DW_OP_GNU_implicit_pointer => {
724 let value = if encoding.version == 2 {
725 bytes
726 .read_address(encoding.address_size)
727 .and_then(Offset::from_u64)?
728 } else {
729 bytes.read_offset(encoding.format)?
730 };
731 let byte_offset = bytes.read_sleb128()?;
732 Ok(Operation::ImplicitPointer {
733 value: DebugInfoOffset(value),
734 byte_offset,
735 })
736 }
737 constants::DW_OP_addrx | constants::DW_OP_GNU_addr_index => {
738 let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
739 Ok(Operation::AddressIndex {
740 index: DebugAddrIndex(index),
741 })
742 }
743 constants::DW_OP_constx | constants::DW_OP_GNU_const_index => {
744 let index = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
745 Ok(Operation::ConstantIndex {
746 index: DebugAddrIndex(index),
747 })
748 }
749 constants::DW_OP_entry_value | constants::DW_OP_GNU_entry_value => {
750 let len = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
751 let expression = bytes.split(len)?;
752 Ok(Operation::EntryValue { expression })
753 }
754 constants::DW_OP_GNU_parameter_ref => {
755 let value = bytes.read_u32().map(R::Offset::from_u32)?;
756 Ok(Operation::ParameterRef {
757 offset: UnitOffset(value),
758 })
759 }
760 constants::DW_OP_const_type | constants::DW_OP_GNU_const_type => {
761 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
762 let len = bytes.read_u8()?;
763 let value = bytes.split(R::Offset::from_u8(len))?;
764 Ok(Operation::TypedLiteral {
765 base_type: UnitOffset(base_type),
766 value,
767 })
768 }
769 constants::DW_OP_regval_type | constants::DW_OP_GNU_regval_type => {
770 let register = bytes.read_uleb128().and_then(Register::from_u64)?;
771 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
772 Ok(Operation::RegisterOffset {
773 register,
774 offset: 0,
775 base_type: UnitOffset(base_type),
776 })
777 }
778 constants::DW_OP_deref_type | constants::DW_OP_GNU_deref_type => {
779 let size = bytes.read_u8()?;
780 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
781 Ok(Operation::Deref {
782 base_type: UnitOffset(base_type),
783 size,
784 space: false,
785 })
786 }
787 constants::DW_OP_xderef_type => {
788 let size = bytes.read_u8()?;
789 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
790 Ok(Operation::Deref {
791 base_type: UnitOffset(base_type),
792 size,
793 space: true,
794 })
795 }
796 constants::DW_OP_convert | constants::DW_OP_GNU_convert => {
797 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
798 Ok(Operation::Convert {
799 base_type: UnitOffset(base_type),
800 })
801 }
802 constants::DW_OP_reinterpret | constants::DW_OP_GNU_reinterpret => {
803 let base_type = bytes.read_uleb128().and_then(R::Offset::from_u64)?;
804 Ok(Operation::Reinterpret {
805 base_type: UnitOffset(base_type),
806 })
807 }
808 constants::DW_OP_GNU_uninit => Ok(Operation::Uninitialized),
809 constants::DW_OP_WASM_location => match bytes.read_u8()? {
810 0x0 => {
811 let index = bytes.read_uleb128_u32()?;
812 Ok(Operation::WasmLocal { index })
813 }
814 0x1 => {
815 let index = bytes.read_uleb128_u32()?;
816 Ok(Operation::WasmGlobal { index })
817 }
818 0x2 => {
819 let index = bytes.read_uleb128_u32()?;
820 Ok(Operation::WasmStack { index })
821 }
822 0x3 => {
823 let index = bytes.read_u32()?;
824 Ok(Operation::WasmGlobal { index })
825 }
826 _ => Err(Error::InvalidExpression(name)),
827 },
828 _ => Err(Error::InvalidExpression(name)),
829 }
830 }
831}
832
833#[derive(Debug)]
834enum EvaluationState<R: Reader> {
835 Start(Option<u64>),
836 Ready,
837 Error(Error),
838 Complete,
839 Waiting(EvaluationWaiting<R>),
840}
841
842#[derive(Debug)]
843enum EvaluationWaiting<R: Reader> {
844 Memory,
845 Register { offset: i64 },
846 FrameBase { offset: i64 },
847 Tls,
848 Cfa,
849 AtLocation,
850 EntryValue,
851 ParameterRef,
852 RelocatedAddress,
853 IndexedAddress,
854 TypedLiteral { value: R },
855 Convert,
856 Reinterpret,
857}
858
859#[derive(Debug, PartialEq)]
863pub enum EvaluationResult<R: Reader> {
864 Complete,
866 RequiresMemory {
870 address: u64,
872 size: u8,
875 space: Option<u64>,
877 base_type: UnitOffset<R::Offset>,
879 },
880 RequiresRegister {
884 register: Register,
886 base_type: UnitOffset<R::Offset>,
888 },
889 RequiresFrameBase,
895 RequiresTls(u64),
899 RequiresCallFrameCfa,
903 RequiresAtLocation(DieReference<R::Offset>),
908 RequiresEntryValue(Expression<R>),
913 RequiresParameterRef(UnitOffset<R::Offset>),
918 RequiresRelocatedAddress(u64),
922 RequiresIndexedAddress {
927 index: DebugAddrIndex<R::Offset>,
930 relocate: bool,
932 },
933 RequiresBaseType(UnitOffset<R::Offset>),
938}
939
940#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
942pub struct Expression<R: Reader>(pub R);
943
944impl<R: Reader> Expression<R> {
945 #[cfg(feature = "read")]
964 #[inline]
965 pub fn evaluation(self, encoding: Encoding) -> Evaluation<R> {
966 Evaluation::new(self.0, encoding)
967 }
968
969 pub fn operations(self, encoding: Encoding) -> OperationIter<R> {
971 OperationIter {
972 input: self.0,
973 encoding,
974 }
975 }
976}
977
978#[derive(Debug, Clone, Copy)]
980pub struct OperationIter<R: Reader> {
981 input: R,
982 encoding: Encoding,
983}
984
985impl<R: Reader> OperationIter<R> {
986 pub fn next(&mut self) -> Result<Option<Operation<R>>> {
988 if self.input.is_empty() {
989 return Ok(None);
990 }
991 match Operation::parse(&mut self.input, self.encoding) {
992 Ok(op) => Ok(Some(op)),
993 Err(e) => {
994 self.input.empty();
995 Err(e)
996 }
997 }
998 }
999
1000 pub fn offset_from(&self, expression: &Expression<R>) -> R::Offset {
1002 self.input.offset_from(&expression.0)
1003 }
1004}
1005
1006#[cfg(feature = "fallible-iterator")]
1007impl<R: Reader> fallible_iterator::FallibleIterator for OperationIter<R> {
1008 type Item = Operation<R>;
1009 type Error = Error;
1010
1011 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
1012 OperationIter::next(self)
1013 }
1014}
1015
1016impl<R: Reader> Iterator for OperationIter<R> {
1017 type Item = Result<Operation<R>>;
1018
1019 fn next(&mut self) -> Option<Self::Item> {
1020 OperationIter::next(self).transpose()
1021 }
1022}
1023
1024#[cfg_attr(
1027 feature = "read",
1028 doc = "
1029Normally you would only need to use [`StoreOnHeap`], which places the stacks and the results
1030on the heap using [`Vec`]. This is the default storage type parameter for [`Evaluation`].
1031"
1032)]
1033pub trait EvaluationStorage<R: Reader> {
1071 type Stack: ArrayLike<Item = Value>;
1073 type ExpressionStack: ArrayLike<Item = (R, R)>;
1075 type Result: ArrayLike<Item = Piece<R>>;
1077}
1078
1079#[cfg(feature = "read")]
1080impl<R: Reader> EvaluationStorage<R> for StoreOnHeap {
1081 type Stack = Vec<Value>;
1082 type ExpressionStack = Vec<(R, R)>;
1083 type Result = Vec<Piece<R>>;
1084}
1085
1086#[derive(Debug)]
1132pub struct Evaluation<R: Reader, S: EvaluationStorage<R> = StoreOnHeap> {
1133 bytecode: R,
1134 encoding: Encoding,
1135 object_address: Option<u64>,
1136 max_iterations: Option<u32>,
1137 iteration: u32,
1138 state: EvaluationState<R>,
1139
1140 addr_mask: u64,
1144
1145 stack: ArrayVec<S::Stack>,
1147
1148 pc: R,
1150
1151 expression_stack: ArrayVec<S::ExpressionStack>,
1154
1155 value_result: Option<Value>,
1156 result: ArrayVec<S::Result>,
1157}
1158
1159#[cfg(feature = "read")]
1160impl<R: Reader> Evaluation<R> {
1161 pub fn new(bytecode: R, encoding: Encoding) -> Self {
1166 Self::new_in(bytecode, encoding)
1167 }
1168
1169 pub fn result(self) -> Vec<Piece<R>> {
1174 match self.state {
1175 EvaluationState::Complete => self.result.into_vec(),
1176 _ => {
1177 panic!("Called `Evaluation::result` on an `Evaluation` that has not been completed")
1178 }
1179 }
1180 }
1181}
1182
1183impl<R: Reader, S: EvaluationStorage<R>> Evaluation<R, S> {
1184 pub fn new_in(bytecode: R, encoding: Encoding) -> Self {
1189 let pc = bytecode.clone();
1190 Evaluation {
1191 bytecode,
1192 encoding,
1193 object_address: None,
1194 max_iterations: None,
1195 iteration: 0,
1196 state: EvaluationState::Start(None),
1197 addr_mask: if encoding.address_size == 8 {
1198 !0u64
1199 } else {
1200 (1 << (8 * u64::from(encoding.address_size))) - 1
1201 },
1202 stack: Default::default(),
1203 expression_stack: Default::default(),
1204 pc,
1205 value_result: None,
1206 result: Default::default(),
1207 }
1208 }
1209
1210 pub fn set_initial_value(&mut self, value: u64) {
1221 match self.state {
1222 EvaluationState::Start(None) => {
1223 self.state = EvaluationState::Start(Some(value));
1224 }
1225 _ => panic!(
1226 "`Evaluation::set_initial_value` was called twice, or after evaluation began."
1227 ),
1228 };
1229 }
1230
1231 pub fn set_object_address(&mut self, value: u64) {
1236 self.object_address = Some(value);
1237 }
1238
1239 pub fn set_max_iterations(&mut self, value: u32) {
1249 self.max_iterations = Some(value);
1250 }
1251
1252 fn pop(&mut self) -> Result<Value> {
1253 match self.stack.pop() {
1254 Some(value) => Ok(value),
1255 None => Err(Error::NotEnoughStackItems),
1256 }
1257 }
1258
1259 fn push(&mut self, value: Value) -> Result<()> {
1260 self.stack.try_push(value).map_err(|_| Error::StackFull)
1261 }
1262
1263 fn evaluate_one_operation(&mut self) -> Result<OperationEvaluationResult<R>> {
1264 let operation = Operation::parse(&mut self.pc, self.encoding)?;
1265
1266 match operation {
1267 Operation::Deref {
1268 base_type,
1269 size,
1270 space,
1271 } => {
1272 if size > self.encoding.address_size {
1273 return Err(Error::InvalidDerefSize(size));
1274 }
1275 let entry = self.pop()?;
1276 let addr = entry.to_u64(self.addr_mask)?;
1277 let addr_space = if space {
1278 let entry = self.pop()?;
1279 let value = entry.to_u64(self.addr_mask)?;
1280 Some(value)
1281 } else {
1282 None
1283 };
1284 return Ok(OperationEvaluationResult::Waiting(
1285 EvaluationWaiting::Memory,
1286 EvaluationResult::RequiresMemory {
1287 address: addr,
1288 size,
1289 space: addr_space,
1290 base_type,
1291 },
1292 ));
1293 }
1294
1295 Operation::Drop => {
1296 self.pop()?;
1297 }
1298 Operation::Pick { index } => {
1299 let len = self.stack.len();
1300 let index = index as usize;
1301 if index >= len {
1302 return Err(Error::NotEnoughStackItems);
1303 }
1304 let value = self.stack[len - index - 1];
1305 self.push(value)?;
1306 }
1307 Operation::Swap => {
1308 let top = self.pop()?;
1309 let next = self.pop()?;
1310 self.push(top)?;
1311 self.push(next)?;
1312 }
1313 Operation::Rot => {
1314 let one = self.pop()?;
1315 let two = self.pop()?;
1316 let three = self.pop()?;
1317 self.push(one)?;
1318 self.push(three)?;
1319 self.push(two)?;
1320 }
1321
1322 Operation::Abs => {
1323 let value = self.pop()?;
1324 let result = value.abs(self.addr_mask)?;
1325 self.push(result)?;
1326 }
1327 Operation::And => {
1328 let rhs = self.pop()?;
1329 let lhs = self.pop()?;
1330 let result = lhs.and(rhs, self.addr_mask)?;
1331 self.push(result)?;
1332 }
1333 Operation::Div => {
1334 let rhs = self.pop()?;
1335 let lhs = self.pop()?;
1336 let result = lhs.div(rhs, self.addr_mask)?;
1337 self.push(result)?;
1338 }
1339 Operation::Minus => {
1340 let rhs = self.pop()?;
1341 let lhs = self.pop()?;
1342 let result = lhs.sub(rhs, self.addr_mask)?;
1343 self.push(result)?;
1344 }
1345 Operation::Mod => {
1346 let rhs = self.pop()?;
1347 let lhs = self.pop()?;
1348 let result = lhs.rem(rhs, self.addr_mask)?;
1349 self.push(result)?;
1350 }
1351 Operation::Mul => {
1352 let rhs = self.pop()?;
1353 let lhs = self.pop()?;
1354 let result = lhs.mul(rhs, self.addr_mask)?;
1355 self.push(result)?;
1356 }
1357 Operation::Neg => {
1358 let v = self.pop()?;
1359 let result = v.neg(self.addr_mask)?;
1360 self.push(result)?;
1361 }
1362 Operation::Not => {
1363 let value = self.pop()?;
1364 let result = value.not(self.addr_mask)?;
1365 self.push(result)?;
1366 }
1367 Operation::Or => {
1368 let rhs = self.pop()?;
1369 let lhs = self.pop()?;
1370 let result = lhs.or(rhs, self.addr_mask)?;
1371 self.push(result)?;
1372 }
1373 Operation::Plus => {
1374 let rhs = self.pop()?;
1375 let lhs = self.pop()?;
1376 let result = lhs.add(rhs, self.addr_mask)?;
1377 self.push(result)?;
1378 }
1379 Operation::PlusConstant { value } => {
1380 let lhs = self.pop()?;
1381 let rhs = Value::from_u64(lhs.value_type(), value)?;
1382 let result = lhs.add(rhs, self.addr_mask)?;
1383 self.push(result)?;
1384 }
1385 Operation::Shl => {
1386 let rhs = self.pop()?;
1387 let lhs = self.pop()?;
1388 let result = lhs.shl(rhs, self.addr_mask)?;
1389 self.push(result)?;
1390 }
1391 Operation::Shr => {
1392 let rhs = self.pop()?;
1393 let lhs = self.pop()?;
1394 let result = lhs.shr(rhs, self.addr_mask)?;
1395 self.push(result)?;
1396 }
1397 Operation::Shra => {
1398 let rhs = self.pop()?;
1399 let lhs = self.pop()?;
1400 let result = lhs.shra(rhs, self.addr_mask)?;
1401 self.push(result)?;
1402 }
1403 Operation::Xor => {
1404 let rhs = self.pop()?;
1405 let lhs = self.pop()?;
1406 let result = lhs.xor(rhs, self.addr_mask)?;
1407 self.push(result)?;
1408 }
1409
1410 Operation::Bra { target } => {
1411 let entry = self.pop()?;
1412 let v = entry.to_u64(self.addr_mask)?;
1413 if v != 0 {
1414 self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
1415 }
1416 }
1417
1418 Operation::Eq => {
1419 let rhs = self.pop()?;
1420 let lhs = self.pop()?;
1421 let result = lhs.eq(rhs, self.addr_mask)?;
1422 self.push(result)?;
1423 }
1424 Operation::Ge => {
1425 let rhs = self.pop()?;
1426 let lhs = self.pop()?;
1427 let result = lhs.ge(rhs, self.addr_mask)?;
1428 self.push(result)?;
1429 }
1430 Operation::Gt => {
1431 let rhs = self.pop()?;
1432 let lhs = self.pop()?;
1433 let result = lhs.gt(rhs, self.addr_mask)?;
1434 self.push(result)?;
1435 }
1436 Operation::Le => {
1437 let rhs = self.pop()?;
1438 let lhs = self.pop()?;
1439 let result = lhs.le(rhs, self.addr_mask)?;
1440 self.push(result)?;
1441 }
1442 Operation::Lt => {
1443 let rhs = self.pop()?;
1444 let lhs = self.pop()?;
1445 let result = lhs.lt(rhs, self.addr_mask)?;
1446 self.push(result)?;
1447 }
1448 Operation::Ne => {
1449 let rhs = self.pop()?;
1450 let lhs = self.pop()?;
1451 let result = lhs.ne(rhs, self.addr_mask)?;
1452 self.push(result)?;
1453 }
1454
1455 Operation::Skip { target } => {
1456 self.pc = compute_pc(&self.pc, &self.bytecode, target)?;
1457 }
1458
1459 Operation::UnsignedConstant { value } => {
1460 self.push(Value::Generic(value))?;
1461 }
1462
1463 Operation::SignedConstant { value } => {
1464 self.push(Value::Generic(value as u64))?;
1465 }
1466
1467 Operation::RegisterOffset {
1468 register,
1469 offset,
1470 base_type,
1471 } => {
1472 return Ok(OperationEvaluationResult::Waiting(
1473 EvaluationWaiting::Register { offset },
1474 EvaluationResult::RequiresRegister {
1475 register,
1476 base_type,
1477 },
1478 ));
1479 }
1480
1481 Operation::FrameOffset { offset } => {
1482 return Ok(OperationEvaluationResult::Waiting(
1483 EvaluationWaiting::FrameBase { offset },
1484 EvaluationResult::RequiresFrameBase,
1485 ));
1486 }
1487
1488 Operation::Nop => {}
1489
1490 Operation::PushObjectAddress => {
1491 if let Some(value) = self.object_address {
1492 self.push(Value::Generic(value))?;
1493 } else {
1494 return Err(Error::InvalidPushObjectAddress);
1495 }
1496 }
1497
1498 Operation::Call { offset } => {
1499 return Ok(OperationEvaluationResult::Waiting(
1500 EvaluationWaiting::AtLocation,
1501 EvaluationResult::RequiresAtLocation(offset),
1502 ));
1503 }
1504
1505 Operation::TLS => {
1506 let entry = self.pop()?;
1507 let index = entry.to_u64(self.addr_mask)?;
1508 return Ok(OperationEvaluationResult::Waiting(
1509 EvaluationWaiting::Tls,
1510 EvaluationResult::RequiresTls(index),
1511 ));
1512 }
1513
1514 Operation::CallFrameCFA => {
1515 return Ok(OperationEvaluationResult::Waiting(
1516 EvaluationWaiting::Cfa,
1517 EvaluationResult::RequiresCallFrameCfa,
1518 ));
1519 }
1520
1521 Operation::Register { register } => {
1522 let location = Location::Register { register };
1523 return Ok(OperationEvaluationResult::Complete { location });
1524 }
1525
1526 Operation::ImplicitValue { ref data } => {
1527 let location = Location::Bytes {
1528 value: data.clone(),
1529 };
1530 return Ok(OperationEvaluationResult::Complete { location });
1531 }
1532
1533 Operation::StackValue => {
1534 let value = self.pop()?;
1535 let location = Location::Value { value };
1536 return Ok(OperationEvaluationResult::Complete { location });
1537 }
1538
1539 Operation::ImplicitPointer { value, byte_offset } => {
1540 let location = Location::ImplicitPointer { value, byte_offset };
1541 return Ok(OperationEvaluationResult::Complete { location });
1542 }
1543
1544 Operation::EntryValue { ref expression } => {
1545 return Ok(OperationEvaluationResult::Waiting(
1546 EvaluationWaiting::EntryValue,
1547 EvaluationResult::RequiresEntryValue(Expression(expression.clone())),
1548 ));
1549 }
1550
1551 Operation::ParameterRef { offset } => {
1552 return Ok(OperationEvaluationResult::Waiting(
1553 EvaluationWaiting::ParameterRef,
1554 EvaluationResult::RequiresParameterRef(offset),
1555 ));
1556 }
1557
1558 Operation::Address { address } => {
1559 return Ok(OperationEvaluationResult::Waiting(
1560 EvaluationWaiting::RelocatedAddress,
1561 EvaluationResult::RequiresRelocatedAddress(address),
1562 ));
1563 }
1564
1565 Operation::AddressIndex { index } => {
1566 return Ok(OperationEvaluationResult::Waiting(
1567 EvaluationWaiting::IndexedAddress,
1568 EvaluationResult::RequiresIndexedAddress {
1569 index,
1570 relocate: true,
1571 },
1572 ));
1573 }
1574
1575 Operation::ConstantIndex { index } => {
1576 return Ok(OperationEvaluationResult::Waiting(
1577 EvaluationWaiting::IndexedAddress,
1578 EvaluationResult::RequiresIndexedAddress {
1579 index,
1580 relocate: false,
1581 },
1582 ));
1583 }
1584
1585 Operation::Piece {
1586 size_in_bits,
1587 bit_offset,
1588 } => {
1589 let location = if self.stack.is_empty() {
1590 Location::Empty
1591 } else {
1592 let entry = self.pop()?;
1593 let address = entry.to_u64(self.addr_mask)?;
1594 Location::Address { address }
1595 };
1596 self.result
1597 .try_push(Piece {
1598 size_in_bits: Some(size_in_bits),
1599 bit_offset,
1600 location,
1601 })
1602 .map_err(|_| Error::StackFull)?;
1603 return Ok(OperationEvaluationResult::Piece);
1604 }
1605
1606 Operation::TypedLiteral { base_type, value } => {
1607 return Ok(OperationEvaluationResult::Waiting(
1608 EvaluationWaiting::TypedLiteral { value },
1609 EvaluationResult::RequiresBaseType(base_type),
1610 ));
1611 }
1612 Operation::Convert { base_type } => {
1613 return Ok(OperationEvaluationResult::Waiting(
1614 EvaluationWaiting::Convert,
1615 EvaluationResult::RequiresBaseType(base_type),
1616 ));
1617 }
1618 Operation::Reinterpret { base_type } => {
1619 return Ok(OperationEvaluationResult::Waiting(
1620 EvaluationWaiting::Reinterpret,
1621 EvaluationResult::RequiresBaseType(base_type),
1622 ));
1623 }
1624 Operation::VariableValue { .. }
1625 | Operation::Uninitialized
1626 | Operation::WasmLocal { .. }
1627 | Operation::WasmGlobal { .. }
1628 | Operation::WasmStack { .. } => {
1629 return Err(Error::UnsupportedEvaluation);
1630 }
1631 }
1632
1633 Ok(OperationEvaluationResult::Incomplete)
1634 }
1635
1636 pub fn value_result(&self) -> Option<Value> {
1644 match self.state {
1645 EvaluationState::Complete => self.value_result,
1646 _ => {
1647 panic!(
1648 "Called `Evaluation::value_result` on an `Evaluation` that has not been completed"
1649 )
1650 }
1651 }
1652 }
1653
1654 pub fn as_result(&self) -> &[Piece<R>] {
1659 match self.state {
1660 EvaluationState::Complete => &self.result,
1661 _ => {
1662 panic!(
1663 "Called `Evaluation::as_result` on an `Evaluation` that has not been completed"
1664 )
1665 }
1666 }
1667 }
1668
1669 pub fn evaluate(&mut self) -> Result<EvaluationResult<R>> {
1675 match self.state {
1676 EvaluationState::Start(initial_value) => {
1677 if let Some(value) = initial_value {
1678 self.push(Value::Generic(value))?;
1679 }
1680 self.state = EvaluationState::Ready;
1681 }
1682 EvaluationState::Ready => {}
1683 EvaluationState::Error(err) => return Err(err),
1684 EvaluationState::Complete => return Ok(EvaluationResult::Complete),
1685 EvaluationState::Waiting(_) => panic!(),
1686 };
1687
1688 match self.evaluate_internal() {
1689 Ok(r) => Ok(r),
1690 Err(e) => {
1691 self.state = EvaluationState::Error(e);
1692 Err(e)
1693 }
1694 }
1695 }
1696
1697 pub fn resume_with_memory(&mut self, value: Value) -> Result<EvaluationResult<R>> {
1705 match self.state {
1706 EvaluationState::Error(err) => return Err(err),
1707 EvaluationState::Waiting(EvaluationWaiting::Memory) => {
1708 self.push(value)?;
1709 }
1710 _ => panic!(
1711 "Called `Evaluation::resume_with_memory` without a preceding `EvaluationResult::RequiresMemory`"
1712 ),
1713 };
1714
1715 self.evaluate_internal()
1716 }
1717
1718 pub fn resume_with_register(&mut self, value: Value) -> Result<EvaluationResult<R>> {
1726 match self.state {
1727 EvaluationState::Error(err) => return Err(err),
1728 EvaluationState::Waiting(EvaluationWaiting::Register { offset }) => {
1729 let offset = Value::from_u64(value.value_type(), offset as u64)?;
1730 let value = value.add(offset, self.addr_mask)?;
1731 self.push(value)?;
1732 }
1733 _ => panic!(
1734 "Called `Evaluation::resume_with_register` without a preceding `EvaluationResult::RequiresRegister`"
1735 ),
1736 };
1737
1738 self.evaluate_internal()
1739 }
1740
1741 pub fn resume_with_frame_base(&mut self, frame_base: u64) -> Result<EvaluationResult<R>> {
1749 match self.state {
1750 EvaluationState::Error(err) => return Err(err),
1751 EvaluationState::Waiting(EvaluationWaiting::FrameBase { offset }) => {
1752 self.push(Value::Generic(frame_base.wrapping_add(offset as u64)))?;
1753 }
1754 _ => panic!(
1755 "Called `Evaluation::resume_with_frame_base` without a preceding `EvaluationResult::RequiresFrameBase`"
1756 ),
1757 };
1758
1759 self.evaluate_internal()
1760 }
1761
1762 pub fn resume_with_tls(&mut self, value: u64) -> Result<EvaluationResult<R>> {
1770 match self.state {
1771 EvaluationState::Error(err) => return Err(err),
1772 EvaluationState::Waiting(EvaluationWaiting::Tls) => {
1773 self.push(Value::Generic(value))?;
1774 }
1775 _ => panic!(
1776 "Called `Evaluation::resume_with_tls` without a preceding `EvaluationResult::RequiresTls`"
1777 ),
1778 };
1779
1780 self.evaluate_internal()
1781 }
1782
1783 pub fn resume_with_call_frame_cfa(&mut self, cfa: u64) -> Result<EvaluationResult<R>> {
1791 match self.state {
1792 EvaluationState::Error(err) => return Err(err),
1793 EvaluationState::Waiting(EvaluationWaiting::Cfa) => {
1794 self.push(Value::Generic(cfa))?;
1795 }
1796 _ => panic!(
1797 "Called `Evaluation::resume_with_call_frame_cfa` without a preceding `EvaluationResult::RequiresCallFrameCfa`"
1798 ),
1799 };
1800
1801 self.evaluate_internal()
1802 }
1803
1804 pub fn resume_with_at_location(&mut self, mut bytes: R) -> Result<EvaluationResult<R>> {
1812 match self.state {
1813 EvaluationState::Error(err) => return Err(err),
1814 EvaluationState::Waiting(EvaluationWaiting::AtLocation) => {
1815 if !bytes.is_empty() {
1816 let mut pc = bytes.clone();
1817 mem::swap(&mut pc, &mut self.pc);
1818 mem::swap(&mut bytes, &mut self.bytecode);
1819 self.expression_stack
1820 .try_push((pc, bytes))
1821 .map_err(|_| Error::StackFull)?;
1822 }
1823 }
1824 _ => panic!(
1825 "Called `Evaluation::resume_with_at_location` without a precedeing `EvaluationResult::RequiresAtLocation`"
1826 ),
1827 };
1828
1829 self.evaluate_internal()
1830 }
1831
1832 pub fn resume_with_entry_value(&mut self, entry_value: Value) -> Result<EvaluationResult<R>> {
1840 match self.state {
1841 EvaluationState::Error(err) => return Err(err),
1842 EvaluationState::Waiting(EvaluationWaiting::EntryValue) => {
1843 self.push(entry_value)?;
1844 }
1845 _ => panic!(
1846 "Called `Evaluation::resume_with_entry_value` without a preceding `EvaluationResult::RequiresEntryValue`"
1847 ),
1848 };
1849
1850 self.evaluate_internal()
1851 }
1852
1853 pub fn resume_with_parameter_ref(
1861 &mut self,
1862 parameter_value: u64,
1863 ) -> Result<EvaluationResult<R>> {
1864 match self.state {
1865 EvaluationState::Error(err) => return Err(err),
1866 EvaluationState::Waiting(EvaluationWaiting::ParameterRef) => {
1867 self.push(Value::Generic(parameter_value))?;
1868 }
1869 _ => panic!(
1870 "Called `Evaluation::resume_with_parameter_ref` without a preceding `EvaluationResult::RequiresParameterRef`"
1871 ),
1872 };
1873
1874 self.evaluate_internal()
1875 }
1876
1877 pub fn resume_with_relocated_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
1886 match self.state {
1887 EvaluationState::Error(err) => return Err(err),
1888 EvaluationState::Waiting(EvaluationWaiting::RelocatedAddress) => {
1889 self.push(Value::Generic(address))?;
1890 }
1891 _ => panic!(
1892 "Called `Evaluation::resume_with_relocated_address` without a preceding `EvaluationResult::RequiresRelocatedAddress`"
1893 ),
1894 };
1895
1896 self.evaluate_internal()
1897 }
1898
1899 pub fn resume_with_indexed_address(&mut self, address: u64) -> Result<EvaluationResult<R>> {
1908 match self.state {
1909 EvaluationState::Error(err) => return Err(err),
1910 EvaluationState::Waiting(EvaluationWaiting::IndexedAddress) => {
1911 self.push(Value::Generic(address))?;
1912 }
1913 _ => panic!(
1914 "Called `Evaluation::resume_with_indexed_address` without a preceding `EvaluationResult::RequiresIndexedAddress`"
1915 ),
1916 };
1917
1918 self.evaluate_internal()
1919 }
1920
1921 pub fn resume_with_base_type(&mut self, base_type: ValueType) -> Result<EvaluationResult<R>> {
1929 let value = match self.state {
1930 EvaluationState::Error(err) => return Err(err),
1931 EvaluationState::Waiting(EvaluationWaiting::TypedLiteral { ref value }) => {
1932 Value::parse(base_type, value.clone())?
1933 }
1934 EvaluationState::Waiting(EvaluationWaiting::Convert) => {
1935 let entry = self.pop()?;
1936 entry.convert(base_type, self.addr_mask)?
1937 }
1938 EvaluationState::Waiting(EvaluationWaiting::Reinterpret) => {
1939 let entry = self.pop()?;
1940 entry.reinterpret(base_type, self.addr_mask)?
1941 }
1942 _ => panic!(
1943 "Called `Evaluation::resume_with_base_type` without a preceding `EvaluationResult::RequiresBaseType`"
1944 ),
1945 };
1946 self.push(value)?;
1947 self.evaluate_internal()
1948 }
1949
1950 fn end_of_expression(&mut self) -> bool {
1951 while self.pc.is_empty() {
1952 match self.expression_stack.pop() {
1953 Some((newpc, newbytes)) => {
1954 self.pc = newpc;
1955 self.bytecode = newbytes;
1956 }
1957 None => return true,
1958 }
1959 }
1960 false
1961 }
1962
1963 fn evaluate_internal(&mut self) -> Result<EvaluationResult<R>> {
1964 while !self.end_of_expression() {
1965 self.iteration += 1;
1966 if let Some(max_iterations) = self.max_iterations
1967 && self.iteration > max_iterations
1968 {
1969 return Err(Error::TooManyIterations);
1970 }
1971
1972 let op_result = self.evaluate_one_operation()?;
1973 match op_result {
1974 OperationEvaluationResult::Piece => {}
1975 OperationEvaluationResult::Incomplete => {
1976 if self.end_of_expression() && !self.result.is_empty() {
1977 return Err(Error::InvalidPiece);
1981 }
1982 }
1983 OperationEvaluationResult::Complete { location } => {
1984 if self.end_of_expression() {
1985 if !self.result.is_empty() {
1986 return Err(Error::InvalidPiece);
1990 }
1991 self.result
1992 .try_push(Piece {
1993 size_in_bits: None,
1994 bit_offset: None,
1995 location,
1996 })
1997 .map_err(|_| Error::StackFull)?;
1998 } else {
1999 match Operation::parse(&mut self.pc, self.encoding)? {
2002 Operation::Piece {
2003 size_in_bits,
2004 bit_offset,
2005 } => {
2006 self.result
2007 .try_push(Piece {
2008 size_in_bits: Some(size_in_bits),
2009 bit_offset,
2010 location,
2011 })
2012 .map_err(|_| Error::StackFull)?;
2013 }
2014 _ => {
2015 let value =
2016 self.bytecode.len().into_u64() - self.pc.len().into_u64() - 1;
2017 return Err(Error::InvalidExpressionTerminator(value));
2018 }
2019 }
2020 }
2021 }
2022 OperationEvaluationResult::Waiting(waiting, result) => {
2023 self.state = EvaluationState::Waiting(waiting);
2024 return Ok(result);
2025 }
2026 }
2027 }
2028
2029 if self.result.is_empty() {
2032 let entry = self.pop()?;
2033 self.value_result = Some(entry);
2034 let addr = entry.to_u64(self.addr_mask)?;
2035 self.result
2036 .try_push(Piece {
2037 size_in_bits: None,
2038 bit_offset: None,
2039 location: Location::Address { address: addr },
2040 })
2041 .map_err(|_| Error::StackFull)?;
2042 }
2043
2044 self.state = EvaluationState::Complete;
2045 Ok(EvaluationResult::Complete)
2046 }
2047}
2048
2049#[cfg(test)]
2050#[cfg(feature = "write")]
2052mod tests {
2053 use super::*;
2054 use crate::common::Format;
2055 use crate::constants;
2056 use crate::endianity::LittleEndian;
2057 use crate::leb128;
2058 use crate::read::{EndianSlice, Error, Result, UnitOffset};
2059 use crate::test_util::GimliSectionMethods;
2060 use test_assembler::{Endian, Section};
2061
2062 fn encoding4() -> Encoding {
2063 Encoding {
2064 format: Format::Dwarf32,
2065 version: 4,
2066 address_size: 4,
2067 }
2068 }
2069
2070 fn encoding8() -> Encoding {
2071 Encoding {
2072 format: Format::Dwarf64,
2073 version: 4,
2074 address_size: 8,
2075 }
2076 }
2077
2078 #[test]
2079 fn test_compute_pc() {
2080 let bytes = [0, 1, 2, 3, 4];
2082 let bytecode = &bytes[..];
2083 let ebuf = &EndianSlice::new(bytecode, LittleEndian);
2084
2085 assert_eq!(compute_pc(ebuf, ebuf, 0), Ok(*ebuf));
2086 assert_eq!(
2087 compute_pc(ebuf, ebuf, -1),
2088 Err(Error::BadBranchTarget(usize::MAX as u64))
2089 );
2090 assert_eq!(compute_pc(ebuf, ebuf, 5), Ok(ebuf.range_from(5..)));
2091 assert_eq!(
2092 compute_pc(&ebuf.range_from(3..), ebuf, -2),
2093 Ok(ebuf.range_from(1..))
2094 );
2095 assert_eq!(
2096 compute_pc(&ebuf.range_from(2..), ebuf, 2),
2097 Ok(ebuf.range_from(4..))
2098 );
2099 }
2100
2101 fn check_op_parse_simple<'input>(
2102 input: &'input [u8],
2103 expect: &Operation<EndianSlice<'input, LittleEndian>>,
2104 encoding: Encoding,
2105 ) {
2106 let buf = EndianSlice::new(input, LittleEndian);
2107 let mut pc = buf;
2108 let value = Operation::parse(&mut pc, encoding);
2109 match value {
2110 Ok(val) => {
2111 assert_eq!(val, *expect);
2112 assert_eq!(pc.len(), 0);
2113 }
2114 _ => panic!("Unexpected result"),
2115 }
2116 }
2117
2118 fn check_op_parse_eof(input: &[u8], encoding: Encoding) {
2119 let buf = EndianSlice::new(input, LittleEndian);
2120 let mut pc = buf;
2121 match Operation::parse(&mut pc, encoding) {
2122 Err(Error::UnexpectedEof(id)) => {
2123 assert!(buf.lookup_offset_id(id).is_some());
2124 }
2125
2126 _ => panic!("Unexpected result"),
2127 }
2128 }
2129
2130 fn check_op_parse<F>(
2131 input: F,
2132 expect: &Operation<EndianSlice<'_, LittleEndian>>,
2133 encoding: Encoding,
2134 ) where
2135 F: Fn(Section) -> Section,
2136 {
2137 let input = input(Section::with_endian(Endian::Little))
2138 .get_contents()
2139 .unwrap();
2140 for i in 1..input.len() {
2141 check_op_parse_eof(&input[..i], encoding);
2142 }
2143 check_op_parse_simple(&input, expect, encoding);
2144 }
2145
2146 #[test]
2147 fn test_op_parse_onebyte() {
2148 let encoding = encoding4();
2150
2151 #[rustfmt::skip]
2153 let inputs = [
2154 (
2155 constants::DW_OP_deref,
2156 Operation::Deref {
2157 base_type: generic_type(),
2158 size: encoding.address_size,
2159 space: false,
2160 },
2161 ),
2162 (constants::DW_OP_dup, Operation::Pick { index: 0 }),
2163 (constants::DW_OP_drop, Operation::Drop),
2164 (constants::DW_OP_over, Operation::Pick { index: 1 }),
2165 (constants::DW_OP_swap, Operation::Swap),
2166 (constants::DW_OP_rot, Operation::Rot),
2167 (
2168 constants::DW_OP_xderef,
2169 Operation::Deref {
2170 base_type: generic_type(),
2171 size: encoding.address_size,
2172 space: true,
2173 },
2174 ),
2175 (constants::DW_OP_abs, Operation::Abs),
2176 (constants::DW_OP_and, Operation::And),
2177 (constants::DW_OP_div, Operation::Div),
2178 (constants::DW_OP_minus, Operation::Minus),
2179 (constants::DW_OP_mod, Operation::Mod),
2180 (constants::DW_OP_mul, Operation::Mul),
2181 (constants::DW_OP_neg, Operation::Neg),
2182 (constants::DW_OP_not, Operation::Not),
2183 (constants::DW_OP_or, Operation::Or),
2184 (constants::DW_OP_plus, Operation::Plus),
2185 (constants::DW_OP_shl, Operation::Shl),
2186 (constants::DW_OP_shr, Operation::Shr),
2187 (constants::DW_OP_shra, Operation::Shra),
2188 (constants::DW_OP_xor, Operation::Xor),
2189 (constants::DW_OP_eq, Operation::Eq),
2190 (constants::DW_OP_ge, Operation::Ge),
2191 (constants::DW_OP_gt, Operation::Gt),
2192 (constants::DW_OP_le, Operation::Le),
2193 (constants::DW_OP_lt, Operation::Lt),
2194 (constants::DW_OP_ne, Operation::Ne),
2195 (constants::DW_OP_lit0, Operation::UnsignedConstant { value: 0 }),
2196 (constants::DW_OP_lit1, Operation::UnsignedConstant { value: 1 }),
2197 (constants::DW_OP_lit2, Operation::UnsignedConstant { value: 2 }),
2198 (constants::DW_OP_lit3, Operation::UnsignedConstant { value: 3 }),
2199 (constants::DW_OP_lit4, Operation::UnsignedConstant { value: 4 }),
2200 (constants::DW_OP_lit5, Operation::UnsignedConstant { value: 5 }),
2201 (constants::DW_OP_lit6, Operation::UnsignedConstant { value: 6 }),
2202 (constants::DW_OP_lit7, Operation::UnsignedConstant { value: 7 }),
2203 (constants::DW_OP_lit8, Operation::UnsignedConstant { value: 8 }),
2204 (constants::DW_OP_lit9, Operation::UnsignedConstant { value: 9 }),
2205 (constants::DW_OP_lit10, Operation::UnsignedConstant { value: 10 }),
2206 (constants::DW_OP_lit11, Operation::UnsignedConstant { value: 11 }),
2207 (constants::DW_OP_lit12, Operation::UnsignedConstant { value: 12 }),
2208 (constants::DW_OP_lit13, Operation::UnsignedConstant { value: 13 }),
2209 (constants::DW_OP_lit14, Operation::UnsignedConstant { value: 14 }),
2210 (constants::DW_OP_lit15, Operation::UnsignedConstant { value: 15 }),
2211 (constants::DW_OP_lit16, Operation::UnsignedConstant { value: 16 }),
2212 (constants::DW_OP_lit17, Operation::UnsignedConstant { value: 17 }),
2213 (constants::DW_OP_lit18, Operation::UnsignedConstant { value: 18 }),
2214 (constants::DW_OP_lit19, Operation::UnsignedConstant { value: 19 }),
2215 (constants::DW_OP_lit20, Operation::UnsignedConstant { value: 20 }),
2216 (constants::DW_OP_lit21, Operation::UnsignedConstant { value: 21 }),
2217 (constants::DW_OP_lit22, Operation::UnsignedConstant { value: 22 }),
2218 (constants::DW_OP_lit23, Operation::UnsignedConstant { value: 23 }),
2219 (constants::DW_OP_lit24, Operation::UnsignedConstant { value: 24 }),
2220 (constants::DW_OP_lit25, Operation::UnsignedConstant { value: 25 }),
2221 (constants::DW_OP_lit26, Operation::UnsignedConstant { value: 26 }),
2222 (constants::DW_OP_lit27, Operation::UnsignedConstant { value: 27 }),
2223 (constants::DW_OP_lit28, Operation::UnsignedConstant { value: 28 }),
2224 (constants::DW_OP_lit29, Operation::UnsignedConstant { value: 29 }),
2225 (constants::DW_OP_lit30, Operation::UnsignedConstant { value: 30 }),
2226 (constants::DW_OP_lit31, Operation::UnsignedConstant { value: 31 }),
2227 (constants::DW_OP_reg0, Operation::Register { register: Register(0) }),
2228 (constants::DW_OP_reg1, Operation::Register { register: Register(1) }),
2229 (constants::DW_OP_reg2, Operation::Register { register: Register(2) }),
2230 (constants::DW_OP_reg3, Operation::Register { register: Register(3) }),
2231 (constants::DW_OP_reg4, Operation::Register { register: Register(4) }),
2232 (constants::DW_OP_reg5, Operation::Register { register: Register(5) }),
2233 (constants::DW_OP_reg6, Operation::Register { register: Register(6) }),
2234 (constants::DW_OP_reg7, Operation::Register { register: Register(7) }),
2235 (constants::DW_OP_reg8, Operation::Register { register: Register(8) }),
2236 (constants::DW_OP_reg9, Operation::Register { register: Register(9) }),
2237 (constants::DW_OP_reg10, Operation::Register { register: Register(10) }),
2238 (constants::DW_OP_reg11, Operation::Register { register: Register(11) }),
2239 (constants::DW_OP_reg12, Operation::Register { register: Register(12) }),
2240 (constants::DW_OP_reg13, Operation::Register { register: Register(13) }),
2241 (constants::DW_OP_reg14, Operation::Register { register: Register(14) }),
2242 (constants::DW_OP_reg15, Operation::Register { register: Register(15) }),
2243 (constants::DW_OP_reg16, Operation::Register { register: Register(16) }),
2244 (constants::DW_OP_reg17, Operation::Register { register: Register(17) }),
2245 (constants::DW_OP_reg18, Operation::Register { register: Register(18) }),
2246 (constants::DW_OP_reg19, Operation::Register { register: Register(19) }),
2247 (constants::DW_OP_reg20, Operation::Register { register: Register(20) }),
2248 (constants::DW_OP_reg21, Operation::Register { register: Register(21) }),
2249 (constants::DW_OP_reg22, Operation::Register { register: Register(22) }),
2250 (constants::DW_OP_reg23, Operation::Register { register: Register(23) }),
2251 (constants::DW_OP_reg24, Operation::Register { register: Register(24) }),
2252 (constants::DW_OP_reg25, Operation::Register { register: Register(25) }),
2253 (constants::DW_OP_reg26, Operation::Register { register: Register(26) }),
2254 (constants::DW_OP_reg27, Operation::Register { register: Register(27) }),
2255 (constants::DW_OP_reg28, Operation::Register { register: Register(28) }),
2256 (constants::DW_OP_reg29, Operation::Register { register: Register(29) }),
2257 (constants::DW_OP_reg30, Operation::Register { register: Register(30) }),
2258 (constants::DW_OP_reg31, Operation::Register { register: Register(31) }),
2259 (constants::DW_OP_nop, Operation::Nop),
2260 (constants::DW_OP_push_object_address, Operation::PushObjectAddress),
2261 (constants::DW_OP_form_tls_address, Operation::TLS),
2262 (constants::DW_OP_GNU_push_tls_address, Operation::TLS),
2263 (constants::DW_OP_call_frame_cfa, Operation::CallFrameCFA),
2264 (constants::DW_OP_stack_value, Operation::StackValue),
2265 (constants::DW_OP_GNU_uninit, Operation::Uninitialized),
2266 ];
2267
2268 let input = [];
2269 check_op_parse_eof(&input[..], encoding);
2270
2271 for item in inputs.iter() {
2272 let (opcode, ref result) = *item;
2273 check_op_parse(|s| s.D8(opcode.0), result, encoding);
2274 }
2275 }
2276
2277 #[test]
2278 fn test_op_parse_twobyte() {
2279 let encoding = encoding4();
2281
2282 let inputs = [
2283 (
2284 constants::DW_OP_const1u,
2285 23,
2286 Operation::UnsignedConstant { value: 23 },
2287 ),
2288 (
2289 constants::DW_OP_const1s,
2290 (-23i8) as u8,
2291 Operation::SignedConstant { value: -23 },
2292 ),
2293 (constants::DW_OP_pick, 7, Operation::Pick { index: 7 }),
2294 (
2295 constants::DW_OP_deref_size,
2296 19,
2297 Operation::Deref {
2298 base_type: generic_type(),
2299 size: 19,
2300 space: false,
2301 },
2302 ),
2303 (
2304 constants::DW_OP_xderef_size,
2305 19,
2306 Operation::Deref {
2307 base_type: generic_type(),
2308 size: 19,
2309 space: true,
2310 },
2311 ),
2312 ];
2313
2314 for item in inputs.iter() {
2315 let (opcode, arg, ref result) = *item;
2316 check_op_parse(|s| s.D8(opcode.0).D8(arg), result, encoding);
2317 }
2318 }
2319
2320 #[test]
2321 fn test_op_parse_threebyte() {
2322 let encoding = encoding4();
2324
2325 let inputs = [
2328 (
2329 constants::DW_OP_const2u,
2330 23,
2331 Operation::UnsignedConstant { value: 23 },
2332 ),
2333 (
2334 constants::DW_OP_const2s,
2335 (-23i16) as u16,
2336 Operation::SignedConstant { value: -23 },
2337 ),
2338 (
2339 constants::DW_OP_call2,
2340 1138,
2341 Operation::Call {
2342 offset: DieReference::UnitRef(UnitOffset(1138)),
2343 },
2344 ),
2345 (
2346 constants::DW_OP_bra,
2347 (-23i16) as u16,
2348 Operation::Bra { target: -23 },
2349 ),
2350 (
2351 constants::DW_OP_skip,
2352 (-23i16) as u16,
2353 Operation::Skip { target: -23 },
2354 ),
2355 ];
2356
2357 for item in inputs.iter() {
2358 let (opcode, arg, ref result) = *item;
2359 check_op_parse(|s| s.D8(opcode.0).L16(arg), result, encoding);
2360 }
2361 }
2362
2363 #[test]
2364 fn test_op_parse_fivebyte() {
2365 let encoding = encoding4();
2367
2368 let inputs = [
2369 (
2370 constants::DW_OP_addr,
2371 0x1234_5678,
2372 Operation::Address {
2373 address: 0x1234_5678,
2374 },
2375 ),
2376 (
2377 constants::DW_OP_const4u,
2378 0x1234_5678,
2379 Operation::UnsignedConstant { value: 0x1234_5678 },
2380 ),
2381 (
2382 constants::DW_OP_const4s,
2383 (-23i32) as u32,
2384 Operation::SignedConstant { value: -23 },
2385 ),
2386 (
2387 constants::DW_OP_call4,
2388 0x1234_5678,
2389 Operation::Call {
2390 offset: DieReference::UnitRef(UnitOffset(0x1234_5678)),
2391 },
2392 ),
2393 (
2394 constants::DW_OP_call_ref,
2395 0x1234_5678,
2396 Operation::Call {
2397 offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678)),
2398 },
2399 ),
2400 (
2401 constants::DW_OP_GNU_variable_value,
2402 0x1234_5678,
2403 Operation::VariableValue {
2404 offset: DebugInfoOffset(0x1234_5678),
2405 },
2406 ),
2407 ];
2408
2409 for item in inputs.iter() {
2410 let (op, arg, ref expect) = *item;
2411 check_op_parse(|s| s.D8(op.0).L32(arg), expect, encoding);
2412 }
2413 }
2414
2415 #[test]
2416 #[cfg(target_pointer_width = "64")]
2417 fn test_op_parse_ninebyte() {
2418 let encoding = encoding8();
2420
2421 let inputs = [
2422 (
2423 constants::DW_OP_addr,
2424 0x1234_5678_1234_5678,
2425 Operation::Address {
2426 address: 0x1234_5678_1234_5678,
2427 },
2428 ),
2429 (
2430 constants::DW_OP_const8u,
2431 0x1234_5678_1234_5678,
2432 Operation::UnsignedConstant {
2433 value: 0x1234_5678_1234_5678,
2434 },
2435 ),
2436 (
2437 constants::DW_OP_const8s,
2438 (-23i64) as u64,
2439 Operation::SignedConstant { value: -23 },
2440 ),
2441 (
2442 constants::DW_OP_call_ref,
2443 0x1234_5678_1234_5678,
2444 Operation::Call {
2445 offset: DieReference::DebugInfoRef(DebugInfoOffset(0x1234_5678_1234_5678)),
2446 },
2447 ),
2448 (
2449 constants::DW_OP_GNU_variable_value,
2450 0x1234_5678_1234_5678,
2451 Operation::VariableValue {
2452 offset: DebugInfoOffset(0x1234_5678_1234_5678),
2453 },
2454 ),
2455 ];
2456
2457 for item in inputs.iter() {
2458 let (op, arg, ref expect) = *item;
2459 check_op_parse(|s| s.D8(op.0).L64(arg), expect, encoding);
2460 }
2461 }
2462
2463 #[test]
2464 fn test_op_parse_sleb() {
2465 let encoding = encoding4();
2467
2468 let values = [
2469 -1i64,
2470 0,
2471 1,
2472 0x100,
2473 0x1eee_eeee,
2474 0x7fff_ffff_ffff_ffff,
2475 -0x100,
2476 -0x1eee_eeee,
2477 -0x7fff_ffff_ffff_ffff,
2478 ];
2479 for value in values.iter() {
2480 let mut inputs = vec![
2481 (
2482 constants::DW_OP_consts.0,
2483 Operation::SignedConstant { value: *value },
2484 ),
2485 (
2486 constants::DW_OP_fbreg.0,
2487 Operation::FrameOffset { offset: *value },
2488 ),
2489 ];
2490
2491 for i in 0..32 {
2492 inputs.push((
2493 constants::DW_OP_breg0.0 + i,
2494 Operation::RegisterOffset {
2495 register: Register(i.into()),
2496 offset: *value,
2497 base_type: UnitOffset(0),
2498 },
2499 ));
2500 }
2501
2502 for item in inputs.iter() {
2503 let (op, ref expect) = *item;
2504 check_op_parse(|s| s.D8(op).sleb(*value), expect, encoding);
2505 }
2506 }
2507 }
2508
2509 #[test]
2510 fn test_op_parse_uleb() {
2511 let encoding = encoding4();
2513
2514 let values = [
2515 0,
2516 1,
2517 0x100,
2518 (!0u16).into(),
2519 0x1eee_eeee,
2520 0x7fff_ffff_ffff_ffff,
2521 !0u64,
2522 ];
2523 for value in values.iter() {
2524 let mut inputs = vec![
2525 (
2526 constants::DW_OP_constu,
2527 Operation::UnsignedConstant { value: *value },
2528 ),
2529 (
2530 constants::DW_OP_plus_uconst,
2531 Operation::PlusConstant { value: *value },
2532 ),
2533 ];
2534
2535 if *value <= (!0u16).into() {
2536 inputs.push((
2537 constants::DW_OP_regx,
2538 Operation::Register {
2539 register: Register::from_u64(*value).unwrap(),
2540 },
2541 ));
2542 }
2543
2544 if *value <= (!0u32).into() {
2545 inputs.extend(&[
2546 (
2547 constants::DW_OP_addrx,
2548 Operation::AddressIndex {
2549 index: DebugAddrIndex(*value as usize),
2550 },
2551 ),
2552 (
2553 constants::DW_OP_constx,
2554 Operation::ConstantIndex {
2555 index: DebugAddrIndex(*value as usize),
2556 },
2557 ),
2558 ]);
2559 }
2560
2561 if *value < !0u64 / 8 {
2563 inputs.push((
2564 constants::DW_OP_piece,
2565 Operation::Piece {
2566 size_in_bits: 8 * value,
2567 bit_offset: None,
2568 },
2569 ));
2570 }
2571
2572 for item in inputs.iter() {
2573 let (op, ref expect) = *item;
2574 let input = Section::with_endian(Endian::Little)
2575 .D8(op.0)
2576 .uleb(*value)
2577 .get_contents()
2578 .unwrap();
2579 check_op_parse_simple(&input, expect, encoding);
2580 }
2581 }
2582 }
2583
2584 #[test]
2585 fn test_op_parse_bregx() {
2586 let encoding = encoding4();
2588
2589 let uvalues = [0, 1, 0x100, !0u16];
2590 let svalues = [
2591 -1i64,
2592 0,
2593 1,
2594 0x100,
2595 0x1eee_eeee,
2596 0x7fff_ffff_ffff_ffff,
2597 -0x100,
2598 -0x1eee_eeee,
2599 -0x7fff_ffff_ffff_ffff,
2600 ];
2601
2602 for v1 in uvalues.iter() {
2603 for v2 in svalues.iter() {
2604 check_op_parse(
2605 |s| s.D8(constants::DW_OP_bregx.0).uleb((*v1).into()).sleb(*v2),
2606 &Operation::RegisterOffset {
2607 register: Register(*v1),
2608 offset: *v2,
2609 base_type: UnitOffset(0),
2610 },
2611 encoding,
2612 );
2613 }
2614 }
2615 }
2616
2617 #[test]
2618 fn test_op_parse_bit_piece() {
2619 let encoding = encoding4();
2621
2622 let values = [0, 1, 0x100, 0x1eee_eeee, 0x7fff_ffff_ffff_ffff, !0u64];
2623
2624 for v1 in values.iter() {
2625 for v2 in values.iter() {
2626 let input = Section::with_endian(Endian::Little)
2627 .D8(constants::DW_OP_bit_piece.0)
2628 .uleb(*v1)
2629 .uleb(*v2)
2630 .get_contents()
2631 .unwrap();
2632 check_op_parse_simple(
2633 &input,
2634 &Operation::Piece {
2635 size_in_bits: *v1,
2636 bit_offset: Some(*v2),
2637 },
2638 encoding,
2639 );
2640 }
2641 }
2642 }
2643
2644 #[test]
2645 fn test_op_parse_implicit_value() {
2646 let encoding = encoding4();
2648
2649 let data = b"hello";
2650
2651 check_op_parse(
2652 |s| {
2653 s.D8(constants::DW_OP_implicit_value.0)
2654 .uleb(data.len() as u64)
2655 .append_bytes(&data[..])
2656 },
2657 &Operation::ImplicitValue {
2658 data: EndianSlice::new(&data[..], LittleEndian),
2659 },
2660 encoding,
2661 );
2662 }
2663
2664 #[test]
2665 fn test_op_parse_const_type() {
2666 let encoding = encoding4();
2668
2669 let data = b"hello";
2670
2671 check_op_parse(
2672 |s| {
2673 s.D8(constants::DW_OP_const_type.0)
2674 .uleb(100)
2675 .D8(data.len() as u8)
2676 .append_bytes(&data[..])
2677 },
2678 &Operation::TypedLiteral {
2679 base_type: UnitOffset(100),
2680 value: EndianSlice::new(&data[..], LittleEndian),
2681 },
2682 encoding,
2683 );
2684 check_op_parse(
2685 |s| {
2686 s.D8(constants::DW_OP_GNU_const_type.0)
2687 .uleb(100)
2688 .D8(data.len() as u8)
2689 .append_bytes(&data[..])
2690 },
2691 &Operation::TypedLiteral {
2692 base_type: UnitOffset(100),
2693 value: EndianSlice::new(&data[..], LittleEndian),
2694 },
2695 encoding,
2696 );
2697 }
2698
2699 #[test]
2700 fn test_op_parse_regval_type() {
2701 let encoding = encoding4();
2703
2704 check_op_parse(
2705 |s| s.D8(constants::DW_OP_regval_type.0).uleb(1).uleb(100),
2706 &Operation::RegisterOffset {
2707 register: Register(1),
2708 offset: 0,
2709 base_type: UnitOffset(100),
2710 },
2711 encoding,
2712 );
2713 check_op_parse(
2714 |s| s.D8(constants::DW_OP_GNU_regval_type.0).uleb(1).uleb(100),
2715 &Operation::RegisterOffset {
2716 register: Register(1),
2717 offset: 0,
2718 base_type: UnitOffset(100),
2719 },
2720 encoding,
2721 );
2722 }
2723
2724 #[test]
2725 fn test_op_parse_deref_type() {
2726 let encoding = encoding4();
2728
2729 check_op_parse(
2730 |s| s.D8(constants::DW_OP_deref_type.0).D8(8).uleb(100),
2731 &Operation::Deref {
2732 base_type: UnitOffset(100),
2733 size: 8,
2734 space: false,
2735 },
2736 encoding,
2737 );
2738 check_op_parse(
2739 |s| s.D8(constants::DW_OP_GNU_deref_type.0).D8(8).uleb(100),
2740 &Operation::Deref {
2741 base_type: UnitOffset(100),
2742 size: 8,
2743 space: false,
2744 },
2745 encoding,
2746 );
2747 check_op_parse(
2748 |s| s.D8(constants::DW_OP_xderef_type.0).D8(8).uleb(100),
2749 &Operation::Deref {
2750 base_type: UnitOffset(100),
2751 size: 8,
2752 space: true,
2753 },
2754 encoding,
2755 );
2756 }
2757
2758 #[test]
2759 fn test_op_convert() {
2760 let encoding = encoding4();
2762
2763 check_op_parse(
2764 |s| s.D8(constants::DW_OP_convert.0).uleb(100),
2765 &Operation::Convert {
2766 base_type: UnitOffset(100),
2767 },
2768 encoding,
2769 );
2770 check_op_parse(
2771 |s| s.D8(constants::DW_OP_GNU_convert.0).uleb(100),
2772 &Operation::Convert {
2773 base_type: UnitOffset(100),
2774 },
2775 encoding,
2776 );
2777 }
2778
2779 #[test]
2780 fn test_op_reinterpret() {
2781 let encoding = encoding4();
2783
2784 check_op_parse(
2785 |s| s.D8(constants::DW_OP_reinterpret.0).uleb(100),
2786 &Operation::Reinterpret {
2787 base_type: UnitOffset(100),
2788 },
2789 encoding,
2790 );
2791 check_op_parse(
2792 |s| s.D8(constants::DW_OP_GNU_reinterpret.0).uleb(100),
2793 &Operation::Reinterpret {
2794 base_type: UnitOffset(100),
2795 },
2796 encoding,
2797 );
2798 }
2799
2800 #[test]
2801 fn test_op_parse_implicit_pointer() {
2802 for op in &[
2803 constants::DW_OP_implicit_pointer,
2804 constants::DW_OP_GNU_implicit_pointer,
2805 ] {
2806 check_op_parse(
2807 |s| s.D8(op.0).D32(0x1234_5678).sleb(0x123),
2808 &Operation::ImplicitPointer {
2809 value: DebugInfoOffset(0x1234_5678),
2810 byte_offset: 0x123,
2811 },
2812 encoding4(),
2813 );
2814
2815 check_op_parse(
2816 |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
2817 &Operation::ImplicitPointer {
2818 value: DebugInfoOffset(0x1234_5678),
2819 byte_offset: 0x123,
2820 },
2821 encoding8(),
2822 );
2823
2824 check_op_parse(
2825 |s| s.D8(op.0).D64(0x1234_5678).sleb(0x123),
2826 &Operation::ImplicitPointer {
2827 value: DebugInfoOffset(0x1234_5678),
2828 byte_offset: 0x123,
2829 },
2830 Encoding {
2831 format: Format::Dwarf32,
2832 version: 2,
2833 address_size: 8,
2834 },
2835 )
2836 }
2837 }
2838
2839 #[test]
2840 fn test_op_parse_entry_value() {
2841 for op in &[
2842 constants::DW_OP_entry_value,
2843 constants::DW_OP_GNU_entry_value,
2844 ] {
2845 let data = b"hello";
2846 check_op_parse(
2847 |s| s.D8(op.0).uleb(data.len() as u64).append_bytes(&data[..]),
2848 &Operation::EntryValue {
2849 expression: EndianSlice::new(&data[..], LittleEndian),
2850 },
2851 encoding4(),
2852 );
2853 }
2854 }
2855
2856 #[test]
2857 fn test_op_parse_gnu_parameter_ref() {
2858 check_op_parse(
2859 |s| s.D8(constants::DW_OP_GNU_parameter_ref.0).D32(0x1234_5678),
2860 &Operation::ParameterRef {
2861 offset: UnitOffset(0x1234_5678),
2862 },
2863 encoding4(),
2864 )
2865 }
2866
2867 #[test]
2868 fn test_op_wasm() {
2869 let encoding = encoding4();
2871
2872 check_op_parse(
2873 |s| s.D8(constants::DW_OP_WASM_location.0).D8(0).uleb(1000),
2874 &Operation::WasmLocal { index: 1000 },
2875 encoding,
2876 );
2877 check_op_parse(
2878 |s| s.D8(constants::DW_OP_WASM_location.0).D8(1).uleb(1000),
2879 &Operation::WasmGlobal { index: 1000 },
2880 encoding,
2881 );
2882 check_op_parse(
2883 |s| s.D8(constants::DW_OP_WASM_location.0).D8(2).uleb(1000),
2884 &Operation::WasmStack { index: 1000 },
2885 encoding,
2886 );
2887 check_op_parse(
2888 |s| s.D8(constants::DW_OP_WASM_location.0).D8(3).D32(1000),
2889 &Operation::WasmGlobal { index: 1000 },
2890 encoding,
2891 );
2892 }
2893
2894 enum AssemblerEntry {
2895 Op(constants::DwOp),
2896 Mark(u8),
2897 Branch(u8),
2898 U8(u8),
2899 U16(u16),
2900 U32(u32),
2901 U64(u64),
2902 Uleb(u64),
2903 Sleb(u64),
2904 }
2905
2906 fn assemble(entries: &[AssemblerEntry]) -> Vec<u8> {
2907 let mut result = Vec::new();
2908
2909 struct Marker(Option<usize>, Vec<usize>);
2910
2911 let mut markers = Vec::new();
2912 for _ in 0..256 {
2913 markers.push(Marker(None, Vec::new()));
2914 }
2915
2916 fn write(stack: &mut [u8], index: usize, mut num: u64, nbytes: u8) {
2917 for i in 0..nbytes as usize {
2918 stack[index + i] = (num & 0xff) as u8;
2919 num >>= 8;
2920 }
2921 }
2922
2923 fn push(stack: &mut Vec<u8>, num: u64, nbytes: u8) {
2924 let index = stack.len();
2925 for _ in 0..nbytes {
2926 stack.push(0);
2927 }
2928 write(stack, index, num, nbytes);
2929 }
2930
2931 for item in entries {
2932 match *item {
2933 AssemblerEntry::Op(op) => result.push(op.0),
2934 AssemblerEntry::Mark(num) => {
2935 assert!(markers[num as usize].0.is_none());
2936 markers[num as usize].0 = Some(result.len());
2937 }
2938 AssemblerEntry::Branch(num) => {
2939 markers[num as usize].1.push(result.len());
2940 push(&mut result, 0, 2);
2941 }
2942 AssemblerEntry::U8(num) => result.push(num),
2943 AssemblerEntry::U16(num) => push(&mut result, u64::from(num), 2),
2944 AssemblerEntry::U32(num) => push(&mut result, u64::from(num), 4),
2945 AssemblerEntry::U64(num) => push(&mut result, num, 8),
2946 AssemblerEntry::Uleb(num) => {
2947 result.extend(leb128::write::Leb128::unsigned(num).bytes());
2948 }
2949 AssemblerEntry::Sleb(num) => {
2950 result.extend(leb128::write::Leb128::signed(num as i64).bytes());
2951 }
2952 }
2953 }
2954
2955 for marker in markers {
2957 if let Some(offset) = marker.0 {
2958 for branch_offset in marker.1 {
2959 let delta = offset.wrapping_sub(branch_offset + 2) as u64;
2960 write(&mut result, branch_offset, delta, 2);
2961 }
2962 }
2963 }
2964
2965 result
2966 }
2967
2968 fn check_eval_with_args<F>(
2969 program: &[AssemblerEntry],
2970 expect: Result<&[Piece<EndianSlice<'_, LittleEndian>>]>,
2971 encoding: Encoding,
2972 object_address: Option<u64>,
2973 initial_value: Option<u64>,
2974 max_iterations: Option<u32>,
2975 f: F,
2976 ) where
2977 for<'a> F: Fn(
2978 &mut Evaluation<EndianSlice<'a, LittleEndian>>,
2979 EvaluationResult<EndianSlice<'a, LittleEndian>>,
2980 ) -> Result<EvaluationResult<EndianSlice<'a, LittleEndian>>>,
2981 {
2982 let bytes = assemble(program);
2983 let bytes = EndianSlice::new(&bytes, LittleEndian);
2984
2985 let mut eval = Evaluation::new(bytes, encoding);
2986
2987 if let Some(val) = object_address {
2988 eval.set_object_address(val);
2989 }
2990 if let Some(val) = initial_value {
2991 eval.set_initial_value(val);
2992 }
2993 if let Some(val) = max_iterations {
2994 eval.set_max_iterations(val);
2995 }
2996
2997 let result = match eval.evaluate() {
2998 Err(e) => Err(e),
2999 Ok(r) => f(&mut eval, r),
3000 };
3001
3002 match (result, expect) {
3003 (Ok(EvaluationResult::Complete), Ok(pieces)) => {
3004 let vec = eval.result();
3005 assert_eq!(vec.len(), pieces.len());
3006 for i in 0..pieces.len() {
3007 assert_eq!(vec[i], pieces[i]);
3008 }
3009 }
3010 (Err(f1), Err(f2)) => {
3011 assert_eq!(f1, f2);
3012 }
3013 otherwise => panic!("Unexpected result: {:?}", otherwise),
3014 }
3015 }
3016
3017 fn check_eval(
3018 program: &[AssemblerEntry],
3019 expect: Result<&[Piece<EndianSlice<'_, LittleEndian>>]>,
3020 encoding: Encoding,
3021 ) {
3022 check_eval_with_args(program, expect, encoding, None, None, None, |_, result| {
3023 Ok(result)
3024 });
3025 }
3026
3027 #[test]
3028 fn test_eval_arith() {
3029 use self::AssemblerEntry::*;
3032 use crate::constants::*;
3033
3034 let done = 0;
3036 let fail = 1;
3037
3038 #[rustfmt::skip]
3039 let program = [
3040 Op(DW_OP_const1u), U8(23),
3041 Op(DW_OP_const1s), U8((-23i8) as u8),
3042 Op(DW_OP_plus),
3043 Op(DW_OP_bra), Branch(fail),
3044
3045 Op(DW_OP_const2u), U16(23),
3046 Op(DW_OP_const2s), U16((-23i16) as u16),
3047 Op(DW_OP_plus),
3048 Op(DW_OP_bra), Branch(fail),
3049
3050 Op(DW_OP_const4u), U32(0x1111_2222),
3051 Op(DW_OP_const4s), U32((-0x1111_2222i32) as u32),
3052 Op(DW_OP_plus),
3053 Op(DW_OP_bra), Branch(fail),
3054
3055 Op(DW_OP_const1s), U8(0xff),
3057 Op(DW_OP_const1u), U8(1),
3058 Op(DW_OP_plus),
3059 Op(DW_OP_bra), Branch(fail),
3060
3061 Op(DW_OP_const1s), U8(0xff),
3062 Op(DW_OP_plus_uconst), Uleb(1),
3063 Op(DW_OP_bra), Branch(fail),
3064
3065 Op(DW_OP_const1s), U8(0),
3067 Op(DW_OP_const1u), U8(1),
3068 Op(DW_OP_minus),
3069 Op(DW_OP_const1s), U8(0xff),
3070 Op(DW_OP_ne),
3071 Op(DW_OP_bra), Branch(fail),
3072
3073 Op(DW_OP_const1s), U8(0xff),
3074 Op(DW_OP_abs),
3075 Op(DW_OP_const1u), U8(1),
3076 Op(DW_OP_minus),
3077 Op(DW_OP_bra), Branch(fail),
3078
3079 Op(DW_OP_const4u), U32(0xf078_fffe),
3080 Op(DW_OP_const4u), U32(0x0f87_0001),
3081 Op(DW_OP_and),
3082 Op(DW_OP_bra), Branch(fail),
3083
3084 Op(DW_OP_const4u), U32(0xf078_fffe),
3085 Op(DW_OP_const4u), U32(0xf000_00fe),
3086 Op(DW_OP_and),
3087 Op(DW_OP_const4u), U32(0xf000_00fe),
3088 Op(DW_OP_ne),
3089 Op(DW_OP_bra), Branch(fail),
3090
3091 Op(DW_OP_const1s), U8(0xfe),
3093 Op(DW_OP_const1s), U8(2),
3094 Op(DW_OP_div),
3095 Op(DW_OP_plus_uconst), Uleb(1),
3096 Op(DW_OP_bra), Branch(fail),
3097
3098 Op(DW_OP_const1s), U8(0xfd),
3100 Op(DW_OP_const1s), U8(2),
3101 Op(DW_OP_mod),
3102 Op(DW_OP_neg),
3103 Op(DW_OP_plus_uconst), Uleb(1),
3104 Op(DW_OP_bra), Branch(fail),
3105
3106 Op(DW_OP_const4u), U32(0x8000_0001),
3108 Op(DW_OP_lit2),
3109 Op(DW_OP_mul),
3110 Op(DW_OP_lit2),
3111 Op(DW_OP_ne),
3112 Op(DW_OP_bra), Branch(fail),
3113
3114 Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3115 Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3116 Op(DW_OP_xor),
3117 Op(DW_OP_bra), Branch(fail),
3118
3119 Op(DW_OP_const4u), U32(0xf0f0_f0f0),
3120 Op(DW_OP_const4u), U32(0x0f0f_0f0f),
3121 Op(DW_OP_or),
3122 Op(DW_OP_not),
3123 Op(DW_OP_bra), Branch(fail),
3124
3125 Op(DW_OP_const8u), U64(0xffff_ffff_0000_0000),
3127 Op(DW_OP_lit2),
3128 Op(DW_OP_div),
3129 Op(DW_OP_bra), Branch(fail),
3130
3131 Op(DW_OP_const1u), U8(0xff),
3132 Op(DW_OP_lit1),
3133 Op(DW_OP_shl),
3134 Op(DW_OP_const2u), U16(0x1fe),
3135 Op(DW_OP_ne),
3136 Op(DW_OP_bra), Branch(fail),
3137
3138 Op(DW_OP_const1u), U8(0xff),
3139 Op(DW_OP_const1u), U8(50),
3140 Op(DW_OP_shl),
3141 Op(DW_OP_bra), Branch(fail),
3142
3143 Op(DW_OP_const1u), U8(0xff),
3145 Op(DW_OP_const1s), U8(0xff),
3146 Op(DW_OP_shl),
3147 Op(DW_OP_bra), Branch(fail),
3148
3149 Op(DW_OP_const1s), U8(0xff),
3150 Op(DW_OP_lit1),
3151 Op(DW_OP_shr),
3152 Op(DW_OP_const4u), U32(0x7fff_ffff),
3153 Op(DW_OP_ne),
3154 Op(DW_OP_bra), Branch(fail),
3155
3156 Op(DW_OP_const1s), U8(0xff),
3157 Op(DW_OP_const1u), U8(0xff),
3158 Op(DW_OP_shr),
3159 Op(DW_OP_bra), Branch(fail),
3160
3161 Op(DW_OP_const1s), U8(0xff),
3162 Op(DW_OP_lit1),
3163 Op(DW_OP_shra),
3164 Op(DW_OP_const1s), U8(0xff),
3165 Op(DW_OP_ne),
3166 Op(DW_OP_bra), Branch(fail),
3167
3168 Op(DW_OP_const1s), U8(0xff),
3169 Op(DW_OP_const1u), U8(0xff),
3170 Op(DW_OP_shra),
3171 Op(DW_OP_const1s), U8(0xff),
3172 Op(DW_OP_ne),
3173 Op(DW_OP_bra), Branch(fail),
3174
3175 Op(DW_OP_lit0),
3177 Op(DW_OP_nop),
3178 Op(DW_OP_skip), Branch(done),
3179
3180 Mark(fail),
3181 Op(DW_OP_lit1),
3182
3183 Mark(done),
3184 Op(DW_OP_stack_value),
3185 ];
3186
3187 let result = [Piece {
3188 size_in_bits: None,
3189 bit_offset: None,
3190 location: Location::Value {
3191 value: Value::Generic(0),
3192 },
3193 }];
3194
3195 check_eval(&program, Ok(&result), encoding4());
3196 }
3197
3198 #[test]
3199 fn test_eval_arith64() {
3200 use self::AssemblerEntry::*;
3203 use crate::constants::*;
3204
3205 let done = 0;
3207 let fail = 1;
3208
3209 #[rustfmt::skip]
3210 let program = [
3211 Op(DW_OP_const8u), U64(0x1111_2222_3333_4444),
3212 Op(DW_OP_const8s), U64((-0x1111_2222_3333_4444i64) as u64),
3213 Op(DW_OP_plus),
3214 Op(DW_OP_bra), Branch(fail),
3215
3216 Op(DW_OP_constu), Uleb(0x1111_2222_3333_4444),
3217 Op(DW_OP_consts), Sleb((-0x1111_2222_3333_4444i64) as u64),
3218 Op(DW_OP_plus),
3219 Op(DW_OP_bra), Branch(fail),
3220
3221 Op(DW_OP_lit1),
3222 Op(DW_OP_plus_uconst), Uleb(!0u64),
3223 Op(DW_OP_bra), Branch(fail),
3224
3225 Op(DW_OP_lit1),
3226 Op(DW_OP_neg),
3227 Op(DW_OP_not),
3228 Op(DW_OP_bra), Branch(fail),
3229
3230 Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3231 Op(DW_OP_const1u), U8(63),
3232 Op(DW_OP_shr),
3233 Op(DW_OP_lit1),
3234 Op(DW_OP_ne),
3235 Op(DW_OP_bra), Branch(fail),
3236
3237 Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3238 Op(DW_OP_const1u), U8(62),
3239 Op(DW_OP_shra),
3240 Op(DW_OP_plus_uconst), Uleb(2),
3241 Op(DW_OP_bra), Branch(fail),
3242
3243 Op(DW_OP_lit1),
3244 Op(DW_OP_const1u), U8(63),
3245 Op(DW_OP_shl),
3246 Op(DW_OP_const8u), U64(0x8000_0000_0000_0000),
3247 Op(DW_OP_ne),
3248 Op(DW_OP_bra), Branch(fail),
3249
3250 Op(DW_OP_lit0),
3252 Op(DW_OP_nop),
3253 Op(DW_OP_skip), Branch(done),
3254
3255 Mark(fail),
3256 Op(DW_OP_lit1),
3257
3258 Mark(done),
3259 Op(DW_OP_stack_value),
3260 ];
3261
3262 let result = [Piece {
3263 size_in_bits: None,
3264 bit_offset: None,
3265 location: Location::Value {
3266 value: Value::Generic(0),
3267 },
3268 }];
3269
3270 check_eval(&program, Ok(&result), encoding8());
3271 }
3272
3273 #[test]
3274 fn test_eval_compare() {
3275 use self::AssemblerEntry::*;
3278 use crate::constants::*;
3279
3280 let done = 0;
3282 let fail = 1;
3283
3284 #[rustfmt::skip]
3285 let program = [
3286 Op(DW_OP_const1s), U8(1),
3288 Op(DW_OP_const1s), U8(0xff),
3289 Op(DW_OP_lt),
3290 Op(DW_OP_bra), Branch(fail),
3291
3292 Op(DW_OP_const1s), U8(0xff),
3293 Op(DW_OP_const1s), U8(1),
3294 Op(DW_OP_gt),
3295 Op(DW_OP_bra), Branch(fail),
3296
3297 Op(DW_OP_const1s), U8(1),
3298 Op(DW_OP_const1s), U8(0xff),
3299 Op(DW_OP_le),
3300 Op(DW_OP_bra), Branch(fail),
3301
3302 Op(DW_OP_const1s), U8(0xff),
3303 Op(DW_OP_const1s), U8(1),
3304 Op(DW_OP_ge),
3305 Op(DW_OP_bra), Branch(fail),
3306
3307 Op(DW_OP_const1s), U8(0xff),
3308 Op(DW_OP_const1s), U8(1),
3309 Op(DW_OP_eq),
3310 Op(DW_OP_bra), Branch(fail),
3311
3312 Op(DW_OP_const4s), U32(1),
3313 Op(DW_OP_const1s), U8(1),
3314 Op(DW_OP_ne),
3315 Op(DW_OP_bra), Branch(fail),
3316
3317 Op(DW_OP_lit0),
3319 Op(DW_OP_nop),
3320 Op(DW_OP_skip), Branch(done),
3321
3322 Mark(fail),
3323 Op(DW_OP_lit1),
3324
3325 Mark(done),
3326 Op(DW_OP_stack_value),
3327 ];
3328
3329 let result = [Piece {
3330 size_in_bits: None,
3331 bit_offset: None,
3332 location: Location::Value {
3333 value: Value::Generic(0),
3334 },
3335 }];
3336
3337 check_eval(&program, Ok(&result), encoding4());
3338 }
3339
3340 #[test]
3341 fn test_eval_stack() {
3342 use self::AssemblerEntry::*;
3345 use crate::constants::*;
3346
3347 #[rustfmt::skip]
3348 let program = [
3349 Op(DW_OP_lit17), Op(DW_OP_dup), Op(DW_OP_over), Op(DW_OP_minus), Op(DW_OP_swap), Op(DW_OP_dup), Op(DW_OP_plus_uconst), Uleb(1), Op(DW_OP_rot), Op(DW_OP_pick), U8(2), Op(DW_OP_pick), U8(3), Op(DW_OP_minus), Op(DW_OP_drop), Op(DW_OP_swap), Op(DW_OP_drop), Op(DW_OP_minus), Op(DW_OP_stack_value),
3365 ];
3366
3367 let result = [Piece {
3368 size_in_bits: None,
3369 bit_offset: None,
3370 location: Location::Value {
3371 value: Value::Generic(1),
3372 },
3373 }];
3374
3375 check_eval(&program, Ok(&result), encoding4());
3376 }
3377
3378 #[test]
3379 fn test_eval_lit_and_reg() {
3380 use self::AssemblerEntry::*;
3383 use crate::constants::*;
3384
3385 let mut program = Vec::new();
3386 program.push(Op(DW_OP_lit0));
3387 for i in 0..32 {
3388 program.push(Op(DwOp(DW_OP_lit0.0 + i)));
3389 program.push(Op(DwOp(DW_OP_breg0.0 + i)));
3390 program.push(Sleb(u64::from(i)));
3391 program.push(Op(DW_OP_plus));
3392 program.push(Op(DW_OP_plus));
3393 }
3394
3395 program.push(Op(DW_OP_bregx));
3396 program.push(Uleb(0x1234));
3397 program.push(Sleb(0x1234));
3398 program.push(Op(DW_OP_plus));
3399
3400 program.push(Op(DW_OP_stack_value));
3401
3402 let result = [Piece {
3403 size_in_bits: None,
3404 bit_offset: None,
3405 location: Location::Value {
3406 value: Value::Generic(496),
3407 },
3408 }];
3409
3410 check_eval_with_args(
3411 &program,
3412 Ok(&result),
3413 encoding4(),
3414 None,
3415 None,
3416 None,
3417 |eval, mut result| {
3418 while result != EvaluationResult::Complete {
3419 result = eval.resume_with_register(match result {
3420 EvaluationResult::RequiresRegister {
3421 register,
3422 base_type,
3423 } => {
3424 assert_eq!(base_type, UnitOffset(0));
3425 Value::Generic(u64::from(register.0).wrapping_neg())
3426 }
3427 _ => panic!(),
3428 })?;
3429 }
3430 Ok(result)
3431 },
3432 );
3433 }
3434
3435 #[test]
3436 fn test_eval_memory() {
3437 use self::AssemblerEntry::*;
3440 use crate::constants::*;
3441
3442 let done = 0;
3444 let fail = 1;
3445
3446 #[rustfmt::skip]
3447 let program = [
3448 Op(DW_OP_addr), U32(0x7fff_ffff),
3449 Op(DW_OP_deref),
3450 Op(DW_OP_const4u), U32(0xffff_fffc),
3451 Op(DW_OP_ne),
3452 Op(DW_OP_bra), Branch(fail),
3453
3454 Op(DW_OP_addr), U32(0x7fff_ffff),
3455 Op(DW_OP_deref_size), U8(2),
3456 Op(DW_OP_const4u), U32(0xfffc),
3457 Op(DW_OP_ne),
3458 Op(DW_OP_bra), Branch(fail),
3459
3460 Op(DW_OP_lit1),
3461 Op(DW_OP_addr), U32(0x7fff_ffff),
3462 Op(DW_OP_xderef),
3463 Op(DW_OP_const4u), U32(0xffff_fffd),
3464 Op(DW_OP_ne),
3465 Op(DW_OP_bra), Branch(fail),
3466
3467 Op(DW_OP_lit1),
3468 Op(DW_OP_addr), U32(0x7fff_ffff),
3469 Op(DW_OP_xderef_size), U8(2),
3470 Op(DW_OP_const4u), U32(0xfffd),
3471 Op(DW_OP_ne),
3472 Op(DW_OP_bra), Branch(fail),
3473
3474 Op(DW_OP_lit17),
3475 Op(DW_OP_form_tls_address),
3476 Op(DW_OP_constu), Uleb(!17),
3477 Op(DW_OP_ne),
3478 Op(DW_OP_bra), Branch(fail),
3479
3480 Op(DW_OP_lit17),
3481 Op(DW_OP_GNU_push_tls_address),
3482 Op(DW_OP_constu), Uleb(!17),
3483 Op(DW_OP_ne),
3484 Op(DW_OP_bra), Branch(fail),
3485
3486 Op(DW_OP_addrx), Uleb(0x10),
3487 Op(DW_OP_deref),
3488 Op(DW_OP_const4u), U32(0x4040),
3489 Op(DW_OP_ne),
3490 Op(DW_OP_bra), Branch(fail),
3491
3492 Op(DW_OP_constx), Uleb(17),
3493 Op(DW_OP_form_tls_address),
3494 Op(DW_OP_constu), Uleb(!27),
3495 Op(DW_OP_ne),
3496 Op(DW_OP_bra), Branch(fail),
3497
3498 Op(DW_OP_lit0),
3500 Op(DW_OP_nop),
3501 Op(DW_OP_skip), Branch(done),
3502
3503 Mark(fail),
3504 Op(DW_OP_lit1),
3505
3506 Mark(done),
3507 Op(DW_OP_stack_value),
3508 ];
3509
3510 let result = [Piece {
3511 size_in_bits: None,
3512 bit_offset: None,
3513 location: Location::Value {
3514 value: Value::Generic(0),
3515 },
3516 }];
3517
3518 check_eval_with_args(
3519 &program,
3520 Ok(&result),
3521 encoding4(),
3522 None,
3523 None,
3524 None,
3525 |eval, mut result| {
3526 while result != EvaluationResult::Complete {
3527 result = match result {
3528 EvaluationResult::RequiresMemory {
3529 address,
3530 size,
3531 space,
3532 base_type,
3533 } => {
3534 assert_eq!(base_type, UnitOffset(0));
3535 let mut v = address << 2;
3536 if let Some(value) = space {
3537 v += value;
3538 }
3539 v &= (1u64 << (8 * size)) - 1;
3540 eval.resume_with_memory(Value::Generic(v))?
3541 }
3542 EvaluationResult::RequiresTls(slot) => eval.resume_with_tls(!slot)?,
3543 EvaluationResult::RequiresRelocatedAddress(address) => {
3544 eval.resume_with_relocated_address(address)?
3545 }
3546 EvaluationResult::RequiresIndexedAddress { index, relocate } => {
3547 if relocate {
3548 eval.resume_with_indexed_address(0x1000 + index.0 as u64)?
3549 } else {
3550 eval.resume_with_indexed_address(10 + index.0 as u64)?
3551 }
3552 }
3553 _ => panic!(),
3554 };
3555 }
3556
3557 Ok(result)
3558 },
3559 );
3560
3561 #[rustfmt::skip]
3562 let program = [
3563 Op(DW_OP_addr), U32(0x7fff_ffff),
3564 Op(DW_OP_deref_size), U8(8),
3565 ];
3566 check_eval_with_args(
3567 &program,
3568 Err(Error::InvalidDerefSize(8)),
3569 encoding4(),
3570 None,
3571 None,
3572 None,
3573 |eval, mut result| {
3574 while result != EvaluationResult::Complete {
3575 result = match result {
3576 EvaluationResult::RequiresMemory {
3577 address,
3578 size,
3579 space,
3580 base_type,
3581 } => {
3582 assert_eq!(base_type, UnitOffset(0));
3583 let mut v = address << 2;
3584 if let Some(value) = space {
3585 v += value;
3586 }
3587 v &= (1u64 << (8 * size)) - 1;
3588 eval.resume_with_memory(Value::Generic(v))?
3589 }
3590 EvaluationResult::RequiresRelocatedAddress(address) => {
3591 eval.resume_with_relocated_address(address)?
3592 }
3593 _ => panic!("Unexpected result: {:?}", result),
3594 };
3595 }
3596
3597 Ok(result)
3598 },
3599 );
3600 }
3601
3602 #[test]
3603 fn test_eval_register() {
3604 use self::AssemblerEntry::*;
3607 use crate::constants::*;
3608
3609 for i in 0..32 {
3610 #[rustfmt::skip]
3611 let program = [
3612 Op(DwOp(DW_OP_reg0.0 + i)),
3613 Op(DW_OP_lit23),
3615 ];
3616 let ok_result = [Piece {
3617 size_in_bits: None,
3618 bit_offset: None,
3619 location: Location::Register {
3620 register: Register(i.into()),
3621 },
3622 }];
3623
3624 check_eval(&program[..1], Ok(&ok_result), encoding4());
3625
3626 check_eval(
3627 &program,
3628 Err(Error::InvalidExpressionTerminator(1)),
3629 encoding4(),
3630 );
3631 }
3632
3633 #[rustfmt::skip]
3634 let program = [
3635 Op(DW_OP_regx), Uleb(0x1234)
3636 ];
3637
3638 let result = [Piece {
3639 size_in_bits: None,
3640 bit_offset: None,
3641 location: Location::Register {
3642 register: Register(0x1234),
3643 },
3644 }];
3645
3646 check_eval(&program, Ok(&result), encoding4());
3647 }
3648
3649 #[test]
3650 fn test_eval_context() {
3651 use self::AssemblerEntry::*;
3654 use crate::constants::*;
3655
3656 #[rustfmt::skip]
3658 let program = [
3659 Op(DW_OP_fbreg), Sleb((-8i8) as u64),
3660 Op(DW_OP_call_frame_cfa),
3661 Op(DW_OP_plus),
3662 Op(DW_OP_neg),
3663 Op(DW_OP_stack_value)
3664 ];
3665
3666 let result = [Piece {
3667 size_in_bits: None,
3668 bit_offset: None,
3669 location: Location::Value {
3670 value: Value::Generic(9),
3671 },
3672 }];
3673
3674 check_eval_with_args(
3675 &program,
3676 Ok(&result),
3677 encoding8(),
3678 None,
3679 None,
3680 None,
3681 |eval, result| {
3682 match result {
3683 EvaluationResult::RequiresFrameBase => {}
3684 _ => panic!(),
3685 };
3686 match eval.resume_with_frame_base(0x0123_4567_89ab_cdef)? {
3687 EvaluationResult::RequiresCallFrameCfa => {}
3688 _ => panic!(),
3689 };
3690 eval.resume_with_call_frame_cfa(0xfedc_ba98_7654_3210)
3691 },
3692 );
3693
3694 #[rustfmt::skip]
3696 let program = [
3697 Op(DW_OP_entry_value), Uleb(8), U64(0x1234_5678),
3698 Op(DW_OP_stack_value)
3699 ];
3700
3701 let result = [Piece {
3702 size_in_bits: None,
3703 bit_offset: None,
3704 location: Location::Value {
3705 value: Value::Generic(0x1234_5678),
3706 },
3707 }];
3708
3709 check_eval_with_args(
3710 &program,
3711 Ok(&result),
3712 encoding8(),
3713 None,
3714 None,
3715 None,
3716 |eval, result| {
3717 let entry_value = match result {
3718 EvaluationResult::RequiresEntryValue(mut expression) => {
3719 expression.0.read_u64()?
3720 }
3721 _ => panic!(),
3722 };
3723 eval.resume_with_entry_value(Value::Generic(entry_value))
3724 },
3725 );
3726
3727 #[rustfmt::skip]
3729 let program = [
3730 Op(DW_OP_push_object_address),
3731 ];
3732
3733 check_eval_with_args(
3734 &program,
3735 Err(Error::InvalidPushObjectAddress),
3736 encoding4(),
3737 None,
3738 None,
3739 None,
3740 |_, _| panic!(),
3741 );
3742
3743 #[rustfmt::skip]
3745 let program = [
3746 Op(DW_OP_push_object_address),
3747 Op(DW_OP_stack_value),
3748 ];
3749
3750 let result = [Piece {
3751 size_in_bits: None,
3752 bit_offset: None,
3753 location: Location::Value {
3754 value: Value::Generic(0xff),
3755 },
3756 }];
3757
3758 check_eval_with_args(
3759 &program,
3760 Ok(&result),
3761 encoding8(),
3762 Some(0xff),
3763 None,
3764 None,
3765 |_, result| Ok(result),
3766 );
3767
3768 #[rustfmt::skip]
3770 let program = [
3771 ];
3772
3773 let result = [Piece {
3774 size_in_bits: None,
3775 bit_offset: None,
3776 location: Location::Address {
3777 address: 0x1234_5678,
3778 },
3779 }];
3780
3781 check_eval_with_args(
3782 &program,
3783 Ok(&result),
3784 encoding8(),
3785 None,
3786 Some(0x1234_5678),
3787 None,
3788 |_, result| Ok(result),
3789 );
3790 }
3791
3792 #[test]
3793 fn test_eval_empty_stack() {
3794 use self::AssemblerEntry::*;
3797 use crate::constants::*;
3798
3799 #[rustfmt::skip]
3800 let program = [
3801 Op(DW_OP_stack_value)
3802 ];
3803
3804 check_eval(&program, Err(Error::NotEnoughStackItems), encoding4());
3805 }
3806
3807 #[test]
3808 fn test_eval_call() {
3809 use self::AssemblerEntry::*;
3812 use crate::constants::*;
3813
3814 #[rustfmt::skip]
3815 let program = [
3816 Op(DW_OP_lit23),
3817 Op(DW_OP_call2), U16(0x7755),
3818 Op(DW_OP_call4), U32(0x7755_aaee),
3819 Op(DW_OP_call_ref), U32(0x7755_aaee),
3820 Op(DW_OP_stack_value)
3821 ];
3822
3823 let result = [Piece {
3824 size_in_bits: None,
3825 bit_offset: None,
3826 location: Location::Value {
3827 value: Value::Generic(23),
3828 },
3829 }];
3830
3831 check_eval_with_args(
3832 &program,
3833 Ok(&result),
3834 encoding4(),
3835 None,
3836 None,
3837 None,
3838 |eval, result| {
3839 let buf = EndianSlice::new(&[], LittleEndian);
3840 match result {
3841 EvaluationResult::RequiresAtLocation(_) => {}
3842 _ => panic!(),
3843 };
3844
3845 eval.resume_with_at_location(buf)?;
3846
3847 match result {
3848 EvaluationResult::RequiresAtLocation(_) => {}
3849 _ => panic!(),
3850 };
3851
3852 eval.resume_with_at_location(buf)?;
3853
3854 match result {
3855 EvaluationResult::RequiresAtLocation(_) => {}
3856 _ => panic!(),
3857 };
3858
3859 eval.resume_with_at_location(buf)
3860 },
3861 );
3862
3863 const SUBR: &[u8] = &[0x32, 0x1e];
3865
3866 let result = [Piece {
3867 size_in_bits: None,
3868 bit_offset: None,
3869 location: Location::Value {
3870 value: Value::Generic(184),
3871 },
3872 }];
3873
3874 check_eval_with_args(
3875 &program,
3876 Ok(&result),
3877 encoding4(),
3878 None,
3879 None,
3880 None,
3881 |eval, result| {
3882 let buf = EndianSlice::new(SUBR, LittleEndian);
3883 match result {
3884 EvaluationResult::RequiresAtLocation(_) => {}
3885 _ => panic!(),
3886 };
3887
3888 eval.resume_with_at_location(buf)?;
3889
3890 match result {
3891 EvaluationResult::RequiresAtLocation(_) => {}
3892 _ => panic!(),
3893 };
3894
3895 eval.resume_with_at_location(buf)?;
3896
3897 match result {
3898 EvaluationResult::RequiresAtLocation(_) => {}
3899 _ => panic!(),
3900 };
3901
3902 eval.resume_with_at_location(buf)
3903 },
3904 );
3905 }
3906
3907 #[test]
3908 fn test_eval_pieces() {
3909 use self::AssemblerEntry::*;
3912 use crate::constants::*;
3913
3914 #[rustfmt::skip]
3916 let program = [
3917 Op(DW_OP_reg3),
3918 Op(DW_OP_piece), Uleb(4),
3919 Op(DW_OP_reg4),
3920 Op(DW_OP_piece), Uleb(2),
3921 ];
3922
3923 let result = [
3924 Piece {
3925 size_in_bits: Some(32),
3926 bit_offset: None,
3927 location: Location::Register {
3928 register: Register(3),
3929 },
3930 },
3931 Piece {
3932 size_in_bits: Some(16),
3933 bit_offset: None,
3934 location: Location::Register {
3935 register: Register(4),
3936 },
3937 },
3938 ];
3939
3940 check_eval(&program, Ok(&result), encoding4());
3941
3942 #[rustfmt::skip]
3945 let program = [
3946 Op(DW_OP_reg0),
3947 Op(DW_OP_piece), Uleb(4),
3948 Op(DW_OP_piece), Uleb(4),
3949 Op(DW_OP_addr), U32(0x7fff_ffff),
3950 Op(DW_OP_piece), Uleb(4),
3951 ];
3952
3953 let result = [
3954 Piece {
3955 size_in_bits: Some(32),
3956 bit_offset: None,
3957 location: Location::Register {
3958 register: Register(0),
3959 },
3960 },
3961 Piece {
3962 size_in_bits: Some(32),
3963 bit_offset: None,
3964 location: Location::Empty,
3965 },
3966 Piece {
3967 size_in_bits: Some(32),
3968 bit_offset: None,
3969 location: Location::Address {
3970 address: 0x7fff_ffff,
3971 },
3972 },
3973 ];
3974
3975 check_eval_with_args(
3976 &program,
3977 Ok(&result),
3978 encoding4(),
3979 None,
3980 None,
3981 None,
3982 |eval, mut result| {
3983 while result != EvaluationResult::Complete {
3984 result = match result {
3985 EvaluationResult::RequiresRelocatedAddress(address) => {
3986 eval.resume_with_relocated_address(address)?
3987 }
3988 _ => panic!(),
3989 };
3990 }
3991
3992 Ok(result)
3993 },
3994 );
3995
3996 #[rustfmt::skip]
3997 let program = [
3998 Op(DW_OP_implicit_value), Uleb(5),
3999 U8(23), U8(24), U8(25), U8(26), U8(0),
4000 ];
4001
4002 const BYTES: &[u8] = &[23, 24, 25, 26, 0];
4003
4004 let result = [Piece {
4005 size_in_bits: None,
4006 bit_offset: None,
4007 location: Location::Bytes {
4008 value: EndianSlice::new(BYTES, LittleEndian),
4009 },
4010 }];
4011
4012 check_eval(&program, Ok(&result), encoding4());
4013
4014 #[rustfmt::skip]
4015 let program = [
4016 Op(DW_OP_lit7),
4017 Op(DW_OP_stack_value),
4018 Op(DW_OP_bit_piece), Uleb(5), Uleb(0),
4019 Op(DW_OP_bit_piece), Uleb(3), Uleb(0),
4020 ];
4021
4022 let result = [
4023 Piece {
4024 size_in_bits: Some(5),
4025 bit_offset: Some(0),
4026 location: Location::Value {
4027 value: Value::Generic(7),
4028 },
4029 },
4030 Piece {
4031 size_in_bits: Some(3),
4032 bit_offset: Some(0),
4033 location: Location::Empty,
4034 },
4035 ];
4036
4037 check_eval(&program, Ok(&result), encoding4());
4038
4039 #[rustfmt::skip]
4040 let program = [
4041 Op(DW_OP_lit7),
4042 ];
4043
4044 let result = [Piece {
4045 size_in_bits: None,
4046 bit_offset: None,
4047 location: Location::Address { address: 7 },
4048 }];
4049
4050 check_eval(&program, Ok(&result), encoding4());
4051
4052 #[rustfmt::skip]
4053 let program = [
4054 Op(DW_OP_implicit_pointer), U32(0x1234_5678), Sleb(0x123),
4055 ];
4056
4057 let result = [Piece {
4058 size_in_bits: None,
4059 bit_offset: None,
4060 location: Location::ImplicitPointer {
4061 value: DebugInfoOffset(0x1234_5678),
4062 byte_offset: 0x123,
4063 },
4064 }];
4065
4066 check_eval(&program, Ok(&result), encoding4());
4067
4068 #[rustfmt::skip]
4069 let program = [
4070 Op(DW_OP_reg3),
4071 Op(DW_OP_piece), Uleb(4),
4072 Op(DW_OP_reg4),
4073 ];
4074
4075 check_eval(&program, Err(Error::InvalidPiece), encoding4());
4076
4077 #[rustfmt::skip]
4078 let program = [
4079 Op(DW_OP_reg3),
4080 Op(DW_OP_piece), Uleb(4),
4081 Op(DW_OP_lit0),
4082 ];
4083
4084 check_eval(&program, Err(Error::InvalidPiece), encoding4());
4085 }
4086
4087 #[test]
4088 fn test_eval_max_iterations() {
4089 use self::AssemblerEntry::*;
4092 use crate::constants::*;
4093
4094 #[rustfmt::skip]
4095 let program = [
4096 Mark(1),
4097 Op(DW_OP_skip), Branch(1),
4098 ];
4099
4100 check_eval_with_args(
4101 &program,
4102 Err(Error::TooManyIterations),
4103 encoding4(),
4104 None,
4105 None,
4106 Some(150),
4107 |_, _| panic!(),
4108 );
4109 }
4110
4111 #[test]
4112 fn test_eval_typed_stack() {
4113 use self::AssemblerEntry::*;
4114 use crate::constants::*;
4115
4116 let base_types = [
4117 ValueType::Generic,
4118 ValueType::U16,
4119 ValueType::U32,
4120 ValueType::F32,
4121 ];
4122
4123 #[rustfmt::skip]
4125 let tests = [
4126 (
4127 &[
4128 Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
4129 Op(DW_OP_stack_value),
4130 ][..],
4131 Value::U16(0x1234),
4132 ),
4133 (
4134 &[
4135 Op(DW_OP_regval_type), Uleb(0x1234), Uleb(1),
4136 Op(DW_OP_stack_value),
4137 ][..],
4138 Value::U16(0x2340),
4139 ),
4140 (
4141 &[
4142 Op(DW_OP_addr), U32(0x7fff_ffff),
4143 Op(DW_OP_deref_type), U8(2), Uleb(1),
4144 Op(DW_OP_stack_value),
4145 ][..],
4146 Value::U16(0xfff0),
4147 ),
4148 (
4149 &[
4150 Op(DW_OP_lit1),
4151 Op(DW_OP_addr), U32(0x7fff_ffff),
4152 Op(DW_OP_xderef_type), U8(2), Uleb(1),
4153 Op(DW_OP_stack_value),
4154 ][..],
4155 Value::U16(0xfff1),
4156 ),
4157 (
4158 &[
4159 Op(DW_OP_const_type), Uleb(1), U8(2), U16(0x1234),
4160 Op(DW_OP_convert), Uleb(2),
4161 Op(DW_OP_stack_value),
4162 ][..],
4163 Value::U32(0x1234),
4164 ),
4165 (
4166 &[
4167 Op(DW_OP_const_type), Uleb(2), U8(4), U32(0x3f80_0000),
4168 Op(DW_OP_reinterpret), Uleb(3),
4169 Op(DW_OP_stack_value),
4170 ][..],
4171 Value::F32(1.0),
4172 ),
4173 ];
4174 for &(program, value) in &tests {
4175 let result = [Piece {
4176 size_in_bits: None,
4177 bit_offset: None,
4178 location: Location::Value { value },
4179 }];
4180
4181 check_eval_with_args(
4182 program,
4183 Ok(&result),
4184 encoding4(),
4185 None,
4186 None,
4187 None,
4188 |eval, mut result| {
4189 while result != EvaluationResult::Complete {
4190 result = match result {
4191 EvaluationResult::RequiresMemory {
4192 address,
4193 size,
4194 space,
4195 base_type,
4196 } => {
4197 let mut v = address << 4;
4198 if let Some(value) = space {
4199 v += value;
4200 }
4201 v &= (1u64 << (8 * size)) - 1;
4202 let v = Value::from_u64(base_types[base_type.0], v)?;
4203 eval.resume_with_memory(v)?
4204 }
4205 EvaluationResult::RequiresRegister {
4206 register,
4207 base_type,
4208 } => {
4209 let v = Value::from_u64(
4210 base_types[base_type.0],
4211 u64::from(register.0) << 4,
4212 )?;
4213 eval.resume_with_register(v)?
4214 }
4215 EvaluationResult::RequiresBaseType(offset) => {
4216 eval.resume_with_base_type(base_types[offset.0])?
4217 }
4218 EvaluationResult::RequiresRelocatedAddress(address) => {
4219 eval.resume_with_relocated_address(address)?
4220 }
4221 _ => panic!("Unexpected result {:?}", result),
4222 }
4223 }
4224 Ok(result)
4225 },
4226 );
4227 }
4228 }
4229}