xref: /freebsd-src/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- DWARFExpression.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Expression/DWARFExpression.h"
100b57cec5SDimitry Andric 
11fe6060f1SDimitry Andric #include <cinttypes>
120b57cec5SDimitry Andric 
13bdd1243dSDimitry Andric #include <optional>
140b57cec5SDimitry Andric #include <vector>
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "lldb/Core/Module.h"
170b57cec5SDimitry Andric #include "lldb/Core/Value.h"
180b57cec5SDimitry Andric #include "lldb/Core/dwarf.h"
190b57cec5SDimitry Andric #include "lldb/Utility/DataEncoder.h"
2081ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
210b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
220b57cec5SDimitry Andric #include "lldb/Utility/RegisterValue.h"
230b57cec5SDimitry Andric #include "lldb/Utility/Scalar.h"
240b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
250b57cec5SDimitry Andric #include "lldb/Utility/VMRange.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric #include "lldb/Host/Host.h"
280b57cec5SDimitry Andric #include "lldb/Utility/Endian.h"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric #include "lldb/Symbol/Function.h"
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
330b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
340b57cec5SDimitry Andric #include "lldb/Target/Process.h"
350b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
360b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
370b57cec5SDimitry Andric #include "lldb/Target/StackID.h"
389dba64beSDimitry Andric #include "lldb/Target/Target.h"
390b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
4081ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
4181ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric using namespace lldb;
460b57cec5SDimitry Andric using namespace lldb_private;
4781ad6265SDimitry Andric using namespace lldb_private::dwarf;
485f757f3fSDimitry Andric using namespace lldb_private::plugin::dwarf;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric // DWARFExpression constructor
51753f127fSDimitry Andric DWARFExpression::DWARFExpression() : m_data() {}
520b57cec5SDimitry Andric 
53753f127fSDimitry Andric DWARFExpression::DWARFExpression(const DataExtractor &data) : m_data(data) {}
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric // Destructor
56fe6060f1SDimitry Andric DWARFExpression::~DWARFExpression() = default;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; }
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric void DWARFExpression::UpdateValue(uint64_t const_value,
610b57cec5SDimitry Andric                                   lldb::offset_t const_value_byte_size,
620b57cec5SDimitry Andric                                   uint8_t addr_byte_size) {
630b57cec5SDimitry Andric   if (!const_value_byte_size)
640b57cec5SDimitry Andric     return;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   m_data.SetData(
670b57cec5SDimitry Andric       DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size)));
680b57cec5SDimitry Andric   m_data.SetByteOrder(endian::InlHostByteOrder());
690b57cec5SDimitry Andric   m_data.SetAddressByteSize(addr_byte_size);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
72753f127fSDimitry Andric void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
730b57cec5SDimitry Andric                                    ABI *abi) const {
74bdd1243dSDimitry Andric   auto *MCRegInfo = abi ? &abi->GetMCRegisterInfo() : nullptr;
75bdd1243dSDimitry Andric   auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum,
76bdd1243dSDimitry Andric                                  bool IsEH) -> llvm::StringRef {
77bdd1243dSDimitry Andric     if (!MCRegInfo)
78bdd1243dSDimitry Andric       return {};
79bdd1243dSDimitry Andric     if (std::optional<unsigned> LLVMRegNum =
80bdd1243dSDimitry Andric             MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
81bdd1243dSDimitry Andric       if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))
82bdd1243dSDimitry Andric         return llvm::StringRef(RegName);
83bdd1243dSDimitry Andric     return {};
84bdd1243dSDimitry Andric   };
85bdd1243dSDimitry Andric   llvm::DIDumpOptions DumpOpts;
86bdd1243dSDimitry Andric   DumpOpts.GetNameForDWARFReg = GetRegName;
87753f127fSDimitry Andric   llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())
88bdd1243dSDimitry Andric       .print(s->AsRawOstream(), DumpOpts, nullptr);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
91753f127fSDimitry Andric RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
940b57cec5SDimitry Andric   m_reg_kind = reg_kind;
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
97*0fca6ea1SDimitry Andric static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
980b57cec5SDimitry Andric                                              lldb::RegisterKind reg_kind,
99*0fca6ea1SDimitry Andric                                              uint32_t reg_num, Value &value) {
100*0fca6ea1SDimitry Andric   if (reg_ctx == nullptr)
101*0fca6ea1SDimitry Andric     return llvm::createStringError("no register context in frame");
102*0fca6ea1SDimitry Andric 
103*0fca6ea1SDimitry Andric   const uint32_t native_reg =
1040b57cec5SDimitry Andric       reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
105*0fca6ea1SDimitry Andric   if (native_reg == LLDB_INVALID_REGNUM)
106*0fca6ea1SDimitry Andric     return llvm::createStringError(
107*0fca6ea1SDimitry Andric         "unable to convert register kind=%u reg_num=%u to a native "
108*0fca6ea1SDimitry Andric         "register number",
1090b57cec5SDimitry Andric         reg_kind, reg_num);
110*0fca6ea1SDimitry Andric 
111*0fca6ea1SDimitry Andric   const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg);
1120b57cec5SDimitry Andric   RegisterValue reg_value;
1130b57cec5SDimitry Andric   if (reg_ctx->ReadRegister(reg_info, reg_value)) {
1140b57cec5SDimitry Andric     if (reg_value.GetScalarValue(value.GetScalar())) {
115fe6060f1SDimitry Andric       value.SetValueType(Value::ValueType::Scalar);
116fe6060f1SDimitry Andric       value.SetContext(Value::ContextType::RegisterInfo,
1170b57cec5SDimitry Andric                        const_cast<RegisterInfo *>(reg_info));
118*0fca6ea1SDimitry Andric       return llvm::Error::success();
119*0fca6ea1SDimitry Andric     }
120*0fca6ea1SDimitry Andric 
1210b57cec5SDimitry Andric     // If we get this error, then we need to implement a value buffer in
1220b57cec5SDimitry Andric     // the dwarf expression evaluation function...
123*0fca6ea1SDimitry Andric     return llvm::createStringError(
124*0fca6ea1SDimitry Andric         "register %s can't be converted to a scalar value", reg_info->name);
125*0fca6ea1SDimitry Andric   }
126*0fca6ea1SDimitry Andric 
127*0fca6ea1SDimitry Andric   return llvm::createStringError("register %s is not available",
1280b57cec5SDimitry Andric                                  reg_info->name);
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1319dba64beSDimitry Andric /// Return the length in bytes of the set of operands for \p op. No guarantees
1329dba64beSDimitry Andric /// are made on the state of \p data after this call.
1330b57cec5SDimitry Andric static offset_t GetOpcodeDataSize(const DataExtractor &data,
1340b57cec5SDimitry Andric                                   const lldb::offset_t data_offset,
135bdd1243dSDimitry Andric                                   const uint8_t op, const DWARFUnit *dwarf_cu) {
1360b57cec5SDimitry Andric   lldb::offset_t offset = data_offset;
1370b57cec5SDimitry Andric   switch (op) {
1380b57cec5SDimitry Andric   case DW_OP_addr:
1390b57cec5SDimitry Andric   case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3)
1400b57cec5SDimitry Andric     return data.GetAddressByteSize();
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   // Opcodes with no arguments
1430b57cec5SDimitry Andric   case DW_OP_deref:                // 0x06
1440b57cec5SDimitry Andric   case DW_OP_dup:                  // 0x12
1450b57cec5SDimitry Andric   case DW_OP_drop:                 // 0x13
1460b57cec5SDimitry Andric   case DW_OP_over:                 // 0x14
1470b57cec5SDimitry Andric   case DW_OP_swap:                 // 0x16
1480b57cec5SDimitry Andric   case DW_OP_rot:                  // 0x17
1490b57cec5SDimitry Andric   case DW_OP_xderef:               // 0x18
1500b57cec5SDimitry Andric   case DW_OP_abs:                  // 0x19
1510b57cec5SDimitry Andric   case DW_OP_and:                  // 0x1a
1520b57cec5SDimitry Andric   case DW_OP_div:                  // 0x1b
1530b57cec5SDimitry Andric   case DW_OP_minus:                // 0x1c
1540b57cec5SDimitry Andric   case DW_OP_mod:                  // 0x1d
1550b57cec5SDimitry Andric   case DW_OP_mul:                  // 0x1e
1560b57cec5SDimitry Andric   case DW_OP_neg:                  // 0x1f
1570b57cec5SDimitry Andric   case DW_OP_not:                  // 0x20
1580b57cec5SDimitry Andric   case DW_OP_or:                   // 0x21
1590b57cec5SDimitry Andric   case DW_OP_plus:                 // 0x22
1600b57cec5SDimitry Andric   case DW_OP_shl:                  // 0x24
1610b57cec5SDimitry Andric   case DW_OP_shr:                  // 0x25
1620b57cec5SDimitry Andric   case DW_OP_shra:                 // 0x26
1630b57cec5SDimitry Andric   case DW_OP_xor:                  // 0x27
1640b57cec5SDimitry Andric   case DW_OP_eq:                   // 0x29
1650b57cec5SDimitry Andric   case DW_OP_ge:                   // 0x2a
1660b57cec5SDimitry Andric   case DW_OP_gt:                   // 0x2b
1670b57cec5SDimitry Andric   case DW_OP_le:                   // 0x2c
1680b57cec5SDimitry Andric   case DW_OP_lt:                   // 0x2d
1690b57cec5SDimitry Andric   case DW_OP_ne:                   // 0x2e
1700b57cec5SDimitry Andric   case DW_OP_lit0:                 // 0x30
1710b57cec5SDimitry Andric   case DW_OP_lit1:                 // 0x31
1720b57cec5SDimitry Andric   case DW_OP_lit2:                 // 0x32
1730b57cec5SDimitry Andric   case DW_OP_lit3:                 // 0x33
1740b57cec5SDimitry Andric   case DW_OP_lit4:                 // 0x34
1750b57cec5SDimitry Andric   case DW_OP_lit5:                 // 0x35
1760b57cec5SDimitry Andric   case DW_OP_lit6:                 // 0x36
1770b57cec5SDimitry Andric   case DW_OP_lit7:                 // 0x37
1780b57cec5SDimitry Andric   case DW_OP_lit8:                 // 0x38
1790b57cec5SDimitry Andric   case DW_OP_lit9:                 // 0x39
1800b57cec5SDimitry Andric   case DW_OP_lit10:                // 0x3A
1810b57cec5SDimitry Andric   case DW_OP_lit11:                // 0x3B
1820b57cec5SDimitry Andric   case DW_OP_lit12:                // 0x3C
1830b57cec5SDimitry Andric   case DW_OP_lit13:                // 0x3D
1840b57cec5SDimitry Andric   case DW_OP_lit14:                // 0x3E
1850b57cec5SDimitry Andric   case DW_OP_lit15:                // 0x3F
1860b57cec5SDimitry Andric   case DW_OP_lit16:                // 0x40
1870b57cec5SDimitry Andric   case DW_OP_lit17:                // 0x41
1880b57cec5SDimitry Andric   case DW_OP_lit18:                // 0x42
1890b57cec5SDimitry Andric   case DW_OP_lit19:                // 0x43
1900b57cec5SDimitry Andric   case DW_OP_lit20:                // 0x44
1910b57cec5SDimitry Andric   case DW_OP_lit21:                // 0x45
1920b57cec5SDimitry Andric   case DW_OP_lit22:                // 0x46
1930b57cec5SDimitry Andric   case DW_OP_lit23:                // 0x47
1940b57cec5SDimitry Andric   case DW_OP_lit24:                // 0x48
1950b57cec5SDimitry Andric   case DW_OP_lit25:                // 0x49
1960b57cec5SDimitry Andric   case DW_OP_lit26:                // 0x4A
1970b57cec5SDimitry Andric   case DW_OP_lit27:                // 0x4B
1980b57cec5SDimitry Andric   case DW_OP_lit28:                // 0x4C
1990b57cec5SDimitry Andric   case DW_OP_lit29:                // 0x4D
2000b57cec5SDimitry Andric   case DW_OP_lit30:                // 0x4E
2010b57cec5SDimitry Andric   case DW_OP_lit31:                // 0x4f
2020b57cec5SDimitry Andric   case DW_OP_reg0:                 // 0x50
2030b57cec5SDimitry Andric   case DW_OP_reg1:                 // 0x51
2040b57cec5SDimitry Andric   case DW_OP_reg2:                 // 0x52
2050b57cec5SDimitry Andric   case DW_OP_reg3:                 // 0x53
2060b57cec5SDimitry Andric   case DW_OP_reg4:                 // 0x54
2070b57cec5SDimitry Andric   case DW_OP_reg5:                 // 0x55
2080b57cec5SDimitry Andric   case DW_OP_reg6:                 // 0x56
2090b57cec5SDimitry Andric   case DW_OP_reg7:                 // 0x57
2100b57cec5SDimitry Andric   case DW_OP_reg8:                 // 0x58
2110b57cec5SDimitry Andric   case DW_OP_reg9:                 // 0x59
2120b57cec5SDimitry Andric   case DW_OP_reg10:                // 0x5A
2130b57cec5SDimitry Andric   case DW_OP_reg11:                // 0x5B
2140b57cec5SDimitry Andric   case DW_OP_reg12:                // 0x5C
2150b57cec5SDimitry Andric   case DW_OP_reg13:                // 0x5D
2160b57cec5SDimitry Andric   case DW_OP_reg14:                // 0x5E
2170b57cec5SDimitry Andric   case DW_OP_reg15:                // 0x5F
2180b57cec5SDimitry Andric   case DW_OP_reg16:                // 0x60
2190b57cec5SDimitry Andric   case DW_OP_reg17:                // 0x61
2200b57cec5SDimitry Andric   case DW_OP_reg18:                // 0x62
2210b57cec5SDimitry Andric   case DW_OP_reg19:                // 0x63
2220b57cec5SDimitry Andric   case DW_OP_reg20:                // 0x64
2230b57cec5SDimitry Andric   case DW_OP_reg21:                // 0x65
2240b57cec5SDimitry Andric   case DW_OP_reg22:                // 0x66
2250b57cec5SDimitry Andric   case DW_OP_reg23:                // 0x67
2260b57cec5SDimitry Andric   case DW_OP_reg24:                // 0x68
2270b57cec5SDimitry Andric   case DW_OP_reg25:                // 0x69
2280b57cec5SDimitry Andric   case DW_OP_reg26:                // 0x6A
2290b57cec5SDimitry Andric   case DW_OP_reg27:                // 0x6B
2300b57cec5SDimitry Andric   case DW_OP_reg28:                // 0x6C
2310b57cec5SDimitry Andric   case DW_OP_reg29:                // 0x6D
2320b57cec5SDimitry Andric   case DW_OP_reg30:                // 0x6E
2330b57cec5SDimitry Andric   case DW_OP_reg31:                // 0x6F
2340b57cec5SDimitry Andric   case DW_OP_nop:                  // 0x96
2350b57cec5SDimitry Andric   case DW_OP_push_object_address:  // 0x97 DWARF3
2360b57cec5SDimitry Andric   case DW_OP_form_tls_address:     // 0x9b DWARF3
2370b57cec5SDimitry Andric   case DW_OP_call_frame_cfa:       // 0x9c DWARF3
2380b57cec5SDimitry Andric   case DW_OP_stack_value:          // 0x9f DWARF4
2390b57cec5SDimitry Andric   case DW_OP_GNU_push_tls_address: // 0xe0 GNU extension
2400b57cec5SDimitry Andric     return 0;
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   // Opcodes with a single 1 byte arguments
2430b57cec5SDimitry Andric   case DW_OP_const1u:     // 0x08 1 1-byte constant
2440b57cec5SDimitry Andric   case DW_OP_const1s:     // 0x09 1 1-byte constant
2450b57cec5SDimitry Andric   case DW_OP_pick:        // 0x15 1 1-byte stack index
2460b57cec5SDimitry Andric   case DW_OP_deref_size:  // 0x94 1 1-byte size of data retrieved
2470b57cec5SDimitry Andric   case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
2480b57cec5SDimitry Andric     return 1;
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   // Opcodes with a single 2 byte arguments
2510b57cec5SDimitry Andric   case DW_OP_const2u: // 0x0a 1 2-byte constant
2520b57cec5SDimitry Andric   case DW_OP_const2s: // 0x0b 1 2-byte constant
2530b57cec5SDimitry Andric   case DW_OP_skip:    // 0x2f 1 signed 2-byte constant
2540b57cec5SDimitry Andric   case DW_OP_bra:     // 0x28 1 signed 2-byte constant
2550b57cec5SDimitry Andric   case DW_OP_call2:   // 0x98 1 2-byte offset of DIE (DWARF3)
2560b57cec5SDimitry Andric     return 2;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   // Opcodes with a single 4 byte arguments
2590b57cec5SDimitry Andric   case DW_OP_const4u: // 0x0c 1 4-byte constant
2600b57cec5SDimitry Andric   case DW_OP_const4s: // 0x0d 1 4-byte constant
2610b57cec5SDimitry Andric   case DW_OP_call4:   // 0x99 1 4-byte offset of DIE (DWARF3)
2620b57cec5SDimitry Andric     return 4;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   // Opcodes with a single 8 byte arguments
2650b57cec5SDimitry Andric   case DW_OP_const8u: // 0x0e 1 8-byte constant
2660b57cec5SDimitry Andric   case DW_OP_const8s: // 0x0f 1 8-byte constant
2670b57cec5SDimitry Andric     return 8;
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   // All opcodes that have a single ULEB (signed or unsigned) argument
2700b57cec5SDimitry Andric   case DW_OP_addrx:           // 0xa1 1 ULEB128 index
2710b57cec5SDimitry Andric   case DW_OP_constu:          // 0x10 1 ULEB128 constant
2720b57cec5SDimitry Andric   case DW_OP_consts:          // 0x11 1 SLEB128 constant
2730b57cec5SDimitry Andric   case DW_OP_plus_uconst:     // 0x23 1 ULEB128 addend
2740b57cec5SDimitry Andric   case DW_OP_breg0:           // 0x70 1 ULEB128 register
2750b57cec5SDimitry Andric   case DW_OP_breg1:           // 0x71 1 ULEB128 register
2760b57cec5SDimitry Andric   case DW_OP_breg2:           // 0x72 1 ULEB128 register
2770b57cec5SDimitry Andric   case DW_OP_breg3:           // 0x73 1 ULEB128 register
2780b57cec5SDimitry Andric   case DW_OP_breg4:           // 0x74 1 ULEB128 register
2790b57cec5SDimitry Andric   case DW_OP_breg5:           // 0x75 1 ULEB128 register
2800b57cec5SDimitry Andric   case DW_OP_breg6:           // 0x76 1 ULEB128 register
2810b57cec5SDimitry Andric   case DW_OP_breg7:           // 0x77 1 ULEB128 register
2820b57cec5SDimitry Andric   case DW_OP_breg8:           // 0x78 1 ULEB128 register
2830b57cec5SDimitry Andric   case DW_OP_breg9:           // 0x79 1 ULEB128 register
2840b57cec5SDimitry Andric   case DW_OP_breg10:          // 0x7a 1 ULEB128 register
2850b57cec5SDimitry Andric   case DW_OP_breg11:          // 0x7b 1 ULEB128 register
2860b57cec5SDimitry Andric   case DW_OP_breg12:          // 0x7c 1 ULEB128 register
2870b57cec5SDimitry Andric   case DW_OP_breg13:          // 0x7d 1 ULEB128 register
2880b57cec5SDimitry Andric   case DW_OP_breg14:          // 0x7e 1 ULEB128 register
2890b57cec5SDimitry Andric   case DW_OP_breg15:          // 0x7f 1 ULEB128 register
2900b57cec5SDimitry Andric   case DW_OP_breg16:          // 0x80 1 ULEB128 register
2910b57cec5SDimitry Andric   case DW_OP_breg17:          // 0x81 1 ULEB128 register
2920b57cec5SDimitry Andric   case DW_OP_breg18:          // 0x82 1 ULEB128 register
2930b57cec5SDimitry Andric   case DW_OP_breg19:          // 0x83 1 ULEB128 register
2940b57cec5SDimitry Andric   case DW_OP_breg20:          // 0x84 1 ULEB128 register
2950b57cec5SDimitry Andric   case DW_OP_breg21:          // 0x85 1 ULEB128 register
2960b57cec5SDimitry Andric   case DW_OP_breg22:          // 0x86 1 ULEB128 register
2970b57cec5SDimitry Andric   case DW_OP_breg23:          // 0x87 1 ULEB128 register
2980b57cec5SDimitry Andric   case DW_OP_breg24:          // 0x88 1 ULEB128 register
2990b57cec5SDimitry Andric   case DW_OP_breg25:          // 0x89 1 ULEB128 register
3000b57cec5SDimitry Andric   case DW_OP_breg26:          // 0x8a 1 ULEB128 register
3010b57cec5SDimitry Andric   case DW_OP_breg27:          // 0x8b 1 ULEB128 register
3020b57cec5SDimitry Andric   case DW_OP_breg28:          // 0x8c 1 ULEB128 register
3030b57cec5SDimitry Andric   case DW_OP_breg29:          // 0x8d 1 ULEB128 register
3040b57cec5SDimitry Andric   case DW_OP_breg30:          // 0x8e 1 ULEB128 register
3050b57cec5SDimitry Andric   case DW_OP_breg31:          // 0x8f 1 ULEB128 register
3060b57cec5SDimitry Andric   case DW_OP_regx:            // 0x90 1 ULEB128 register
3070b57cec5SDimitry Andric   case DW_OP_fbreg:           // 0x91 1 SLEB128 offset
3080b57cec5SDimitry Andric   case DW_OP_piece:           // 0x93 1 ULEB128 size of piece addressed
3090b57cec5SDimitry Andric   case DW_OP_GNU_addr_index:  // 0xfb 1 ULEB128 index
3100b57cec5SDimitry Andric   case DW_OP_GNU_const_index: // 0xfc 1 ULEB128 index
3110b57cec5SDimitry Andric     data.Skip_LEB128(&offset);
3120b57cec5SDimitry Andric     return offset - data_offset;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   // All opcodes that have a 2 ULEB (signed or unsigned) arguments
3150b57cec5SDimitry Andric   case DW_OP_bregx:     // 0x92 2 ULEB128 register followed by SLEB128 offset
3160b57cec5SDimitry Andric   case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
3170b57cec5SDimitry Andric     data.Skip_LEB128(&offset);
3180b57cec5SDimitry Andric     data.Skip_LEB128(&offset);
3190b57cec5SDimitry Andric     return offset - data_offset;
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size
3220b57cec5SDimitry Andric                              // (DWARF4)
3230b57cec5SDimitry Andric   {
3240b57cec5SDimitry Andric     uint64_t block_len = data.Skip_LEB128(&offset);
3250b57cec5SDimitry Andric     offset += block_len;
3260b57cec5SDimitry Andric     return offset - data_offset;
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric 
3295ffd83dbSDimitry Andric   case DW_OP_GNU_entry_value:
3309dba64beSDimitry Andric   case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block
3319dba64beSDimitry Andric   {
3329dba64beSDimitry Andric     uint64_t subexpr_len = data.GetULEB128(&offset);
3339dba64beSDimitry Andric     return (offset - data_offset) + subexpr_len;
3349dba64beSDimitry Andric   }
3359dba64beSDimitry Andric 
3360b57cec5SDimitry Andric   default:
337bdd1243dSDimitry Andric     if (!dwarf_cu) {
3380b57cec5SDimitry Andric       return LLDB_INVALID_OFFSET;
3390b57cec5SDimitry Andric     }
340bdd1243dSDimitry Andric     return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(
341bdd1243dSDimitry Andric         data, data_offset, op);
342bdd1243dSDimitry Andric   }
343bdd1243dSDimitry Andric }
3440b57cec5SDimitry Andric 
345753f127fSDimitry Andric lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
3460b57cec5SDimitry Andric                                                      bool &error) const {
3470b57cec5SDimitry Andric   error = false;
3480b57cec5SDimitry Andric   lldb::offset_t offset = 0;
3490b57cec5SDimitry Andric   while (m_data.ValidOffset(offset)) {
3500b57cec5SDimitry Andric     const uint8_t op = m_data.GetU8(&offset);
3510b57cec5SDimitry Andric 
35206c3fb27SDimitry Andric     if (op == DW_OP_addr)
35306c3fb27SDimitry Andric       return m_data.GetAddress(&offset);
35406c3fb27SDimitry Andric     if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
3550b57cec5SDimitry Andric       uint64_t index = m_data.GetULEB128(&offset);
35606c3fb27SDimitry Andric       if (dwarf_cu)
35706c3fb27SDimitry Andric         return dwarf_cu->ReadAddressFromDebugAddrSection(index);
3580b57cec5SDimitry Andric       error = true;
3590b57cec5SDimitry Andric       break;
3600b57cec5SDimitry Andric     }
361bdd1243dSDimitry Andric     const offset_t op_arg_size =
362bdd1243dSDimitry Andric         GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
3630b57cec5SDimitry Andric     if (op_arg_size == LLDB_INVALID_OFFSET) {
3640b57cec5SDimitry Andric       error = true;
3650b57cec5SDimitry Andric       break;
3660b57cec5SDimitry Andric     }
3670b57cec5SDimitry Andric     offset += op_arg_size;
3680b57cec5SDimitry Andric   }
3690b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
372bdd1243dSDimitry Andric bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
373bdd1243dSDimitry Andric                                         lldb::addr_t file_addr) {
3740b57cec5SDimitry Andric   lldb::offset_t offset = 0;
3750b57cec5SDimitry Andric   while (m_data.ValidOffset(offset)) {
3760b57cec5SDimitry Andric     const uint8_t op = m_data.GetU8(&offset);
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric     if (op == DW_OP_addr) {
3790b57cec5SDimitry Andric       const uint32_t addr_byte_size = m_data.GetAddressByteSize();
3800b57cec5SDimitry Andric       // We have to make a copy of the data as we don't know if this data is
3810b57cec5SDimitry Andric       // from a read only memory mapped buffer, so we duplicate all of the data
3820b57cec5SDimitry Andric       // first, then modify it, and if all goes well, we then replace the data
3830b57cec5SDimitry Andric       // for this expression
3840b57cec5SDimitry Andric 
3850eae32dcSDimitry Andric       // Make en encoder that contains a copy of the location expression data
3860eae32dcSDimitry Andric       // so we can write the address into the buffer using the correct byte
3870eae32dcSDimitry Andric       // order.
3880eae32dcSDimitry Andric       DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
3890b57cec5SDimitry Andric                           m_data.GetByteOrder(), addr_byte_size);
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric       // Replace the address in the new buffer
3920eae32dcSDimitry Andric       if (encoder.PutAddress(offset, file_addr) == UINT32_MAX)
3930b57cec5SDimitry Andric         return false;
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric       // All went well, so now we can reset the data using a shared pointer to
3960b57cec5SDimitry Andric       // the heap data so "m_data" will now correctly manage the heap data.
3970eae32dcSDimitry Andric       m_data.SetData(encoder.GetDataBuffer());
3980b57cec5SDimitry Andric       return true;
39906c3fb27SDimitry Andric     }
40006c3fb27SDimitry Andric     if (op == DW_OP_addrx) {
40106c3fb27SDimitry Andric       // Replace DW_OP_addrx with DW_OP_addr, since we can't modify the
40206c3fb27SDimitry Andric       // read-only debug_addr table.
40306c3fb27SDimitry Andric       // Subtract one to account for the opcode.
40406c3fb27SDimitry Andric       llvm::ArrayRef data_before_op = m_data.GetData().take_front(offset - 1);
40506c3fb27SDimitry Andric 
40606c3fb27SDimitry Andric       // Read the addrx index to determine how many bytes it needs.
40706c3fb27SDimitry Andric       const lldb::offset_t old_offset = offset;
40806c3fb27SDimitry Andric       m_data.GetULEB128(&offset);
40906c3fb27SDimitry Andric       if (old_offset == offset)
41006c3fb27SDimitry Andric         return false;
41106c3fb27SDimitry Andric       llvm::ArrayRef data_after_op = m_data.GetData().drop_front(offset);
41206c3fb27SDimitry Andric 
41306c3fb27SDimitry Andric       DataEncoder encoder(m_data.GetByteOrder(), m_data.GetAddressByteSize());
41406c3fb27SDimitry Andric       encoder.AppendData(data_before_op);
41506c3fb27SDimitry Andric       encoder.AppendU8(DW_OP_addr);
41606c3fb27SDimitry Andric       encoder.AppendAddress(file_addr);
41706c3fb27SDimitry Andric       encoder.AppendData(data_after_op);
41806c3fb27SDimitry Andric       m_data.SetData(encoder.GetDataBuffer());
41906c3fb27SDimitry Andric       return true;
42006c3fb27SDimitry Andric     }
421bdd1243dSDimitry Andric     const offset_t op_arg_size =
422bdd1243dSDimitry Andric         GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
4230b57cec5SDimitry Andric     if (op_arg_size == LLDB_INVALID_OFFSET)
4240b57cec5SDimitry Andric       break;
4250b57cec5SDimitry Andric     offset += op_arg_size;
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   return false;
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
430bdd1243dSDimitry Andric bool DWARFExpression::ContainsThreadLocalStorage(
431bdd1243dSDimitry Andric     const DWARFUnit *dwarf_cu) const {
4320b57cec5SDimitry Andric   lldb::offset_t offset = 0;
4330b57cec5SDimitry Andric   while (m_data.ValidOffset(offset)) {
4340b57cec5SDimitry Andric     const uint8_t op = m_data.GetU8(&offset);
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric     if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
4370b57cec5SDimitry Andric       return true;
438bdd1243dSDimitry Andric     const offset_t op_arg_size =
439bdd1243dSDimitry Andric         GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
4400b57cec5SDimitry Andric     if (op_arg_size == LLDB_INVALID_OFFSET)
4410b57cec5SDimitry Andric       return false;
4420b57cec5SDimitry Andric     offset += op_arg_size;
4430b57cec5SDimitry Andric   }
4440b57cec5SDimitry Andric   return false;
4450b57cec5SDimitry Andric }
4460b57cec5SDimitry Andric bool DWARFExpression::LinkThreadLocalStorage(
447bdd1243dSDimitry Andric     const DWARFUnit *dwarf_cu,
4480b57cec5SDimitry Andric     std::function<lldb::addr_t(lldb::addr_t file_addr)> const
4490b57cec5SDimitry Andric         &link_address_callback) {
4500b57cec5SDimitry Andric   const uint32_t addr_byte_size = m_data.GetAddressByteSize();
4510b57cec5SDimitry Andric   // We have to make a copy of the data as we don't know if this data is from a
4520b57cec5SDimitry Andric   // read only memory mapped buffer, so we duplicate all of the data first,
4530b57cec5SDimitry Andric   // then modify it, and if all goes well, we then replace the data for this
4540eae32dcSDimitry Andric   // expression.
4550eae32dcSDimitry Andric   // Make en encoder that contains a copy of the location expression data so we
4560eae32dcSDimitry Andric   // can write the address into the buffer using the correct byte order.
4570eae32dcSDimitry Andric   DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
4580b57cec5SDimitry Andric                       m_data.GetByteOrder(), addr_byte_size);
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   lldb::offset_t offset = 0;
4610b57cec5SDimitry Andric   lldb::offset_t const_offset = 0;
4620b57cec5SDimitry Andric   lldb::addr_t const_value = 0;
4630b57cec5SDimitry Andric   size_t const_byte_size = 0;
4640b57cec5SDimitry Andric   while (m_data.ValidOffset(offset)) {
4650b57cec5SDimitry Andric     const uint8_t op = m_data.GetU8(&offset);
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric     bool decoded_data = false;
4680b57cec5SDimitry Andric     switch (op) {
4690b57cec5SDimitry Andric     case DW_OP_const4u:
4700b57cec5SDimitry Andric       // Remember the const offset in case we later have a
4710b57cec5SDimitry Andric       // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
4720b57cec5SDimitry Andric       const_offset = offset;
4730b57cec5SDimitry Andric       const_value = m_data.GetU32(&offset);
4740b57cec5SDimitry Andric       decoded_data = true;
4750b57cec5SDimitry Andric       const_byte_size = 4;
4760b57cec5SDimitry Andric       break;
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric     case DW_OP_const8u:
4790b57cec5SDimitry Andric       // Remember the const offset in case we later have a
4800b57cec5SDimitry Andric       // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
4810b57cec5SDimitry Andric       const_offset = offset;
4820b57cec5SDimitry Andric       const_value = m_data.GetU64(&offset);
4830b57cec5SDimitry Andric       decoded_data = true;
4840b57cec5SDimitry Andric       const_byte_size = 8;
4850b57cec5SDimitry Andric       break;
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric     case DW_OP_form_tls_address:
4880b57cec5SDimitry Andric     case DW_OP_GNU_push_tls_address:
4890b57cec5SDimitry Andric       // DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded
4900b57cec5SDimitry Andric       // by a file address on the stack. We assume that DW_OP_const4u or
4910b57cec5SDimitry Andric       // DW_OP_const8u is used for these values, and we check that the last
4920b57cec5SDimitry Andric       // opcode we got before either of these was DW_OP_const4u or
493bdd1243dSDimitry Andric       // DW_OP_const8u. If so, then we can link the value accordingly. For
4940b57cec5SDimitry Andric       // Darwin, the value in the DW_OP_const4u or DW_OP_const8u is the file
4950b57cec5SDimitry Andric       // address of a structure that contains a function pointer, the pthread
4960b57cec5SDimitry Andric       // key and the offset into the data pointed to by the pthread key. So we
4970b57cec5SDimitry Andric       // must link this address and also set the module of this expression to
4980b57cec5SDimitry Andric       // the new_module_sp so we can resolve the file address correctly
4990b57cec5SDimitry Andric       if (const_byte_size > 0) {
5000b57cec5SDimitry Andric         lldb::addr_t linked_file_addr = link_address_callback(const_value);
5010b57cec5SDimitry Andric         if (linked_file_addr == LLDB_INVALID_ADDRESS)
5020b57cec5SDimitry Andric           return false;
5030b57cec5SDimitry Andric         // Replace the address in the new buffer
504480093f4SDimitry Andric         if (encoder.PutUnsigned(const_offset, const_byte_size,
5050b57cec5SDimitry Andric                                 linked_file_addr) == UINT32_MAX)
5060b57cec5SDimitry Andric           return false;
5070b57cec5SDimitry Andric       }
5080b57cec5SDimitry Andric       break;
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric     default:
5110b57cec5SDimitry Andric       const_offset = 0;
5120b57cec5SDimitry Andric       const_value = 0;
5130b57cec5SDimitry Andric       const_byte_size = 0;
5140b57cec5SDimitry Andric       break;
5150b57cec5SDimitry Andric     }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric     if (!decoded_data) {
518bdd1243dSDimitry Andric       const offset_t op_arg_size =
519bdd1243dSDimitry Andric           GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
5200b57cec5SDimitry Andric       if (op_arg_size == LLDB_INVALID_OFFSET)
5210b57cec5SDimitry Andric         return false;
5220b57cec5SDimitry Andric       else
5230b57cec5SDimitry Andric         offset += op_arg_size;
5240b57cec5SDimitry Andric     }
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
5270eae32dcSDimitry Andric   m_data.SetData(encoder.GetDataBuffer());
5280b57cec5SDimitry Andric   return true;
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric 
531*0fca6ea1SDimitry Andric static llvm::Error Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
5329dba64beSDimitry Andric                                               ExecutionContext *exe_ctx,
5339dba64beSDimitry Andric                                               RegisterContext *reg_ctx,
5349dba64beSDimitry Andric                                               const DataExtractor &opcodes,
5359dba64beSDimitry Andric                                               lldb::offset_t &opcode_offset,
536*0fca6ea1SDimitry Andric                                               Log *log) {
5379dba64beSDimitry Andric   // DW_OP_entry_value(sub-expr) describes the location a variable had upon
5389dba64beSDimitry Andric   // function entry: this variable location is presumed to be optimized out at
5399dba64beSDimitry Andric   // the current PC value.  The caller of the function may have call site
5409dba64beSDimitry Andric   // information that describes an alternate location for the variable (e.g. a
5419dba64beSDimitry Andric   // constant literal, or a spilled stack value) in the parent frame.
5429dba64beSDimitry Andric   //
5439dba64beSDimitry Andric   // Example (this is pseudo-code & pseudo-DWARF, but hopefully illustrative):
5449dba64beSDimitry Andric   //
5459dba64beSDimitry Andric   //     void child(int &sink, int x) {
5469dba64beSDimitry Andric   //       ...
5479dba64beSDimitry Andric   //       /* "x" gets optimized out. */
5489dba64beSDimitry Andric   //
5499dba64beSDimitry Andric   //       /* The location of "x" here is: DW_OP_entry_value($reg2). */
5509dba64beSDimitry Andric   //       ++sink;
5519dba64beSDimitry Andric   //     }
5529dba64beSDimitry Andric   //
5539dba64beSDimitry Andric   //     void parent() {
5549dba64beSDimitry Andric   //       int sink;
5559dba64beSDimitry Andric   //
5569dba64beSDimitry Andric   //       /*
5579dba64beSDimitry Andric   //        * The callsite information emitted here is:
5589dba64beSDimitry Andric   //        *
5599dba64beSDimitry Andric   //        * DW_TAG_call_site
5609dba64beSDimitry Andric   //        *   DW_AT_return_pc ... (for "child(sink, 123);")
5619dba64beSDimitry Andric   //        *   DW_TAG_call_site_parameter (for "sink")
5629dba64beSDimitry Andric   //        *     DW_AT_location   ($reg1)
5639dba64beSDimitry Andric   //        *     DW_AT_call_value ($SP - 8)
5649dba64beSDimitry Andric   //        *   DW_TAG_call_site_parameter (for "x")
5659dba64beSDimitry Andric   //        *     DW_AT_location   ($reg2)
5669dba64beSDimitry Andric   //        *     DW_AT_call_value ($literal 123)
5679dba64beSDimitry Andric   //        *
5689dba64beSDimitry Andric   //        * DW_TAG_call_site
5699dba64beSDimitry Andric   //        *   DW_AT_return_pc ... (for "child(sink, 456);")
5709dba64beSDimitry Andric   //        *   ...
5719dba64beSDimitry Andric   //        */
5729dba64beSDimitry Andric   //       child(sink, 123);
5739dba64beSDimitry Andric   //       child(sink, 456);
5749dba64beSDimitry Andric   //     }
5759dba64beSDimitry Andric   //
5769dba64beSDimitry Andric   // When the program stops at "++sink" within `child`, the debugger determines
5779dba64beSDimitry Andric   // the call site by analyzing the return address. Once the call site is found,
5789dba64beSDimitry Andric   // the debugger determines which parameter is referenced by DW_OP_entry_value
5799dba64beSDimitry Andric   // and evaluates the corresponding location for that parameter in `parent`.
5809dba64beSDimitry Andric 
5819dba64beSDimitry Andric   // 1. Find the function which pushed the current frame onto the stack.
5829dba64beSDimitry Andric   if ((!exe_ctx || !exe_ctx->HasTargetScope()) || !reg_ctx) {
583*0fca6ea1SDimitry Andric     return llvm::createStringError("no exe/reg context");
5849dba64beSDimitry Andric   }
5859dba64beSDimitry Andric 
5869dba64beSDimitry Andric   StackFrame *current_frame = exe_ctx->GetFramePtr();
5879dba64beSDimitry Andric   Thread *thread = exe_ctx->GetThreadPtr();
588*0fca6ea1SDimitry Andric   if (!current_frame || !thread)
589*0fca6ea1SDimitry Andric     return llvm::createStringError("no current frame/thread");
5909dba64beSDimitry Andric 
5919dba64beSDimitry Andric   Target &target = exe_ctx->GetTargetRef();
5929dba64beSDimitry Andric   StackFrameSP parent_frame = nullptr;
5939dba64beSDimitry Andric   addr_t return_pc = LLDB_INVALID_ADDRESS;
5949dba64beSDimitry Andric   uint32_t current_frame_idx = current_frame->GetFrameIndex();
595*0fca6ea1SDimitry Andric 
596*0fca6ea1SDimitry Andric   for (uint32_t parent_frame_idx = current_frame_idx + 1;;parent_frame_idx++) {
5979dba64beSDimitry Andric     parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);
598*0fca6ea1SDimitry Andric     // If this is null, we're at the end of the stack.
5999dba64beSDimitry Andric     if (!parent_frame)
6009dba64beSDimitry Andric       break;
6019dba64beSDimitry Andric 
6029dba64beSDimitry Andric     // Record the first valid return address, even if this is an inlined frame,
6039dba64beSDimitry Andric     // in order to look up the associated call edge in the first non-inlined
6049dba64beSDimitry Andric     // parent frame.
6059dba64beSDimitry Andric     if (return_pc == LLDB_INVALID_ADDRESS) {
6069dba64beSDimitry Andric       return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
607*0fca6ea1SDimitry Andric       LLDB_LOG(log, "immediate ancestor with pc = {0:x}", return_pc);
6089dba64beSDimitry Andric     }
6099dba64beSDimitry Andric 
6109dba64beSDimitry Andric     // If we've found an inlined frame, skip it (these have no call site
6119dba64beSDimitry Andric     // parameters).
6129dba64beSDimitry Andric     if (parent_frame->IsInlined())
6139dba64beSDimitry Andric       continue;
6149dba64beSDimitry Andric 
6159dba64beSDimitry Andric     // We've found the first non-inlined parent frame.
6169dba64beSDimitry Andric     break;
6179dba64beSDimitry Andric   }
6189dba64beSDimitry Andric   if (!parent_frame || !parent_frame->GetRegisterContext()) {
619*0fca6ea1SDimitry Andric     return llvm::createStringError("no parent frame with reg ctx");
6209dba64beSDimitry Andric   }
6219dba64beSDimitry Andric 
6229dba64beSDimitry Andric   Function *parent_func =
6239dba64beSDimitry Andric       parent_frame->GetSymbolContext(eSymbolContextFunction).function;
624*0fca6ea1SDimitry Andric   if (!parent_func)
625*0fca6ea1SDimitry Andric     return llvm::createStringError("no parent function");
6269dba64beSDimitry Andric 
6279dba64beSDimitry Andric   // 2. Find the call edge in the parent function responsible for creating the
6289dba64beSDimitry Andric   //    current activation.
6299dba64beSDimitry Andric   Function *current_func =
6309dba64beSDimitry Andric       current_frame->GetSymbolContext(eSymbolContextFunction).function;
631*0fca6ea1SDimitry Andric   if (!current_func)
632*0fca6ea1SDimitry Andric     return llvm::createStringError("no current function");
6339dba64beSDimitry Andric 
6349dba64beSDimitry Andric   CallEdge *call_edge = nullptr;
6359dba64beSDimitry Andric   ModuleList &modlist = target.GetImages();
636480093f4SDimitry Andric   ExecutionContext parent_exe_ctx = *exe_ctx;
637480093f4SDimitry Andric   parent_exe_ctx.SetFrameSP(parent_frame);
6389dba64beSDimitry Andric   if (!parent_frame->IsArtificial()) {
6399dba64beSDimitry Andric     // If the parent frame is not artificial, the current activation may be
6409dba64beSDimitry Andric     // produced by an ambiguous tail call. In this case, refuse to proceed.
6419dba64beSDimitry Andric     call_edge = parent_func->GetCallEdgeForReturnAddress(return_pc, target);
6429dba64beSDimitry Andric     if (!call_edge) {
643*0fca6ea1SDimitry Andric       return llvm::createStringError(
644*0fca6ea1SDimitry Andric           llvm::formatv("no call edge for retn-pc = {0:x} in parent frame {1}",
645*0fca6ea1SDimitry Andric                         return_pc, parent_func->GetName()));
6469dba64beSDimitry Andric     }
647480093f4SDimitry Andric     Function *callee_func = call_edge->GetCallee(modlist, parent_exe_ctx);
6489dba64beSDimitry Andric     if (callee_func != current_func) {
649*0fca6ea1SDimitry Andric       return llvm::createStringError(
650*0fca6ea1SDimitry Andric           "ambiguous call sequence, can't find real parent frame");
6519dba64beSDimitry Andric     }
6529dba64beSDimitry Andric   } else {
6539dba64beSDimitry Andric     // The StackFrameList solver machinery has deduced that an unambiguous tail
6549dba64beSDimitry Andric     // call sequence that produced the current activation.  The first edge in
6559dba64beSDimitry Andric     // the parent that points to the current function must be valid.
656480093f4SDimitry Andric     for (auto &edge : parent_func->GetTailCallingEdges()) {
657480093f4SDimitry Andric       if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) {
658480093f4SDimitry Andric         call_edge = edge.get();
6599dba64beSDimitry Andric         break;
6609dba64beSDimitry Andric       }
6619dba64beSDimitry Andric     }
6629dba64beSDimitry Andric   }
663*0fca6ea1SDimitry Andric   if (!call_edge)
664*0fca6ea1SDimitry Andric     return llvm::createStringError("no unambiguous edge from parent "
6659dba64beSDimitry Andric                                    "to current function");
6669dba64beSDimitry Andric 
6679dba64beSDimitry Andric   // 3. Attempt to locate the DW_OP_entry_value expression in the set of
6689dba64beSDimitry Andric   //    available call site parameters. If found, evaluate the corresponding
6699dba64beSDimitry Andric   //    parameter in the context of the parent frame.
6709dba64beSDimitry Andric   const uint32_t subexpr_len = opcodes.GetULEB128(&opcode_offset);
6719dba64beSDimitry Andric   const void *subexpr_data = opcodes.GetData(&opcode_offset, subexpr_len);
672*0fca6ea1SDimitry Andric   if (!subexpr_data)
673*0fca6ea1SDimitry Andric     return llvm::createStringError("subexpr could not be read");
6749dba64beSDimitry Andric 
6759dba64beSDimitry Andric   const CallSiteParameter *matched_param = nullptr;
6769dba64beSDimitry Andric   for (const CallSiteParameter &param : call_edge->GetCallSiteParameters()) {
6779dba64beSDimitry Andric     DataExtractor param_subexpr_extractor;
6789dba64beSDimitry Andric     if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))
6799dba64beSDimitry Andric       continue;
6809dba64beSDimitry Andric     lldb::offset_t param_subexpr_offset = 0;
6819dba64beSDimitry Andric     const void *param_subexpr_data =
6829dba64beSDimitry Andric         param_subexpr_extractor.GetData(&param_subexpr_offset, subexpr_len);
6839dba64beSDimitry Andric     if (!param_subexpr_data ||
6849dba64beSDimitry Andric         param_subexpr_extractor.BytesLeft(param_subexpr_offset) != 0)
6859dba64beSDimitry Andric       continue;
6869dba64beSDimitry Andric 
6879dba64beSDimitry Andric     // At this point, the DW_OP_entry_value sub-expression and the callee-side
6889dba64beSDimitry Andric     // expression in the call site parameter are known to have the same length.
6899dba64beSDimitry Andric     // Check whether they are equal.
6909dba64beSDimitry Andric     //
6919dba64beSDimitry Andric     // Note that an equality check is sufficient: the contents of the
6929dba64beSDimitry Andric     // DW_OP_entry_value subexpression are only used to identify the right call
6939dba64beSDimitry Andric     // site parameter in the parent, and do not require any special handling.
6949dba64beSDimitry Andric     if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {
6959dba64beSDimitry Andric       matched_param = &param;
6969dba64beSDimitry Andric       break;
6979dba64beSDimitry Andric     }
6989dba64beSDimitry Andric   }
699*0fca6ea1SDimitry Andric   if (!matched_param)
700*0fca6ea1SDimitry Andric     return llvm::createStringError("no matching call site param found");
7019dba64beSDimitry Andric 
7029dba64beSDimitry Andric   // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
7039dba64beSDimitry Andric   // subexpresion whenever llvm does.
704753f127fSDimitry Andric   const DWARFExpressionList &param_expr = matched_param->LocationInCaller;
705*0fca6ea1SDimitry Andric 
706*0fca6ea1SDimitry Andric   llvm::Expected<Value> maybe_result = param_expr.Evaluate(
707*0fca6ea1SDimitry Andric       &parent_exe_ctx, parent_frame->GetRegisterContext().get(),
708753f127fSDimitry Andric       LLDB_INVALID_ADDRESS,
7099dba64beSDimitry Andric       /*initial_value_ptr=*/nullptr,
710*0fca6ea1SDimitry Andric       /*object_address_ptr=*/nullptr);
711*0fca6ea1SDimitry Andric   if (!maybe_result) {
7129dba64beSDimitry Andric     LLDB_LOG(log,
7139dba64beSDimitry Andric              "Evaluate_DW_OP_entry_value: call site param evaluation failed");
714*0fca6ea1SDimitry Andric     return maybe_result.takeError();
7159dba64beSDimitry Andric   }
7169dba64beSDimitry Andric 
717*0fca6ea1SDimitry Andric   stack.push_back(*maybe_result);
718*0fca6ea1SDimitry Andric   return llvm::Error::success();
7199dba64beSDimitry Andric }
7209dba64beSDimitry Andric 
721fe6060f1SDimitry Andric namespace {
722fe6060f1SDimitry Andric /// The location description kinds described by the DWARF v5
723fe6060f1SDimitry Andric /// specification.  Composite locations are handled out-of-band and
724fe6060f1SDimitry Andric /// thus aren't part of the enum.
725fe6060f1SDimitry Andric enum LocationDescriptionKind {
726fe6060f1SDimitry Andric   Empty,
727fe6060f1SDimitry Andric   Memory,
728fe6060f1SDimitry Andric   Register,
729fe6060f1SDimitry Andric   Implicit
730fe6060f1SDimitry Andric   /* Composite*/
731fe6060f1SDimitry Andric };
732fe6060f1SDimitry Andric /// Adjust value's ValueType according to the kind of location description.
733fe6060f1SDimitry Andric void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,
734fe6060f1SDimitry Andric                                             LocationDescriptionKind kind,
735fe6060f1SDimitry Andric                                             Value *value = nullptr) {
736fe6060f1SDimitry Andric   // Note that this function is conflating DWARF expressions with
737fe6060f1SDimitry Andric   // DWARF location descriptions. Perhaps it would be better to define
738bdd1243dSDimitry Andric   // a wrapper for DWARFExpression::Eval() that deals with DWARF
739fe6060f1SDimitry Andric   // location descriptions (which consist of one or more DWARF
740fe6060f1SDimitry Andric   // expressions). But doing this would mean we'd also need factor the
741fe6060f1SDimitry Andric   // handling of DW_OP_(bit_)piece out of this function.
742fe6060f1SDimitry Andric   if (dwarf_cu && dwarf_cu->GetVersion() >= 4) {
743fe6060f1SDimitry Andric     const char *log_msg = "DWARF location description kind: %s";
744fe6060f1SDimitry Andric     switch (kind) {
745fe6060f1SDimitry Andric     case Empty:
746fe6060f1SDimitry Andric       LLDB_LOGF(log, log_msg, "Empty");
747fe6060f1SDimitry Andric       break;
748fe6060f1SDimitry Andric     case Memory:
749fe6060f1SDimitry Andric       LLDB_LOGF(log, log_msg, "Memory");
750fe6060f1SDimitry Andric       if (value->GetValueType() == Value::ValueType::Scalar)
751fe6060f1SDimitry Andric         value->SetValueType(Value::ValueType::LoadAddress);
752fe6060f1SDimitry Andric       break;
753fe6060f1SDimitry Andric     case Register:
754fe6060f1SDimitry Andric       LLDB_LOGF(log, log_msg, "Register");
755fe6060f1SDimitry Andric       value->SetValueType(Value::ValueType::Scalar);
756fe6060f1SDimitry Andric       break;
757fe6060f1SDimitry Andric     case Implicit:
758fe6060f1SDimitry Andric       LLDB_LOGF(log, log_msg, "Implicit");
759fe6060f1SDimitry Andric       if (value->GetValueType() == Value::ValueType::LoadAddress)
760fe6060f1SDimitry Andric         value->SetValueType(Value::ValueType::Scalar);
761fe6060f1SDimitry Andric       break;
762fe6060f1SDimitry Andric     }
763fe6060f1SDimitry Andric   }
764fe6060f1SDimitry Andric }
765fe6060f1SDimitry Andric } // namespace
766fe6060f1SDimitry Andric 
76781ad6265SDimitry Andric /// Helper function to move common code used to resolve a file address and turn
76881ad6265SDimitry Andric /// into a load address.
76981ad6265SDimitry Andric ///
77081ad6265SDimitry Andric /// \param exe_ctx Pointer to the execution context
77181ad6265SDimitry Andric /// \param module_sp shared_ptr contains the module if we have one
77281ad6265SDimitry Andric /// \param dw_op_type C-style string used to vary the error output
77381ad6265SDimitry Andric /// \param file_addr the file address we are trying to resolve and turn into a
77481ad6265SDimitry Andric ///                  load address
775bdd1243dSDimitry Andric /// \param so_addr out parameter, will be set to load address or section offset
77681ad6265SDimitry Andric /// \param check_sectionoffset bool which determines if having a section offset
77781ad6265SDimitry Andric ///                            but not a load address is considerd a success
778bdd1243dSDimitry Andric /// \returns std::optional containing the load address if resolving and getting
77981ad6265SDimitry Andric ///          the load address succeed or an empty Optinal otherwise. If
78081ad6265SDimitry Andric ///          check_sectionoffset is true we consider LLDB_INVALID_ADDRESS a
78181ad6265SDimitry Andric ///          success if so_addr.IsSectionOffset() is true.
782*0fca6ea1SDimitry Andric static llvm::Expected<lldb::addr_t>
78381ad6265SDimitry Andric ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp,
784*0fca6ea1SDimitry Andric                    const char *dw_op_type, lldb::addr_t file_addr,
785*0fca6ea1SDimitry Andric                    Address &so_addr, bool check_sectionoffset = false) {
786*0fca6ea1SDimitry Andric   if (!module_sp)
787*0fca6ea1SDimitry Andric     return llvm::createStringError("need module to resolve file address for %s",
788*0fca6ea1SDimitry Andric                                    dw_op_type);
78981ad6265SDimitry Andric 
790*0fca6ea1SDimitry Andric   if (!module_sp->ResolveFileAddress(file_addr, so_addr))
791*0fca6ea1SDimitry Andric     return llvm::createStringError("failed to resolve file address in module");
79281ad6265SDimitry Andric 
793*0fca6ea1SDimitry Andric   const addr_t load_addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
79481ad6265SDimitry Andric 
79581ad6265SDimitry Andric   if (load_addr == LLDB_INVALID_ADDRESS &&
796*0fca6ea1SDimitry Andric       (check_sectionoffset && !so_addr.IsSectionOffset()))
797*0fca6ea1SDimitry Andric     return llvm::createStringError("failed to resolve load address");
79881ad6265SDimitry Andric 
79981ad6265SDimitry Andric   return load_addr;
80081ad6265SDimitry Andric }
80181ad6265SDimitry Andric 
80281ad6265SDimitry Andric /// Helper function to move common code used to load sized data from a uint8_t
80381ad6265SDimitry Andric /// buffer.
80481ad6265SDimitry Andric ///
80581ad6265SDimitry Andric /// \param addr_bytes uint8_t buffer containg raw data
80681ad6265SDimitry Andric /// \param size_addr_bytes how large is the underlying raw data
80781ad6265SDimitry Andric /// \param byte_order what is the byter order of the underlyig data
80881ad6265SDimitry Andric /// \param size How much of the underlying data we want to use
80981ad6265SDimitry Andric /// \return The underlying data converted into a Scalar
81081ad6265SDimitry Andric static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
81181ad6265SDimitry Andric                                          size_t size_addr_bytes,
81281ad6265SDimitry Andric                                          ByteOrder byte_order, size_t size) {
81381ad6265SDimitry Andric   DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size);
81481ad6265SDimitry Andric 
81581ad6265SDimitry Andric   lldb::offset_t addr_data_offset = 0;
81681ad6265SDimitry Andric   if (size <= 8)
81781ad6265SDimitry Andric     return addr_data.GetMaxU64(&addr_data_offset, size);
81881ad6265SDimitry Andric   else
81981ad6265SDimitry Andric     return addr_data.GetAddress(&addr_data_offset);
82081ad6265SDimitry Andric }
82181ad6265SDimitry Andric 
822*0fca6ea1SDimitry Andric llvm::Expected<Value> DWARFExpression::Evaluate(
8230b57cec5SDimitry Andric     ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
8240b57cec5SDimitry Andric     lldb::ModuleSP module_sp, const DataExtractor &opcodes,
8259dba64beSDimitry Andric     const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
826*0fca6ea1SDimitry Andric     const Value *initial_value_ptr, const Value *object_address_ptr) {
8270b57cec5SDimitry Andric 
828*0fca6ea1SDimitry Andric   if (opcodes.GetByteSize() == 0)
829*0fca6ea1SDimitry Andric     return llvm::createStringError(
8300b57cec5SDimitry Andric         "no location, value may have been optimized out");
8310b57cec5SDimitry Andric   std::vector<Value> stack;
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   Process *process = nullptr;
8340b57cec5SDimitry Andric   StackFrame *frame = nullptr;
835bdd1243dSDimitry Andric   Target *target = nullptr;
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric   if (exe_ctx) {
8380b57cec5SDimitry Andric     process = exe_ctx->GetProcessPtr();
8390b57cec5SDimitry Andric     frame = exe_ctx->GetFramePtr();
840bdd1243dSDimitry Andric     target = exe_ctx->GetTargetPtr();
8410b57cec5SDimitry Andric   }
8420b57cec5SDimitry Andric   if (reg_ctx == nullptr && frame)
8430b57cec5SDimitry Andric     reg_ctx = frame->GetRegisterContext().get();
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   if (initial_value_ptr)
8460b57cec5SDimitry Andric     stack.push_back(*initial_value_ptr);
8470b57cec5SDimitry Andric 
8489dba64beSDimitry Andric   lldb::offset_t offset = 0;
8490b57cec5SDimitry Andric   Value tmp;
8500b57cec5SDimitry Andric   uint32_t reg_num;
8510b57cec5SDimitry Andric 
8525ffd83dbSDimitry Andric   /// Insertion point for evaluating multi-piece expression.
8530b57cec5SDimitry Andric   uint64_t op_piece_offset = 0;
8540b57cec5SDimitry Andric   Value pieces; // Used for DW_OP_piece
8550b57cec5SDimitry Andric 
85681ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
857e8d8bef9SDimitry Andric   // A generic type is "an integral type that has the size of an address and an
858e8d8bef9SDimitry Andric   // unspecified signedness". For now, just use the signedness of the operand.
859e8d8bef9SDimitry Andric   // TODO: Implement a real typed stack, and store the genericness of the value
860e8d8bef9SDimitry Andric   // there.
861e8d8bef9SDimitry Andric   auto to_generic = [&](auto v) {
862e8d8bef9SDimitry Andric     bool is_signed = std::is_signed<decltype(v)>::value;
863e8d8bef9SDimitry Andric     return Scalar(llvm::APSInt(
864e8d8bef9SDimitry Andric         llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),
865e8d8bef9SDimitry Andric         !is_signed));
866e8d8bef9SDimitry Andric   };
8670b57cec5SDimitry Andric 
868fe6060f1SDimitry Andric   // The default kind is a memory location. This is updated by any
869fe6060f1SDimitry Andric   // operation that changes this, such as DW_OP_stack_value, and reset
870fe6060f1SDimitry Andric   // by composition operations like DW_OP_piece.
871fe6060f1SDimitry Andric   LocationDescriptionKind dwarf4_location_description_kind = Memory;
872fe6060f1SDimitry Andric 
8739dba64beSDimitry Andric   while (opcodes.ValidOffset(offset)) {
8740b57cec5SDimitry Andric     const lldb::offset_t op_offset = offset;
8750b57cec5SDimitry Andric     const uint8_t op = opcodes.GetU8(&offset);
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     if (log && log->GetVerbose()) {
8780b57cec5SDimitry Andric       size_t count = stack.size();
8799dba64beSDimitry Andric       LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
8800b57cec5SDimitry Andric                 (uint64_t)count);
8810b57cec5SDimitry Andric       for (size_t i = 0; i < count; ++i) {
8820b57cec5SDimitry Andric         StreamString new_value;
8830b57cec5SDimitry Andric         new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
8840b57cec5SDimitry Andric         stack[i].Dump(&new_value);
8859dba64beSDimitry Andric         LLDB_LOGF(log, "  %s", new_value.GetData());
8860b57cec5SDimitry Andric       }
8879dba64beSDimitry Andric       LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,
8889dba64beSDimitry Andric                 DW_OP_value_to_name(op));
8890b57cec5SDimitry Andric     }
8900b57cec5SDimitry Andric 
891*0fca6ea1SDimitry Andric     if (std::optional<unsigned> arity =
892*0fca6ea1SDimitry Andric             llvm::dwarf::OperationArity(static_cast<LocationAtom>(op))) {
893*0fca6ea1SDimitry Andric       if (stack.size() < *arity)
894*0fca6ea1SDimitry Andric         return llvm::createStringError(
895*0fca6ea1SDimitry Andric             "%s needs at least %d stack entries (stack has %d entries)",
896*0fca6ea1SDimitry Andric             DW_OP_value_to_name(op), *arity, stack.size());
897*0fca6ea1SDimitry Andric     }
898*0fca6ea1SDimitry Andric 
8990b57cec5SDimitry Andric     switch (op) {
9000b57cec5SDimitry Andric     // The DW_OP_addr operation has a single operand that encodes a machine
9010b57cec5SDimitry Andric     // address and whose size is the size of an address on the target machine.
9020b57cec5SDimitry Andric     case DW_OP_addr:
9030b57cec5SDimitry Andric       stack.push_back(Scalar(opcodes.GetAddress(&offset)));
904bdd1243dSDimitry Andric       if (target &&
905bdd1243dSDimitry Andric           target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
906bdd1243dSDimitry Andric         // wasm file sections aren't mapped into memory, therefore addresses can
907bdd1243dSDimitry Andric         // never point into a file section and are always LoadAddresses.
908bdd1243dSDimitry Andric         stack.back().SetValueType(Value::ValueType::LoadAddress);
909bdd1243dSDimitry Andric       } else {
910fe6060f1SDimitry Andric         stack.back().SetValueType(Value::ValueType::FileAddress);
911bdd1243dSDimitry Andric       }
9120b57cec5SDimitry Andric       break;
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric     // The DW_OP_addr_sect_offset4 is used for any location expressions in
9150b57cec5SDimitry Andric     // shared libraries that have a location like:
9160b57cec5SDimitry Andric     //  DW_OP_addr(0x1000)
9170b57cec5SDimitry Andric     // If this address resides in a shared library, then this virtual address
9180b57cec5SDimitry Andric     // won't make sense when it is evaluated in the context of a running
9190b57cec5SDimitry Andric     // process where shared libraries have been slid. To account for this, this
9200b57cec5SDimitry Andric     // new address type where we can store the section pointer and a 4 byte
9210b57cec5SDimitry Andric     // offset.
9220b57cec5SDimitry Andric     //      case DW_OP_addr_sect_offset4:
9230b57cec5SDimitry Andric     //          {
9240b57cec5SDimitry Andric     //              result_type = eResultTypeFileAddress;
9250b57cec5SDimitry Andric     //              lldb::Section *sect = (lldb::Section
9260b57cec5SDimitry Andric     //              *)opcodes.GetMaxU64(&offset, sizeof(void *));
9270b57cec5SDimitry Andric     //              lldb::addr_t sect_offset = opcodes.GetU32(&offset);
9280b57cec5SDimitry Andric     //
9290b57cec5SDimitry Andric     //              Address so_addr (sect, sect_offset);
9300b57cec5SDimitry Andric     //              lldb::addr_t load_addr = so_addr.GetLoadAddress();
9310b57cec5SDimitry Andric     //              if (load_addr != LLDB_INVALID_ADDRESS)
9320b57cec5SDimitry Andric     //              {
9330b57cec5SDimitry Andric     //                  // We successfully resolve a file address to a load
9340b57cec5SDimitry Andric     //                  // address.
9350b57cec5SDimitry Andric     //                  stack.push_back(load_addr);
9360b57cec5SDimitry Andric     //                  break;
9370b57cec5SDimitry Andric     //              }
9380b57cec5SDimitry Andric     //              else
9390b57cec5SDimitry Andric     //              {
9400b57cec5SDimitry Andric     //                  // We were able
9410b57cec5SDimitry Andric     //                  if (error_ptr)
9420b57cec5SDimitry Andric     //                      error_ptr->SetErrorStringWithFormat ("Section %s in
9430b57cec5SDimitry Andric     //                      %s is not currently loaded.\n",
9440b57cec5SDimitry Andric     //                      sect->GetName().AsCString(),
9450b57cec5SDimitry Andric     //                      sect->GetModule()->GetFileSpec().GetFilename().AsCString());
9460b57cec5SDimitry Andric     //                  return false;
9470b57cec5SDimitry Andric     //              }
9480b57cec5SDimitry Andric     //          }
9490b57cec5SDimitry Andric     //          break;
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric     // OPCODE: DW_OP_deref
9520b57cec5SDimitry Andric     // OPERANDS: none
9530b57cec5SDimitry Andric     // DESCRIPTION: Pops the top stack entry and treats it as an address.
9540b57cec5SDimitry Andric     // The value retrieved from that address is pushed. The size of the data
9550b57cec5SDimitry Andric     // retrieved from the dereferenced address is the size of an address on the
9560b57cec5SDimitry Andric     // target machine.
9570b57cec5SDimitry Andric     case DW_OP_deref: {
958*0fca6ea1SDimitry Andric       if (stack.empty())
959*0fca6ea1SDimitry Andric         return llvm::createStringError(
960*0fca6ea1SDimitry Andric             "expression stack empty for DW_OP_deref");
9610b57cec5SDimitry Andric       Value::ValueType value_type = stack.back().GetValueType();
9620b57cec5SDimitry Andric       switch (value_type) {
963fe6060f1SDimitry Andric       case Value::ValueType::HostAddress: {
9640b57cec5SDimitry Andric         void *src = (void *)stack.back().GetScalar().ULongLong();
9650b57cec5SDimitry Andric         intptr_t ptr;
9660b57cec5SDimitry Andric         ::memcpy(&ptr, src, sizeof(void *));
9670b57cec5SDimitry Andric         stack.back().GetScalar() = ptr;
9680b57cec5SDimitry Andric         stack.back().ClearContext();
9690b57cec5SDimitry Andric       } break;
970fe6060f1SDimitry Andric       case Value::ValueType::FileAddress: {
9710b57cec5SDimitry Andric         auto file_addr = stack.back().GetScalar().ULongLong(
9720b57cec5SDimitry Andric             LLDB_INVALID_ADDRESS);
97381ad6265SDimitry Andric 
9740b57cec5SDimitry Andric         Address so_addr;
97581ad6265SDimitry Andric         auto maybe_load_addr = ResolveLoadAddress(
976*0fca6ea1SDimitry Andric             exe_ctx, module_sp, "DW_OP_deref", file_addr, so_addr);
97781ad6265SDimitry Andric 
97881ad6265SDimitry Andric         if (!maybe_load_addr)
979*0fca6ea1SDimitry Andric           return maybe_load_addr.takeError();
98081ad6265SDimitry Andric 
98181ad6265SDimitry Andric         stack.back().GetScalar() = *maybe_load_addr;
982fe6060f1SDimitry Andric         // Fall through to load address promotion code below.
983bdd1243dSDimitry Andric       }
984bdd1243dSDimitry Andric         [[fallthrough]];
985fe6060f1SDimitry Andric       case Value::ValueType::Scalar:
986fe6060f1SDimitry Andric         // Promote Scalar to LoadAddress and fall through.
987fe6060f1SDimitry Andric         stack.back().SetValueType(Value::ValueType::LoadAddress);
988bdd1243dSDimitry Andric         [[fallthrough]];
989fe6060f1SDimitry Andric       case Value::ValueType::LoadAddress:
9900b57cec5SDimitry Andric         if (exe_ctx) {
9910b57cec5SDimitry Andric           if (process) {
9920b57cec5SDimitry Andric             lldb::addr_t pointer_addr =
9930b57cec5SDimitry Andric                 stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
9940b57cec5SDimitry Andric             Status error;
9950b57cec5SDimitry Andric             lldb::addr_t pointer_value =
9960b57cec5SDimitry Andric                 process->ReadPointerFromMemory(pointer_addr, error);
9970b57cec5SDimitry Andric             if (pointer_value != LLDB_INVALID_ADDRESS) {
998fe6060f1SDimitry Andric               if (ABISP abi_sp = process->GetABI())
999fe6060f1SDimitry Andric                 pointer_value = abi_sp->FixCodeAddress(pointer_value);
10000b57cec5SDimitry Andric               stack.back().GetScalar() = pointer_value;
10010b57cec5SDimitry Andric               stack.back().ClearContext();
10020b57cec5SDimitry Andric             } else {
1003*0fca6ea1SDimitry Andric               return llvm::createStringError(
10040b57cec5SDimitry Andric                   "Failed to dereference pointer from 0x%" PRIx64
10050b57cec5SDimitry Andric                   " for DW_OP_deref: %s\n",
10060b57cec5SDimitry Andric                   pointer_addr, error.AsCString());
10070b57cec5SDimitry Andric             }
10080b57cec5SDimitry Andric           } else {
1009*0fca6ea1SDimitry Andric             return llvm::createStringError("NULL process for DW_OP_deref");
10100b57cec5SDimitry Andric           }
10110b57cec5SDimitry Andric         } else {
1012*0fca6ea1SDimitry Andric           return llvm::createStringError(
1013*0fca6ea1SDimitry Andric               "NULL execution context for DW_OP_deref");
10140b57cec5SDimitry Andric         }
10150b57cec5SDimitry Andric         break;
10160b57cec5SDimitry Andric 
1017fe6060f1SDimitry Andric       case Value::ValueType::Invalid:
1018*0fca6ea1SDimitry Andric         return llvm::createStringError("invalid value type for DW_OP_deref");
10190b57cec5SDimitry Andric       }
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric     } break;
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric     // OPCODE: DW_OP_deref_size
10240b57cec5SDimitry Andric     // OPERANDS: 1
10250b57cec5SDimitry Andric     //  1 - uint8_t that specifies the size of the data to dereference.
10260b57cec5SDimitry Andric     // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
10270b57cec5SDimitry Andric     // stack entry and treats it as an address. The value retrieved from that
10280b57cec5SDimitry Andric     // address is pushed. In the DW_OP_deref_size operation, however, the size
10290b57cec5SDimitry Andric     // in bytes of the data retrieved from the dereferenced address is
10300b57cec5SDimitry Andric     // specified by the single operand. This operand is a 1-byte unsigned
10310b57cec5SDimitry Andric     // integral constant whose value may not be larger than the size of an
10320b57cec5SDimitry Andric     // address on the target machine. The data retrieved is zero extended to
10330b57cec5SDimitry Andric     // the size of an address on the target machine before being pushed on the
10340b57cec5SDimitry Andric     // expression stack.
10350b57cec5SDimitry Andric     case DW_OP_deref_size: {
10360b57cec5SDimitry Andric       if (stack.empty()) {
1037*0fca6ea1SDimitry Andric         return llvm::createStringError(
1038*0fca6ea1SDimitry Andric             "expression stack empty for DW_OP_deref_size");
10390b57cec5SDimitry Andric       }
10400b57cec5SDimitry Andric       uint8_t size = opcodes.GetU8(&offset);
104106c3fb27SDimitry Andric       if (size > 8) {
1042*0fca6ea1SDimitry Andric         return llvm::createStringError(
1043*0fca6ea1SDimitry Andric             "Invalid address size for DW_OP_deref_size: %d\n", size);
104406c3fb27SDimitry Andric       }
10450b57cec5SDimitry Andric       Value::ValueType value_type = stack.back().GetValueType();
10460b57cec5SDimitry Andric       switch (value_type) {
1047fe6060f1SDimitry Andric       case Value::ValueType::HostAddress: {
10480b57cec5SDimitry Andric         void *src = (void *)stack.back().GetScalar().ULongLong();
10490b57cec5SDimitry Andric         intptr_t ptr;
10500b57cec5SDimitry Andric         ::memcpy(&ptr, src, sizeof(void *));
10510b57cec5SDimitry Andric         // I can't decide whether the size operand should apply to the bytes in
10520b57cec5SDimitry Andric         // their
10530b57cec5SDimitry Andric         // lldb-host endianness or the target endianness.. I doubt this'll ever
10540b57cec5SDimitry Andric         // come up but I'll opt for assuming big endian regardless.
10550b57cec5SDimitry Andric         switch (size) {
10560b57cec5SDimitry Andric         case 1:
10570b57cec5SDimitry Andric           ptr = ptr & 0xff;
10580b57cec5SDimitry Andric           break;
10590b57cec5SDimitry Andric         case 2:
10600b57cec5SDimitry Andric           ptr = ptr & 0xffff;
10610b57cec5SDimitry Andric           break;
10620b57cec5SDimitry Andric         case 3:
10630b57cec5SDimitry Andric           ptr = ptr & 0xffffff;
10640b57cec5SDimitry Andric           break;
10650b57cec5SDimitry Andric         case 4:
10660b57cec5SDimitry Andric           ptr = ptr & 0xffffffff;
10670b57cec5SDimitry Andric           break;
10680b57cec5SDimitry Andric         // the casts are added to work around the case where intptr_t is a 32
10690b57cec5SDimitry Andric         // bit quantity;
10700b57cec5SDimitry Andric         // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
10710b57cec5SDimitry Andric         // program.
10720b57cec5SDimitry Andric         case 5:
10730b57cec5SDimitry Andric           ptr = (intptr_t)ptr & 0xffffffffffULL;
10740b57cec5SDimitry Andric           break;
10750b57cec5SDimitry Andric         case 6:
10760b57cec5SDimitry Andric           ptr = (intptr_t)ptr & 0xffffffffffffULL;
10770b57cec5SDimitry Andric           break;
10780b57cec5SDimitry Andric         case 7:
10790b57cec5SDimitry Andric           ptr = (intptr_t)ptr & 0xffffffffffffffULL;
10800b57cec5SDimitry Andric           break;
10810b57cec5SDimitry Andric         default:
10820b57cec5SDimitry Andric           break;
10830b57cec5SDimitry Andric         }
10840b57cec5SDimitry Andric         stack.back().GetScalar() = ptr;
10850b57cec5SDimitry Andric         stack.back().ClearContext();
10860b57cec5SDimitry Andric       } break;
108781ad6265SDimitry Andric       case Value::ValueType::FileAddress: {
108881ad6265SDimitry Andric         auto file_addr =
108981ad6265SDimitry Andric             stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
109081ad6265SDimitry Andric         Address so_addr;
1091*0fca6ea1SDimitry Andric         auto maybe_load_addr = ResolveLoadAddress(
1092*0fca6ea1SDimitry Andric             exe_ctx, module_sp, "DW_OP_deref_size", file_addr, so_addr,
109381ad6265SDimitry Andric             /*check_sectionoffset=*/true);
109481ad6265SDimitry Andric 
109581ad6265SDimitry Andric         if (!maybe_load_addr)
1096*0fca6ea1SDimitry Andric           return maybe_load_addr.takeError();
109781ad6265SDimitry Andric 
109881ad6265SDimitry Andric         addr_t load_addr = *maybe_load_addr;
109981ad6265SDimitry Andric 
110081ad6265SDimitry Andric         if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset()) {
110181ad6265SDimitry Andric           uint8_t addr_bytes[8];
110281ad6265SDimitry Andric           Status error;
110381ad6265SDimitry Andric 
110406c3fb27SDimitry Andric           if (target &&
110506c3fb27SDimitry Andric               target->ReadMemory(so_addr, &addr_bytes, size, error,
110681ad6265SDimitry Andric                                  /*force_live_memory=*/false) == size) {
110781ad6265SDimitry Andric             ObjectFile *objfile = module_sp->GetObjectFile();
110881ad6265SDimitry Andric 
110981ad6265SDimitry Andric             stack.back().GetScalar() = DerefSizeExtractDataHelper(
111081ad6265SDimitry Andric                 addr_bytes, size, objfile->GetByteOrder(), size);
111181ad6265SDimitry Andric             stack.back().ClearContext();
111281ad6265SDimitry Andric             break;
111381ad6265SDimitry Andric           } else {
1114*0fca6ea1SDimitry Andric             return llvm::createStringError(
111506c3fb27SDimitry Andric                 "Failed to dereference pointer for DW_OP_deref_size: "
111681ad6265SDimitry Andric                 "%s\n",
111781ad6265SDimitry Andric                 error.AsCString());
111881ad6265SDimitry Andric           }
111981ad6265SDimitry Andric         }
112081ad6265SDimitry Andric         stack.back().GetScalar() = load_addr;
112181ad6265SDimitry Andric         // Fall through to load address promotion code below.
112281ad6265SDimitry Andric       }
112381ad6265SDimitry Andric 
1124bdd1243dSDimitry Andric         [[fallthrough]];
1125fe6060f1SDimitry Andric       case Value::ValueType::Scalar:
1126fe6060f1SDimitry Andric       case Value::ValueType::LoadAddress:
11270b57cec5SDimitry Andric         if (exe_ctx) {
11280b57cec5SDimitry Andric           if (process) {
11290b57cec5SDimitry Andric             lldb::addr_t pointer_addr =
11300b57cec5SDimitry Andric                 stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
11310b57cec5SDimitry Andric             uint8_t addr_bytes[sizeof(lldb::addr_t)];
11320b57cec5SDimitry Andric             Status error;
11330b57cec5SDimitry Andric             if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==
11340b57cec5SDimitry Andric                 size) {
113581ad6265SDimitry Andric 
11360b57cec5SDimitry Andric               stack.back().GetScalar() =
113781ad6265SDimitry Andric                   DerefSizeExtractDataHelper(addr_bytes, sizeof(addr_bytes),
113881ad6265SDimitry Andric                                              process->GetByteOrder(), size);
11390b57cec5SDimitry Andric               stack.back().ClearContext();
11400b57cec5SDimitry Andric             } else {
1141*0fca6ea1SDimitry Andric               return llvm::createStringError(
11420b57cec5SDimitry Andric                   "Failed to dereference pointer from 0x%" PRIx64
11430b57cec5SDimitry Andric                   " for DW_OP_deref: %s\n",
11440b57cec5SDimitry Andric                   pointer_addr, error.AsCString());
11450b57cec5SDimitry Andric             }
11460b57cec5SDimitry Andric           } else {
1147*0fca6ea1SDimitry Andric 
1148*0fca6ea1SDimitry Andric             return llvm::createStringError("NULL process for DW_OP_deref_size");
11490b57cec5SDimitry Andric           }
11500b57cec5SDimitry Andric         } else {
1151*0fca6ea1SDimitry Andric           return llvm::createStringError(
1152*0fca6ea1SDimitry Andric               "NULL execution context for DW_OP_deref_size");
11530b57cec5SDimitry Andric         }
11540b57cec5SDimitry Andric         break;
11550b57cec5SDimitry Andric 
1156fe6060f1SDimitry Andric       case Value::ValueType::Invalid:
1157*0fca6ea1SDimitry Andric 
1158*0fca6ea1SDimitry Andric         return llvm::createStringError("invalid value for DW_OP_deref_size");
11590b57cec5SDimitry Andric       }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric     } break;
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric     // OPCODE: DW_OP_xderef_size
11640b57cec5SDimitry Andric     // OPERANDS: 1
11650b57cec5SDimitry Andric     //  1 - uint8_t that specifies the size of the data to dereference.
11660b57cec5SDimitry Andric     // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
11670b57cec5SDimitry Andric     // the top of the stack is treated as an address. The second stack entry is
11680b57cec5SDimitry Andric     // treated as an "address space identifier" for those architectures that
11690b57cec5SDimitry Andric     // support multiple address spaces. The top two stack elements are popped,
11700b57cec5SDimitry Andric     // a data item is retrieved through an implementation-defined address
11710b57cec5SDimitry Andric     // calculation and pushed as the new stack top. In the DW_OP_xderef_size
11720b57cec5SDimitry Andric     // operation, however, the size in bytes of the data retrieved from the
11730b57cec5SDimitry Andric     // dereferenced address is specified by the single operand. This operand is
11740b57cec5SDimitry Andric     // a 1-byte unsigned integral constant whose value may not be larger than
11750b57cec5SDimitry Andric     // the size of an address on the target machine. The data retrieved is zero
11760b57cec5SDimitry Andric     // extended to the size of an address on the target machine before being
11770b57cec5SDimitry Andric     // pushed on the expression stack.
11780b57cec5SDimitry Andric     case DW_OP_xderef_size:
1179*0fca6ea1SDimitry Andric       return llvm::createStringError("unimplemented opcode: DW_OP_xderef_size");
11800b57cec5SDimitry Andric     // OPCODE: DW_OP_xderef
11810b57cec5SDimitry Andric     // OPERANDS: none
11820b57cec5SDimitry Andric     // DESCRIPTION: Provides an extended dereference mechanism. The entry at
11830b57cec5SDimitry Andric     // the top of the stack is treated as an address. The second stack entry is
11840b57cec5SDimitry Andric     // treated as an "address space identifier" for those architectures that
11850b57cec5SDimitry Andric     // support multiple address spaces. The top two stack elements are popped,
11860b57cec5SDimitry Andric     // a data item is retrieved through an implementation-defined address
11870b57cec5SDimitry Andric     // calculation and pushed as the new stack top. The size of the data
11880b57cec5SDimitry Andric     // retrieved from the dereferenced address is the size of an address on the
11890b57cec5SDimitry Andric     // target machine.
11900b57cec5SDimitry Andric     case DW_OP_xderef:
1191*0fca6ea1SDimitry Andric       return llvm::createStringError("unimplemented opcode: DW_OP_xderef");
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric     // All DW_OP_constXXX opcodes have a single operand as noted below:
11940b57cec5SDimitry Andric     //
11950b57cec5SDimitry Andric     // Opcode           Operand 1
1196e8d8bef9SDimitry Andric     // DW_OP_const1u    1-byte unsigned integer constant
1197e8d8bef9SDimitry Andric     // DW_OP_const1s    1-byte signed integer constant
1198e8d8bef9SDimitry Andric     // DW_OP_const2u    2-byte unsigned integer constant
1199e8d8bef9SDimitry Andric     // DW_OP_const2s    2-byte signed integer constant
1200e8d8bef9SDimitry Andric     // DW_OP_const4u    4-byte unsigned integer constant
1201e8d8bef9SDimitry Andric     // DW_OP_const4s    4-byte signed integer constant
1202e8d8bef9SDimitry Andric     // DW_OP_const8u    8-byte unsigned integer constant
1203e8d8bef9SDimitry Andric     // DW_OP_const8s    8-byte signed integer constant
1204e8d8bef9SDimitry Andric     // DW_OP_constu     unsigned LEB128 integer constant
1205e8d8bef9SDimitry Andric     // DW_OP_consts     signed LEB128 integer constant
12060b57cec5SDimitry Andric     case DW_OP_const1u:
1207e8d8bef9SDimitry Andric       stack.push_back(to_generic(opcodes.GetU8(&offset)));
12080b57cec5SDimitry Andric       break;
12090b57cec5SDimitry Andric     case DW_OP_const1s:
1210e8d8bef9SDimitry Andric       stack.push_back(to_generic((int8_t)opcodes.GetU8(&offset)));
12110b57cec5SDimitry Andric       break;
12120b57cec5SDimitry Andric     case DW_OP_const2u:
1213e8d8bef9SDimitry Andric       stack.push_back(to_generic(opcodes.GetU16(&offset)));
12140b57cec5SDimitry Andric       break;
12150b57cec5SDimitry Andric     case DW_OP_const2s:
1216e8d8bef9SDimitry Andric       stack.push_back(to_generic((int16_t)opcodes.GetU16(&offset)));
12170b57cec5SDimitry Andric       break;
12180b57cec5SDimitry Andric     case DW_OP_const4u:
1219e8d8bef9SDimitry Andric       stack.push_back(to_generic(opcodes.GetU32(&offset)));
12200b57cec5SDimitry Andric       break;
12210b57cec5SDimitry Andric     case DW_OP_const4s:
1222e8d8bef9SDimitry Andric       stack.push_back(to_generic((int32_t)opcodes.GetU32(&offset)));
12230b57cec5SDimitry Andric       break;
12240b57cec5SDimitry Andric     case DW_OP_const8u:
1225e8d8bef9SDimitry Andric       stack.push_back(to_generic(opcodes.GetU64(&offset)));
12260b57cec5SDimitry Andric       break;
12270b57cec5SDimitry Andric     case DW_OP_const8s:
1228e8d8bef9SDimitry Andric       stack.push_back(to_generic((int64_t)opcodes.GetU64(&offset)));
12290b57cec5SDimitry Andric       break;
1230e8d8bef9SDimitry Andric     // These should also use to_generic, but we can't do that due to a
1231e8d8bef9SDimitry Andric     // producer-side bug in llvm. See llvm.org/pr48087.
12320b57cec5SDimitry Andric     case DW_OP_constu:
12330b57cec5SDimitry Andric       stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
12340b57cec5SDimitry Andric       break;
12350b57cec5SDimitry Andric     case DW_OP_consts:
12360b57cec5SDimitry Andric       stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
12370b57cec5SDimitry Andric       break;
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric     // OPCODE: DW_OP_dup
12400b57cec5SDimitry Andric     // OPERANDS: none
12410b57cec5SDimitry Andric     // DESCRIPTION: duplicates the value at the top of the stack
12420b57cec5SDimitry Andric     case DW_OP_dup:
12430b57cec5SDimitry Andric       if (stack.empty()) {
1244*0fca6ea1SDimitry Andric         return llvm::createStringError("expression stack empty for DW_OP_dup");
12450b57cec5SDimitry Andric       } else
12460b57cec5SDimitry Andric         stack.push_back(stack.back());
12470b57cec5SDimitry Andric       break;
12480b57cec5SDimitry Andric 
12490b57cec5SDimitry Andric     // OPCODE: DW_OP_drop
12500b57cec5SDimitry Andric     // OPERANDS: none
12510b57cec5SDimitry Andric     // DESCRIPTION: pops the value at the top of the stack
12520b57cec5SDimitry Andric     case DW_OP_drop:
12530b57cec5SDimitry Andric       if (stack.empty()) {
1254*0fca6ea1SDimitry Andric         return llvm::createStringError("expression stack empty for DW_OP_drop");
12550b57cec5SDimitry Andric       } else
12560b57cec5SDimitry Andric         stack.pop_back();
12570b57cec5SDimitry Andric       break;
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric     // OPCODE: DW_OP_over
12600b57cec5SDimitry Andric     // OPERANDS: none
12610b57cec5SDimitry Andric     // DESCRIPTION: Duplicates the entry currently second in the stack at
12620b57cec5SDimitry Andric     // the top of the stack.
12630b57cec5SDimitry Andric     case DW_OP_over:
12640b57cec5SDimitry Andric       stack.push_back(stack[stack.size() - 2]);
12650b57cec5SDimitry Andric       break;
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric     // OPCODE: DW_OP_pick
12680b57cec5SDimitry Andric     // OPERANDS: uint8_t index into the current stack
12690b57cec5SDimitry Andric     // DESCRIPTION: The stack entry with the specified index (0 through 255,
12700b57cec5SDimitry Andric     // inclusive) is pushed on the stack
12710b57cec5SDimitry Andric     case DW_OP_pick: {
12720b57cec5SDimitry Andric       uint8_t pick_idx = opcodes.GetU8(&offset);
12730b57cec5SDimitry Andric       if (pick_idx < stack.size())
12740b57cec5SDimitry Andric         stack.push_back(stack[stack.size() - 1 - pick_idx]);
12750b57cec5SDimitry Andric       else {
1276*0fca6ea1SDimitry Andric         return llvm::createStringError(
12770b57cec5SDimitry Andric             "Index %u out of range for DW_OP_pick.\n", pick_idx);
12780b57cec5SDimitry Andric       }
12790b57cec5SDimitry Andric     } break;
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric     // OPCODE: DW_OP_swap
12820b57cec5SDimitry Andric     // OPERANDS: none
12830b57cec5SDimitry Andric     // DESCRIPTION: swaps the top two stack entries. The entry at the top
12840b57cec5SDimitry Andric     // of the stack becomes the second stack entry, and the second entry
12850b57cec5SDimitry Andric     // becomes the top of the stack
12860b57cec5SDimitry Andric     case DW_OP_swap:
12870b57cec5SDimitry Andric       tmp = stack.back();
12880b57cec5SDimitry Andric       stack.back() = stack[stack.size() - 2];
12890b57cec5SDimitry Andric       stack[stack.size() - 2] = tmp;
12900b57cec5SDimitry Andric       break;
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric     // OPCODE: DW_OP_rot
12930b57cec5SDimitry Andric     // OPERANDS: none
12940b57cec5SDimitry Andric     // DESCRIPTION: Rotates the first three stack entries. The entry at
12950b57cec5SDimitry Andric     // the top of the stack becomes the third stack entry, the second entry
12960b57cec5SDimitry Andric     // becomes the top of the stack, and the third entry becomes the second
12970b57cec5SDimitry Andric     // entry.
1298*0fca6ea1SDimitry Andric     case DW_OP_rot: {
12990b57cec5SDimitry Andric       size_t last_idx = stack.size() - 1;
13000b57cec5SDimitry Andric       Value old_top = stack[last_idx];
13010b57cec5SDimitry Andric       stack[last_idx] = stack[last_idx - 1];
13020b57cec5SDimitry Andric       stack[last_idx - 1] = stack[last_idx - 2];
13030b57cec5SDimitry Andric       stack[last_idx - 2] = old_top;
1304*0fca6ea1SDimitry Andric     } break;
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric     // OPCODE: DW_OP_abs
13070b57cec5SDimitry Andric     // OPERANDS: none
13080b57cec5SDimitry Andric     // DESCRIPTION: pops the top stack entry, interprets it as a signed
13090b57cec5SDimitry Andric     // value and pushes its absolute value. If the absolute value can not be
13100b57cec5SDimitry Andric     // represented, the result is undefined.
13110b57cec5SDimitry Andric     case DW_OP_abs:
1312*0fca6ea1SDimitry Andric       if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) {
1313*0fca6ea1SDimitry Andric         return llvm::createStringError(
1314*0fca6ea1SDimitry Andric             "failed to take the absolute value of the first stack item");
13150b57cec5SDimitry Andric       }
13160b57cec5SDimitry Andric       break;
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric     // OPCODE: DW_OP_and
13190b57cec5SDimitry Andric     // OPERANDS: none
13200b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, performs a bitwise and
13210b57cec5SDimitry Andric     // operation on the two, and pushes the result.
13220b57cec5SDimitry Andric     case DW_OP_and:
13230b57cec5SDimitry Andric       tmp = stack.back();
13240b57cec5SDimitry Andric       stack.pop_back();
13250b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
13260b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
13270b57cec5SDimitry Andric       break;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric     // OPCODE: DW_OP_div
13300b57cec5SDimitry Andric     // OPERANDS: none
13310b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, divides the former second
13320b57cec5SDimitry Andric     // entry by the former top of the stack using signed division, and pushes
13330b57cec5SDimitry Andric     // the result.
1334*0fca6ea1SDimitry Andric     case DW_OP_div: {
13350b57cec5SDimitry Andric       tmp = stack.back();
1336*0fca6ea1SDimitry Andric       if (tmp.ResolveValue(exe_ctx).IsZero())
1337*0fca6ea1SDimitry Andric         return llvm::createStringError("divide by zero");
1338*0fca6ea1SDimitry Andric 
13390b57cec5SDimitry Andric       stack.pop_back();
134006c3fb27SDimitry Andric       Scalar divisor, dividend;
134106c3fb27SDimitry Andric       divisor = tmp.ResolveValue(exe_ctx);
134206c3fb27SDimitry Andric       dividend = stack.back().ResolveValue(exe_ctx);
134306c3fb27SDimitry Andric       divisor.MakeSigned();
134406c3fb27SDimitry Andric       dividend.MakeSigned();
134506c3fb27SDimitry Andric       stack.back() = dividend / divisor;
1346*0fca6ea1SDimitry Andric 
1347*0fca6ea1SDimitry Andric       if (!stack.back().ResolveValue(exe_ctx).IsValid())
1348*0fca6ea1SDimitry Andric         return llvm::createStringError("divide failed");
1349*0fca6ea1SDimitry Andric     } break;
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric     // OPCODE: DW_OP_minus
13520b57cec5SDimitry Andric     // OPERANDS: none
13530b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, subtracts the former top
13540b57cec5SDimitry Andric     // of the stack from the former second entry, and pushes the result.
13550b57cec5SDimitry Andric     case DW_OP_minus:
13560b57cec5SDimitry Andric       tmp = stack.back();
13570b57cec5SDimitry Andric       stack.pop_back();
13580b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
13590b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
13600b57cec5SDimitry Andric       break;
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric     // OPCODE: DW_OP_mod
13630b57cec5SDimitry Andric     // OPERANDS: none
13640b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values and pushes the result of
13650b57cec5SDimitry Andric     // the calculation: former second stack entry modulo the former top of the
13660b57cec5SDimitry Andric     // stack.
13670b57cec5SDimitry Andric     case DW_OP_mod:
13680b57cec5SDimitry Andric       tmp = stack.back();
13690b57cec5SDimitry Andric       stack.pop_back();
13700b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
13710b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
13720b57cec5SDimitry Andric       break;
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric     // OPCODE: DW_OP_mul
13750b57cec5SDimitry Andric     // OPERANDS: none
13760b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, multiplies them
13770b57cec5SDimitry Andric     // together, and pushes the result.
13780b57cec5SDimitry Andric     case DW_OP_mul:
13790b57cec5SDimitry Andric       tmp = stack.back();
13800b57cec5SDimitry Andric       stack.pop_back();
13810b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
13820b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
13830b57cec5SDimitry Andric       break;
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric     // OPCODE: DW_OP_neg
13860b57cec5SDimitry Andric     // OPERANDS: none
13870b57cec5SDimitry Andric     // DESCRIPTION: pops the top stack entry, and pushes its negation.
13880b57cec5SDimitry Andric     case DW_OP_neg:
1389*0fca6ea1SDimitry Andric       if (!stack.back().ResolveValue(exe_ctx).UnaryNegate())
1390*0fca6ea1SDimitry Andric         return llvm::createStringError("unary negate failed");
13910b57cec5SDimitry Andric       break;
13920b57cec5SDimitry Andric 
13930b57cec5SDimitry Andric     // OPCODE: DW_OP_not
13940b57cec5SDimitry Andric     // OPERANDS: none
13950b57cec5SDimitry Andric     // DESCRIPTION: pops the top stack entry, and pushes its bitwise
13960b57cec5SDimitry Andric     // complement
13970b57cec5SDimitry Andric     case DW_OP_not:
1398*0fca6ea1SDimitry Andric       if (!stack.back().ResolveValue(exe_ctx).OnesComplement())
1399*0fca6ea1SDimitry Andric         return llvm::createStringError("logical NOT failed");
14000b57cec5SDimitry Andric       break;
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric     // OPCODE: DW_OP_or
14030b57cec5SDimitry Andric     // OPERANDS: none
14040b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, performs a bitwise or
14050b57cec5SDimitry Andric     // operation on the two, and pushes the result.
14060b57cec5SDimitry Andric     case DW_OP_or:
14070b57cec5SDimitry Andric       tmp = stack.back();
14080b57cec5SDimitry Andric       stack.pop_back();
14090b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
14100b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
14110b57cec5SDimitry Andric       break;
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric     // OPCODE: DW_OP_plus
14140b57cec5SDimitry Andric     // OPERANDS: none
14150b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, adds them together, and
14160b57cec5SDimitry Andric     // pushes the result.
14170b57cec5SDimitry Andric     case DW_OP_plus:
14180b57cec5SDimitry Andric       tmp = stack.back();
14190b57cec5SDimitry Andric       stack.pop_back();
14200b57cec5SDimitry Andric       stack.back().GetScalar() += tmp.GetScalar();
14210b57cec5SDimitry Andric       break;
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric     // OPCODE: DW_OP_plus_uconst
14240b57cec5SDimitry Andric     // OPERANDS: none
14250b57cec5SDimitry Andric     // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
14260b57cec5SDimitry Andric     // constant operand and pushes the result.
1427*0fca6ea1SDimitry Andric     case DW_OP_plus_uconst: {
14280b57cec5SDimitry Andric       const uint64_t uconst_value = opcodes.GetULEB128(&offset);
14290b57cec5SDimitry Andric       // Implicit conversion from a UINT to a Scalar...
14300b57cec5SDimitry Andric       stack.back().GetScalar() += uconst_value;
1431*0fca6ea1SDimitry Andric       if (!stack.back().GetScalar().IsValid())
1432*0fca6ea1SDimitry Andric         return llvm::createStringError("DW_OP_plus_uconst failed");
1433*0fca6ea1SDimitry Andric     } break;
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric     // OPCODE: DW_OP_shl
14360b57cec5SDimitry Andric     // OPERANDS: none
14370b57cec5SDimitry Andric     // DESCRIPTION:  pops the top two stack entries, shifts the former
14380b57cec5SDimitry Andric     // second entry left by the number of bits specified by the former top of
14390b57cec5SDimitry Andric     // the stack, and pushes the result.
14400b57cec5SDimitry Andric     case DW_OP_shl:
14410b57cec5SDimitry Andric       tmp = stack.back();
14420b57cec5SDimitry Andric       stack.pop_back();
14430b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
14440b57cec5SDimitry Andric       break;
14450b57cec5SDimitry Andric 
14460b57cec5SDimitry Andric     // OPCODE: DW_OP_shr
14470b57cec5SDimitry Andric     // OPERANDS: none
14480b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, shifts the former second
14490b57cec5SDimitry Andric     // entry right logically (filling with zero bits) by the number of bits
14500b57cec5SDimitry Andric     // specified by the former top of the stack, and pushes the result.
14510b57cec5SDimitry Andric     case DW_OP_shr:
14520b57cec5SDimitry Andric       tmp = stack.back();
14530b57cec5SDimitry Andric       stack.pop_back();
14540b57cec5SDimitry Andric       if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical(
1455*0fca6ea1SDimitry Andric               tmp.ResolveValue(exe_ctx)))
1456*0fca6ea1SDimitry Andric         return llvm::createStringError("DW_OP_shr failed");
14570b57cec5SDimitry Andric       break;
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric     // OPCODE: DW_OP_shra
14600b57cec5SDimitry Andric     // OPERANDS: none
14610b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, shifts the former second
14620b57cec5SDimitry Andric     // entry right arithmetically (divide the magnitude by 2, keep the same
14630b57cec5SDimitry Andric     // sign for the result) by the number of bits specified by the former top
14640b57cec5SDimitry Andric     // of the stack, and pushes the result.
14650b57cec5SDimitry Andric     case DW_OP_shra:
14660b57cec5SDimitry Andric       tmp = stack.back();
14670b57cec5SDimitry Andric       stack.pop_back();
14680b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
14690b57cec5SDimitry Andric       break;
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric     // OPCODE: DW_OP_xor
14720b57cec5SDimitry Andric     // OPERANDS: none
14730b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack entries, performs the bitwise
14740b57cec5SDimitry Andric     // exclusive-or operation on the two, and pushes the result.
14750b57cec5SDimitry Andric     case DW_OP_xor:
14760b57cec5SDimitry Andric       tmp = stack.back();
14770b57cec5SDimitry Andric       stack.pop_back();
14780b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
14790b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
14800b57cec5SDimitry Andric       break;
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric     // OPCODE: DW_OP_skip
14830b57cec5SDimitry Andric     // OPERANDS: int16_t
14840b57cec5SDimitry Andric     // DESCRIPTION:  An unconditional branch. Its single operand is a 2-byte
14850b57cec5SDimitry Andric     // signed integer constant. The 2-byte constant is the number of bytes of
14860b57cec5SDimitry Andric     // the DWARF expression to skip forward or backward from the current
14870b57cec5SDimitry Andric     // operation, beginning after the 2-byte constant.
14880b57cec5SDimitry Andric     case DW_OP_skip: {
14890b57cec5SDimitry Andric       int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
14900b57cec5SDimitry Andric       lldb::offset_t new_offset = offset + skip_offset;
1491fcaf7f86SDimitry Andric       // New offset can point at the end of the data, in this case we should
1492fcaf7f86SDimitry Andric       // terminate the DWARF expression evaluation (will happen in the loop
1493fcaf7f86SDimitry Andric       // condition).
1494fcaf7f86SDimitry Andric       if (new_offset <= opcodes.GetByteSize())
14950b57cec5SDimitry Andric         offset = new_offset;
14960b57cec5SDimitry Andric       else {
1497*0fca6ea1SDimitry Andric         return llvm::createStringError(llvm::formatv(
1498fcaf7f86SDimitry Andric             "Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}", offset,
1499*0fca6ea1SDimitry Andric             skip_offset, opcodes.GetByteSize()));
15000b57cec5SDimitry Andric       }
15010b57cec5SDimitry Andric     } break;
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric     // OPCODE: DW_OP_bra
15040b57cec5SDimitry Andric     // OPERANDS: int16_t
15050b57cec5SDimitry Andric     // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
15060b57cec5SDimitry Andric     // signed integer constant. This operation pops the top of stack. If the
15070b57cec5SDimitry Andric     // value popped is not the constant 0, the 2-byte constant operand is the
15080b57cec5SDimitry Andric     // number of bytes of the DWARF expression to skip forward or backward from
15090b57cec5SDimitry Andric     // the current operation, beginning after the 2-byte constant.
1510*0fca6ea1SDimitry Andric     case DW_OP_bra: {
15110b57cec5SDimitry Andric       tmp = stack.back();
15120b57cec5SDimitry Andric       stack.pop_back();
15130b57cec5SDimitry Andric       int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
15140b57cec5SDimitry Andric       Scalar zero(0);
15150b57cec5SDimitry Andric       if (tmp.ResolveValue(exe_ctx) != zero) {
15160b57cec5SDimitry Andric         lldb::offset_t new_offset = offset + bra_offset;
1517fcaf7f86SDimitry Andric         // New offset can point at the end of the data, in this case we should
1518fcaf7f86SDimitry Andric         // terminate the DWARF expression evaluation (will happen in the loop
1519fcaf7f86SDimitry Andric         // condition).
1520fcaf7f86SDimitry Andric         if (new_offset <= opcodes.GetByteSize())
15210b57cec5SDimitry Andric           offset = new_offset;
15220b57cec5SDimitry Andric         else {
1523*0fca6ea1SDimitry Andric           return llvm::createStringError(llvm::formatv(
1524fcaf7f86SDimitry Andric               "Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}", offset,
1525*0fca6ea1SDimitry Andric               bra_offset, opcodes.GetByteSize()));
15260b57cec5SDimitry Andric         }
15270b57cec5SDimitry Andric       }
1528*0fca6ea1SDimitry Andric     } break;
15290b57cec5SDimitry Andric 
15300b57cec5SDimitry Andric     // OPCODE: DW_OP_eq
15310b57cec5SDimitry Andric     // OPERANDS: none
15320b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
15330b57cec5SDimitry Andric     // equals (==) operator.
15340b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
15350b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
15360b57cec5SDimitry Andric     // operation is false.
15370b57cec5SDimitry Andric     case DW_OP_eq:
15380b57cec5SDimitry Andric       tmp = stack.back();
15390b57cec5SDimitry Andric       stack.pop_back();
15400b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
15410b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
15420b57cec5SDimitry Andric       break;
15430b57cec5SDimitry Andric 
15440b57cec5SDimitry Andric     // OPCODE: DW_OP_ge
15450b57cec5SDimitry Andric     // OPERANDS: none
15460b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
15470b57cec5SDimitry Andric     // greater than or equal to (>=) operator.
15480b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
15490b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
15500b57cec5SDimitry Andric     // operation is false.
15510b57cec5SDimitry Andric     case DW_OP_ge:
15520b57cec5SDimitry Andric       tmp = stack.back();
15530b57cec5SDimitry Andric       stack.pop_back();
15540b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
15550b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
15560b57cec5SDimitry Andric       break;
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric     // OPCODE: DW_OP_gt
15590b57cec5SDimitry Andric     // OPERANDS: none
15600b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
15610b57cec5SDimitry Andric     // greater than (>) operator.
15620b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
15630b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
15640b57cec5SDimitry Andric     // operation is false.
15650b57cec5SDimitry Andric     case DW_OP_gt:
15660b57cec5SDimitry Andric       tmp = stack.back();
15670b57cec5SDimitry Andric       stack.pop_back();
15680b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
15690b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
15700b57cec5SDimitry Andric       break;
15710b57cec5SDimitry Andric 
15720b57cec5SDimitry Andric     // OPCODE: DW_OP_le
15730b57cec5SDimitry Andric     // OPERANDS: none
15740b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
15750b57cec5SDimitry Andric     // less than or equal to (<=) operator.
15760b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
15770b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
15780b57cec5SDimitry Andric     // operation is false.
15790b57cec5SDimitry Andric     case DW_OP_le:
15800b57cec5SDimitry Andric       tmp = stack.back();
15810b57cec5SDimitry Andric       stack.pop_back();
15820b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
15830b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
15840b57cec5SDimitry Andric       break;
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric     // OPCODE: DW_OP_lt
15870b57cec5SDimitry Andric     // OPERANDS: none
15880b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
15890b57cec5SDimitry Andric     // less than (<) operator.
15900b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
15910b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
15920b57cec5SDimitry Andric     // operation is false.
15930b57cec5SDimitry Andric     case DW_OP_lt:
15940b57cec5SDimitry Andric       tmp = stack.back();
15950b57cec5SDimitry Andric       stack.pop_back();
15960b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
15970b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
15980b57cec5SDimitry Andric       break;
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric     // OPCODE: DW_OP_ne
16010b57cec5SDimitry Andric     // OPERANDS: none
16020b57cec5SDimitry Andric     // DESCRIPTION: pops the top two stack values, compares using the
16030b57cec5SDimitry Andric     // not equal (!=) operator.
16040b57cec5SDimitry Andric     // STACK RESULT: push the constant value 1 onto the stack if the result
16050b57cec5SDimitry Andric     // of the operation is true or the constant value 0 if the result of the
16060b57cec5SDimitry Andric     // operation is false.
16070b57cec5SDimitry Andric     case DW_OP_ne:
16080b57cec5SDimitry Andric       tmp = stack.back();
16090b57cec5SDimitry Andric       stack.pop_back();
16100b57cec5SDimitry Andric       stack.back().ResolveValue(exe_ctx) =
16110b57cec5SDimitry Andric           stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
16120b57cec5SDimitry Andric       break;
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric     // OPCODE: DW_OP_litn
16150b57cec5SDimitry Andric     // OPERANDS: none
16160b57cec5SDimitry Andric     // DESCRIPTION: encode the unsigned literal values from 0 through 31.
16170b57cec5SDimitry Andric     // STACK RESULT: push the unsigned literal constant value onto the top
16180b57cec5SDimitry Andric     // of the stack.
16190b57cec5SDimitry Andric     case DW_OP_lit0:
16200b57cec5SDimitry Andric     case DW_OP_lit1:
16210b57cec5SDimitry Andric     case DW_OP_lit2:
16220b57cec5SDimitry Andric     case DW_OP_lit3:
16230b57cec5SDimitry Andric     case DW_OP_lit4:
16240b57cec5SDimitry Andric     case DW_OP_lit5:
16250b57cec5SDimitry Andric     case DW_OP_lit6:
16260b57cec5SDimitry Andric     case DW_OP_lit7:
16270b57cec5SDimitry Andric     case DW_OP_lit8:
16280b57cec5SDimitry Andric     case DW_OP_lit9:
16290b57cec5SDimitry Andric     case DW_OP_lit10:
16300b57cec5SDimitry Andric     case DW_OP_lit11:
16310b57cec5SDimitry Andric     case DW_OP_lit12:
16320b57cec5SDimitry Andric     case DW_OP_lit13:
16330b57cec5SDimitry Andric     case DW_OP_lit14:
16340b57cec5SDimitry Andric     case DW_OP_lit15:
16350b57cec5SDimitry Andric     case DW_OP_lit16:
16360b57cec5SDimitry Andric     case DW_OP_lit17:
16370b57cec5SDimitry Andric     case DW_OP_lit18:
16380b57cec5SDimitry Andric     case DW_OP_lit19:
16390b57cec5SDimitry Andric     case DW_OP_lit20:
16400b57cec5SDimitry Andric     case DW_OP_lit21:
16410b57cec5SDimitry Andric     case DW_OP_lit22:
16420b57cec5SDimitry Andric     case DW_OP_lit23:
16430b57cec5SDimitry Andric     case DW_OP_lit24:
16440b57cec5SDimitry Andric     case DW_OP_lit25:
16450b57cec5SDimitry Andric     case DW_OP_lit26:
16460b57cec5SDimitry Andric     case DW_OP_lit27:
16470b57cec5SDimitry Andric     case DW_OP_lit28:
16480b57cec5SDimitry Andric     case DW_OP_lit29:
16490b57cec5SDimitry Andric     case DW_OP_lit30:
16500b57cec5SDimitry Andric     case DW_OP_lit31:
1651e8d8bef9SDimitry Andric       stack.push_back(to_generic(op - DW_OP_lit0));
16520b57cec5SDimitry Andric       break;
16530b57cec5SDimitry Andric 
16540b57cec5SDimitry Andric     // OPCODE: DW_OP_regN
16550b57cec5SDimitry Andric     // OPERANDS: none
16560b57cec5SDimitry Andric     // DESCRIPTION: Push the value in register n on the top of the stack.
16570b57cec5SDimitry Andric     case DW_OP_reg0:
16580b57cec5SDimitry Andric     case DW_OP_reg1:
16590b57cec5SDimitry Andric     case DW_OP_reg2:
16600b57cec5SDimitry Andric     case DW_OP_reg3:
16610b57cec5SDimitry Andric     case DW_OP_reg4:
16620b57cec5SDimitry Andric     case DW_OP_reg5:
16630b57cec5SDimitry Andric     case DW_OP_reg6:
16640b57cec5SDimitry Andric     case DW_OP_reg7:
16650b57cec5SDimitry Andric     case DW_OP_reg8:
16660b57cec5SDimitry Andric     case DW_OP_reg9:
16670b57cec5SDimitry Andric     case DW_OP_reg10:
16680b57cec5SDimitry Andric     case DW_OP_reg11:
16690b57cec5SDimitry Andric     case DW_OP_reg12:
16700b57cec5SDimitry Andric     case DW_OP_reg13:
16710b57cec5SDimitry Andric     case DW_OP_reg14:
16720b57cec5SDimitry Andric     case DW_OP_reg15:
16730b57cec5SDimitry Andric     case DW_OP_reg16:
16740b57cec5SDimitry Andric     case DW_OP_reg17:
16750b57cec5SDimitry Andric     case DW_OP_reg18:
16760b57cec5SDimitry Andric     case DW_OP_reg19:
16770b57cec5SDimitry Andric     case DW_OP_reg20:
16780b57cec5SDimitry Andric     case DW_OP_reg21:
16790b57cec5SDimitry Andric     case DW_OP_reg22:
16800b57cec5SDimitry Andric     case DW_OP_reg23:
16810b57cec5SDimitry Andric     case DW_OP_reg24:
16820b57cec5SDimitry Andric     case DW_OP_reg25:
16830b57cec5SDimitry Andric     case DW_OP_reg26:
16840b57cec5SDimitry Andric     case DW_OP_reg27:
16850b57cec5SDimitry Andric     case DW_OP_reg28:
16860b57cec5SDimitry Andric     case DW_OP_reg29:
16870b57cec5SDimitry Andric     case DW_OP_reg30:
16880b57cec5SDimitry Andric     case DW_OP_reg31: {
1689fe6060f1SDimitry Andric       dwarf4_location_description_kind = Register;
16900b57cec5SDimitry Andric       reg_num = op - DW_OP_reg0;
16910b57cec5SDimitry Andric 
1692*0fca6ea1SDimitry Andric       if (llvm::Error err =
1693*0fca6ea1SDimitry Andric               ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
1694*0fca6ea1SDimitry Andric         return err;
16950b57cec5SDimitry Andric       stack.push_back(tmp);
16960b57cec5SDimitry Andric     } break;
16970b57cec5SDimitry Andric     // OPCODE: DW_OP_regx
16980b57cec5SDimitry Andric     // OPERANDS:
16990b57cec5SDimitry Andric     //      ULEB128 literal operand that encodes the register.
17000b57cec5SDimitry Andric     // DESCRIPTION: Push the value in register on the top of the stack.
17010b57cec5SDimitry Andric     case DW_OP_regx: {
1702fe6060f1SDimitry Andric       dwarf4_location_description_kind = Register;
17030b57cec5SDimitry Andric       reg_num = opcodes.GetULEB128(&offset);
1704*0fca6ea1SDimitry Andric       Status read_err;
1705*0fca6ea1SDimitry Andric       if (llvm::Error err =
1706*0fca6ea1SDimitry Andric               ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
1707*0fca6ea1SDimitry Andric         return err;
17080b57cec5SDimitry Andric       stack.push_back(tmp);
17090b57cec5SDimitry Andric     } break;
17100b57cec5SDimitry Andric 
17110b57cec5SDimitry Andric     // OPCODE: DW_OP_bregN
17120b57cec5SDimitry Andric     // OPERANDS:
17130b57cec5SDimitry Andric     //      SLEB128 offset from register N
17140b57cec5SDimitry Andric     // DESCRIPTION: Value is in memory at the address specified by register
17150b57cec5SDimitry Andric     // N plus an offset.
17160b57cec5SDimitry Andric     case DW_OP_breg0:
17170b57cec5SDimitry Andric     case DW_OP_breg1:
17180b57cec5SDimitry Andric     case DW_OP_breg2:
17190b57cec5SDimitry Andric     case DW_OP_breg3:
17200b57cec5SDimitry Andric     case DW_OP_breg4:
17210b57cec5SDimitry Andric     case DW_OP_breg5:
17220b57cec5SDimitry Andric     case DW_OP_breg6:
17230b57cec5SDimitry Andric     case DW_OP_breg7:
17240b57cec5SDimitry Andric     case DW_OP_breg8:
17250b57cec5SDimitry Andric     case DW_OP_breg9:
17260b57cec5SDimitry Andric     case DW_OP_breg10:
17270b57cec5SDimitry Andric     case DW_OP_breg11:
17280b57cec5SDimitry Andric     case DW_OP_breg12:
17290b57cec5SDimitry Andric     case DW_OP_breg13:
17300b57cec5SDimitry Andric     case DW_OP_breg14:
17310b57cec5SDimitry Andric     case DW_OP_breg15:
17320b57cec5SDimitry Andric     case DW_OP_breg16:
17330b57cec5SDimitry Andric     case DW_OP_breg17:
17340b57cec5SDimitry Andric     case DW_OP_breg18:
17350b57cec5SDimitry Andric     case DW_OP_breg19:
17360b57cec5SDimitry Andric     case DW_OP_breg20:
17370b57cec5SDimitry Andric     case DW_OP_breg21:
17380b57cec5SDimitry Andric     case DW_OP_breg22:
17390b57cec5SDimitry Andric     case DW_OP_breg23:
17400b57cec5SDimitry Andric     case DW_OP_breg24:
17410b57cec5SDimitry Andric     case DW_OP_breg25:
17420b57cec5SDimitry Andric     case DW_OP_breg26:
17430b57cec5SDimitry Andric     case DW_OP_breg27:
17440b57cec5SDimitry Andric     case DW_OP_breg28:
17450b57cec5SDimitry Andric     case DW_OP_breg29:
17460b57cec5SDimitry Andric     case DW_OP_breg30:
17470b57cec5SDimitry Andric     case DW_OP_breg31: {
17480b57cec5SDimitry Andric       reg_num = op - DW_OP_breg0;
1749*0fca6ea1SDimitry Andric       if (llvm::Error err =
1750*0fca6ea1SDimitry Andric               ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
1751*0fca6ea1SDimitry Andric         return err;
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric       int64_t breg_offset = opcodes.GetSLEB128(&offset);
17540b57cec5SDimitry Andric       tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
17550b57cec5SDimitry Andric       tmp.ClearContext();
17560b57cec5SDimitry Andric       stack.push_back(tmp);
1757fe6060f1SDimitry Andric       stack.back().SetValueType(Value::ValueType::LoadAddress);
17580b57cec5SDimitry Andric     } break;
17590b57cec5SDimitry Andric     // OPCODE: DW_OP_bregx
17600b57cec5SDimitry Andric     // OPERANDS: 2
17610b57cec5SDimitry Andric     //      ULEB128 literal operand that encodes the register.
17620b57cec5SDimitry Andric     //      SLEB128 offset from register N
17630b57cec5SDimitry Andric     // DESCRIPTION: Value is in memory at the address specified by register
17640b57cec5SDimitry Andric     // N plus an offset.
17650b57cec5SDimitry Andric     case DW_OP_bregx: {
17660b57cec5SDimitry Andric       reg_num = opcodes.GetULEB128(&offset);
1767*0fca6ea1SDimitry Andric       if (llvm::Error err =
1768*0fca6ea1SDimitry Andric               ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
1769*0fca6ea1SDimitry Andric         return err;
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric       int64_t breg_offset = opcodes.GetSLEB128(&offset);
17720b57cec5SDimitry Andric       tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
17730b57cec5SDimitry Andric       tmp.ClearContext();
17740b57cec5SDimitry Andric       stack.push_back(tmp);
1775fe6060f1SDimitry Andric       stack.back().SetValueType(Value::ValueType::LoadAddress);
17760b57cec5SDimitry Andric     } break;
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric     case DW_OP_fbreg:
17790b57cec5SDimitry Andric       if (exe_ctx) {
17800b57cec5SDimitry Andric         if (frame) {
17810b57cec5SDimitry Andric           Scalar value;
1782*0fca6ea1SDimitry Andric           Status fb_err;
1783*0fca6ea1SDimitry Andric           if (frame->GetFrameBaseValue(value, &fb_err)) {
17840b57cec5SDimitry Andric             int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
17850b57cec5SDimitry Andric             value += fbreg_offset;
17860b57cec5SDimitry Andric             stack.push_back(value);
1787fe6060f1SDimitry Andric             stack.back().SetValueType(Value::ValueType::LoadAddress);
17880b57cec5SDimitry Andric           } else
1789*0fca6ea1SDimitry Andric             return fb_err.ToError();
17900b57cec5SDimitry Andric         } else {
1791*0fca6ea1SDimitry Andric           return llvm::createStringError(
1792*0fca6ea1SDimitry Andric               "invalid stack frame in context for DW_OP_fbreg opcode");
17930b57cec5SDimitry Andric         }
17940b57cec5SDimitry Andric       } else {
1795*0fca6ea1SDimitry Andric         return llvm::createStringError(
1796*0fca6ea1SDimitry Andric             "NULL execution context for DW_OP_fbreg");
17970b57cec5SDimitry Andric       }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric       break;
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric     // OPCODE: DW_OP_nop
18020b57cec5SDimitry Andric     // OPERANDS: none
18030b57cec5SDimitry Andric     // DESCRIPTION: A place holder. It has no effect on the location stack
18040b57cec5SDimitry Andric     // or any of its values.
18050b57cec5SDimitry Andric     case DW_OP_nop:
18060b57cec5SDimitry Andric       break;
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric     // OPCODE: DW_OP_piece
18090b57cec5SDimitry Andric     // OPERANDS: 1
18100b57cec5SDimitry Andric     //      ULEB128: byte size of the piece
18110b57cec5SDimitry Andric     // DESCRIPTION: The operand describes the size in bytes of the piece of
18120b57cec5SDimitry Andric     // the object referenced by the DWARF expression whose result is at the top
18130b57cec5SDimitry Andric     // of the stack. If the piece is located in a register, but does not occupy
18140b57cec5SDimitry Andric     // the entire register, the placement of the piece within that register is
18150b57cec5SDimitry Andric     // defined by the ABI.
18160b57cec5SDimitry Andric     //
18170b57cec5SDimitry Andric     // Many compilers store a single variable in sets of registers, or store a
18180b57cec5SDimitry Andric     // variable partially in memory and partially in registers. DW_OP_piece
18190b57cec5SDimitry Andric     // provides a way of describing how large a part of a variable a particular
18200b57cec5SDimitry Andric     // DWARF expression refers to.
18210b57cec5SDimitry Andric     case DW_OP_piece: {
1822fe6060f1SDimitry Andric       LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
1823fe6060f1SDimitry Andric       // Reset for the next piece.
1824fe6060f1SDimitry Andric       dwarf4_location_description_kind = Memory;
1825fe6060f1SDimitry Andric 
18260b57cec5SDimitry Andric       const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);
18270b57cec5SDimitry Andric 
18280b57cec5SDimitry Andric       if (piece_byte_size > 0) {
18290b57cec5SDimitry Andric         Value curr_piece;
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric         if (stack.empty()) {
1832fe6060f1SDimitry Andric           UpdateValueTypeFromLocationDescription(
1833fe6060f1SDimitry Andric               log, dwarf_cu, LocationDescriptionKind::Empty);
18340b57cec5SDimitry Andric           // In a multi-piece expression, this means that the current piece is
18350b57cec5SDimitry Andric           // not available. Fill with zeros for now by resizing the data and
18360b57cec5SDimitry Andric           // appending it
18370b57cec5SDimitry Andric           curr_piece.ResizeData(piece_byte_size);
183847395794SDimitry Andric           // Note that "0" is not a correct value for the unknown bits.
183947395794SDimitry Andric           // It would be better to also return a mask of valid bits together
184047395794SDimitry Andric           // with the expression result, so the debugger can print missing
184147395794SDimitry Andric           // members as "<optimized out>" or something.
18420b57cec5SDimitry Andric           ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
18430b57cec5SDimitry Andric           pieces.AppendDataToHostBuffer(curr_piece);
18440b57cec5SDimitry Andric         } else {
18450b57cec5SDimitry Andric           Status error;
18460b57cec5SDimitry Andric           // Extract the current piece into "curr_piece"
18470b57cec5SDimitry Andric           Value curr_piece_source_value(stack.back());
18480b57cec5SDimitry Andric           stack.pop_back();
1849fe6060f1SDimitry Andric           UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc,
1850fe6060f1SDimitry Andric                                                  &curr_piece_source_value);
18510b57cec5SDimitry Andric 
18520b57cec5SDimitry Andric           const Value::ValueType curr_piece_source_value_type =
18530b57cec5SDimitry Andric               curr_piece_source_value.GetValueType();
1854*0fca6ea1SDimitry Andric           Scalar &scalar = curr_piece_source_value.GetScalar();
1855*0fca6ea1SDimitry Andric           const lldb::addr_t addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
18560b57cec5SDimitry Andric           switch (curr_piece_source_value_type) {
1857fe6060f1SDimitry Andric           case Value::ValueType::Invalid:
1858*0fca6ea1SDimitry Andric             return llvm::createStringError("invalid value type");
1859fe6060f1SDimitry Andric           case Value::ValueType::LoadAddress:
1860*0fca6ea1SDimitry Andric           case Value::ValueType::FileAddress: {
1861*0fca6ea1SDimitry Andric             if (target) {
18620b57cec5SDimitry Andric               if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
1863*0fca6ea1SDimitry Andric                 if (target->ReadMemory(addr, curr_piece.GetBuffer().GetBytes(),
1864*0fca6ea1SDimitry Andric                                        piece_byte_size, error,
1865*0fca6ea1SDimitry Andric                                        /*force_live_memory=*/false) !=
1866*0fca6ea1SDimitry Andric                     piece_byte_size) {
1867*0fca6ea1SDimitry Andric                   const char *addr_type = (curr_piece_source_value_type ==
1868*0fca6ea1SDimitry Andric                                            Value::ValueType::LoadAddress)
1869*0fca6ea1SDimitry Andric                                               ? "load"
1870*0fca6ea1SDimitry Andric                                               : "file";
1871*0fca6ea1SDimitry Andric                   return llvm::createStringError(
18720b57cec5SDimitry Andric                       "failed to read memory DW_OP_piece(%" PRIu64
1873*0fca6ea1SDimitry Andric                       ") from %s address 0x%" PRIx64,
1874*0fca6ea1SDimitry Andric                       piece_byte_size, addr_type, addr);
18750b57cec5SDimitry Andric                 }
18760b57cec5SDimitry Andric               } else {
1877*0fca6ea1SDimitry Andric                 return llvm::createStringError(
18780b57cec5SDimitry Andric                     "failed to resize the piece memory buffer for "
18790b57cec5SDimitry Andric                     "DW_OP_piece(%" PRIu64 ")",
18800b57cec5SDimitry Andric                     piece_byte_size);
18810b57cec5SDimitry Andric               }
18820b57cec5SDimitry Andric             }
1883*0fca6ea1SDimitry Andric           } break;
1884*0fca6ea1SDimitry Andric           case Value::ValueType::HostAddress: {
1885*0fca6ea1SDimitry Andric             return llvm::createStringError(
18860b57cec5SDimitry Andric                 "failed to read memory DW_OP_piece(%" PRIu64
1887*0fca6ea1SDimitry Andric                 ") from host address 0x%" PRIx64,
1888*0fca6ea1SDimitry Andric                 piece_byte_size, addr);
1889*0fca6ea1SDimitry Andric           } break;
18900b57cec5SDimitry Andric 
1891fe6060f1SDimitry Andric           case Value::ValueType::Scalar: {
18920b57cec5SDimitry Andric             uint32_t bit_size = piece_byte_size * 8;
18930b57cec5SDimitry Andric             uint32_t bit_offset = 0;
189447395794SDimitry Andric             if (!scalar.ExtractBitfield(
18950b57cec5SDimitry Andric                     bit_size, bit_offset)) {
1896*0fca6ea1SDimitry Andric               return llvm::createStringError(
18970b57cec5SDimitry Andric                   "unable to extract %" PRIu64 " bytes from a %" PRIu64
18980b57cec5SDimitry Andric                   " byte scalar value.",
18990b57cec5SDimitry Andric                   piece_byte_size,
1900*0fca6ea1SDimitry Andric                   (uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
19010b57cec5SDimitry Andric             }
190247395794SDimitry Andric             // Create curr_piece with bit_size. By default Scalar
190347395794SDimitry Andric             // grows to the nearest host integer type.
190447395794SDimitry Andric             llvm::APInt fail_value(1, 0, false);
190547395794SDimitry Andric             llvm::APInt ap_int = scalar.UInt128(fail_value);
190647395794SDimitry Andric             assert(ap_int.getBitWidth() >= bit_size);
190747395794SDimitry Andric             llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
190847395794SDimitry Andric                                          ap_int.getNumWords()};
190947395794SDimitry Andric             curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
19100b57cec5SDimitry Andric           } break;
19110b57cec5SDimitry Andric           }
19120b57cec5SDimitry Andric 
19130b57cec5SDimitry Andric           // Check if this is the first piece?
19140b57cec5SDimitry Andric           if (op_piece_offset == 0) {
19150b57cec5SDimitry Andric             // This is the first piece, we should push it back onto the stack
19160b57cec5SDimitry Andric             // so subsequent pieces will be able to access this piece and add
191747395794SDimitry Andric             // to it.
19180b57cec5SDimitry Andric             if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
1919*0fca6ea1SDimitry Andric               return llvm::createStringError("failed to append piece data");
19200b57cec5SDimitry Andric             }
19210b57cec5SDimitry Andric           } else {
19220b57cec5SDimitry Andric             // If this is the second or later piece there should be a value on
192347395794SDimitry Andric             // the stack.
19240b57cec5SDimitry Andric             if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
1925*0fca6ea1SDimitry Andric               return llvm::createStringError(
19260b57cec5SDimitry Andric                   "DW_OP_piece for offset %" PRIu64
19270b57cec5SDimitry Andric                   " but top of stack is of size %" PRIu64,
19280b57cec5SDimitry Andric                   op_piece_offset, pieces.GetBuffer().GetByteSize());
19290b57cec5SDimitry Andric             }
19300b57cec5SDimitry Andric 
1931*0fca6ea1SDimitry Andric             if (pieces.AppendDataToHostBuffer(curr_piece) == 0)
1932*0fca6ea1SDimitry Andric               return llvm::createStringError("failed to append piece data");
19330b57cec5SDimitry Andric           }
19340b57cec5SDimitry Andric         }
193547395794SDimitry Andric         op_piece_offset += piece_byte_size;
19360b57cec5SDimitry Andric       }
19370b57cec5SDimitry Andric     } break;
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric     case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
19400b57cec5SDimitry Andric       if (stack.size() < 1) {
1941fe6060f1SDimitry Andric         UpdateValueTypeFromLocationDescription(log, dwarf_cu,
1942fe6060f1SDimitry Andric                                                LocationDescriptionKind::Empty);
1943fe6060f1SDimitry Andric         // Reset for the next piece.
1944fe6060f1SDimitry Andric         dwarf4_location_description_kind = Memory;
1945*0fca6ea1SDimitry Andric         return llvm::createStringError(
1946*0fca6ea1SDimitry Andric             "expression stack needs at least 1 item for DW_OP_bit_piece");
19470b57cec5SDimitry Andric       } else {
1948fe6060f1SDimitry Andric         UpdateValueTypeFromLocationDescription(
1949fe6060f1SDimitry Andric             log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
1950fe6060f1SDimitry Andric         // Reset for the next piece.
1951fe6060f1SDimitry Andric         dwarf4_location_description_kind = Memory;
19520b57cec5SDimitry Andric         const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);
19530b57cec5SDimitry Andric         const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);
19540b57cec5SDimitry Andric         switch (stack.back().GetValueType()) {
1955fe6060f1SDimitry Andric         case Value::ValueType::Invalid:
1956*0fca6ea1SDimitry Andric           return llvm::createStringError(
1957*0fca6ea1SDimitry Andric               "unable to extract bit value from invalid value");
1958fe6060f1SDimitry Andric         case Value::ValueType::Scalar: {
19590b57cec5SDimitry Andric           if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
19600b57cec5SDimitry Andric                                                         piece_bit_offset)) {
1961*0fca6ea1SDimitry Andric             return llvm::createStringError(
19620b57cec5SDimitry Andric                 "unable to extract %" PRIu64 " bit value with %" PRIu64
19630b57cec5SDimitry Andric                 " bit offset from a %" PRIu64 " bit scalar value.",
19640b57cec5SDimitry Andric                 piece_bit_size, piece_bit_offset,
19650b57cec5SDimitry Andric                 (uint64_t)(stack.back().GetScalar().GetByteSize() * 8));
19660b57cec5SDimitry Andric           }
19670b57cec5SDimitry Andric         } break;
19680b57cec5SDimitry Andric 
1969fe6060f1SDimitry Andric         case Value::ValueType::FileAddress:
1970fe6060f1SDimitry Andric         case Value::ValueType::LoadAddress:
1971fe6060f1SDimitry Andric         case Value::ValueType::HostAddress:
1972*0fca6ea1SDimitry Andric           return llvm::createStringError(
19730b57cec5SDimitry Andric               "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
19740b57cec5SDimitry Andric               ", bit_offset = %" PRIu64 ") from an address value.",
19750b57cec5SDimitry Andric               piece_bit_size, piece_bit_offset);
19760b57cec5SDimitry Andric         }
19770b57cec5SDimitry Andric       }
19780b57cec5SDimitry Andric       break;
19790b57cec5SDimitry Andric 
1980e8d8bef9SDimitry Andric     // OPCODE: DW_OP_implicit_value
1981e8d8bef9SDimitry Andric     // OPERANDS: 2
1982e8d8bef9SDimitry Andric     //      ULEB128  size of the value block in bytes
1983e8d8bef9SDimitry Andric     //      uint8_t* block bytes encoding value in target's memory
1984e8d8bef9SDimitry Andric     //      representation
1985e8d8bef9SDimitry Andric     // DESCRIPTION: Value is immediately stored in block in the debug info with
1986e8d8bef9SDimitry Andric     // the memory representation of the target.
1987e8d8bef9SDimitry Andric     case DW_OP_implicit_value: {
1988fe6060f1SDimitry Andric       dwarf4_location_description_kind = Implicit;
1989fe6060f1SDimitry Andric 
1990e8d8bef9SDimitry Andric       const uint32_t len = opcodes.GetULEB128(&offset);
1991e8d8bef9SDimitry Andric       const void *data = opcodes.GetData(&offset, len);
1992e8d8bef9SDimitry Andric 
1993e8d8bef9SDimitry Andric       if (!data) {
1994e8d8bef9SDimitry Andric         LLDB_LOG(log, "Evaluate_DW_OP_implicit_value: could not be read data");
1995*0fca6ea1SDimitry Andric         return llvm::createStringError("could not evaluate %s",
1996e8d8bef9SDimitry Andric                                        DW_OP_value_to_name(op));
1997e8d8bef9SDimitry Andric       }
1998e8d8bef9SDimitry Andric 
1999e8d8bef9SDimitry Andric       Value result(data, len);
2000e8d8bef9SDimitry Andric       stack.push_back(result);
2001e8d8bef9SDimitry Andric       break;
2002e8d8bef9SDimitry Andric     }
2003e8d8bef9SDimitry Andric 
2004fe6060f1SDimitry Andric     case DW_OP_implicit_pointer: {
2005fe6060f1SDimitry Andric       dwarf4_location_description_kind = Implicit;
2006*0fca6ea1SDimitry Andric       return llvm::createStringError("Could not evaluate %s.",
2007*0fca6ea1SDimitry Andric                                      DW_OP_value_to_name(op));
2008fe6060f1SDimitry Andric     }
2009fe6060f1SDimitry Andric 
20100b57cec5SDimitry Andric     // OPCODE: DW_OP_push_object_address
20110b57cec5SDimitry Andric     // OPERANDS: none
20120b57cec5SDimitry Andric     // DESCRIPTION: Pushes the address of the object currently being
20130b57cec5SDimitry Andric     // evaluated as part of evaluation of a user presented expression. This
20140b57cec5SDimitry Andric     // object may correspond to an independent variable described by its own
20150b57cec5SDimitry Andric     // DIE or it may be a component of an array, structure, or class whose
20160b57cec5SDimitry Andric     // address has been dynamically determined by an earlier step during user
20170b57cec5SDimitry Andric     // expression evaluation.
20180b57cec5SDimitry Andric     case DW_OP_push_object_address:
20190b57cec5SDimitry Andric       if (object_address_ptr)
20200b57cec5SDimitry Andric         stack.push_back(*object_address_ptr);
20210b57cec5SDimitry Andric       else {
2022*0fca6ea1SDimitry Andric         return llvm::createStringError("DW_OP_push_object_address used without "
20230b57cec5SDimitry Andric                                        "specifying an object address");
20240b57cec5SDimitry Andric       }
20250b57cec5SDimitry Andric       break;
20260b57cec5SDimitry Andric 
20270b57cec5SDimitry Andric     // OPCODE: DW_OP_call2
20280b57cec5SDimitry Andric     // OPERANDS:
20290b57cec5SDimitry Andric     //      uint16_t compile unit relative offset of a DIE
20300b57cec5SDimitry Andric     // DESCRIPTION: Performs subroutine calls during evaluation
20310b57cec5SDimitry Andric     // of a DWARF expression. The operand is the 2-byte unsigned offset of a
20320b57cec5SDimitry Andric     // debugging information entry in the current compilation unit.
20330b57cec5SDimitry Andric     //
20340b57cec5SDimitry Andric     // Operand interpretation is exactly like that for DW_FORM_ref2.
20350b57cec5SDimitry Andric     //
20360b57cec5SDimitry Andric     // This operation transfers control of DWARF expression evaluation to the
20370b57cec5SDimitry Andric     // DW_AT_location attribute of the referenced DIE. If there is no such
20380b57cec5SDimitry Andric     // attribute, then there is no effect. Execution of the DWARF expression of
20390b57cec5SDimitry Andric     // a DW_AT_location attribute may add to and/or remove from values on the
20400b57cec5SDimitry Andric     // stack. Execution returns to the point following the call when the end of
20410b57cec5SDimitry Andric     // the attribute is reached. Values on the stack at the time of the call
20420b57cec5SDimitry Andric     // may be used as parameters by the called expression and values left on
20430b57cec5SDimitry Andric     // the stack by the called expression may be used as return values by prior
20440b57cec5SDimitry Andric     // agreement between the calling and called expressions.
20450b57cec5SDimitry Andric     case DW_OP_call2:
2046*0fca6ea1SDimitry Andric       return llvm::createStringError("unimplemented opcode DW_OP_call2");
20470b57cec5SDimitry Andric     // OPCODE: DW_OP_call4
20480b57cec5SDimitry Andric     // OPERANDS: 1
20490b57cec5SDimitry Andric     //      uint32_t compile unit relative offset of a DIE
20500b57cec5SDimitry Andric     // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
20510b57cec5SDimitry Andric     // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of
20520b57cec5SDimitry Andric     // a debugging information entry in  the current compilation unit.
20530b57cec5SDimitry Andric     //
20540b57cec5SDimitry Andric     // Operand interpretation DW_OP_call4 is exactly like that for
20550b57cec5SDimitry Andric     // DW_FORM_ref4.
20560b57cec5SDimitry Andric     //
20570b57cec5SDimitry Andric     // This operation transfers control of DWARF expression evaluation to the
20580b57cec5SDimitry Andric     // DW_AT_location attribute of the referenced DIE. If there is no such
20590b57cec5SDimitry Andric     // attribute, then there is no effect. Execution of the DWARF expression of
20600b57cec5SDimitry Andric     // a DW_AT_location attribute may add to and/or remove from values on the
20610b57cec5SDimitry Andric     // stack. Execution returns to the point following the call when the end of
20620b57cec5SDimitry Andric     // the attribute is reached. Values on the stack at the time of the call
20630b57cec5SDimitry Andric     // may be used as parameters by the called expression and values left on
20640b57cec5SDimitry Andric     // the stack by the called expression may be used as return values by prior
20650b57cec5SDimitry Andric     // agreement between the calling and called expressions.
20660b57cec5SDimitry Andric     case DW_OP_call4:
2067*0fca6ea1SDimitry Andric       return llvm::createStringError("unimplemented opcode DW_OP_call4");
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric     // OPCODE: DW_OP_stack_value
20700b57cec5SDimitry Andric     // OPERANDS: None
20710b57cec5SDimitry Andric     // DESCRIPTION: Specifies that the object does not exist in memory but
20720b57cec5SDimitry Andric     // rather is a constant value.  The value from the top of the stack is the
20730b57cec5SDimitry Andric     // value to be used.  This is the actual object value and not the location.
20740b57cec5SDimitry Andric     case DW_OP_stack_value:
2075fe6060f1SDimitry Andric       dwarf4_location_description_kind = Implicit;
2076fe6060f1SDimitry Andric       stack.back().SetValueType(Value::ValueType::Scalar);
20770b57cec5SDimitry Andric       break;
20780b57cec5SDimitry Andric 
20799dba64beSDimitry Andric     // OPCODE: DW_OP_convert
20809dba64beSDimitry Andric     // OPERANDS: 1
20819dba64beSDimitry Andric     //      A ULEB128 that is either a DIE offset of a
20829dba64beSDimitry Andric     //      DW_TAG_base_type or 0 for the generic (pointer-sized) type.
20839dba64beSDimitry Andric     //
20849dba64beSDimitry Andric     // DESCRIPTION: Pop the top stack element, convert it to a
20859dba64beSDimitry Andric     // different type, and push the result.
20869dba64beSDimitry Andric     case DW_OP_convert: {
20879dba64beSDimitry Andric       const uint64_t die_offset = opcodes.GetULEB128(&offset);
20889dba64beSDimitry Andric       uint64_t bit_size;
20895ffd83dbSDimitry Andric       bool sign;
20909dba64beSDimitry Andric       if (die_offset == 0) {
20919dba64beSDimitry Andric         // The generic type has the size of an address on the target
20929dba64beSDimitry Andric         // machine and an unspecified signedness. Scalar has no
20939dba64beSDimitry Andric         // "unspecified signedness", so we use unsigned types.
2094*0fca6ea1SDimitry Andric         if (!module_sp)
2095*0fca6ea1SDimitry Andric           return llvm::createStringError("no module");
20965ffd83dbSDimitry Andric         sign = false;
20979dba64beSDimitry Andric         bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
2098*0fca6ea1SDimitry Andric         if (!bit_size)
2099*0fca6ea1SDimitry Andric           return llvm::createStringError("unspecified architecture");
21009dba64beSDimitry Andric       } else {
2101bdd1243dSDimitry Andric         // Retrieve the type DIE that the value is being converted to. This
2102bdd1243dSDimitry Andric         // offset is compile unit relative so we need to fix it up.
2103bdd1243dSDimitry Andric         const uint64_t abs_die_offset = die_offset +  dwarf_cu->GetOffset();
21049dba64beSDimitry Andric         // FIXME: the constness has annoying ripple effects.
2105bdd1243dSDimitry Andric         DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
2106*0fca6ea1SDimitry Andric         if (!die)
2107*0fca6ea1SDimitry Andric           return llvm::createStringError(
2108*0fca6ea1SDimitry Andric               "cannot resolve DW_OP_convert type DIE");
21099dba64beSDimitry Andric         uint64_t encoding =
21109dba64beSDimitry Andric             die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
21119dba64beSDimitry Andric         bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
21129dba64beSDimitry Andric         if (!bit_size)
21139dba64beSDimitry Andric           bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
2114*0fca6ea1SDimitry Andric         if (!bit_size)
2115*0fca6ea1SDimitry Andric           return llvm::createStringError(
2116*0fca6ea1SDimitry Andric               "unsupported type size in DW_OP_convert");
21179dba64beSDimitry Andric         switch (encoding) {
21189dba64beSDimitry Andric         case DW_ATE_signed:
21199dba64beSDimitry Andric         case DW_ATE_signed_char:
21205ffd83dbSDimitry Andric           sign = true;
21219dba64beSDimitry Andric           break;
21229dba64beSDimitry Andric         case DW_ATE_unsigned:
21239dba64beSDimitry Andric         case DW_ATE_unsigned_char:
21245ffd83dbSDimitry Andric           sign = false;
21259dba64beSDimitry Andric           break;
21269dba64beSDimitry Andric         default:
2127*0fca6ea1SDimitry Andric           return llvm::createStringError(
2128*0fca6ea1SDimitry Andric               "unsupported encoding in DW_OP_convert");
21299dba64beSDimitry Andric         }
21309dba64beSDimitry Andric       }
21319dba64beSDimitry Andric       Scalar &top = stack.back().ResolveValue(exe_ctx);
21325ffd83dbSDimitry Andric       top.TruncOrExtendTo(bit_size, sign);
21339dba64beSDimitry Andric       break;
21349dba64beSDimitry Andric     }
21359dba64beSDimitry Andric 
21360b57cec5SDimitry Andric     // OPCODE: DW_OP_call_frame_cfa
21370b57cec5SDimitry Andric     // OPERANDS: None
21380b57cec5SDimitry Andric     // DESCRIPTION: Specifies a DWARF expression that pushes the value of
21390b57cec5SDimitry Andric     // the canonical frame address consistent with the call frame information
21400b57cec5SDimitry Andric     // located in .debug_frame (or in the FDEs of the eh_frame section).
21410b57cec5SDimitry Andric     case DW_OP_call_frame_cfa:
21420b57cec5SDimitry Andric       if (frame) {
21430b57cec5SDimitry Andric         // Note that we don't have to parse FDEs because this DWARF expression
21440b57cec5SDimitry Andric         // is commonly evaluated with a valid stack frame.
21450b57cec5SDimitry Andric         StackID id = frame->GetStackID();
21460b57cec5SDimitry Andric         addr_t cfa = id.GetCallFrameAddress();
21470b57cec5SDimitry Andric         if (cfa != LLDB_INVALID_ADDRESS) {
21480b57cec5SDimitry Andric           stack.push_back(Scalar(cfa));
2149fe6060f1SDimitry Andric           stack.back().SetValueType(Value::ValueType::LoadAddress);
21500b57cec5SDimitry Andric         } else {
2151*0fca6ea1SDimitry Andric           return llvm::createStringError(
2152*0fca6ea1SDimitry Andric               "stack frame does not include a canonical "
2153*0fca6ea1SDimitry Andric               "frame address for DW_OP_call_frame_cfa "
2154*0fca6ea1SDimitry Andric               "opcode");
2155*0fca6ea1SDimitry Andric         }
2156*0fca6ea1SDimitry Andric       } else {
2157*0fca6ea1SDimitry Andric         return llvm::createStringError("unvalid stack frame in context for "
2158*0fca6ea1SDimitry Andric                                        "DW_OP_call_frame_cfa opcode");
21590b57cec5SDimitry Andric       }
21600b57cec5SDimitry Andric       break;
21610b57cec5SDimitry Andric 
21620b57cec5SDimitry Andric     // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension
21630b57cec5SDimitry Andric     // opcode, DW_OP_GNU_push_tls_address)
21640b57cec5SDimitry Andric     // OPERANDS: none
21650b57cec5SDimitry Andric     // DESCRIPTION: Pops a TLS offset from the stack, converts it to
21660b57cec5SDimitry Andric     // an address in the current thread's thread-local storage block, and
21670b57cec5SDimitry Andric     // pushes it on the stack.
21680b57cec5SDimitry Andric     case DW_OP_form_tls_address:
21690b57cec5SDimitry Andric     case DW_OP_GNU_push_tls_address: {
21700b57cec5SDimitry Andric       if (stack.size() < 1) {
21710b57cec5SDimitry Andric         if (op == DW_OP_form_tls_address)
2172*0fca6ea1SDimitry Andric           return llvm::createStringError(
2173*0fca6ea1SDimitry Andric               "DW_OP_form_tls_address needs an argument");
21740b57cec5SDimitry Andric         else
2175*0fca6ea1SDimitry Andric           return llvm::createStringError(
2176*0fca6ea1SDimitry Andric               "DW_OP_GNU_push_tls_address needs an argument");
21770b57cec5SDimitry Andric       }
21780b57cec5SDimitry Andric 
2179*0fca6ea1SDimitry Andric       if (!exe_ctx || !module_sp)
2180*0fca6ea1SDimitry Andric         return llvm::createStringError("no context to evaluate TLS within");
21810b57cec5SDimitry Andric 
21820b57cec5SDimitry Andric       Thread *thread = exe_ctx->GetThreadPtr();
2183*0fca6ea1SDimitry Andric       if (!thread)
2184*0fca6ea1SDimitry Andric         return llvm::createStringError("no thread to evaluate TLS within");
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric       // Lookup the TLS block address for this thread and module.
21870b57cec5SDimitry Andric       const addr_t tls_file_addr =
21880b57cec5SDimitry Andric           stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
21890b57cec5SDimitry Andric       const addr_t tls_load_addr =
21900b57cec5SDimitry Andric           thread->GetThreadLocalData(module_sp, tls_file_addr);
21910b57cec5SDimitry Andric 
2192*0fca6ea1SDimitry Andric       if (tls_load_addr == LLDB_INVALID_ADDRESS)
2193*0fca6ea1SDimitry Andric         return llvm::createStringError(
2194*0fca6ea1SDimitry Andric             "no TLS data currently exists for this thread");
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric       stack.back().GetScalar() = tls_load_addr;
2197fe6060f1SDimitry Andric       stack.back().SetValueType(Value::ValueType::LoadAddress);
21980b57cec5SDimitry Andric     } break;
21990b57cec5SDimitry Andric 
22000b57cec5SDimitry Andric     // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
22010b57cec5SDimitry Andric     // OPERANDS: 1
22020b57cec5SDimitry Andric     //      ULEB128: index to the .debug_addr section
22030b57cec5SDimitry Andric     // DESCRIPTION: Pushes an address to the stack from the .debug_addr
22040b57cec5SDimitry Andric     // section with the base address specified by the DW_AT_addr_base attribute
22050b57cec5SDimitry Andric     // and the 0 based index is the ULEB128 encoded index.
22060b57cec5SDimitry Andric     case DW_OP_addrx:
22070b57cec5SDimitry Andric     case DW_OP_GNU_addr_index: {
2208*0fca6ea1SDimitry Andric       if (!dwarf_cu)
2209*0fca6ea1SDimitry Andric         return llvm::createStringError("DW_OP_GNU_addr_index found without a "
22100b57cec5SDimitry Andric                                        "compile unit being specified");
22110b57cec5SDimitry Andric       uint64_t index = opcodes.GetULEB128(&offset);
2212753f127fSDimitry Andric       lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
22130b57cec5SDimitry Andric       stack.push_back(Scalar(value));
2214bdd1243dSDimitry Andric       if (target &&
2215bdd1243dSDimitry Andric           target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
2216bdd1243dSDimitry Andric         // wasm file sections aren't mapped into memory, therefore addresses can
2217bdd1243dSDimitry Andric         // never point into a file section and are always LoadAddresses.
2218bdd1243dSDimitry Andric         stack.back().SetValueType(Value::ValueType::LoadAddress);
2219bdd1243dSDimitry Andric       } else {
2220fe6060f1SDimitry Andric         stack.back().SetValueType(Value::ValueType::FileAddress);
2221bdd1243dSDimitry Andric       }
22220b57cec5SDimitry Andric     } break;
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric     // OPCODE: DW_OP_GNU_const_index
22250b57cec5SDimitry Andric     // OPERANDS: 1
22260b57cec5SDimitry Andric     //      ULEB128: index to the .debug_addr section
22270b57cec5SDimitry Andric     // DESCRIPTION: Pushes an constant with the size of a machine address to
22280b57cec5SDimitry Andric     // the stack from the .debug_addr section with the base address specified
22290b57cec5SDimitry Andric     // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128
22300b57cec5SDimitry Andric     // encoded index.
22310b57cec5SDimitry Andric     case DW_OP_GNU_const_index: {
22320b57cec5SDimitry Andric       if (!dwarf_cu) {
2233*0fca6ea1SDimitry Andric         return llvm::createStringError("DW_OP_GNU_const_index found without a "
22340b57cec5SDimitry Andric                                        "compile unit being specified");
22350b57cec5SDimitry Andric       }
22360b57cec5SDimitry Andric       uint64_t index = opcodes.GetULEB128(&offset);
2237753f127fSDimitry Andric       lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
22380b57cec5SDimitry Andric       stack.push_back(Scalar(value));
22390b57cec5SDimitry Andric     } break;
22400b57cec5SDimitry Andric 
22415ffd83dbSDimitry Andric     case DW_OP_GNU_entry_value:
22429dba64beSDimitry Andric     case DW_OP_entry_value: {
2243*0fca6ea1SDimitry Andric       if (llvm::Error err = Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx,
2244*0fca6ea1SDimitry Andric                                                        opcodes, offset, log))
2245*0fca6ea1SDimitry Andric         return llvm::createStringError(
2246*0fca6ea1SDimitry Andric             "could not evaluate DW_OP_entry_value: %s",
2247*0fca6ea1SDimitry Andric             llvm::toString(std::move(err)).c_str());
22489dba64beSDimitry Andric       break;
22499dba64beSDimitry Andric     }
22509dba64beSDimitry Andric 
22510b57cec5SDimitry Andric     default:
2252bdd1243dSDimitry Andric       if (dwarf_cu) {
2253bdd1243dSDimitry Andric         if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode(
2254bdd1243dSDimitry Andric                 op, opcodes, offset, stack)) {
2255bdd1243dSDimitry Andric           break;
2256bdd1243dSDimitry Andric         }
2257bdd1243dSDimitry Andric       }
2258*0fca6ea1SDimitry Andric       return llvm::createStringError(llvm::formatv(
2259*0fca6ea1SDimitry Andric           "Unhandled opcode {0} in DWARFExpression", LocationAtom(op)));
22600b57cec5SDimitry Andric     }
22610b57cec5SDimitry Andric   }
22620b57cec5SDimitry Andric 
22630b57cec5SDimitry Andric   if (stack.empty()) {
22640b57cec5SDimitry Andric     // Nothing on the stack, check if we created a piece value from DW_OP_piece
22650b57cec5SDimitry Andric     // or DW_OP_bit_piece opcodes
2266*0fca6ea1SDimitry Andric     if (pieces.GetBuffer().GetByteSize())
2267*0fca6ea1SDimitry Andric       return pieces;
2268*0fca6ea1SDimitry Andric 
2269*0fca6ea1SDimitry Andric     return llvm::createStringError("stack empty after evaluation");
22700b57cec5SDimitry Andric   }
2271fe6060f1SDimitry Andric 
2272fe6060f1SDimitry Andric   UpdateValueTypeFromLocationDescription(
2273fe6060f1SDimitry Andric       log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
2274fe6060f1SDimitry Andric 
22750b57cec5SDimitry Andric   if (log && log->GetVerbose()) {
22760b57cec5SDimitry Andric     size_t count = stack.size();
2277fe6060f1SDimitry Andric     LLDB_LOGF(log,
2278fe6060f1SDimitry Andric               "Stack after operation has %" PRIu64 " values:", (uint64_t)count);
22790b57cec5SDimitry Andric     for (size_t i = 0; i < count; ++i) {
22800b57cec5SDimitry Andric       StreamString new_value;
22810b57cec5SDimitry Andric       new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
22820b57cec5SDimitry Andric       stack[i].Dump(&new_value);
22839dba64beSDimitry Andric       LLDB_LOGF(log, "  %s", new_value.GetData());
22840b57cec5SDimitry Andric     }
22850b57cec5SDimitry Andric   }
2286*0fca6ea1SDimitry Andric   return stack.back();
22870b57cec5SDimitry Andric }
22880b57cec5SDimitry Andric 
2289753f127fSDimitry Andric bool DWARFExpression::ParseDWARFLocationList(
2290753f127fSDimitry Andric     const DWARFUnit *dwarf_cu, const DataExtractor &data,
2291753f127fSDimitry Andric     DWARFExpressionList *location_list) {
2292753f127fSDimitry Andric   location_list->Clear();
2293480093f4SDimitry Andric   std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
2294753f127fSDimitry Andric       dwarf_cu->GetLocationTable(data);
2295753f127fSDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
2296480093f4SDimitry Andric   auto lookup_addr =
2297bdd1243dSDimitry Andric       [&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> {
2298753f127fSDimitry Andric     addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
2299480093f4SDimitry Andric     if (address == LLDB_INVALID_ADDRESS)
2300bdd1243dSDimitry Andric       return std::nullopt;
2301480093f4SDimitry Andric     return llvm::object::SectionedAddress{address};
2302480093f4SDimitry Andric   };
2303480093f4SDimitry Andric   auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {
2304480093f4SDimitry Andric     if (!loc) {
2305480093f4SDimitry Andric       LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
23060b57cec5SDimitry Andric       return true;
23070b57cec5SDimitry Andric     }
2308753f127fSDimitry Andric     auto buffer_sp =
2309753f127fSDimitry Andric         std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
2310753f127fSDimitry Andric     DWARFExpression expr = DWARFExpression(DataExtractor(
2311753f127fSDimitry Andric         buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));
2312753f127fSDimitry Andric     location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
2313753f127fSDimitry Andric     return true;
2314480093f4SDimitry Andric   };
231581ad6265SDimitry Andric   llvm::Error error = loctable_up->visitAbsoluteLocationList(
2316753f127fSDimitry Andric       0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
2317480093f4SDimitry Andric       lookup_addr, process_list);
2318753f127fSDimitry Andric   location_list->Sort();
231981ad6265SDimitry Andric   if (error) {
232081ad6265SDimitry Andric     LLDB_LOG_ERROR(log, std::move(error), "{0}");
232181ad6265SDimitry Andric     return false;
232281ad6265SDimitry Andric   }
232381ad6265SDimitry Andric   return true;
232481ad6265SDimitry Andric }
232581ad6265SDimitry Andric 
2326753f127fSDimitry Andric bool DWARFExpression::MatchesOperand(
2327753f127fSDimitry Andric     StackFrame &frame, const Instruction::Operand &operand) const {
23280b57cec5SDimitry Andric   using namespace OperandMatchers;
23290b57cec5SDimitry Andric 
23300b57cec5SDimitry Andric   RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
23310b57cec5SDimitry Andric   if (!reg_ctx_sp) {
23320b57cec5SDimitry Andric     return false;
23330b57cec5SDimitry Andric   }
23340b57cec5SDimitry Andric 
2335753f127fSDimitry Andric   DataExtractor opcodes(m_data);
2336480093f4SDimitry Andric 
2337480093f4SDimitry Andric   lldb::offset_t op_offset = 0;
23380b57cec5SDimitry Andric   uint8_t opcode = opcodes.GetU8(&op_offset);
23390b57cec5SDimitry Andric 
23400b57cec5SDimitry Andric   if (opcode == DW_OP_fbreg) {
23410b57cec5SDimitry Andric     int64_t offset = opcodes.GetSLEB128(&op_offset);
23420b57cec5SDimitry Andric 
2343753f127fSDimitry Andric     DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);
23440b57cec5SDimitry Andric     if (!fb_expr) {
23450b57cec5SDimitry Andric       return false;
23460b57cec5SDimitry Andric     }
23470b57cec5SDimitry Andric 
23480b57cec5SDimitry Andric     auto recurse = [&frame, fb_expr](const Instruction::Operand &child) {
23490b57cec5SDimitry Andric       return fb_expr->MatchesOperand(frame, child);
23500b57cec5SDimitry Andric     };
23510b57cec5SDimitry Andric 
23520b57cec5SDimitry Andric     if (!offset &&
23530b57cec5SDimitry Andric         MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
23540b57cec5SDimitry Andric                      recurse)(operand)) {
23550b57cec5SDimitry Andric       return true;
23560b57cec5SDimitry Andric     }
23570b57cec5SDimitry Andric 
23580b57cec5SDimitry Andric     return MatchUnaryOp(
23590b57cec5SDimitry Andric         MatchOpType(Instruction::Operand::Type::Dereference),
23600b57cec5SDimitry Andric         MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
23610b57cec5SDimitry Andric                       MatchImmOp(offset), recurse))(operand);
23620b57cec5SDimitry Andric   }
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric   bool dereference = false;
23650b57cec5SDimitry Andric   const RegisterInfo *reg = nullptr;
23660b57cec5SDimitry Andric   int64_t offset = 0;
23670b57cec5SDimitry Andric 
23680b57cec5SDimitry Andric   if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) {
23690b57cec5SDimitry Andric     reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0);
23700b57cec5SDimitry Andric   } else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) {
23710b57cec5SDimitry Andric     offset = opcodes.GetSLEB128(&op_offset);
23720b57cec5SDimitry Andric     reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_breg0);
23730b57cec5SDimitry Andric   } else if (opcode == DW_OP_regx) {
23740b57cec5SDimitry Andric     uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));
23750b57cec5SDimitry Andric     reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);
23760b57cec5SDimitry Andric   } else if (opcode == DW_OP_bregx) {
23770b57cec5SDimitry Andric     uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));
23780b57cec5SDimitry Andric     offset = opcodes.GetSLEB128(&op_offset);
23790b57cec5SDimitry Andric     reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);
23800b57cec5SDimitry Andric   } else {
23810b57cec5SDimitry Andric     return false;
23820b57cec5SDimitry Andric   }
23830b57cec5SDimitry Andric 
23840b57cec5SDimitry Andric   if (!reg) {
23850b57cec5SDimitry Andric     return false;
23860b57cec5SDimitry Andric   }
23870b57cec5SDimitry Andric 
23880b57cec5SDimitry Andric   if (dereference) {
23890b57cec5SDimitry Andric     if (!offset &&
23900b57cec5SDimitry Andric         MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
23910b57cec5SDimitry Andric                      MatchRegOp(*reg))(operand)) {
23920b57cec5SDimitry Andric       return true;
23930b57cec5SDimitry Andric     }
23940b57cec5SDimitry Andric 
23950b57cec5SDimitry Andric     return MatchUnaryOp(
23960b57cec5SDimitry Andric         MatchOpType(Instruction::Operand::Type::Dereference),
23970b57cec5SDimitry Andric         MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
23980b57cec5SDimitry Andric                       MatchRegOp(*reg),
23990b57cec5SDimitry Andric                       MatchImmOp(offset)))(operand);
24000b57cec5SDimitry Andric   } else {
24010b57cec5SDimitry Andric     return MatchRegOp(*reg)(operand);
24020b57cec5SDimitry Andric   }
24030b57cec5SDimitry Andric }
2404