diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Expression/DWARFExpression.cpp | |
parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) |
Notes
Diffstat (limited to 'source/Expression/DWARFExpression.cpp')
-rw-r--r-- | source/Expression/DWARFExpression.cpp | 367 |
1 files changed, 45 insertions, 322 deletions
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp index a6249b3a2864..a9d365325d9e 100644 --- a/source/Expression/DWARFExpression.cpp +++ b/source/Expression/DWARFExpression.cpp @@ -1,9 +1,8 @@ //===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -47,25 +46,20 @@ ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu, uint32_t index_size = dwarf_cu->GetAddressByteSize(); dw_offset_t addr_base = dwarf_cu->GetAddrBase(); lldb::offset_t offset = addr_base + index * index_size; - return dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64( - &offset, index_size); + return dwarf_cu->GetSymbolFileDWARF() + .GetDWARFContext() + .getOrLoadAddrData() + .GetMaxU64(&offset, index_size); } -//---------------------------------------------------------------------- // DWARFExpression constructor -//---------------------------------------------------------------------- -DWARFExpression::DWARFExpression(DWARFUnit *dwarf_cu) - : m_module_wp(), m_data(), m_dwarf_cu(dwarf_cu), +DWARFExpression::DWARFExpression() + : m_module_wp(), m_data(), m_dwarf_cu(nullptr), m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {} -DWARFExpression::DWARFExpression(const DWARFExpression &rhs) - : m_module_wp(rhs.m_module_wp), m_data(rhs.m_data), - m_dwarf_cu(rhs.m_dwarf_cu), m_reg_kind(rhs.m_reg_kind), - m_loclist_slide(rhs.m_loclist_slide) {} - DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor &data, - DWARFUnit *dwarf_cu, + const DWARFUnit *dwarf_cu, lldb::offset_t data_offset, lldb::offset_t data_length) : m_module_wp(), m_data(data, data_offset, data_length), @@ -75,58 +69,21 @@ DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, m_module_wp = module_sp; } -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- DWARFExpression::~DWARFExpression() {} bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; } -void DWARFExpression::SetOpcodeData(const DataExtractor &data) { - m_data = data; -} - -void DWARFExpression::CopyOpcodeData(lldb::ModuleSP module_sp, - const DataExtractor &data, - lldb::offset_t data_offset, - lldb::offset_t data_length) { - const uint8_t *bytes = data.PeekData(data_offset, data_length); - if (bytes) { - m_module_wp = module_sp; - m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length))); - m_data.SetByteOrder(data.GetByteOrder()); - m_data.SetAddressByteSize(data.GetAddressByteSize()); - } -} - -void DWARFExpression::CopyOpcodeData(const void *data, - lldb::offset_t data_length, - ByteOrder byte_order, - uint8_t addr_byte_size) { - if (data && data_length) { - m_data.SetData(DataBufferSP(new DataBufferHeap(data, data_length))); - m_data.SetByteOrder(byte_order); - m_data.SetAddressByteSize(addr_byte_size); - } -} - -void DWARFExpression::CopyOpcodeData(uint64_t const_value, - lldb::offset_t const_value_byte_size, - uint8_t addr_byte_size) { - if (const_value_byte_size) { - m_data.SetData( - DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size))); - m_data.SetByteOrder(endian::InlHostByteOrder()); - m_data.SetAddressByteSize(addr_byte_size); - } -} +void DWARFExpression::UpdateValue(uint64_t const_value, + lldb::offset_t const_value_byte_size, + uint8_t addr_byte_size) { + if (!const_value_byte_size) + return; -void DWARFExpression::SetOpcodeData(lldb::ModuleSP module_sp, - const DataExtractor &data, - lldb::offset_t data_offset, - lldb::offset_t data_length) { - m_module_wp = module_sp; - m_data.SetData(data, data_offset, data_length); + m_data.SetData( + DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size))); + m_data.SetByteOrder(endian::InlHostByteOrder()); + m_data.SetAddressByteSize(addr_byte_size); } void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, @@ -491,23 +448,6 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset)); break; - // case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break; - // // 0x9c DWARF3 - // case DW_OP_bit_piece: // 0x9d DWARF3 2 - // s->Printf("DW_OP_bit_piece(0x%x, 0x%x)", - // m_data.GetULEB128(&offset), m_data.GetULEB128(&offset)); - // break; - // case DW_OP_lo_user: s->PutCString("DW_OP_lo_user"); break; - // // 0xe0 - // case DW_OP_hi_user: s->PutCString("DW_OP_hi_user"); break; - // // 0xff - // case DW_OP_APPLE_extern: - // s->Printf("DW_OP_APPLE_extern(%" PRIu64 ")", - // m_data.GetULEB128(&offset)); - // break; - // case DW_OP_APPLE_array_ref: - // s->PutCString("DW_OP_APPLE_array_ref"); - // break; case DW_OP_form_tls_address: s->PutCString("DW_OP_form_tls_address"); // 0x9b break; @@ -515,6 +455,10 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); break; + case DW_OP_addrx: + s->Printf("DW_OP_addrx(0x%" PRIx64 ")", + m_data.GetULEB128(&offset)); + break; case DW_OP_GNU_const_index: // 0xfc s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); @@ -525,62 +469,6 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, case DW_OP_APPLE_uninit: s->PutCString("DW_OP_APPLE_uninit"); // 0xF0 break; - // case DW_OP_APPLE_assign: // 0xF1 - pops value off and - // assigns it to second item on stack (2nd item must have - // assignable context) - // s->PutCString("DW_OP_APPLE_assign"); - // break; - // case DW_OP_APPLE_address_of: // 0xF2 - gets the address of - // the top stack item (top item must be a variable, or have - // value_type that is an address already) - // s->PutCString("DW_OP_APPLE_address_of"); - // break; - // case DW_OP_APPLE_value_of: // 0xF3 - pops the value off the - // stack and pushes the value of that object (top item must be a - // variable, or expression local) - // s->PutCString("DW_OP_APPLE_value_of"); - // break; - // case DW_OP_APPLE_deref_type: // 0xF4 - gets the address of - // the top stack item (top item must be a variable, or a clang - // type) - // s->PutCString("DW_OP_APPLE_deref_type"); - // break; - // case DW_OP_APPLE_expr_local: // 0xF5 - ULEB128 expression - // local index - // s->Printf("DW_OP_APPLE_expr_local(%" PRIu64 ")", - // m_data.GetULEB128(&offset)); - // break; - // case DW_OP_APPLE_constf: // 0xF6 - 1 byte float size, - // followed by constant float data - // { - // uint8_t float_length = m_data.GetU8(&offset); - // s->Printf("DW_OP_APPLE_constf(<%u> ", float_length); - // m_data.Dump(s, offset, eFormatHex, float_length, 1, - // UINT32_MAX, DW_INVALID_ADDRESS, 0, 0); - // s->PutChar(')'); - // // Consume the float data - // m_data.GetData(&offset, float_length); - // } - // break; - // case DW_OP_APPLE_scalar_cast: - // s->Printf("DW_OP_APPLE_scalar_cast(%s)", - // Scalar::GetValueTypeAsCString - // ((Scalar::Type)m_data.GetU8(&offset))); - // break; - // case DW_OP_APPLE_clang_cast: - // { - // clang::Type *clang_type = (clang::Type - // *)m_data.GetMaxU64(&offset, sizeof(void*)); - // s->Printf("DW_OP_APPLE_clang_cast(%p)", clang_type); - // } - // break; - // case DW_OP_APPLE_clear: - // s->PutCString("DW_OP_APPLE_clear"); - // break; - // case DW_OP_APPLE_error: // 0xFF - Stops expression - // evaluation and returns an error (no args) - // s->PutCString("DW_OP_APPLE_error"); - // break; } } } @@ -653,7 +541,7 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx, lldb::RegisterKind reg_kind, uint32_t reg_num, Status *error_ptr, Value &value) { - if (reg_ctx == NULL) { + if (reg_ctx == nullptr) { if (error_ptr) error_ptr->SetErrorStringWithFormat("No register context in frame.\n"); } else { @@ -695,52 +583,6 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx, return false; } -// bool -// DWARFExpression::LocationListContainsLoadAddress (Process* process, const -// Address &addr) const -//{ -// return LocationListContainsLoadAddress(process, -// addr.GetLoadAddress(process)); -//} -// -// bool -// DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t -// load_addr) const -//{ -// if (load_addr == LLDB_INVALID_ADDRESS) -// return false; -// -// if (IsLocationList()) -// { -// lldb::offset_t offset = 0; -// -// addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process); -// -// if (loc_list_base_addr == LLDB_INVALID_ADDRESS) -// return false; -// -// while (m_data.ValidOffset(offset)) -// { -// // We need to figure out what the value is for the location. -// addr_t lo_pc = m_data.GetAddress(&offset); -// addr_t hi_pc = m_data.GetAddress(&offset); -// if (lo_pc == 0 && hi_pc == 0) -// break; -// else -// { -// lo_pc += loc_list_base_addr; -// hi_pc += loc_list_base_addr; -// -// if (lo_pc <= load_addr && load_addr < hi_pc) -// return true; -// -// offset += m_data.GetU16(&offset); -// } -// } -// } -// return false; -//} - static offset_t GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op) { @@ -878,6 +720,7 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data, return 8; // All opcodes that have a single ULEB (signed or unsigned) argument + case DW_OP_addrx: // 0xa1 1 ULEB128 index case DW_OP_constu: // 0x10 1 ULEB128 constant case DW_OP_consts: // 0x11 1 SLEB128 constant case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend @@ -958,7 +801,7 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx, return op_file_addr; else ++curr_op_addr_idx; - } else if (op == DW_OP_GNU_addr_index) { + } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) { uint64_t index = m_data.GetULEB128(&offset); if (curr_op_addr_idx == op_addr_idx) { if (!m_dwarf_cu) { @@ -996,12 +839,12 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) { // for this expression // So first we copy the data into a heap buffer - std::unique_ptr<DataBufferHeap> head_data_ap( + std::unique_ptr<DataBufferHeap> head_data_up( new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize())); // Make en encoder so we can write the address into the buffer using the // correct byte order (endianness) - DataEncoder encoder(head_data_ap->GetBytes(), head_data_ap->GetByteSize(), + DataEncoder encoder(head_data_up->GetBytes(), head_data_up->GetByteSize(), m_data.GetByteOrder(), addr_byte_size); // Replace the address in the new buffer @@ -1010,7 +853,7 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) { // All went well, so now we can reset the data using a shared pointer to // the heap data so "m_data" will now correctly manage the heap data. - m_data.SetData(DataBufferSP(head_data_ap.release())); + m_data.SetData(DataBufferSP(head_data_up.release())); return true; } else { const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op); @@ -1252,7 +1095,7 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, if (IsLocationList()) { lldb::offset_t offset = 0; addr_t pc; - StackFrame *frame = NULL; + StackFrame *frame = nullptr; if (reg_ctx) pc = reg_ctx->GetPC(); else { @@ -1313,7 +1156,7 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, bool DWARFExpression::Evaluate( ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, - DWARFUnit *dwarf_cu, const lldb::offset_t opcodes_offset, + const DWARFUnit *dwarf_cu, const lldb::offset_t opcodes_offset, const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) { @@ -1326,14 +1169,14 @@ bool DWARFExpression::Evaluate( } std::vector<Value> stack; - Process *process = NULL; - StackFrame *frame = NULL; + Process *process = nullptr; + StackFrame *frame = nullptr; if (exe_ctx) { process = exe_ctx->GetProcessPtr(); frame = exe_ctx->GetFramePtr(); } - if (reg_ctx == NULL && frame) + if (reg_ctx == nullptr && frame) reg_ctx = frame->GetRegisterContext().get(); if (initial_value_ptr) @@ -1375,10 +1218,8 @@ bool DWARFExpression::Evaluate( } switch (op) { - //---------------------------------------------------------------------- // The DW_OP_addr operation has a single operand that encodes a machine // address and whose size is the size of an address on the target machine. - //---------------------------------------------------------------------- case DW_OP_addr: stack.push_back(Scalar(opcodes.GetAddress(&offset))); stack.back().SetValueType(Value::eValueTypeFileAddress); @@ -1389,7 +1230,6 @@ bool DWARFExpression::Evaluate( frame->CalculateTarget().get()); break; - //---------------------------------------------------------------------- // The DW_OP_addr_sect_offset4 is used for any location expressions in // shared libraries that have a location like: // DW_OP_addr(0x1000) @@ -1398,7 +1238,6 @@ bool DWARFExpression::Evaluate( // process where shared libraries have been slid. To account for this, this // new address type where we can store the section pointer and a 4 byte // offset. - //---------------------------------------------------------------------- // case DW_OP_addr_sect_offset4: // { // result_type = eResultTypeFileAddress; @@ -1428,14 +1267,12 @@ bool DWARFExpression::Evaluate( // } // break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_deref // OPERANDS: none // DESCRIPTION: Pops the top stack entry and treats it as an address. // The value retrieved from that address is pushed. The size of the data // retrieved from the dereferenced address is the size of an address on the // target machine. - //---------------------------------------------------------------------- case DW_OP_deref: { if (stack.empty()) { if (error_ptr) @@ -1517,7 +1354,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_deref_size // OPERANDS: 1 // 1 - uint8_t that specifies the size of the data to dereference. @@ -1530,7 +1366,6 @@ bool DWARFExpression::Evaluate( // address on the target machine. The data retrieved is zero extended to // the size of an address on the target machine before being pushed on the // expression stack. - //---------------------------------------------------------------------- case DW_OP_deref_size: { if (stack.empty()) { if (error_ptr) @@ -1639,7 +1474,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_xderef_size // OPERANDS: 1 // 1 - uint8_t that specifies the size of the data to dereference. @@ -1655,12 +1489,10 @@ bool DWARFExpression::Evaluate( // the size of an address on the target machine. The data retrieved is zero // extended to the size of an address on the target machine before being // pushed on the expression stack. - //---------------------------------------------------------------------- case DW_OP_xderef_size: if (error_ptr) error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size."); return false; - //---------------------------------------------------------------------- // OPCODE: DW_OP_xderef // OPERANDS: none // DESCRIPTION: Provides an extended dereference mechanism. The entry at @@ -1671,17 +1503,14 @@ bool DWARFExpression::Evaluate( // calculation and pushed as the new stack top. The size of the data // retrieved from the dereferenced address is the size of an address on the // target machine. - //---------------------------------------------------------------------- case DW_OP_xderef: if (error_ptr) error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef."); return false; - //---------------------------------------------------------------------- // All DW_OP_constXXX opcodes have a single operand as noted below: // // Opcode Operand 1 - // --------------- ---------------------------------------------------- // DW_OP_const1u 1-byte unsigned integer constant DW_OP_const1s // 1-byte signed integer constant DW_OP_const2u 2-byte unsigned integer // constant DW_OP_const2s 2-byte signed integer constant DW_OP_const4u @@ -1689,7 +1518,6 @@ bool DWARFExpression::Evaluate( // constant DW_OP_const8u 8-byte unsigned integer constant DW_OP_const8s // 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer // constant DW_OP_consts signed LEB128 integer constant - //---------------------------------------------------------------------- case DW_OP_const1u: stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset))); break; @@ -1721,11 +1549,9 @@ bool DWARFExpression::Evaluate( stack.push_back(Scalar(opcodes.GetSLEB128(&offset))); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_dup // OPERANDS: none // DESCRIPTION: duplicates the value at the top of the stack - //---------------------------------------------------------------------- case DW_OP_dup: if (stack.empty()) { if (error_ptr) @@ -1735,11 +1561,9 @@ bool DWARFExpression::Evaluate( stack.push_back(stack.back()); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_drop // OPERANDS: none // DESCRIPTION: pops the value at the top of the stack - //---------------------------------------------------------------------- case DW_OP_drop: if (stack.empty()) { if (error_ptr) @@ -1749,12 +1573,10 @@ bool DWARFExpression::Evaluate( stack.pop_back(); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_over // OPERANDS: none // DESCRIPTION: Duplicates the entry currently second in the stack at // the top of the stack. - //---------------------------------------------------------------------- case DW_OP_over: if (stack.size() < 2) { if (error_ptr) @@ -1765,16 +1587,14 @@ bool DWARFExpression::Evaluate( stack.push_back(stack[stack.size() - 2]); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_pick // OPERANDS: uint8_t index into the current stack // DESCRIPTION: The stack entry with the specified index (0 through 255, // inclusive) is pushed on the stack - //---------------------------------------------------------------------- case DW_OP_pick: { uint8_t pick_idx = opcodes.GetU8(&offset); if (pick_idx < stack.size()) - stack.push_back(stack[pick_idx]); + stack.push_back(stack[stack.size() - 1 - pick_idx]); else { if (error_ptr) error_ptr->SetErrorStringWithFormat( @@ -1783,13 +1603,11 @@ bool DWARFExpression::Evaluate( } } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_swap // OPERANDS: none // DESCRIPTION: swaps the top two stack entries. The entry at the top // of the stack becomes the second stack entry, and the second entry // becomes the top of the stack - //---------------------------------------------------------------------- case DW_OP_swap: if (stack.size() < 2) { if (error_ptr) @@ -1803,14 +1621,12 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_rot // OPERANDS: none // DESCRIPTION: Rotates the first three stack entries. The entry at // the top of the stack becomes the third stack entry, the second entry // becomes the top of the stack, and the third entry becomes the second // entry. - //---------------------------------------------------------------------- case DW_OP_rot: if (stack.size() < 3) { if (error_ptr) @@ -1826,13 +1642,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_abs // OPERANDS: none // DESCRIPTION: pops the top stack entry, interprets it as a signed // value and pushes its absolute value. If the absolute value can not be // represented, the result is undefined. - //---------------------------------------------------------------------- case DW_OP_abs: if (stack.empty()) { if (error_ptr) @@ -1847,12 +1661,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_and // OPERANDS: none // DESCRIPTION: pops the top two stack values, performs a bitwise and // operation on the two, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_and: if (stack.size() < 2) { if (error_ptr) @@ -1867,13 +1679,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_div // OPERANDS: none // DESCRIPTION: pops the top two stack values, divides the former second // entry by the former top of the stack using signed division, and pushes // the result. - //---------------------------------------------------------------------- case DW_OP_div: if (stack.size() < 2) { if (error_ptr) @@ -1899,12 +1709,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_minus // OPERANDS: none // DESCRIPTION: pops the top two stack values, subtracts the former top // of the stack from the former second entry, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_minus: if (stack.size() < 2) { if (error_ptr) @@ -1919,13 +1727,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_mod // OPERANDS: none // DESCRIPTION: pops the top two stack values and pushes the result of // the calculation: former second stack entry modulo the former top of the // stack. - //---------------------------------------------------------------------- case DW_OP_mod: if (stack.size() < 2) { if (error_ptr) @@ -1940,12 +1746,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_mul // OPERANDS: none // DESCRIPTION: pops the top two stack entries, multiplies them // together, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_mul: if (stack.size() < 2) { if (error_ptr) @@ -1960,11 +1764,9 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_neg // OPERANDS: none // DESCRIPTION: pops the top stack entry, and pushes its negation. - //---------------------------------------------------------------------- case DW_OP_neg: if (stack.empty()) { if (error_ptr) @@ -1980,12 +1782,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_not // OPERANDS: none // DESCRIPTION: pops the top stack entry, and pushes its bitwise // complement - //---------------------------------------------------------------------- case DW_OP_not: if (stack.empty()) { if (error_ptr) @@ -2001,12 +1801,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_or // OPERANDS: none // DESCRIPTION: pops the top two stack entries, performs a bitwise or // operation on the two, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_or: if (stack.size() < 2) { if (error_ptr) @@ -2021,12 +1819,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_plus // OPERANDS: none // DESCRIPTION: pops the top two stack entries, adds them together, and // pushes the result. - //---------------------------------------------------------------------- case DW_OP_plus: if (stack.size() < 2) { if (error_ptr) @@ -2040,12 +1836,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_plus_uconst // OPERANDS: none // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128 // constant operand and pushes the result. - //---------------------------------------------------------------------- case DW_OP_plus_uconst: if (stack.empty()) { if (error_ptr) @@ -2064,13 +1858,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_shl // OPERANDS: none // DESCRIPTION: pops the top two stack entries, shifts the former // second entry left by the number of bits specified by the former top of // the stack, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_shl: if (stack.size() < 2) { if (error_ptr) @@ -2084,13 +1876,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_shr // OPERANDS: none // DESCRIPTION: pops the top two stack entries, shifts the former second // entry right logically (filling with zero bits) by the number of bits // specified by the former top of the stack, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_shr: if (stack.size() < 2) { if (error_ptr) @@ -2109,14 +1899,12 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_shra // OPERANDS: none // DESCRIPTION: pops the top two stack entries, shifts the former second // entry right arithmetically (divide the magnitude by 2, keep the same // sign for the result) by the number of bits specified by the former top // of the stack, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_shra: if (stack.size() < 2) { if (error_ptr) @@ -2130,12 +1918,10 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_xor // OPERANDS: none // DESCRIPTION: pops the top two stack entries, performs the bitwise // exclusive-or operation on the two, and pushes the result. - //---------------------------------------------------------------------- case DW_OP_xor: if (stack.size() < 2) { if (error_ptr) @@ -2150,14 +1936,12 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_skip // OPERANDS: int16_t // DESCRIPTION: An unconditional branch. Its single operand is a 2-byte // signed integer constant. The 2-byte constant is the number of bytes of // the DWARF expression to skip forward or backward from the current // operation, beginning after the 2-byte constant. - //---------------------------------------------------------------------- case DW_OP_skip: { int16_t skip_offset = (int16_t)opcodes.GetU16(&offset); lldb::offset_t new_offset = offset + skip_offset; @@ -2170,7 +1954,6 @@ bool DWARFExpression::Evaluate( } } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_bra // OPERANDS: int16_t // DESCRIPTION: A conditional branch. Its single operand is a 2-byte @@ -2178,7 +1961,6 @@ bool DWARFExpression::Evaluate( // value popped is not the constant 0, the 2-byte constant operand is the // number of bytes of the DWARF expression to skip forward or backward from // the current operation, beginning after the 2-byte constant. - //---------------------------------------------------------------------- case DW_OP_bra: if (stack.empty()) { if (error_ptr) @@ -2203,7 +1985,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_eq // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2211,7 +1992,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_eq: if (stack.size() < 2) { if (error_ptr) @@ -2226,7 +2006,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_ge // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2234,7 +2013,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_ge: if (stack.size() < 2) { if (error_ptr) @@ -2249,7 +2027,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_gt // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2257,7 +2034,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_gt: if (stack.size() < 2) { if (error_ptr) @@ -2272,7 +2048,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_le // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2280,7 +2055,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_le: if (stack.size() < 2) { if (error_ptr) @@ -2295,7 +2069,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_lt // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2303,7 +2076,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_lt: if (stack.size() < 2) { if (error_ptr) @@ -2318,7 +2090,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_ne // OPERANDS: none // DESCRIPTION: pops the top two stack values, compares using the @@ -2326,7 +2097,6 @@ bool DWARFExpression::Evaluate( // STACK RESULT: push the constant value 1 onto the stack if the result // of the operation is true or the constant value 0 if the result of the // operation is false. - //---------------------------------------------------------------------- case DW_OP_ne: if (stack.size() < 2) { if (error_ptr) @@ -2341,13 +2111,11 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_litn // OPERANDS: none // DESCRIPTION: encode the unsigned literal values from 0 through 31. // STACK RESULT: push the unsigned literal constant value onto the top // of the stack. - //---------------------------------------------------------------------- case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: @@ -2383,11 +2151,9 @@ bool DWARFExpression::Evaluate( stack.push_back(Scalar((uint64_t)(op - DW_OP_lit0))); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_regN // OPERANDS: none // DESCRIPTION: Push the value in register n on the top of the stack. - //---------------------------------------------------------------------- case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: @@ -2427,12 +2193,10 @@ bool DWARFExpression::Evaluate( else return false; } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_regx // OPERANDS: // ULEB128 literal operand that encodes the register. // DESCRIPTION: Push the value in register on the top of the stack. - //---------------------------------------------------------------------- case DW_OP_regx: { reg_num = opcodes.GetULEB128(&offset); if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp)) @@ -2441,13 +2205,11 @@ bool DWARFExpression::Evaluate( return false; } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_bregN // OPERANDS: // SLEB128 offset from register N // DESCRIPTION: Value is in memory at the address specified by register // N plus an offset. - //---------------------------------------------------------------------- case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: @@ -2492,14 +2254,12 @@ bool DWARFExpression::Evaluate( } else return false; } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_bregx // OPERANDS: 2 // ULEB128 literal operand that encodes the register. // SLEB128 offset from register N // DESCRIPTION: Value is in memory at the address specified by register // N plus an offset. - //---------------------------------------------------------------------- case DW_OP_bregx: { reg_num = opcodes.GetULEB128(&offset); @@ -2540,16 +2300,13 @@ bool DWARFExpression::Evaluate( break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_nop // OPERANDS: none // DESCRIPTION: A place holder. It has no effect on the location stack // or any of its values. - //---------------------------------------------------------------------- case DW_OP_nop: break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_piece // OPERANDS: 1 // ULEB128: byte size of the piece @@ -2563,7 +2320,6 @@ bool DWARFExpression::Evaluate( // variable partially in memory and partially in registers. DW_OP_piece // provides a way of describing how large a part of a variable a particular // DWARF expression refers to. - //---------------------------------------------------------------------- case DW_OP_piece: { const uint64_t piece_byte_size = opcodes.GetULEB128(&offset); @@ -2740,7 +2496,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_push_object_address // OPERANDS: none // DESCRIPTION: Pushes the address of the object currently being @@ -2749,7 +2504,6 @@ bool DWARFExpression::Evaluate( // DIE or it may be a component of an array, structure, or class whose // address has been dynamically determined by an earlier step during user // expression evaluation. - //---------------------------------------------------------------------- case DW_OP_push_object_address: if (object_address_ptr) stack.push_back(*object_address_ptr); @@ -2761,7 +2515,6 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_call2 // OPERANDS: // uint16_t compile unit relative offset of a DIE @@ -2780,12 +2533,10 @@ bool DWARFExpression::Evaluate( // may be used as parameters by the called expression and values left on // the stack by the called expression may be used as return values by prior // agreement between the calling and called expressions. - //---------------------------------------------------------------------- case DW_OP_call2: if (error_ptr) error_ptr->SetErrorString("Unimplemented opcode DW_OP_call2."); return false; - //---------------------------------------------------------------------- // OPCODE: DW_OP_call4 // OPERANDS: 1 // uint32_t compile unit relative offset of a DIE @@ -2805,30 +2556,25 @@ bool DWARFExpression::Evaluate( // may be used as parameters by the called expression and values left on // the stack by the called expression may be used as return values by prior // agreement between the calling and called expressions. - //---------------------------------------------------------------------- case DW_OP_call4: if (error_ptr) error_ptr->SetErrorString("Unimplemented opcode DW_OP_call4."); return false; - //---------------------------------------------------------------------- // OPCODE: DW_OP_stack_value // OPERANDS: None // DESCRIPTION: Specifies that the object does not exist in memory but // rather is a constant value. The value from the top of the stack is the // value to be used. This is the actual object value and not the location. - //---------------------------------------------------------------------- case DW_OP_stack_value: stack.back().SetValueType(Value::eValueTypeScalar); break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_call_frame_cfa // OPERANDS: None // DESCRIPTION: Specifies a DWARF expression that pushes the value of // the canonical frame address consistent with the call frame information // located in .debug_frame (or in the FDEs of the eh_frame section). - //---------------------------------------------------------------------- case DW_OP_call_frame_cfa: if (frame) { // Note that we don't have to parse FDEs because this DWARF expression @@ -2850,14 +2596,12 @@ bool DWARFExpression::Evaluate( } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension // opcode, DW_OP_GNU_push_tls_address) // OPERANDS: none // DESCRIPTION: Pops a TLS offset from the stack, converts it to // an address in the current thread's thread-local storage block, and // pushes it on the stack. - //---------------------------------------------------------------------- case DW_OP_form_tls_address: case DW_OP_GNU_push_tls_address: { if (stack.size() < 1) { @@ -2902,14 +2646,13 @@ bool DWARFExpression::Evaluate( stack.back().SetValueType(Value::eValueTypeLoadAddress); } break; - //---------------------------------------------------------------------- - // OPCODE: DW_OP_GNU_addr_index + // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.) // OPERANDS: 1 // ULEB128: index to the .debug_addr section // DESCRIPTION: Pushes an address to the stack from the .debug_addr // section with the base address specified by the DW_AT_addr_base attribute // and the 0 based index is the ULEB128 encoded index. - //---------------------------------------------------------------------- + case DW_OP_addrx: case DW_OP_GNU_addr_index: { if (!dwarf_cu) { if (error_ptr) @@ -2918,17 +2661,11 @@ bool DWARFExpression::Evaluate( return false; } uint64_t index = opcodes.GetULEB128(&offset); - uint32_t index_size = dwarf_cu->GetAddressByteSize(); - dw_offset_t addr_base = dwarf_cu->GetAddrBase(); - lldb::offset_t offset = addr_base + index * index_size; - uint64_t value = - dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64( - &offset, index_size); + lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index); stack.push_back(Scalar(value)); stack.back().SetValueType(Value::eValueTypeFileAddress); } break; - //---------------------------------------------------------------------- // OPCODE: DW_OP_GNU_const_index // OPERANDS: 1 // ULEB128: index to the .debug_addr section @@ -2936,7 +2673,6 @@ bool DWARFExpression::Evaluate( // the stack from the .debug_addr section with the base address specified // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128 // encoded index. - //---------------------------------------------------------------------- case DW_OP_GNU_const_index: { if (!dwarf_cu) { if (error_ptr) @@ -2945,22 +2681,8 @@ bool DWARFExpression::Evaluate( return false; } uint64_t index = opcodes.GetULEB128(&offset); - uint32_t index_size = dwarf_cu->GetAddressByteSize(); - dw_offset_t addr_base = dwarf_cu->GetAddrBase(); - lldb::offset_t offset = addr_base + index * index_size; - const DWARFDataExtractor &debug_addr = - dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data(); - switch (index_size) { - case 4: - stack.push_back(Scalar(debug_addr.GetU32(&offset))); - break; - case 8: - stack.push_back(Scalar(debug_addr.GetU64(&offset))); - break; - default: - assert(false && "Unhandled index size"); - return false; - } + lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index); + stack.push_back(Scalar(value)); } break; default: @@ -3028,7 +2750,7 @@ bool DWARFExpression::AddressRangeForLocationListEntry( return false; DWARFExpression::LocationListFormat format = - dwarf_cu->GetSymbolFileDWARF()->GetLocationListFormat(); + dwarf_cu->GetSymbolFileDWARF().GetLocationListFormat(); switch (format) { case NonLocationList: return false; @@ -3195,6 +2917,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, case DW_OP_call_ref: size = dwarf_ref_size; break; + case DW_OP_addrx: case DW_OP_piece: case DW_OP_plus_uconst: case DW_OP_regx: @@ -3204,7 +2927,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, break; default: s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); - return true; + return false; } switch (size) { @@ -3250,7 +2973,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, break; } - return false; + return true; } bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data, @@ -3289,7 +3012,7 @@ void DWARFExpression::PrintDWARFLocationList( s.Indent(); if (cu) s.AddressRange(start_addr + base_addr, end_addr + base_addr, - cu->GetAddressByteSize(), NULL, ": "); + cu->GetAddressByteSize(), nullptr, ": "); uint32_t loc_length = debug_loc_data.GetU16(&offset); DataExtractor locationData(debug_loc_data, offset, loc_length); |