Path: blob/main/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp
39587 views
//===-- DWARFExpression.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Expression/DWARFExpression.h"910#include <cinttypes>1112#include <optional>13#include <vector>1415#include "lldb/Core/Module.h"16#include "lldb/Core/Value.h"17#include "lldb/Core/dwarf.h"18#include "lldb/Utility/DataEncoder.h"19#include "lldb/Utility/LLDBLog.h"20#include "lldb/Utility/Log.h"21#include "lldb/Utility/RegisterValue.h"22#include "lldb/Utility/Scalar.h"23#include "lldb/Utility/StreamString.h"24#include "lldb/Utility/VMRange.h"2526#include "lldb/Host/Host.h"27#include "lldb/Utility/Endian.h"2829#include "lldb/Symbol/Function.h"3031#include "lldb/Target/ABI.h"32#include "lldb/Target/ExecutionContext.h"33#include "lldb/Target/Process.h"34#include "lldb/Target/RegisterContext.h"35#include "lldb/Target/StackFrame.h"36#include "lldb/Target/StackID.h"37#include "lldb/Target/Target.h"38#include "lldb/Target/Thread.h"39#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"40#include "llvm/DebugInfo/DWARF/DWARFExpression.h"4142#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"4344using namespace lldb;45using namespace lldb_private;46using namespace lldb_private::dwarf;47using namespace lldb_private::plugin::dwarf;4849// DWARFExpression constructor50DWARFExpression::DWARFExpression() : m_data() {}5152DWARFExpression::DWARFExpression(const DataExtractor &data) : m_data(data) {}5354// Destructor55DWARFExpression::~DWARFExpression() = default;5657bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; }5859void DWARFExpression::UpdateValue(uint64_t const_value,60lldb::offset_t const_value_byte_size,61uint8_t addr_byte_size) {62if (!const_value_byte_size)63return;6465m_data.SetData(66DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size)));67m_data.SetByteOrder(endian::InlHostByteOrder());68m_data.SetAddressByteSize(addr_byte_size);69}7071void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,72ABI *abi) const {73auto *MCRegInfo = abi ? &abi->GetMCRegisterInfo() : nullptr;74auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum,75bool IsEH) -> llvm::StringRef {76if (!MCRegInfo)77return {};78if (std::optional<unsigned> LLVMRegNum =79MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))80if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))81return llvm::StringRef(RegName);82return {};83};84llvm::DIDumpOptions DumpOpts;85DumpOpts.GetNameForDWARFReg = GetRegName;86llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())87.print(s->AsRawOstream(), DumpOpts, nullptr);88}8990RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }9192void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {93m_reg_kind = reg_kind;94}9596static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,97lldb::RegisterKind reg_kind,98uint32_t reg_num, Value &value) {99if (reg_ctx == nullptr)100return llvm::createStringError("no register context in frame");101102const uint32_t native_reg =103reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);104if (native_reg == LLDB_INVALID_REGNUM)105return llvm::createStringError(106"unable to convert register kind=%u reg_num=%u to a native "107"register number",108reg_kind, reg_num);109110const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg);111RegisterValue reg_value;112if (reg_ctx->ReadRegister(reg_info, reg_value)) {113if (reg_value.GetScalarValue(value.GetScalar())) {114value.SetValueType(Value::ValueType::Scalar);115value.SetContext(Value::ContextType::RegisterInfo,116const_cast<RegisterInfo *>(reg_info));117return llvm::Error::success();118}119120// If we get this error, then we need to implement a value buffer in121// the dwarf expression evaluation function...122return llvm::createStringError(123"register %s can't be converted to a scalar value", reg_info->name);124}125126return llvm::createStringError("register %s is not available",127reg_info->name);128}129130/// Return the length in bytes of the set of operands for \p op. No guarantees131/// are made on the state of \p data after this call.132static offset_t GetOpcodeDataSize(const DataExtractor &data,133const lldb::offset_t data_offset,134const uint8_t op, const DWARFUnit *dwarf_cu) {135lldb::offset_t offset = data_offset;136switch (op) {137case DW_OP_addr:138case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3)139return data.GetAddressByteSize();140141// Opcodes with no arguments142case DW_OP_deref: // 0x06143case DW_OP_dup: // 0x12144case DW_OP_drop: // 0x13145case DW_OP_over: // 0x14146case DW_OP_swap: // 0x16147case DW_OP_rot: // 0x17148case DW_OP_xderef: // 0x18149case DW_OP_abs: // 0x19150case DW_OP_and: // 0x1a151case DW_OP_div: // 0x1b152case DW_OP_minus: // 0x1c153case DW_OP_mod: // 0x1d154case DW_OP_mul: // 0x1e155case DW_OP_neg: // 0x1f156case DW_OP_not: // 0x20157case DW_OP_or: // 0x21158case DW_OP_plus: // 0x22159case DW_OP_shl: // 0x24160case DW_OP_shr: // 0x25161case DW_OP_shra: // 0x26162case DW_OP_xor: // 0x27163case DW_OP_eq: // 0x29164case DW_OP_ge: // 0x2a165case DW_OP_gt: // 0x2b166case DW_OP_le: // 0x2c167case DW_OP_lt: // 0x2d168case DW_OP_ne: // 0x2e169case DW_OP_lit0: // 0x30170case DW_OP_lit1: // 0x31171case DW_OP_lit2: // 0x32172case DW_OP_lit3: // 0x33173case DW_OP_lit4: // 0x34174case DW_OP_lit5: // 0x35175case DW_OP_lit6: // 0x36176case DW_OP_lit7: // 0x37177case DW_OP_lit8: // 0x38178case DW_OP_lit9: // 0x39179case DW_OP_lit10: // 0x3A180case DW_OP_lit11: // 0x3B181case DW_OP_lit12: // 0x3C182case DW_OP_lit13: // 0x3D183case DW_OP_lit14: // 0x3E184case DW_OP_lit15: // 0x3F185case DW_OP_lit16: // 0x40186case DW_OP_lit17: // 0x41187case DW_OP_lit18: // 0x42188case DW_OP_lit19: // 0x43189case DW_OP_lit20: // 0x44190case DW_OP_lit21: // 0x45191case DW_OP_lit22: // 0x46192case DW_OP_lit23: // 0x47193case DW_OP_lit24: // 0x48194case DW_OP_lit25: // 0x49195case DW_OP_lit26: // 0x4A196case DW_OP_lit27: // 0x4B197case DW_OP_lit28: // 0x4C198case DW_OP_lit29: // 0x4D199case DW_OP_lit30: // 0x4E200case DW_OP_lit31: // 0x4f201case DW_OP_reg0: // 0x50202case DW_OP_reg1: // 0x51203case DW_OP_reg2: // 0x52204case DW_OP_reg3: // 0x53205case DW_OP_reg4: // 0x54206case DW_OP_reg5: // 0x55207case DW_OP_reg6: // 0x56208case DW_OP_reg7: // 0x57209case DW_OP_reg8: // 0x58210case DW_OP_reg9: // 0x59211case DW_OP_reg10: // 0x5A212case DW_OP_reg11: // 0x5B213case DW_OP_reg12: // 0x5C214case DW_OP_reg13: // 0x5D215case DW_OP_reg14: // 0x5E216case DW_OP_reg15: // 0x5F217case DW_OP_reg16: // 0x60218case DW_OP_reg17: // 0x61219case DW_OP_reg18: // 0x62220case DW_OP_reg19: // 0x63221case DW_OP_reg20: // 0x64222case DW_OP_reg21: // 0x65223case DW_OP_reg22: // 0x66224case DW_OP_reg23: // 0x67225case DW_OP_reg24: // 0x68226case DW_OP_reg25: // 0x69227case DW_OP_reg26: // 0x6A228case DW_OP_reg27: // 0x6B229case DW_OP_reg28: // 0x6C230case DW_OP_reg29: // 0x6D231case DW_OP_reg30: // 0x6E232case DW_OP_reg31: // 0x6F233case DW_OP_nop: // 0x96234case DW_OP_push_object_address: // 0x97 DWARF3235case DW_OP_form_tls_address: // 0x9b DWARF3236case DW_OP_call_frame_cfa: // 0x9c DWARF3237case DW_OP_stack_value: // 0x9f DWARF4238case DW_OP_GNU_push_tls_address: // 0xe0 GNU extension239return 0;240241// Opcodes with a single 1 byte arguments242case DW_OP_const1u: // 0x08 1 1-byte constant243case DW_OP_const1s: // 0x09 1 1-byte constant244case DW_OP_pick: // 0x15 1 1-byte stack index245case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved246case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved247return 1;248249// Opcodes with a single 2 byte arguments250case DW_OP_const2u: // 0x0a 1 2-byte constant251case DW_OP_const2s: // 0x0b 1 2-byte constant252case DW_OP_skip: // 0x2f 1 signed 2-byte constant253case DW_OP_bra: // 0x28 1 signed 2-byte constant254case DW_OP_call2: // 0x98 1 2-byte offset of DIE (DWARF3)255return 2;256257// Opcodes with a single 4 byte arguments258case DW_OP_const4u: // 0x0c 1 4-byte constant259case DW_OP_const4s: // 0x0d 1 4-byte constant260case DW_OP_call4: // 0x99 1 4-byte offset of DIE (DWARF3)261return 4;262263// Opcodes with a single 8 byte arguments264case DW_OP_const8u: // 0x0e 1 8-byte constant265case DW_OP_const8s: // 0x0f 1 8-byte constant266return 8;267268// All opcodes that have a single ULEB (signed or unsigned) argument269case DW_OP_addrx: // 0xa1 1 ULEB128 index270case DW_OP_constu: // 0x10 1 ULEB128 constant271case DW_OP_consts: // 0x11 1 SLEB128 constant272case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend273case DW_OP_breg0: // 0x70 1 ULEB128 register274case DW_OP_breg1: // 0x71 1 ULEB128 register275case DW_OP_breg2: // 0x72 1 ULEB128 register276case DW_OP_breg3: // 0x73 1 ULEB128 register277case DW_OP_breg4: // 0x74 1 ULEB128 register278case DW_OP_breg5: // 0x75 1 ULEB128 register279case DW_OP_breg6: // 0x76 1 ULEB128 register280case DW_OP_breg7: // 0x77 1 ULEB128 register281case DW_OP_breg8: // 0x78 1 ULEB128 register282case DW_OP_breg9: // 0x79 1 ULEB128 register283case DW_OP_breg10: // 0x7a 1 ULEB128 register284case DW_OP_breg11: // 0x7b 1 ULEB128 register285case DW_OP_breg12: // 0x7c 1 ULEB128 register286case DW_OP_breg13: // 0x7d 1 ULEB128 register287case DW_OP_breg14: // 0x7e 1 ULEB128 register288case DW_OP_breg15: // 0x7f 1 ULEB128 register289case DW_OP_breg16: // 0x80 1 ULEB128 register290case DW_OP_breg17: // 0x81 1 ULEB128 register291case DW_OP_breg18: // 0x82 1 ULEB128 register292case DW_OP_breg19: // 0x83 1 ULEB128 register293case DW_OP_breg20: // 0x84 1 ULEB128 register294case DW_OP_breg21: // 0x85 1 ULEB128 register295case DW_OP_breg22: // 0x86 1 ULEB128 register296case DW_OP_breg23: // 0x87 1 ULEB128 register297case DW_OP_breg24: // 0x88 1 ULEB128 register298case DW_OP_breg25: // 0x89 1 ULEB128 register299case DW_OP_breg26: // 0x8a 1 ULEB128 register300case DW_OP_breg27: // 0x8b 1 ULEB128 register301case DW_OP_breg28: // 0x8c 1 ULEB128 register302case DW_OP_breg29: // 0x8d 1 ULEB128 register303case DW_OP_breg30: // 0x8e 1 ULEB128 register304case DW_OP_breg31: // 0x8f 1 ULEB128 register305case DW_OP_regx: // 0x90 1 ULEB128 register306case DW_OP_fbreg: // 0x91 1 SLEB128 offset307case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed308case DW_OP_GNU_addr_index: // 0xfb 1 ULEB128 index309case DW_OP_GNU_const_index: // 0xfc 1 ULEB128 index310data.Skip_LEB128(&offset);311return offset - data_offset;312313// All opcodes that have a 2 ULEB (signed or unsigned) arguments314case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset315case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);316data.Skip_LEB128(&offset);317data.Skip_LEB128(&offset);318return offset - data_offset;319320case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size321// (DWARF4)322{323uint64_t block_len = data.Skip_LEB128(&offset);324offset += block_len;325return offset - data_offset;326}327328case DW_OP_GNU_entry_value:329case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block330{331uint64_t subexpr_len = data.GetULEB128(&offset);332return (offset - data_offset) + subexpr_len;333}334335default:336if (!dwarf_cu) {337return LLDB_INVALID_OFFSET;338}339return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(340data, data_offset, op);341}342}343344lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,345bool &error) const {346error = false;347lldb::offset_t offset = 0;348while (m_data.ValidOffset(offset)) {349const uint8_t op = m_data.GetU8(&offset);350351if (op == DW_OP_addr)352return m_data.GetAddress(&offset);353if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {354uint64_t index = m_data.GetULEB128(&offset);355if (dwarf_cu)356return dwarf_cu->ReadAddressFromDebugAddrSection(index);357error = true;358break;359}360const offset_t op_arg_size =361GetOpcodeDataSize(m_data, offset, op, dwarf_cu);362if (op_arg_size == LLDB_INVALID_OFFSET) {363error = true;364break;365}366offset += op_arg_size;367}368return LLDB_INVALID_ADDRESS;369}370371bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,372lldb::addr_t file_addr) {373lldb::offset_t offset = 0;374while (m_data.ValidOffset(offset)) {375const uint8_t op = m_data.GetU8(&offset);376377if (op == DW_OP_addr) {378const uint32_t addr_byte_size = m_data.GetAddressByteSize();379// We have to make a copy of the data as we don't know if this data is380// from a read only memory mapped buffer, so we duplicate all of the data381// first, then modify it, and if all goes well, we then replace the data382// for this expression383384// Make en encoder that contains a copy of the location expression data385// so we can write the address into the buffer using the correct byte386// order.387DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),388m_data.GetByteOrder(), addr_byte_size);389390// Replace the address in the new buffer391if (encoder.PutAddress(offset, file_addr) == UINT32_MAX)392return false;393394// All went well, so now we can reset the data using a shared pointer to395// the heap data so "m_data" will now correctly manage the heap data.396m_data.SetData(encoder.GetDataBuffer());397return true;398}399if (op == DW_OP_addrx) {400// Replace DW_OP_addrx with DW_OP_addr, since we can't modify the401// read-only debug_addr table.402// Subtract one to account for the opcode.403llvm::ArrayRef data_before_op = m_data.GetData().take_front(offset - 1);404405// Read the addrx index to determine how many bytes it needs.406const lldb::offset_t old_offset = offset;407m_data.GetULEB128(&offset);408if (old_offset == offset)409return false;410llvm::ArrayRef data_after_op = m_data.GetData().drop_front(offset);411412DataEncoder encoder(m_data.GetByteOrder(), m_data.GetAddressByteSize());413encoder.AppendData(data_before_op);414encoder.AppendU8(DW_OP_addr);415encoder.AppendAddress(file_addr);416encoder.AppendData(data_after_op);417m_data.SetData(encoder.GetDataBuffer());418return true;419}420const offset_t op_arg_size =421GetOpcodeDataSize(m_data, offset, op, dwarf_cu);422if (op_arg_size == LLDB_INVALID_OFFSET)423break;424offset += op_arg_size;425}426return false;427}428429bool DWARFExpression::ContainsThreadLocalStorage(430const DWARFUnit *dwarf_cu) const {431lldb::offset_t offset = 0;432while (m_data.ValidOffset(offset)) {433const uint8_t op = m_data.GetU8(&offset);434435if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)436return true;437const offset_t op_arg_size =438GetOpcodeDataSize(m_data, offset, op, dwarf_cu);439if (op_arg_size == LLDB_INVALID_OFFSET)440return false;441offset += op_arg_size;442}443return false;444}445bool DWARFExpression::LinkThreadLocalStorage(446const DWARFUnit *dwarf_cu,447std::function<lldb::addr_t(lldb::addr_t file_addr)> const448&link_address_callback) {449const uint32_t addr_byte_size = m_data.GetAddressByteSize();450// We have to make a copy of the data as we don't know if this data is from a451// read only memory mapped buffer, so we duplicate all of the data first,452// then modify it, and if all goes well, we then replace the data for this453// expression.454// Make en encoder that contains a copy of the location expression data so we455// can write the address into the buffer using the correct byte order.456DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),457m_data.GetByteOrder(), addr_byte_size);458459lldb::offset_t offset = 0;460lldb::offset_t const_offset = 0;461lldb::addr_t const_value = 0;462size_t const_byte_size = 0;463while (m_data.ValidOffset(offset)) {464const uint8_t op = m_data.GetU8(&offset);465466bool decoded_data = false;467switch (op) {468case DW_OP_const4u:469// Remember the const offset in case we later have a470// DW_OP_form_tls_address or DW_OP_GNU_push_tls_address471const_offset = offset;472const_value = m_data.GetU32(&offset);473decoded_data = true;474const_byte_size = 4;475break;476477case DW_OP_const8u:478// Remember the const offset in case we later have a479// DW_OP_form_tls_address or DW_OP_GNU_push_tls_address480const_offset = offset;481const_value = m_data.GetU64(&offset);482decoded_data = true;483const_byte_size = 8;484break;485486case DW_OP_form_tls_address:487case DW_OP_GNU_push_tls_address:488// DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded489// by a file address on the stack. We assume that DW_OP_const4u or490// DW_OP_const8u is used for these values, and we check that the last491// opcode we got before either of these was DW_OP_const4u or492// DW_OP_const8u. If so, then we can link the value accordingly. For493// Darwin, the value in the DW_OP_const4u or DW_OP_const8u is the file494// address of a structure that contains a function pointer, the pthread495// key and the offset into the data pointed to by the pthread key. So we496// must link this address and also set the module of this expression to497// the new_module_sp so we can resolve the file address correctly498if (const_byte_size > 0) {499lldb::addr_t linked_file_addr = link_address_callback(const_value);500if (linked_file_addr == LLDB_INVALID_ADDRESS)501return false;502// Replace the address in the new buffer503if (encoder.PutUnsigned(const_offset, const_byte_size,504linked_file_addr) == UINT32_MAX)505return false;506}507break;508509default:510const_offset = 0;511const_value = 0;512const_byte_size = 0;513break;514}515516if (!decoded_data) {517const offset_t op_arg_size =518GetOpcodeDataSize(m_data, offset, op, dwarf_cu);519if (op_arg_size == LLDB_INVALID_OFFSET)520return false;521else522offset += op_arg_size;523}524}525526m_data.SetData(encoder.GetDataBuffer());527return true;528}529530static llvm::Error Evaluate_DW_OP_entry_value(std::vector<Value> &stack,531ExecutionContext *exe_ctx,532RegisterContext *reg_ctx,533const DataExtractor &opcodes,534lldb::offset_t &opcode_offset,535Log *log) {536// DW_OP_entry_value(sub-expr) describes the location a variable had upon537// function entry: this variable location is presumed to be optimized out at538// the current PC value. The caller of the function may have call site539// information that describes an alternate location for the variable (e.g. a540// constant literal, or a spilled stack value) in the parent frame.541//542// Example (this is pseudo-code & pseudo-DWARF, but hopefully illustrative):543//544// void child(int &sink, int x) {545// ...546// /* "x" gets optimized out. */547//548// /* The location of "x" here is: DW_OP_entry_value($reg2). */549// ++sink;550// }551//552// void parent() {553// int sink;554//555// /*556// * The callsite information emitted here is:557// *558// * DW_TAG_call_site559// * DW_AT_return_pc ... (for "child(sink, 123);")560// * DW_TAG_call_site_parameter (for "sink")561// * DW_AT_location ($reg1)562// * DW_AT_call_value ($SP - 8)563// * DW_TAG_call_site_parameter (for "x")564// * DW_AT_location ($reg2)565// * DW_AT_call_value ($literal 123)566// *567// * DW_TAG_call_site568// * DW_AT_return_pc ... (for "child(sink, 456);")569// * ...570// */571// child(sink, 123);572// child(sink, 456);573// }574//575// When the program stops at "++sink" within `child`, the debugger determines576// the call site by analyzing the return address. Once the call site is found,577// the debugger determines which parameter is referenced by DW_OP_entry_value578// and evaluates the corresponding location for that parameter in `parent`.579580// 1. Find the function which pushed the current frame onto the stack.581if ((!exe_ctx || !exe_ctx->HasTargetScope()) || !reg_ctx) {582return llvm::createStringError("no exe/reg context");583}584585StackFrame *current_frame = exe_ctx->GetFramePtr();586Thread *thread = exe_ctx->GetThreadPtr();587if (!current_frame || !thread)588return llvm::createStringError("no current frame/thread");589590Target &target = exe_ctx->GetTargetRef();591StackFrameSP parent_frame = nullptr;592addr_t return_pc = LLDB_INVALID_ADDRESS;593uint32_t current_frame_idx = current_frame->GetFrameIndex();594595for (uint32_t parent_frame_idx = current_frame_idx + 1;;parent_frame_idx++) {596parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);597// If this is null, we're at the end of the stack.598if (!parent_frame)599break;600601// Record the first valid return address, even if this is an inlined frame,602// in order to look up the associated call edge in the first non-inlined603// parent frame.604if (return_pc == LLDB_INVALID_ADDRESS) {605return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);606LLDB_LOG(log, "immediate ancestor with pc = {0:x}", return_pc);607}608609// If we've found an inlined frame, skip it (these have no call site610// parameters).611if (parent_frame->IsInlined())612continue;613614// We've found the first non-inlined parent frame.615break;616}617if (!parent_frame || !parent_frame->GetRegisterContext()) {618return llvm::createStringError("no parent frame with reg ctx");619}620621Function *parent_func =622parent_frame->GetSymbolContext(eSymbolContextFunction).function;623if (!parent_func)624return llvm::createStringError("no parent function");625626// 2. Find the call edge in the parent function responsible for creating the627// current activation.628Function *current_func =629current_frame->GetSymbolContext(eSymbolContextFunction).function;630if (!current_func)631return llvm::createStringError("no current function");632633CallEdge *call_edge = nullptr;634ModuleList &modlist = target.GetImages();635ExecutionContext parent_exe_ctx = *exe_ctx;636parent_exe_ctx.SetFrameSP(parent_frame);637if (!parent_frame->IsArtificial()) {638// If the parent frame is not artificial, the current activation may be639// produced by an ambiguous tail call. In this case, refuse to proceed.640call_edge = parent_func->GetCallEdgeForReturnAddress(return_pc, target);641if (!call_edge) {642return llvm::createStringError(643llvm::formatv("no call edge for retn-pc = {0:x} in parent frame {1}",644return_pc, parent_func->GetName()));645}646Function *callee_func = call_edge->GetCallee(modlist, parent_exe_ctx);647if (callee_func != current_func) {648return llvm::createStringError(649"ambiguous call sequence, can't find real parent frame");650}651} else {652// The StackFrameList solver machinery has deduced that an unambiguous tail653// call sequence that produced the current activation. The first edge in654// the parent that points to the current function must be valid.655for (auto &edge : parent_func->GetTailCallingEdges()) {656if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) {657call_edge = edge.get();658break;659}660}661}662if (!call_edge)663return llvm::createStringError("no unambiguous edge from parent "664"to current function");665666// 3. Attempt to locate the DW_OP_entry_value expression in the set of667// available call site parameters. If found, evaluate the corresponding668// parameter in the context of the parent frame.669const uint32_t subexpr_len = opcodes.GetULEB128(&opcode_offset);670const void *subexpr_data = opcodes.GetData(&opcode_offset, subexpr_len);671if (!subexpr_data)672return llvm::createStringError("subexpr could not be read");673674const CallSiteParameter *matched_param = nullptr;675for (const CallSiteParameter ¶m : call_edge->GetCallSiteParameters()) {676DataExtractor param_subexpr_extractor;677if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))678continue;679lldb::offset_t param_subexpr_offset = 0;680const void *param_subexpr_data =681param_subexpr_extractor.GetData(¶m_subexpr_offset, subexpr_len);682if (!param_subexpr_data ||683param_subexpr_extractor.BytesLeft(param_subexpr_offset) != 0)684continue;685686// At this point, the DW_OP_entry_value sub-expression and the callee-side687// expression in the call site parameter are known to have the same length.688// Check whether they are equal.689//690// Note that an equality check is sufficient: the contents of the691// DW_OP_entry_value subexpression are only used to identify the right call692// site parameter in the parent, and do not require any special handling.693if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {694matched_param = ¶m;695break;696}697}698if (!matched_param)699return llvm::createStringError("no matching call site param found");700701// TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value702// subexpresion whenever llvm does.703const DWARFExpressionList ¶m_expr = matched_param->LocationInCaller;704705llvm::Expected<Value> maybe_result = param_expr.Evaluate(706&parent_exe_ctx, parent_frame->GetRegisterContext().get(),707LLDB_INVALID_ADDRESS,708/*initial_value_ptr=*/nullptr,709/*object_address_ptr=*/nullptr);710if (!maybe_result) {711LLDB_LOG(log,712"Evaluate_DW_OP_entry_value: call site param evaluation failed");713return maybe_result.takeError();714}715716stack.push_back(*maybe_result);717return llvm::Error::success();718}719720namespace {721/// The location description kinds described by the DWARF v5722/// specification. Composite locations are handled out-of-band and723/// thus aren't part of the enum.724enum LocationDescriptionKind {725Empty,726Memory,727Register,728Implicit729/* Composite*/730};731/// Adjust value's ValueType according to the kind of location description.732void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,733LocationDescriptionKind kind,734Value *value = nullptr) {735// Note that this function is conflating DWARF expressions with736// DWARF location descriptions. Perhaps it would be better to define737// a wrapper for DWARFExpression::Eval() that deals with DWARF738// location descriptions (which consist of one or more DWARF739// expressions). But doing this would mean we'd also need factor the740// handling of DW_OP_(bit_)piece out of this function.741if (dwarf_cu && dwarf_cu->GetVersion() >= 4) {742const char *log_msg = "DWARF location description kind: %s";743switch (kind) {744case Empty:745LLDB_LOGF(log, log_msg, "Empty");746break;747case Memory:748LLDB_LOGF(log, log_msg, "Memory");749if (value->GetValueType() == Value::ValueType::Scalar)750value->SetValueType(Value::ValueType::LoadAddress);751break;752case Register:753LLDB_LOGF(log, log_msg, "Register");754value->SetValueType(Value::ValueType::Scalar);755break;756case Implicit:757LLDB_LOGF(log, log_msg, "Implicit");758if (value->GetValueType() == Value::ValueType::LoadAddress)759value->SetValueType(Value::ValueType::Scalar);760break;761}762}763}764} // namespace765766/// Helper function to move common code used to resolve a file address and turn767/// into a load address.768///769/// \param exe_ctx Pointer to the execution context770/// \param module_sp shared_ptr contains the module if we have one771/// \param dw_op_type C-style string used to vary the error output772/// \param file_addr the file address we are trying to resolve and turn into a773/// load address774/// \param so_addr out parameter, will be set to load address or section offset775/// \param check_sectionoffset bool which determines if having a section offset776/// but not a load address is considerd a success777/// \returns std::optional containing the load address if resolving and getting778/// the load address succeed or an empty Optinal otherwise. If779/// check_sectionoffset is true we consider LLDB_INVALID_ADDRESS a780/// success if so_addr.IsSectionOffset() is true.781static llvm::Expected<lldb::addr_t>782ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp,783const char *dw_op_type, lldb::addr_t file_addr,784Address &so_addr, bool check_sectionoffset = false) {785if (!module_sp)786return llvm::createStringError("need module to resolve file address for %s",787dw_op_type);788789if (!module_sp->ResolveFileAddress(file_addr, so_addr))790return llvm::createStringError("failed to resolve file address in module");791792const addr_t load_addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());793794if (load_addr == LLDB_INVALID_ADDRESS &&795(check_sectionoffset && !so_addr.IsSectionOffset()))796return llvm::createStringError("failed to resolve load address");797798return load_addr;799}800801/// Helper function to move common code used to load sized data from a uint8_t802/// buffer.803///804/// \param addr_bytes uint8_t buffer containg raw data805/// \param size_addr_bytes how large is the underlying raw data806/// \param byte_order what is the byter order of the underlyig data807/// \param size How much of the underlying data we want to use808/// \return The underlying data converted into a Scalar809static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,810size_t size_addr_bytes,811ByteOrder byte_order, size_t size) {812DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size);813814lldb::offset_t addr_data_offset = 0;815if (size <= 8)816return addr_data.GetMaxU64(&addr_data_offset, size);817else818return addr_data.GetAddress(&addr_data_offset);819}820821llvm::Expected<Value> DWARFExpression::Evaluate(822ExecutionContext *exe_ctx, RegisterContext *reg_ctx,823lldb::ModuleSP module_sp, const DataExtractor &opcodes,824const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,825const Value *initial_value_ptr, const Value *object_address_ptr) {826827if (opcodes.GetByteSize() == 0)828return llvm::createStringError(829"no location, value may have been optimized out");830std::vector<Value> stack;831832Process *process = nullptr;833StackFrame *frame = nullptr;834Target *target = nullptr;835836if (exe_ctx) {837process = exe_ctx->GetProcessPtr();838frame = exe_ctx->GetFramePtr();839target = exe_ctx->GetTargetPtr();840}841if (reg_ctx == nullptr && frame)842reg_ctx = frame->GetRegisterContext().get();843844if (initial_value_ptr)845stack.push_back(*initial_value_ptr);846847lldb::offset_t offset = 0;848Value tmp;849uint32_t reg_num;850851/// Insertion point for evaluating multi-piece expression.852uint64_t op_piece_offset = 0;853Value pieces; // Used for DW_OP_piece854855Log *log = GetLog(LLDBLog::Expressions);856// A generic type is "an integral type that has the size of an address and an857// unspecified signedness". For now, just use the signedness of the operand.858// TODO: Implement a real typed stack, and store the genericness of the value859// there.860auto to_generic = [&](auto v) {861bool is_signed = std::is_signed<decltype(v)>::value;862return Scalar(llvm::APSInt(863llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),864!is_signed));865};866867// The default kind is a memory location. This is updated by any868// operation that changes this, such as DW_OP_stack_value, and reset869// by composition operations like DW_OP_piece.870LocationDescriptionKind dwarf4_location_description_kind = Memory;871872while (opcodes.ValidOffset(offset)) {873const lldb::offset_t op_offset = offset;874const uint8_t op = opcodes.GetU8(&offset);875876if (log && log->GetVerbose()) {877size_t count = stack.size();878LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",879(uint64_t)count);880for (size_t i = 0; i < count; ++i) {881StreamString new_value;882new_value.Printf("[%" PRIu64 "]", (uint64_t)i);883stack[i].Dump(&new_value);884LLDB_LOGF(log, " %s", new_value.GetData());885}886LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,887DW_OP_value_to_name(op));888}889890if (std::optional<unsigned> arity =891llvm::dwarf::OperationArity(static_cast<LocationAtom>(op))) {892if (stack.size() < *arity)893return llvm::createStringError(894"%s needs at least %d stack entries (stack has %d entries)",895DW_OP_value_to_name(op), *arity, stack.size());896}897898switch (op) {899// The DW_OP_addr operation has a single operand that encodes a machine900// address and whose size is the size of an address on the target machine.901case DW_OP_addr:902stack.push_back(Scalar(opcodes.GetAddress(&offset)));903if (target &&904target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {905// wasm file sections aren't mapped into memory, therefore addresses can906// never point into a file section and are always LoadAddresses.907stack.back().SetValueType(Value::ValueType::LoadAddress);908} else {909stack.back().SetValueType(Value::ValueType::FileAddress);910}911break;912913// The DW_OP_addr_sect_offset4 is used for any location expressions in914// shared libraries that have a location like:915// DW_OP_addr(0x1000)916// If this address resides in a shared library, then this virtual address917// won't make sense when it is evaluated in the context of a running918// process where shared libraries have been slid. To account for this, this919// new address type where we can store the section pointer and a 4 byte920// offset.921// case DW_OP_addr_sect_offset4:922// {923// result_type = eResultTypeFileAddress;924// lldb::Section *sect = (lldb::Section925// *)opcodes.GetMaxU64(&offset, sizeof(void *));926// lldb::addr_t sect_offset = opcodes.GetU32(&offset);927//928// Address so_addr (sect, sect_offset);929// lldb::addr_t load_addr = so_addr.GetLoadAddress();930// if (load_addr != LLDB_INVALID_ADDRESS)931// {932// // We successfully resolve a file address to a load933// // address.934// stack.push_back(load_addr);935// break;936// }937// else938// {939// // We were able940// if (error_ptr)941// error_ptr->SetErrorStringWithFormat ("Section %s in942// %s is not currently loaded.\n",943// sect->GetName().AsCString(),944// sect->GetModule()->GetFileSpec().GetFilename().AsCString());945// return false;946// }947// }948// break;949950// OPCODE: DW_OP_deref951// OPERANDS: none952// DESCRIPTION: Pops the top stack entry and treats it as an address.953// The value retrieved from that address is pushed. The size of the data954// retrieved from the dereferenced address is the size of an address on the955// target machine.956case DW_OP_deref: {957if (stack.empty())958return llvm::createStringError(959"expression stack empty for DW_OP_deref");960Value::ValueType value_type = stack.back().GetValueType();961switch (value_type) {962case Value::ValueType::HostAddress: {963void *src = (void *)stack.back().GetScalar().ULongLong();964intptr_t ptr;965::memcpy(&ptr, src, sizeof(void *));966stack.back().GetScalar() = ptr;967stack.back().ClearContext();968} break;969case Value::ValueType::FileAddress: {970auto file_addr = stack.back().GetScalar().ULongLong(971LLDB_INVALID_ADDRESS);972973Address so_addr;974auto maybe_load_addr = ResolveLoadAddress(975exe_ctx, module_sp, "DW_OP_deref", file_addr, so_addr);976977if (!maybe_load_addr)978return maybe_load_addr.takeError();979980stack.back().GetScalar() = *maybe_load_addr;981// Fall through to load address promotion code below.982}983[[fallthrough]];984case Value::ValueType::Scalar:985// Promote Scalar to LoadAddress and fall through.986stack.back().SetValueType(Value::ValueType::LoadAddress);987[[fallthrough]];988case Value::ValueType::LoadAddress:989if (exe_ctx) {990if (process) {991lldb::addr_t pointer_addr =992stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);993Status error;994lldb::addr_t pointer_value =995process->ReadPointerFromMemory(pointer_addr, error);996if (pointer_value != LLDB_INVALID_ADDRESS) {997if (ABISP abi_sp = process->GetABI())998pointer_value = abi_sp->FixCodeAddress(pointer_value);999stack.back().GetScalar() = pointer_value;1000stack.back().ClearContext();1001} else {1002return llvm::createStringError(1003"Failed to dereference pointer from 0x%" PRIx641004" for DW_OP_deref: %s\n",1005pointer_addr, error.AsCString());1006}1007} else {1008return llvm::createStringError("NULL process for DW_OP_deref");1009}1010} else {1011return llvm::createStringError(1012"NULL execution context for DW_OP_deref");1013}1014break;10151016case Value::ValueType::Invalid:1017return llvm::createStringError("invalid value type for DW_OP_deref");1018}10191020} break;10211022// OPCODE: DW_OP_deref_size1023// OPERANDS: 11024// 1 - uint8_t that specifies the size of the data to dereference.1025// DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top1026// stack entry and treats it as an address. The value retrieved from that1027// address is pushed. In the DW_OP_deref_size operation, however, the size1028// in bytes of the data retrieved from the dereferenced address is1029// specified by the single operand. This operand is a 1-byte unsigned1030// integral constant whose value may not be larger than the size of an1031// address on the target machine. The data retrieved is zero extended to1032// the size of an address on the target machine before being pushed on the1033// expression stack.1034case DW_OP_deref_size: {1035if (stack.empty()) {1036return llvm::createStringError(1037"expression stack empty for DW_OP_deref_size");1038}1039uint8_t size = opcodes.GetU8(&offset);1040if (size > 8) {1041return llvm::createStringError(1042"Invalid address size for DW_OP_deref_size: %d\n", size);1043}1044Value::ValueType value_type = stack.back().GetValueType();1045switch (value_type) {1046case Value::ValueType::HostAddress: {1047void *src = (void *)stack.back().GetScalar().ULongLong();1048intptr_t ptr;1049::memcpy(&ptr, src, sizeof(void *));1050// I can't decide whether the size operand should apply to the bytes in1051// their1052// lldb-host endianness or the target endianness.. I doubt this'll ever1053// come up but I'll opt for assuming big endian regardless.1054switch (size) {1055case 1:1056ptr = ptr & 0xff;1057break;1058case 2:1059ptr = ptr & 0xffff;1060break;1061case 3:1062ptr = ptr & 0xffffff;1063break;1064case 4:1065ptr = ptr & 0xffffffff;1066break;1067// the casts are added to work around the case where intptr_t is a 321068// bit quantity;1069// presumably we won't hit the 5..7 cases if (void*) is 32-bits in this1070// program.1071case 5:1072ptr = (intptr_t)ptr & 0xffffffffffULL;1073break;1074case 6:1075ptr = (intptr_t)ptr & 0xffffffffffffULL;1076break;1077case 7:1078ptr = (intptr_t)ptr & 0xffffffffffffffULL;1079break;1080default:1081break;1082}1083stack.back().GetScalar() = ptr;1084stack.back().ClearContext();1085} break;1086case Value::ValueType::FileAddress: {1087auto file_addr =1088stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);1089Address so_addr;1090auto maybe_load_addr = ResolveLoadAddress(1091exe_ctx, module_sp, "DW_OP_deref_size", file_addr, so_addr,1092/*check_sectionoffset=*/true);10931094if (!maybe_load_addr)1095return maybe_load_addr.takeError();10961097addr_t load_addr = *maybe_load_addr;10981099if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset()) {1100uint8_t addr_bytes[8];1101Status error;11021103if (target &&1104target->ReadMemory(so_addr, &addr_bytes, size, error,1105/*force_live_memory=*/false) == size) {1106ObjectFile *objfile = module_sp->GetObjectFile();11071108stack.back().GetScalar() = DerefSizeExtractDataHelper(1109addr_bytes, size, objfile->GetByteOrder(), size);1110stack.back().ClearContext();1111break;1112} else {1113return llvm::createStringError(1114"Failed to dereference pointer for DW_OP_deref_size: "1115"%s\n",1116error.AsCString());1117}1118}1119stack.back().GetScalar() = load_addr;1120// Fall through to load address promotion code below.1121}11221123[[fallthrough]];1124case Value::ValueType::Scalar:1125case Value::ValueType::LoadAddress:1126if (exe_ctx) {1127if (process) {1128lldb::addr_t pointer_addr =1129stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);1130uint8_t addr_bytes[sizeof(lldb::addr_t)];1131Status error;1132if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==1133size) {11341135stack.back().GetScalar() =1136DerefSizeExtractDataHelper(addr_bytes, sizeof(addr_bytes),1137process->GetByteOrder(), size);1138stack.back().ClearContext();1139} else {1140return llvm::createStringError(1141"Failed to dereference pointer from 0x%" PRIx641142" for DW_OP_deref: %s\n",1143pointer_addr, error.AsCString());1144}1145} else {11461147return llvm::createStringError("NULL process for DW_OP_deref_size");1148}1149} else {1150return llvm::createStringError(1151"NULL execution context for DW_OP_deref_size");1152}1153break;11541155case Value::ValueType::Invalid:11561157return llvm::createStringError("invalid value for DW_OP_deref_size");1158}11591160} break;11611162// OPCODE: DW_OP_xderef_size1163// OPERANDS: 11164// 1 - uint8_t that specifies the size of the data to dereference.1165// DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at1166// the top of the stack is treated as an address. The second stack entry is1167// treated as an "address space identifier" for those architectures that1168// support multiple address spaces. The top two stack elements are popped,1169// a data item is retrieved through an implementation-defined address1170// calculation and pushed as the new stack top. In the DW_OP_xderef_size1171// operation, however, the size in bytes of the data retrieved from the1172// dereferenced address is specified by the single operand. This operand is1173// a 1-byte unsigned integral constant whose value may not be larger than1174// the size of an address on the target machine. The data retrieved is zero1175// extended to the size of an address on the target machine before being1176// pushed on the expression stack.1177case DW_OP_xderef_size:1178return llvm::createStringError("unimplemented opcode: DW_OP_xderef_size");1179// OPCODE: DW_OP_xderef1180// OPERANDS: none1181// DESCRIPTION: Provides an extended dereference mechanism. The entry at1182// the top of the stack is treated as an address. The second stack entry is1183// treated as an "address space identifier" for those architectures that1184// support multiple address spaces. The top two stack elements are popped,1185// a data item is retrieved through an implementation-defined address1186// calculation and pushed as the new stack top. The size of the data1187// retrieved from the dereferenced address is the size of an address on the1188// target machine.1189case DW_OP_xderef:1190return llvm::createStringError("unimplemented opcode: DW_OP_xderef");11911192// All DW_OP_constXXX opcodes have a single operand as noted below:1193//1194// Opcode Operand 11195// DW_OP_const1u 1-byte unsigned integer constant1196// DW_OP_const1s 1-byte signed integer constant1197// DW_OP_const2u 2-byte unsigned integer constant1198// DW_OP_const2s 2-byte signed integer constant1199// DW_OP_const4u 4-byte unsigned integer constant1200// DW_OP_const4s 4-byte signed integer constant1201// DW_OP_const8u 8-byte unsigned integer constant1202// DW_OP_const8s 8-byte signed integer constant1203// DW_OP_constu unsigned LEB128 integer constant1204// DW_OP_consts signed LEB128 integer constant1205case DW_OP_const1u:1206stack.push_back(to_generic(opcodes.GetU8(&offset)));1207break;1208case DW_OP_const1s:1209stack.push_back(to_generic((int8_t)opcodes.GetU8(&offset)));1210break;1211case DW_OP_const2u:1212stack.push_back(to_generic(opcodes.GetU16(&offset)));1213break;1214case DW_OP_const2s:1215stack.push_back(to_generic((int16_t)opcodes.GetU16(&offset)));1216break;1217case DW_OP_const4u:1218stack.push_back(to_generic(opcodes.GetU32(&offset)));1219break;1220case DW_OP_const4s:1221stack.push_back(to_generic((int32_t)opcodes.GetU32(&offset)));1222break;1223case DW_OP_const8u:1224stack.push_back(to_generic(opcodes.GetU64(&offset)));1225break;1226case DW_OP_const8s:1227stack.push_back(to_generic((int64_t)opcodes.GetU64(&offset)));1228break;1229// These should also use to_generic, but we can't do that due to a1230// producer-side bug in llvm. See llvm.org/pr48087.1231case DW_OP_constu:1232stack.push_back(Scalar(opcodes.GetULEB128(&offset)));1233break;1234case DW_OP_consts:1235stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));1236break;12371238// OPCODE: DW_OP_dup1239// OPERANDS: none1240// DESCRIPTION: duplicates the value at the top of the stack1241case DW_OP_dup:1242if (stack.empty()) {1243return llvm::createStringError("expression stack empty for DW_OP_dup");1244} else1245stack.push_back(stack.back());1246break;12471248// OPCODE: DW_OP_drop1249// OPERANDS: none1250// DESCRIPTION: pops the value at the top of the stack1251case DW_OP_drop:1252if (stack.empty()) {1253return llvm::createStringError("expression stack empty for DW_OP_drop");1254} else1255stack.pop_back();1256break;12571258// OPCODE: DW_OP_over1259// OPERANDS: none1260// DESCRIPTION: Duplicates the entry currently second in the stack at1261// the top of the stack.1262case DW_OP_over:1263stack.push_back(stack[stack.size() - 2]);1264break;12651266// OPCODE: DW_OP_pick1267// OPERANDS: uint8_t index into the current stack1268// DESCRIPTION: The stack entry with the specified index (0 through 255,1269// inclusive) is pushed on the stack1270case DW_OP_pick: {1271uint8_t pick_idx = opcodes.GetU8(&offset);1272if (pick_idx < stack.size())1273stack.push_back(stack[stack.size() - 1 - pick_idx]);1274else {1275return llvm::createStringError(1276"Index %u out of range for DW_OP_pick.\n", pick_idx);1277}1278} break;12791280// OPCODE: DW_OP_swap1281// OPERANDS: none1282// DESCRIPTION: swaps the top two stack entries. The entry at the top1283// of the stack becomes the second stack entry, and the second entry1284// becomes the top of the stack1285case DW_OP_swap:1286tmp = stack.back();1287stack.back() = stack[stack.size() - 2];1288stack[stack.size() - 2] = tmp;1289break;12901291// OPCODE: DW_OP_rot1292// OPERANDS: none1293// DESCRIPTION: Rotates the first three stack entries. The entry at1294// the top of the stack becomes the third stack entry, the second entry1295// becomes the top of the stack, and the third entry becomes the second1296// entry.1297case DW_OP_rot: {1298size_t last_idx = stack.size() - 1;1299Value old_top = stack[last_idx];1300stack[last_idx] = stack[last_idx - 1];1301stack[last_idx - 1] = stack[last_idx - 2];1302stack[last_idx - 2] = old_top;1303} break;13041305// OPCODE: DW_OP_abs1306// OPERANDS: none1307// DESCRIPTION: pops the top stack entry, interprets it as a signed1308// value and pushes its absolute value. If the absolute value can not be1309// represented, the result is undefined.1310case DW_OP_abs:1311if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) {1312return llvm::createStringError(1313"failed to take the absolute value of the first stack item");1314}1315break;13161317// OPCODE: DW_OP_and1318// OPERANDS: none1319// DESCRIPTION: pops the top two stack values, performs a bitwise and1320// operation on the two, and pushes the result.1321case DW_OP_and:1322tmp = stack.back();1323stack.pop_back();1324stack.back().ResolveValue(exe_ctx) =1325stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);1326break;13271328// OPCODE: DW_OP_div1329// OPERANDS: none1330// DESCRIPTION: pops the top two stack values, divides the former second1331// entry by the former top of the stack using signed division, and pushes1332// the result.1333case DW_OP_div: {1334tmp = stack.back();1335if (tmp.ResolveValue(exe_ctx).IsZero())1336return llvm::createStringError("divide by zero");13371338stack.pop_back();1339Scalar divisor, dividend;1340divisor = tmp.ResolveValue(exe_ctx);1341dividend = stack.back().ResolveValue(exe_ctx);1342divisor.MakeSigned();1343dividend.MakeSigned();1344stack.back() = dividend / divisor;13451346if (!stack.back().ResolveValue(exe_ctx).IsValid())1347return llvm::createStringError("divide failed");1348} break;13491350// OPCODE: DW_OP_minus1351// OPERANDS: none1352// DESCRIPTION: pops the top two stack values, subtracts the former top1353// of the stack from the former second entry, and pushes the result.1354case DW_OP_minus:1355tmp = stack.back();1356stack.pop_back();1357stack.back().ResolveValue(exe_ctx) =1358stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);1359break;13601361// OPCODE: DW_OP_mod1362// OPERANDS: none1363// DESCRIPTION: pops the top two stack values and pushes the result of1364// the calculation: former second stack entry modulo the former top of the1365// stack.1366case DW_OP_mod:1367tmp = stack.back();1368stack.pop_back();1369stack.back().ResolveValue(exe_ctx) =1370stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);1371break;13721373// OPCODE: DW_OP_mul1374// OPERANDS: none1375// DESCRIPTION: pops the top two stack entries, multiplies them1376// together, and pushes the result.1377case DW_OP_mul:1378tmp = stack.back();1379stack.pop_back();1380stack.back().ResolveValue(exe_ctx) =1381stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);1382break;13831384// OPCODE: DW_OP_neg1385// OPERANDS: none1386// DESCRIPTION: pops the top stack entry, and pushes its negation.1387case DW_OP_neg:1388if (!stack.back().ResolveValue(exe_ctx).UnaryNegate())1389return llvm::createStringError("unary negate failed");1390break;13911392// OPCODE: DW_OP_not1393// OPERANDS: none1394// DESCRIPTION: pops the top stack entry, and pushes its bitwise1395// complement1396case DW_OP_not:1397if (!stack.back().ResolveValue(exe_ctx).OnesComplement())1398return llvm::createStringError("logical NOT failed");1399break;14001401// OPCODE: DW_OP_or1402// OPERANDS: none1403// DESCRIPTION: pops the top two stack entries, performs a bitwise or1404// operation on the two, and pushes the result.1405case DW_OP_or:1406tmp = stack.back();1407stack.pop_back();1408stack.back().ResolveValue(exe_ctx) =1409stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);1410break;14111412// OPCODE: DW_OP_plus1413// OPERANDS: none1414// DESCRIPTION: pops the top two stack entries, adds them together, and1415// pushes the result.1416case DW_OP_plus:1417tmp = stack.back();1418stack.pop_back();1419stack.back().GetScalar() += tmp.GetScalar();1420break;14211422// OPCODE: DW_OP_plus_uconst1423// OPERANDS: none1424// DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB1281425// constant operand and pushes the result.1426case DW_OP_plus_uconst: {1427const uint64_t uconst_value = opcodes.GetULEB128(&offset);1428// Implicit conversion from a UINT to a Scalar...1429stack.back().GetScalar() += uconst_value;1430if (!stack.back().GetScalar().IsValid())1431return llvm::createStringError("DW_OP_plus_uconst failed");1432} break;14331434// OPCODE: DW_OP_shl1435// OPERANDS: none1436// DESCRIPTION: pops the top two stack entries, shifts the former1437// second entry left by the number of bits specified by the former top of1438// the stack, and pushes the result.1439case DW_OP_shl:1440tmp = stack.back();1441stack.pop_back();1442stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);1443break;14441445// OPCODE: DW_OP_shr1446// OPERANDS: none1447// DESCRIPTION: pops the top two stack entries, shifts the former second1448// entry right logically (filling with zero bits) by the number of bits1449// specified by the former top of the stack, and pushes the result.1450case DW_OP_shr:1451tmp = stack.back();1452stack.pop_back();1453if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical(1454tmp.ResolveValue(exe_ctx)))1455return llvm::createStringError("DW_OP_shr failed");1456break;14571458// OPCODE: DW_OP_shra1459// OPERANDS: none1460// DESCRIPTION: pops the top two stack entries, shifts the former second1461// entry right arithmetically (divide the magnitude by 2, keep the same1462// sign for the result) by the number of bits specified by the former top1463// of the stack, and pushes the result.1464case DW_OP_shra:1465tmp = stack.back();1466stack.pop_back();1467stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);1468break;14691470// OPCODE: DW_OP_xor1471// OPERANDS: none1472// DESCRIPTION: pops the top two stack entries, performs the bitwise1473// exclusive-or operation on the two, and pushes the result.1474case DW_OP_xor:1475tmp = stack.back();1476stack.pop_back();1477stack.back().ResolveValue(exe_ctx) =1478stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);1479break;14801481// OPCODE: DW_OP_skip1482// OPERANDS: int16_t1483// DESCRIPTION: An unconditional branch. Its single operand is a 2-byte1484// signed integer constant. The 2-byte constant is the number of bytes of1485// the DWARF expression to skip forward or backward from the current1486// operation, beginning after the 2-byte constant.1487case DW_OP_skip: {1488int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);1489lldb::offset_t new_offset = offset + skip_offset;1490// New offset can point at the end of the data, in this case we should1491// terminate the DWARF expression evaluation (will happen in the loop1492// condition).1493if (new_offset <= opcodes.GetByteSize())1494offset = new_offset;1495else {1496return llvm::createStringError(llvm::formatv(1497"Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}", offset,1498skip_offset, opcodes.GetByteSize()));1499}1500} break;15011502// OPCODE: DW_OP_bra1503// OPERANDS: int16_t1504// DESCRIPTION: A conditional branch. Its single operand is a 2-byte1505// signed integer constant. This operation pops the top of stack. If the1506// value popped is not the constant 0, the 2-byte constant operand is the1507// number of bytes of the DWARF expression to skip forward or backward from1508// the current operation, beginning after the 2-byte constant.1509case DW_OP_bra: {1510tmp = stack.back();1511stack.pop_back();1512int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);1513Scalar zero(0);1514if (tmp.ResolveValue(exe_ctx) != zero) {1515lldb::offset_t new_offset = offset + bra_offset;1516// New offset can point at the end of the data, in this case we should1517// terminate the DWARF expression evaluation (will happen in the loop1518// condition).1519if (new_offset <= opcodes.GetByteSize())1520offset = new_offset;1521else {1522return llvm::createStringError(llvm::formatv(1523"Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}", offset,1524bra_offset, opcodes.GetByteSize()));1525}1526}1527} break;15281529// OPCODE: DW_OP_eq1530// OPERANDS: none1531// DESCRIPTION: pops the top two stack values, compares using the1532// equals (==) operator.1533// STACK RESULT: push the constant value 1 onto the stack if the result1534// of the operation is true or the constant value 0 if the result of the1535// operation is false.1536case DW_OP_eq:1537tmp = stack.back();1538stack.pop_back();1539stack.back().ResolveValue(exe_ctx) =1540stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);1541break;15421543// OPCODE: DW_OP_ge1544// OPERANDS: none1545// DESCRIPTION: pops the top two stack values, compares using the1546// greater than or equal to (>=) operator.1547// STACK RESULT: push the constant value 1 onto the stack if the result1548// of the operation is true or the constant value 0 if the result of the1549// operation is false.1550case DW_OP_ge:1551tmp = stack.back();1552stack.pop_back();1553stack.back().ResolveValue(exe_ctx) =1554stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);1555break;15561557// OPCODE: DW_OP_gt1558// OPERANDS: none1559// DESCRIPTION: pops the top two stack values, compares using the1560// greater than (>) operator.1561// STACK RESULT: push the constant value 1 onto the stack if the result1562// of the operation is true or the constant value 0 if the result of the1563// operation is false.1564case DW_OP_gt:1565tmp = stack.back();1566stack.pop_back();1567stack.back().ResolveValue(exe_ctx) =1568stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);1569break;15701571// OPCODE: DW_OP_le1572// OPERANDS: none1573// DESCRIPTION: pops the top two stack values, compares using the1574// less than or equal to (<=) operator.1575// STACK RESULT: push the constant value 1 onto the stack if the result1576// of the operation is true or the constant value 0 if the result of the1577// operation is false.1578case DW_OP_le:1579tmp = stack.back();1580stack.pop_back();1581stack.back().ResolveValue(exe_ctx) =1582stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);1583break;15841585// OPCODE: DW_OP_lt1586// OPERANDS: none1587// DESCRIPTION: pops the top two stack values, compares using the1588// less than (<) operator.1589// STACK RESULT: push the constant value 1 onto the stack if the result1590// of the operation is true or the constant value 0 if the result of the1591// operation is false.1592case DW_OP_lt:1593tmp = stack.back();1594stack.pop_back();1595stack.back().ResolveValue(exe_ctx) =1596stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);1597break;15981599// OPCODE: DW_OP_ne1600// OPERANDS: none1601// DESCRIPTION: pops the top two stack values, compares using the1602// not equal (!=) operator.1603// STACK RESULT: push the constant value 1 onto the stack if the result1604// of the operation is true or the constant value 0 if the result of the1605// operation is false.1606case DW_OP_ne:1607tmp = stack.back();1608stack.pop_back();1609stack.back().ResolveValue(exe_ctx) =1610stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);1611break;16121613// OPCODE: DW_OP_litn1614// OPERANDS: none1615// DESCRIPTION: encode the unsigned literal values from 0 through 31.1616// STACK RESULT: push the unsigned literal constant value onto the top1617// of the stack.1618case DW_OP_lit0:1619case DW_OP_lit1:1620case DW_OP_lit2:1621case DW_OP_lit3:1622case DW_OP_lit4:1623case DW_OP_lit5:1624case DW_OP_lit6:1625case DW_OP_lit7:1626case DW_OP_lit8:1627case DW_OP_lit9:1628case DW_OP_lit10:1629case DW_OP_lit11:1630case DW_OP_lit12:1631case DW_OP_lit13:1632case DW_OP_lit14:1633case DW_OP_lit15:1634case DW_OP_lit16:1635case DW_OP_lit17:1636case DW_OP_lit18:1637case DW_OP_lit19:1638case DW_OP_lit20:1639case DW_OP_lit21:1640case DW_OP_lit22:1641case DW_OP_lit23:1642case DW_OP_lit24:1643case DW_OP_lit25:1644case DW_OP_lit26:1645case DW_OP_lit27:1646case DW_OP_lit28:1647case DW_OP_lit29:1648case DW_OP_lit30:1649case DW_OP_lit31:1650stack.push_back(to_generic(op - DW_OP_lit0));1651break;16521653// OPCODE: DW_OP_regN1654// OPERANDS: none1655// DESCRIPTION: Push the value in register n on the top of the stack.1656case DW_OP_reg0:1657case DW_OP_reg1:1658case DW_OP_reg2:1659case DW_OP_reg3:1660case DW_OP_reg4:1661case DW_OP_reg5:1662case DW_OP_reg6:1663case DW_OP_reg7:1664case DW_OP_reg8:1665case DW_OP_reg9:1666case DW_OP_reg10:1667case DW_OP_reg11:1668case DW_OP_reg12:1669case DW_OP_reg13:1670case DW_OP_reg14:1671case DW_OP_reg15:1672case DW_OP_reg16:1673case DW_OP_reg17:1674case DW_OP_reg18:1675case DW_OP_reg19:1676case DW_OP_reg20:1677case DW_OP_reg21:1678case DW_OP_reg22:1679case DW_OP_reg23:1680case DW_OP_reg24:1681case DW_OP_reg25:1682case DW_OP_reg26:1683case DW_OP_reg27:1684case DW_OP_reg28:1685case DW_OP_reg29:1686case DW_OP_reg30:1687case DW_OP_reg31: {1688dwarf4_location_description_kind = Register;1689reg_num = op - DW_OP_reg0;16901691if (llvm::Error err =1692ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))1693return err;1694stack.push_back(tmp);1695} break;1696// OPCODE: DW_OP_regx1697// OPERANDS:1698// ULEB128 literal operand that encodes the register.1699// DESCRIPTION: Push the value in register on the top of the stack.1700case DW_OP_regx: {1701dwarf4_location_description_kind = Register;1702reg_num = opcodes.GetULEB128(&offset);1703Status read_err;1704if (llvm::Error err =1705ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))1706return err;1707stack.push_back(tmp);1708} break;17091710// OPCODE: DW_OP_bregN1711// OPERANDS:1712// SLEB128 offset from register N1713// DESCRIPTION: Value is in memory at the address specified by register1714// N plus an offset.1715case DW_OP_breg0:1716case DW_OP_breg1:1717case DW_OP_breg2:1718case DW_OP_breg3:1719case DW_OP_breg4:1720case DW_OP_breg5:1721case DW_OP_breg6:1722case DW_OP_breg7:1723case DW_OP_breg8:1724case DW_OP_breg9:1725case DW_OP_breg10:1726case DW_OP_breg11:1727case DW_OP_breg12:1728case DW_OP_breg13:1729case DW_OP_breg14:1730case DW_OP_breg15:1731case DW_OP_breg16:1732case DW_OP_breg17:1733case DW_OP_breg18:1734case DW_OP_breg19:1735case DW_OP_breg20:1736case DW_OP_breg21:1737case DW_OP_breg22:1738case DW_OP_breg23:1739case DW_OP_breg24:1740case DW_OP_breg25:1741case DW_OP_breg26:1742case DW_OP_breg27:1743case DW_OP_breg28:1744case DW_OP_breg29:1745case DW_OP_breg30:1746case DW_OP_breg31: {1747reg_num = op - DW_OP_breg0;1748if (llvm::Error err =1749ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))1750return err;17511752int64_t breg_offset = opcodes.GetSLEB128(&offset);1753tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;1754tmp.ClearContext();1755stack.push_back(tmp);1756stack.back().SetValueType(Value::ValueType::LoadAddress);1757} break;1758// OPCODE: DW_OP_bregx1759// OPERANDS: 21760// ULEB128 literal operand that encodes the register.1761// SLEB128 offset from register N1762// DESCRIPTION: Value is in memory at the address specified by register1763// N plus an offset.1764case DW_OP_bregx: {1765reg_num = opcodes.GetULEB128(&offset);1766if (llvm::Error err =1767ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))1768return err;17691770int64_t breg_offset = opcodes.GetSLEB128(&offset);1771tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;1772tmp.ClearContext();1773stack.push_back(tmp);1774stack.back().SetValueType(Value::ValueType::LoadAddress);1775} break;17761777case DW_OP_fbreg:1778if (exe_ctx) {1779if (frame) {1780Scalar value;1781Status fb_err;1782if (frame->GetFrameBaseValue(value, &fb_err)) {1783int64_t fbreg_offset = opcodes.GetSLEB128(&offset);1784value += fbreg_offset;1785stack.push_back(value);1786stack.back().SetValueType(Value::ValueType::LoadAddress);1787} else1788return fb_err.ToError();1789} else {1790return llvm::createStringError(1791"invalid stack frame in context for DW_OP_fbreg opcode");1792}1793} else {1794return llvm::createStringError(1795"NULL execution context for DW_OP_fbreg");1796}17971798break;17991800// OPCODE: DW_OP_nop1801// OPERANDS: none1802// DESCRIPTION: A place holder. It has no effect on the location stack1803// or any of its values.1804case DW_OP_nop:1805break;18061807// OPCODE: DW_OP_piece1808// OPERANDS: 11809// ULEB128: byte size of the piece1810// DESCRIPTION: The operand describes the size in bytes of the piece of1811// the object referenced by the DWARF expression whose result is at the top1812// of the stack. If the piece is located in a register, but does not occupy1813// the entire register, the placement of the piece within that register is1814// defined by the ABI.1815//1816// Many compilers store a single variable in sets of registers, or store a1817// variable partially in memory and partially in registers. DW_OP_piece1818// provides a way of describing how large a part of a variable a particular1819// DWARF expression refers to.1820case DW_OP_piece: {1821LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;1822// Reset for the next piece.1823dwarf4_location_description_kind = Memory;18241825const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);18261827if (piece_byte_size > 0) {1828Value curr_piece;18291830if (stack.empty()) {1831UpdateValueTypeFromLocationDescription(1832log, dwarf_cu, LocationDescriptionKind::Empty);1833// In a multi-piece expression, this means that the current piece is1834// not available. Fill with zeros for now by resizing the data and1835// appending it1836curr_piece.ResizeData(piece_byte_size);1837// Note that "0" is not a correct value for the unknown bits.1838// It would be better to also return a mask of valid bits together1839// with the expression result, so the debugger can print missing1840// members as "<optimized out>" or something.1841::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);1842pieces.AppendDataToHostBuffer(curr_piece);1843} else {1844Status error;1845// Extract the current piece into "curr_piece"1846Value curr_piece_source_value(stack.back());1847stack.pop_back();1848UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc,1849&curr_piece_source_value);18501851const Value::ValueType curr_piece_source_value_type =1852curr_piece_source_value.GetValueType();1853Scalar &scalar = curr_piece_source_value.GetScalar();1854const lldb::addr_t addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);1855switch (curr_piece_source_value_type) {1856case Value::ValueType::Invalid:1857return llvm::createStringError("invalid value type");1858case Value::ValueType::LoadAddress:1859case Value::ValueType::FileAddress: {1860if (target) {1861if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {1862if (target->ReadMemory(addr, curr_piece.GetBuffer().GetBytes(),1863piece_byte_size, error,1864/*force_live_memory=*/false) !=1865piece_byte_size) {1866const char *addr_type = (curr_piece_source_value_type ==1867Value::ValueType::LoadAddress)1868? "load"1869: "file";1870return llvm::createStringError(1871"failed to read memory DW_OP_piece(%" PRIu641872") from %s address 0x%" PRIx64,1873piece_byte_size, addr_type, addr);1874}1875} else {1876return llvm::createStringError(1877"failed to resize the piece memory buffer for "1878"DW_OP_piece(%" PRIu64 ")",1879piece_byte_size);1880}1881}1882} break;1883case Value::ValueType::HostAddress: {1884return llvm::createStringError(1885"failed to read memory DW_OP_piece(%" PRIu641886") from host address 0x%" PRIx64,1887piece_byte_size, addr);1888} break;18891890case Value::ValueType::Scalar: {1891uint32_t bit_size = piece_byte_size * 8;1892uint32_t bit_offset = 0;1893if (!scalar.ExtractBitfield(1894bit_size, bit_offset)) {1895return llvm::createStringError(1896"unable to extract %" PRIu64 " bytes from a %" PRIu641897" byte scalar value.",1898piece_byte_size,1899(uint64_t)curr_piece_source_value.GetScalar().GetByteSize());1900}1901// Create curr_piece with bit_size. By default Scalar1902// grows to the nearest host integer type.1903llvm::APInt fail_value(1, 0, false);1904llvm::APInt ap_int = scalar.UInt128(fail_value);1905assert(ap_int.getBitWidth() >= bit_size);1906llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),1907ap_int.getNumWords()};1908curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));1909} break;1910}19111912// Check if this is the first piece?1913if (op_piece_offset == 0) {1914// This is the first piece, we should push it back onto the stack1915// so subsequent pieces will be able to access this piece and add1916// to it.1917if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {1918return llvm::createStringError("failed to append piece data");1919}1920} else {1921// If this is the second or later piece there should be a value on1922// the stack.1923if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {1924return llvm::createStringError(1925"DW_OP_piece for offset %" PRIu641926" but top of stack is of size %" PRIu64,1927op_piece_offset, pieces.GetBuffer().GetByteSize());1928}19291930if (pieces.AppendDataToHostBuffer(curr_piece) == 0)1931return llvm::createStringError("failed to append piece data");1932}1933}1934op_piece_offset += piece_byte_size;1935}1936} break;19371938case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);1939if (stack.size() < 1) {1940UpdateValueTypeFromLocationDescription(log, dwarf_cu,1941LocationDescriptionKind::Empty);1942// Reset for the next piece.1943dwarf4_location_description_kind = Memory;1944return llvm::createStringError(1945"expression stack needs at least 1 item for DW_OP_bit_piece");1946} else {1947UpdateValueTypeFromLocationDescription(1948log, dwarf_cu, dwarf4_location_description_kind, &stack.back());1949// Reset for the next piece.1950dwarf4_location_description_kind = Memory;1951const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);1952const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);1953switch (stack.back().GetValueType()) {1954case Value::ValueType::Invalid:1955return llvm::createStringError(1956"unable to extract bit value from invalid value");1957case Value::ValueType::Scalar: {1958if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,1959piece_bit_offset)) {1960return llvm::createStringError(1961"unable to extract %" PRIu64 " bit value with %" PRIu641962" bit offset from a %" PRIu64 " bit scalar value.",1963piece_bit_size, piece_bit_offset,1964(uint64_t)(stack.back().GetScalar().GetByteSize() * 8));1965}1966} break;19671968case Value::ValueType::FileAddress:1969case Value::ValueType::LoadAddress:1970case Value::ValueType::HostAddress:1971return llvm::createStringError(1972"unable to extract DW_OP_bit_piece(bit_size = %" PRIu641973", bit_offset = %" PRIu64 ") from an address value.",1974piece_bit_size, piece_bit_offset);1975}1976}1977break;19781979// OPCODE: DW_OP_implicit_value1980// OPERANDS: 21981// ULEB128 size of the value block in bytes1982// uint8_t* block bytes encoding value in target's memory1983// representation1984// DESCRIPTION: Value is immediately stored in block in the debug info with1985// the memory representation of the target.1986case DW_OP_implicit_value: {1987dwarf4_location_description_kind = Implicit;19881989const uint32_t len = opcodes.GetULEB128(&offset);1990const void *data = opcodes.GetData(&offset, len);19911992if (!data) {1993LLDB_LOG(log, "Evaluate_DW_OP_implicit_value: could not be read data");1994return llvm::createStringError("could not evaluate %s",1995DW_OP_value_to_name(op));1996}19971998Value result(data, len);1999stack.push_back(result);2000break;2001}20022003case DW_OP_implicit_pointer: {2004dwarf4_location_description_kind = Implicit;2005return llvm::createStringError("Could not evaluate %s.",2006DW_OP_value_to_name(op));2007}20082009// OPCODE: DW_OP_push_object_address2010// OPERANDS: none2011// DESCRIPTION: Pushes the address of the object currently being2012// evaluated as part of evaluation of a user presented expression. This2013// object may correspond to an independent variable described by its own2014// DIE or it may be a component of an array, structure, or class whose2015// address has been dynamically determined by an earlier step during user2016// expression evaluation.2017case DW_OP_push_object_address:2018if (object_address_ptr)2019stack.push_back(*object_address_ptr);2020else {2021return llvm::createStringError("DW_OP_push_object_address used without "2022"specifying an object address");2023}2024break;20252026// OPCODE: DW_OP_call22027// OPERANDS:2028// uint16_t compile unit relative offset of a DIE2029// DESCRIPTION: Performs subroutine calls during evaluation2030// of a DWARF expression. The operand is the 2-byte unsigned offset of a2031// debugging information entry in the current compilation unit.2032//2033// Operand interpretation is exactly like that for DW_FORM_ref2.2034//2035// This operation transfers control of DWARF expression evaluation to the2036// DW_AT_location attribute of the referenced DIE. If there is no such2037// attribute, then there is no effect. Execution of the DWARF expression of2038// a DW_AT_location attribute may add to and/or remove from values on the2039// stack. Execution returns to the point following the call when the end of2040// the attribute is reached. Values on the stack at the time of the call2041// may be used as parameters by the called expression and values left on2042// the stack by the called expression may be used as return values by prior2043// agreement between the calling and called expressions.2044case DW_OP_call2:2045return llvm::createStringError("unimplemented opcode DW_OP_call2");2046// OPCODE: DW_OP_call42047// OPERANDS: 12048// uint32_t compile unit relative offset of a DIE2049// DESCRIPTION: Performs a subroutine call during evaluation of a DWARF2050// expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of2051// a debugging information entry in the current compilation unit.2052//2053// Operand interpretation DW_OP_call4 is exactly like that for2054// DW_FORM_ref4.2055//2056// This operation transfers control of DWARF expression evaluation to the2057// DW_AT_location attribute of the referenced DIE. If there is no such2058// attribute, then there is no effect. Execution of the DWARF expression of2059// a DW_AT_location attribute may add to and/or remove from values on the2060// stack. Execution returns to the point following the call when the end of2061// the attribute is reached. Values on the stack at the time of the call2062// may be used as parameters by the called expression and values left on2063// the stack by the called expression may be used as return values by prior2064// agreement between the calling and called expressions.2065case DW_OP_call4:2066return llvm::createStringError("unimplemented opcode DW_OP_call4");20672068// OPCODE: DW_OP_stack_value2069// OPERANDS: None2070// DESCRIPTION: Specifies that the object does not exist in memory but2071// rather is a constant value. The value from the top of the stack is the2072// value to be used. This is the actual object value and not the location.2073case DW_OP_stack_value:2074dwarf4_location_description_kind = Implicit;2075stack.back().SetValueType(Value::ValueType::Scalar);2076break;20772078// OPCODE: DW_OP_convert2079// OPERANDS: 12080// A ULEB128 that is either a DIE offset of a2081// DW_TAG_base_type or 0 for the generic (pointer-sized) type.2082//2083// DESCRIPTION: Pop the top stack element, convert it to a2084// different type, and push the result.2085case DW_OP_convert: {2086const uint64_t die_offset = opcodes.GetULEB128(&offset);2087uint64_t bit_size;2088bool sign;2089if (die_offset == 0) {2090// The generic type has the size of an address on the target2091// machine and an unspecified signedness. Scalar has no2092// "unspecified signedness", so we use unsigned types.2093if (!module_sp)2094return llvm::createStringError("no module");2095sign = false;2096bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;2097if (!bit_size)2098return llvm::createStringError("unspecified architecture");2099} else {2100// Retrieve the type DIE that the value is being converted to. This2101// offset is compile unit relative so we need to fix it up.2102const uint64_t abs_die_offset = die_offset + dwarf_cu->GetOffset();2103// FIXME: the constness has annoying ripple effects.2104DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);2105if (!die)2106return llvm::createStringError(2107"cannot resolve DW_OP_convert type DIE");2108uint64_t encoding =2109die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);2110bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;2111if (!bit_size)2112bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);2113if (!bit_size)2114return llvm::createStringError(2115"unsupported type size in DW_OP_convert");2116switch (encoding) {2117case DW_ATE_signed:2118case DW_ATE_signed_char:2119sign = true;2120break;2121case DW_ATE_unsigned:2122case DW_ATE_unsigned_char:2123sign = false;2124break;2125default:2126return llvm::createStringError(2127"unsupported encoding in DW_OP_convert");2128}2129}2130Scalar &top = stack.back().ResolveValue(exe_ctx);2131top.TruncOrExtendTo(bit_size, sign);2132break;2133}21342135// OPCODE: DW_OP_call_frame_cfa2136// OPERANDS: None2137// DESCRIPTION: Specifies a DWARF expression that pushes the value of2138// the canonical frame address consistent with the call frame information2139// located in .debug_frame (or in the FDEs of the eh_frame section).2140case DW_OP_call_frame_cfa:2141if (frame) {2142// Note that we don't have to parse FDEs because this DWARF expression2143// is commonly evaluated with a valid stack frame.2144StackID id = frame->GetStackID();2145addr_t cfa = id.GetCallFrameAddress();2146if (cfa != LLDB_INVALID_ADDRESS) {2147stack.push_back(Scalar(cfa));2148stack.back().SetValueType(Value::ValueType::LoadAddress);2149} else {2150return llvm::createStringError(2151"stack frame does not include a canonical "2152"frame address for DW_OP_call_frame_cfa "2153"opcode");2154}2155} else {2156return llvm::createStringError("unvalid stack frame in context for "2157"DW_OP_call_frame_cfa opcode");2158}2159break;21602161// OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension2162// opcode, DW_OP_GNU_push_tls_address)2163// OPERANDS: none2164// DESCRIPTION: Pops a TLS offset from the stack, converts it to2165// an address in the current thread's thread-local storage block, and2166// pushes it on the stack.2167case DW_OP_form_tls_address:2168case DW_OP_GNU_push_tls_address: {2169if (stack.size() < 1) {2170if (op == DW_OP_form_tls_address)2171return llvm::createStringError(2172"DW_OP_form_tls_address needs an argument");2173else2174return llvm::createStringError(2175"DW_OP_GNU_push_tls_address needs an argument");2176}21772178if (!exe_ctx || !module_sp)2179return llvm::createStringError("no context to evaluate TLS within");21802181Thread *thread = exe_ctx->GetThreadPtr();2182if (!thread)2183return llvm::createStringError("no thread to evaluate TLS within");21842185// Lookup the TLS block address for this thread and module.2186const addr_t tls_file_addr =2187stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);2188const addr_t tls_load_addr =2189thread->GetThreadLocalData(module_sp, tls_file_addr);21902191if (tls_load_addr == LLDB_INVALID_ADDRESS)2192return llvm::createStringError(2193"no TLS data currently exists for this thread");21942195stack.back().GetScalar() = tls_load_addr;2196stack.back().SetValueType(Value::ValueType::LoadAddress);2197} break;21982199// OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)2200// OPERANDS: 12201// ULEB128: index to the .debug_addr section2202// DESCRIPTION: Pushes an address to the stack from the .debug_addr2203// section with the base address specified by the DW_AT_addr_base attribute2204// and the 0 based index is the ULEB128 encoded index.2205case DW_OP_addrx:2206case DW_OP_GNU_addr_index: {2207if (!dwarf_cu)2208return llvm::createStringError("DW_OP_GNU_addr_index found without a "2209"compile unit being specified");2210uint64_t index = opcodes.GetULEB128(&offset);2211lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);2212stack.push_back(Scalar(value));2213if (target &&2214target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {2215// wasm file sections aren't mapped into memory, therefore addresses can2216// never point into a file section and are always LoadAddresses.2217stack.back().SetValueType(Value::ValueType::LoadAddress);2218} else {2219stack.back().SetValueType(Value::ValueType::FileAddress);2220}2221} break;22222223// OPCODE: DW_OP_GNU_const_index2224// OPERANDS: 12225// ULEB128: index to the .debug_addr section2226// DESCRIPTION: Pushes an constant with the size of a machine address to2227// the stack from the .debug_addr section with the base address specified2228// by the DW_AT_addr_base attribute and the 0 based index is the ULEB1282229// encoded index.2230case DW_OP_GNU_const_index: {2231if (!dwarf_cu) {2232return llvm::createStringError("DW_OP_GNU_const_index found without a "2233"compile unit being specified");2234}2235uint64_t index = opcodes.GetULEB128(&offset);2236lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);2237stack.push_back(Scalar(value));2238} break;22392240case DW_OP_GNU_entry_value:2241case DW_OP_entry_value: {2242if (llvm::Error err = Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx,2243opcodes, offset, log))2244return llvm::createStringError(2245"could not evaluate DW_OP_entry_value: %s",2246llvm::toString(std::move(err)).c_str());2247break;2248}22492250default:2251if (dwarf_cu) {2252if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode(2253op, opcodes, offset, stack)) {2254break;2255}2256}2257return llvm::createStringError(llvm::formatv(2258"Unhandled opcode {0} in DWARFExpression", LocationAtom(op)));2259}2260}22612262if (stack.empty()) {2263// Nothing on the stack, check if we created a piece value from DW_OP_piece2264// or DW_OP_bit_piece opcodes2265if (pieces.GetBuffer().GetByteSize())2266return pieces;22672268return llvm::createStringError("stack empty after evaluation");2269}22702271UpdateValueTypeFromLocationDescription(2272log, dwarf_cu, dwarf4_location_description_kind, &stack.back());22732274if (log && log->GetVerbose()) {2275size_t count = stack.size();2276LLDB_LOGF(log,2277"Stack after operation has %" PRIu64 " values:", (uint64_t)count);2278for (size_t i = 0; i < count; ++i) {2279StreamString new_value;2280new_value.Printf("[%" PRIu64 "]", (uint64_t)i);2281stack[i].Dump(&new_value);2282LLDB_LOGF(log, " %s", new_value.GetData());2283}2284}2285return stack.back();2286}22872288bool DWARFExpression::ParseDWARFLocationList(2289const DWARFUnit *dwarf_cu, const DataExtractor &data,2290DWARFExpressionList *location_list) {2291location_list->Clear();2292std::unique_ptr<llvm::DWARFLocationTable> loctable_up =2293dwarf_cu->GetLocationTable(data);2294Log *log = GetLog(LLDBLog::Expressions);2295auto lookup_addr =2296[&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> {2297addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);2298if (address == LLDB_INVALID_ADDRESS)2299return std::nullopt;2300return llvm::object::SectionedAddress{address};2301};2302auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {2303if (!loc) {2304LLDB_LOG_ERROR(log, loc.takeError(), "{0}");2305return true;2306}2307auto buffer_sp =2308std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());2309DWARFExpression expr = DWARFExpression(DataExtractor(2310buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));2311location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);2312return true;2313};2314llvm::Error error = loctable_up->visitAbsoluteLocationList(23150, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},2316lookup_addr, process_list);2317location_list->Sort();2318if (error) {2319LLDB_LOG_ERROR(log, std::move(error), "{0}");2320return false;2321}2322return true;2323}23242325bool DWARFExpression::MatchesOperand(2326StackFrame &frame, const Instruction::Operand &operand) const {2327using namespace OperandMatchers;23282329RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();2330if (!reg_ctx_sp) {2331return false;2332}23332334DataExtractor opcodes(m_data);23352336lldb::offset_t op_offset = 0;2337uint8_t opcode = opcodes.GetU8(&op_offset);23382339if (opcode == DW_OP_fbreg) {2340int64_t offset = opcodes.GetSLEB128(&op_offset);23412342DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);2343if (!fb_expr) {2344return false;2345}23462347auto recurse = [&frame, fb_expr](const Instruction::Operand &child) {2348return fb_expr->MatchesOperand(frame, child);2349};23502351if (!offset &&2352MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),2353recurse)(operand)) {2354return true;2355}23562357return MatchUnaryOp(2358MatchOpType(Instruction::Operand::Type::Dereference),2359MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),2360MatchImmOp(offset), recurse))(operand);2361}23622363bool dereference = false;2364const RegisterInfo *reg = nullptr;2365int64_t offset = 0;23662367if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) {2368reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0);2369} else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) {2370offset = opcodes.GetSLEB128(&op_offset);2371reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_breg0);2372} else if (opcode == DW_OP_regx) {2373uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));2374reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);2375} else if (opcode == DW_OP_bregx) {2376uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));2377offset = opcodes.GetSLEB128(&op_offset);2378reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);2379} else {2380return false;2381}23822383if (!reg) {2384return false;2385}23862387if (dereference) {2388if (!offset &&2389MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),2390MatchRegOp(*reg))(operand)) {2391return true;2392}23932394return MatchUnaryOp(2395MatchOpType(Instruction::Operand::Type::Dereference),2396MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),2397MatchRegOp(*reg),2398MatchImmOp(offset)))(operand);2399} else {2400return MatchRegOp(*reg)(operand);2401}2402}240324042405