Coverage Report

Created: 2024-10-16 07:58

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