diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -15,6 +15,7 @@ #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" #include @@ -137,6 +138,7 @@ static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, const DWARFUnit *dwarf_cu, + const llvm::DenseMap *addrx_map, const lldb::RegisterKind reg_set, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, @@ -151,6 +153,10 @@ return data.GetByteSize() > 0; } + const llvm::DenseMap &GetAddrxMap() const { + return m_addrx_map; + } + void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const; @@ -159,6 +165,8 @@ /// A data extractor capable of reading opcode bytes DataExtractor m_data; + llvm::DenseMap m_addrx_map; + /// One of the defines that starts with LLDB_REGKIND_ lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF; }; diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -375,7 +375,8 @@ error = true; break; } - + if (auto it = m_addrx_map.find(index); it != m_addrx_map.end()) + return it->getSecond(); return dwarf_cu->ReadAddressFromDebugAddrSection(index); } ++curr_op_addr_idx; @@ -419,13 +420,20 @@ // the heap data so "m_data" will now correctly manage the heap data. m_data.SetData(encoder.GetDataBuffer()); return true; - } else { - const offset_t op_arg_size = - GetOpcodeDataSize(m_data, offset, op, dwarf_cu); - if (op_arg_size == LLDB_INVALID_OFFSET) - break; - offset += op_arg_size; } + if (op == DW_OP_addrx) { + lldb::offset_t old_offset = offset; + uint64_t index = m_data.GetULEB128(&offset); + if (old_offset == offset) + return false; + m_addrx_map[index] = file_addr; + return true; + } + const offset_t op_arg_size = + GetOpcodeDataSize(m_data, offset, op, dwarf_cu); + if (op_arg_size == LLDB_INVALID_OFFSET) + break; + offset += op_arg_size; } return false; } @@ -856,9 +864,10 @@ bool DWARFExpression::Evaluate( ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, - const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind, - const Value *initial_value_ptr, const Value *object_address_ptr, - Value &result, Status *error_ptr) { + const DWARFUnit *dwarf_cu, + const llvm::DenseMap *addrx_map, + const lldb::RegisterKind reg_kind, const Value *initial_value_ptr, + const Value *object_address_ptr, Value &result, Status *error_ptr) { if (opcodes.GetByteSize() == 0) { if (error_ptr) @@ -2536,7 +2545,12 @@ return false; } uint64_t index = opcodes.GetULEB128(&offset); - lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index); + lldb::addr_t value = [&] { + if (addrx_map) + if (auto it = addrx_map->find(index); it != addrx_map->end()) + return it->second; + return dwarf_cu->ReadAddressFromDebugAddrSection(index); + }(); stack.push_back(Scalar(value)); if (target && target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) { diff --git a/lldb/source/Expression/DWARFExpressionList.cpp b/lldb/source/Expression/DWARFExpressionList.cpp --- a/lldb/source/Expression/DWARFExpressionList.cpp +++ b/lldb/source/Expression/DWARFExpressionList.cpp @@ -242,7 +242,7 @@ } expr.GetExpressionData(data); reg_kind = expr.GetRegisterKind(); - return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data, - m_dwarf_cu, reg_kind, initial_value_ptr, - object_address_ptr, result, error_ptr); + return DWARFExpression::Evaluate( + exe_ctx, reg_ctx, module_sp, data, m_dwarf_cu, &expr.GetAddrxMap(), + reg_kind, initial_value_ptr, object_address_ptr, result, error_ptr); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1415,7 +1415,7 @@ if (DWARFExpression::Evaluate( nullptr, nullptr, module_sp, DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, + die.GetCU(), nullptr, eRegisterKindDWARF, &initialValue, nullptr, memberOffset, nullptr)) { member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); } @@ -2542,8 +2542,8 @@ nullptr, // RegisterContext * module_sp, DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, - memberOffset, nullptr)) { + die.GetCU(), nullptr, eRegisterKindDWARF, &initialValue, + nullptr, memberOffset, nullptr)) { member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); } } else { diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -34,11 +34,11 @@ /*addr_size*/ 4); Value result; Status status; - if (!DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp, - extractor, unit, lldb::eRegisterKindLLDB, - /*initial_value_ptr*/ nullptr, - /*object_address_ptr*/ nullptr, result, - &status)) + if (!DWARFExpression::Evaluate( + exe_ctx, /*reg_ctx*/ nullptr, module_sp, extractor, unit, nullptr, + lldb::eRegisterKindLLDB, + /*initial_value_ptr*/ nullptr, + /*object_address_ptr*/ nullptr, result, &status)) return status.ToError(); switch (result.GetValueType()) { @@ -429,7 +429,7 @@ Status status; ASSERT_TRUE(DWARFExpression::Evaluate( &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, - /*unit*/ nullptr, lldb::eRegisterKindLLDB, + /*unit*/ nullptr, nullptr, lldb::eRegisterKindLLDB, /*initial_value_ptr*/ nullptr, /*object_address_ptr*/ nullptr, result, &status)) << status.ToError(); @@ -508,7 +508,7 @@ Status status; ASSERT_TRUE(DWARFExpression::Evaluate( &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, dwarf_cu, - lldb::eRegisterKindLLDB, + nullptr, lldb::eRegisterKindLLDB, /*initial_value_ptr*/ nullptr, /*object_address_ptr*/ nullptr, result, &status)) << status.ToError();