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