summaryrefslogtreecommitdiff
path: root/source/Expression/DWARFExpression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Expression/DWARFExpression.cpp')
-rw-r--r--source/Expression/DWARFExpression.cpp367
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);