Coverage Report

Created: 2023-04-25 07:07

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