Coverage Report

Created: 2026-03-26 07:41

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