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}