-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[LLDB][NFC] Added the interface DWARFExpression::Delegate to break dependencies and reduce lldb-server size #131645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
464460d
b5a5592
8e6a957
4269226
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,6 @@ | |
|
|
||
| #include "lldb/Core/Module.h" | ||
| #include "lldb/Core/Value.h" | ||
| #include "lldb/Core/dwarf.h" | ||
| #include "lldb/Utility/DataEncoder.h" | ||
| #include "lldb/Utility/LLDBLog.h" | ||
| #include "lldb/Utility/Log.h" | ||
|
|
@@ -37,7 +36,6 @@ | |
| #include "lldb/Target/StackID.h" | ||
| #include "lldb/Target/Target.h" | ||
| #include "lldb/Target/Thread.h" | ||
| #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" | ||
| #include "llvm/DebugInfo/DWARF/DWARFExpression.h" | ||
|
|
||
| #include "Plugins/SymbolFile/DWARF/DWARFUnit.h" | ||
|
||
|
|
@@ -130,10 +128,10 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx, | |
|
|
||
| /// Return the length in bytes of the set of operands for \p op. No guarantees | ||
| /// are made on the state of \p data after this call. | ||
| static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, | ||
| const lldb::offset_t data_offset, | ||
| const LocationAtom op, | ||
| const DWARFUnit *dwarf_cu) { | ||
| static lldb::offset_t | ||
| GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset, | ||
| const LocationAtom op, | ||
| const DWARFExpression::Delegate *dwarf_cu) { | ||
| lldb::offset_t offset = data_offset; | ||
| switch (op) { | ||
| // Only used in LLVM metadata. | ||
|
|
@@ -362,7 +360,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, | |
| // + LEB128 | ||
| { | ||
| data.Skip_LEB128(&offset); | ||
| return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset; | ||
| return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset - | ||
| data_offset; | ||
| } | ||
|
|
||
| case DW_OP_GNU_entry_value: | ||
|
|
@@ -387,14 +386,13 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, | |
| } | ||
|
|
||
| if (dwarf_cu) | ||
| return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize( | ||
| data, data_offset, op); | ||
| return dwarf_cu->GetVendorDWARFOpcodeSize(data, data_offset, op); | ||
|
|
||
| return LLDB_INVALID_OFFSET; | ||
| } | ||
|
|
||
| llvm::Expected<lldb::addr_t> | ||
| DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const { | ||
| llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr( | ||
| const DWARFExpression::Delegate *dwarf_cu) const { | ||
| lldb::offset_t offset = 0; | ||
| while (m_data.ValidOffset(offset)) { | ||
| const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset)); | ||
|
|
@@ -422,8 +420,8 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const { | |
| return LLDB_INVALID_ADDRESS; | ||
| } | ||
|
|
||
| bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu, | ||
| lldb::addr_t file_addr) { | ||
| bool DWARFExpression::Update_DW_OP_addr( | ||
| const DWARFExpression::Delegate *dwarf_cu, lldb::addr_t file_addr) { | ||
| lldb::offset_t offset = 0; | ||
| while (m_data.ValidOffset(offset)) { | ||
| const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset)); | ||
|
|
@@ -481,7 +479,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu, | |
| } | ||
|
|
||
| bool DWARFExpression::ContainsThreadLocalStorage( | ||
| const DWARFUnit *dwarf_cu) const { | ||
| const DWARFExpression::Delegate *dwarf_cu) const { | ||
| lldb::offset_t offset = 0; | ||
| while (m_data.ValidOffset(offset)) { | ||
| const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset)); | ||
|
|
@@ -497,7 +495,7 @@ bool DWARFExpression::ContainsThreadLocalStorage( | |
| return false; | ||
| } | ||
| bool DWARFExpression::LinkThreadLocalStorage( | ||
| const DWARFUnit *dwarf_cu, | ||
| const DWARFExpression::Delegate *dwarf_cu, | ||
| std::function<lldb::addr_t(lldb::addr_t file_addr)> const | ||
| &link_address_callback) { | ||
| const uint32_t addr_byte_size = m_data.GetAddressByteSize(); | ||
|
|
@@ -783,9 +781,9 @@ enum LocationDescriptionKind { | |
| /* Composite*/ | ||
| }; | ||
| /// Adjust value's ValueType according to the kind of location description. | ||
| void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu, | ||
| LocationDescriptionKind kind, | ||
| Value *value = nullptr) { | ||
| void UpdateValueTypeFromLocationDescription( | ||
| Log *log, const DWARFExpression::Delegate *dwarf_cu, | ||
| LocationDescriptionKind kind, Value *value = nullptr) { | ||
| // Note that this function is conflating DWARF expressions with | ||
| // DWARF location descriptions. Perhaps it would be better to define | ||
| // a wrapper for DWARFExpression::Eval() that deals with DWARF | ||
|
|
@@ -875,8 +873,9 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes, | |
| llvm::Expected<Value> 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) { | ||
| const DWARFExpression::Delegate *dwarf_cu, | ||
| const lldb::RegisterKind reg_kind, const Value *initial_value_ptr, | ||
| const Value *object_address_ptr) { | ||
|
|
||
| if (opcodes.GetByteSize() == 0) | ||
| return llvm::createStringError( | ||
|
|
@@ -2164,35 +2163,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate( | |
| if (!bit_size) | ||
| return llvm::createStringError("unspecified architecture"); | ||
| } else { | ||
| // Retrieve the type DIE that the value is being converted to. This | ||
| // offset is compile unit relative so we need to fix it up. | ||
| const uint64_t abs_die_offset = die_offset + dwarf_cu->GetOffset(); | ||
| // FIXME: the constness has annoying ripple effects. | ||
| DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset); | ||
| if (!die) | ||
| return llvm::createStringError( | ||
| "cannot resolve DW_OP_convert type DIE"); | ||
| uint64_t encoding = | ||
| die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user); | ||
| bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; | ||
| if (!bit_size) | ||
| bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0); | ||
| if (!bit_size) | ||
| return llvm::createStringError( | ||
| "unsupported type size in DW_OP_convert"); | ||
| switch (encoding) { | ||
| case DW_ATE_signed: | ||
| case DW_ATE_signed_char: | ||
| sign = true; | ||
| break; | ||
| case DW_ATE_unsigned: | ||
| case DW_ATE_unsigned_char: | ||
| sign = false; | ||
| break; | ||
| default: | ||
| return llvm::createStringError( | ||
| "unsupported encoding in DW_OP_convert"); | ||
| } | ||
| if (llvm::Error err = | ||
| const_cast<DWARFExpression::Delegate *>(dwarf_cu) | ||
| ->GetDIEBitSizeAndSign(die_offset, bit_size, sign)) | ||
| return err; | ||
| } | ||
| Scalar &top = stack.back().ResolveValue(exe_ctx); | ||
| top.TruncOrExtendTo(bit_size, sign); | ||
|
|
@@ -2316,8 +2290,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate( | |
|
|
||
| default: | ||
| if (dwarf_cu) { | ||
| if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode( | ||
| op, opcodes, offset, stack)) { | ||
| if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) { | ||
| break; | ||
| } | ||
| } | ||
|
|
@@ -2352,43 +2325,6 @@ llvm::Expected<Value> DWARFExpression::Evaluate( | |
| return stack.back(); | ||
| } | ||
|
|
||
| bool DWARFExpression::ParseDWARFLocationList( | ||
| const DWARFUnit *dwarf_cu, const DataExtractor &data, | ||
| DWARFExpressionList *location_list) { | ||
| location_list->Clear(); | ||
| std::unique_ptr<llvm::DWARFLocationTable> loctable_up = | ||
| dwarf_cu->GetLocationTable(data); | ||
| Log *log = GetLog(LLDBLog::Expressions); | ||
| auto lookup_addr = | ||
| [&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> { | ||
| addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index); | ||
| if (address == LLDB_INVALID_ADDRESS) | ||
| return std::nullopt; | ||
| return llvm::object::SectionedAddress{address}; | ||
| }; | ||
| auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) { | ||
| if (!loc) { | ||
| LLDB_LOG_ERROR(log, loc.takeError(), "{0}"); | ||
| return true; | ||
| } | ||
| auto buffer_sp = | ||
| std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size()); | ||
| DWARFExpression expr = DWARFExpression(DataExtractor( | ||
| buffer_sp, data.GetByteOrder(), data.GetAddressByteSize())); | ||
| location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr); | ||
| return true; | ||
| }; | ||
| llvm::Error error = loctable_up->visitAbsoluteLocationList( | ||
| 0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()}, | ||
| lookup_addr, process_list); | ||
| location_list->Sort(); | ||
| if (error) { | ||
| LLDB_LOG_ERROR(log, std::move(error), "{0}"); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool DWARFExpression::MatchesOperand( | ||
| StackFrame &frame, const Instruction::Operand &operand) const { | ||
| using namespace OperandMatchers; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -696,6 +696,87 @@ llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { | |||||||||||||
| return llvm::StringRef(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| llvm::Error DWARFUnit::GetDIEBitSizeAndSign(uint64_t die_offset, | ||||||||||||||
| uint64_t &bit_size, bool &sign) { | ||||||||||||||
| // Retrieve the type DIE that the value is being converted to. This | ||||||||||||||
| // offset is compile unit relative so we need to fix it up. | ||||||||||||||
| const uint64_t abs_die_offset = die_offset + GetOffset(); | ||||||||||||||
| // FIXME: the constness has annoying ripple effects. | ||||||||||||||
| DWARFDIE die = GetDIE(abs_die_offset); | ||||||||||||||
| if (!die) | ||||||||||||||
| return llvm::createStringError("cannot resolve DW_OP_convert type DIE"); | ||||||||||||||
| uint64_t encoding = | ||||||||||||||
| die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user); | ||||||||||||||
| bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; | ||||||||||||||
| if (!bit_size) | ||||||||||||||
| bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0); | ||||||||||||||
| if (!bit_size) | ||||||||||||||
| return llvm::createStringError("unsupported type size in DW_OP_convert"); | ||||||||||||||
|
||||||||||||||
| return llvm::createStringError("unsupported type size in DW_OP_convert"); | |
| return llvm::createStringError("unsupported type size"); |
Let's not mention DW_OP_convert here. (same below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change this to a reference while we're here.
| bool DWARFUnit::ParseDWARFLocationList( | |
| const DataExtractor &data, DWARFExpressionList *location_list) const { | |
| location_list->Clear(); | |
| bool DWARFUnit::ParseDWARFLocationList( | |
| const DataExtractor &data, DWARFExpressionList &location_list) const { | |
| location_list.Clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm prioritizing the interface over implementation, so I'm making the method const. You can put the const_cast into the implementation (I think it's only needed for
GetDIE. I am also emphasizing the relativeness of the die offset as lldb default is to use absolute section offsets)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.