https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/131645
>From 464460db7550673bac788ad11e3ed4d45946cd71 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev <dvassil...@accesssoftek.com> Date: Mon, 17 Mar 2025 19:13:20 +0400 Subject: [PATCH 1/3] [LLDB][NFC] Added the interface DWARFUnitInterface to break dependencies and reduce lldb-server size This patch addresses the issue #129543. After this patch DWARFExpression does not call DWARFUnit directly and does not depend on lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp and a lot of clang code. After this patch the size of lldb-server binary (Linux Aarch64) is reduced from 42MB to 13MB with LLVM 20.0.0 and from 47MB to 17MB with LLVM 21.0.0. --- .../include/lldb/Expression/DWARFExpression.h | 23 ++++---- lldb/source/Expression/DWARFExpression.cpp | 55 ++++++------------- .../SymbolFile/DWARF/DWARFFormValue.cpp | 6 +- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 39 ++++++++++--- .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 50 +++++++++++++---- 5 files changed, 101 insertions(+), 72 deletions(-) diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index 2c1e717ee32eb..cf4098f2acc51 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -23,7 +23,7 @@ namespace lldb_private { namespace plugin { namespace dwarf { -class DWARFUnit; +class DWARFUnitInterface; } // namespace dwarf } // namespace plugin @@ -65,20 +65,20 @@ class DWARFExpression { /// \return /// The address specified by the operation, if the operation exists, or /// an llvm::Error otherwise. - llvm::Expected<lldb::addr_t> - GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const; + llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr( + const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const; - bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu, + bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu, lldb::addr_t file_addr); void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, uint8_t addr_byte_size); - bool - ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const; + bool ContainsThreadLocalStorage( + const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const; bool LinkThreadLocalStorage( - const plugin::dwarf::DWARFUnit *dwarf_cu, + const plugin::dwarf::DWARFUnitInterface *dwarf_cu, std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback); @@ -132,13 +132,14 @@ class DWARFExpression { static llvm::Expected<Value> Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, - const plugin::dwarf::DWARFUnit *dwarf_cu, + const plugin::dwarf::DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_set, const Value *initial_value_ptr, const Value *object_address_ptr); - static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu, - const DataExtractor &data, - DWARFExpressionList *loc_list); + static bool + ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu, + const DataExtractor &data, + DWARFExpressionList *loc_list); bool GetExpressionData(DataExtractor &data) const { data = m_data; diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index f48f3ab9307dd..41fbca59db60f 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -133,7 +133,7 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx, static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset, const LocationAtom op, - const DWARFUnit *dwarf_cu) { + const DWARFUnitInterface *dwarf_cu) { lldb::offset_t offset = data_offset; switch (op) { // Only used in LLVM metadata. @@ -362,7 +362,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, // + LEB128 { data.Skip_LEB128(&offset); - return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset; + return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset - + data_offset; } case DW_OP_GNU_entry_value: @@ -393,8 +394,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, 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 DWARFUnitInterface *dwarf_cu) const { lldb::offset_t offset = 0; while (m_data.ValidOffset(offset)) { const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset)); @@ -422,7 +423,7 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const { return LLDB_INVALID_ADDRESS; } -bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu, +bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu, lldb::addr_t file_addr) { lldb::offset_t offset = 0; while (m_data.ValidOffset(offset)) { @@ -481,7 +482,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu, } bool DWARFExpression::ContainsThreadLocalStorage( - const DWARFUnit *dwarf_cu) const { + const DWARFUnitInterface *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 +498,7 @@ bool DWARFExpression::ContainsThreadLocalStorage( return false; } bool DWARFExpression::LinkThreadLocalStorage( - const DWARFUnit *dwarf_cu, + const DWARFUnitInterface *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,7 +784,8 @@ enum LocationDescriptionKind { /* Composite*/ }; /// Adjust value's ValueType according to the kind of location description. -void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu, +void UpdateValueTypeFromLocationDescription(Log *log, + const DWARFUnitInterface *dwarf_cu, LocationDescriptionKind kind, Value *value = nullptr) { // Note that this function is conflating DWARF expressions with @@ -875,7 +877,7 @@ 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 DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_kind, const Value *initial_value_ptr, const Value *object_address_ptr) { if (opcodes.GetByteSize() == 0) @@ -2164,35 +2166,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<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign( + die_offset, bit_size, sign)) + return err; } Scalar &top = stack.back().ResolveValue(exe_ctx); top.TruncOrExtendTo(bit_size, sign); @@ -2353,7 +2330,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate( } bool DWARFExpression::ParseDWARFLocationList( - const DWARFUnit *dwarf_cu, const DataExtractor &data, + const DWARFUnitInterface *dwarf_cu, const DataExtractor &data, DWARFExpressionList *location_list) { location_list->Clear(); std::unique_ptr<llvm::DWARFLocationTable> loctable_up = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index fd3d45cef4c5e..c2f4cc6a24af7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, switch (m_form) { case DW_FORM_addr: assert(m_unit); - m_value.uval = - data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit)); + m_value.uval = data.GetMaxU64( + offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit)); break; case DW_FORM_block1: m_value.uval = data.GetU8(offset_ptr); @@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // Compile unit address sized values case DW_FORM_addr: - *offset_ptr += DWARFUnit::GetAddressByteSize(unit); + *offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit); return true; case DW_FORM_ref_addr: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 1ceeef76f7cc3..168b134b84e2f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -672,6 +672,37 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) { return DWARFDIE(); // Not found } +llvm::Error DWARFUnit::GetBitSizeAndSign(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"); + 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"); + } + return llvm::Error::success(); +} + llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { DWARFDebugInfoEntry die; if (!die.Extract(GetData(), *this, &die_offset)) @@ -703,14 +734,6 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { return *this; } -uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) { - if (cu) - return cu->GetAddressByteSize(); - return DWARFUnit::GetDefaultAddressSize(); -} - -uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } - DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() { if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) { SymbolFileDWARFDwo *dwo = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index ba142ae86fe0e..8d0bf51208108 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -38,7 +38,34 @@ enum DWARFProducer { eProducerOther }; -class DWARFUnit : public UserID { +class DWARFUnitInterface { +public: + DWARFUnitInterface() = default; + virtual ~DWARFUnitInterface() = default; + + virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0; + virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0; + virtual uint16_t GetVersion() const = 0; + virtual std::unique_ptr<llvm::DWARFLocationTable> + GetLocationTable(const DataExtractor &data) const = 0; + virtual dw_addr_t GetBaseAddress() const = 0; + virtual uint8_t GetAddressByteSize() const = 0; + virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, + bool &sign) = 0; + + static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) { + if (cu) + return cu->GetAddressByteSize(); + return GetDefaultAddressSize(); + } + + static uint8_t GetDefaultAddressSize() { return 4; } + + DWARFUnitInterface(const DWARFUnitInterface &) = delete; + DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete; +}; + +class DWARFUnit : public UserID, public DWARFUnitInterface { using die_iterator_range = llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>; @@ -116,12 +143,14 @@ class DWARFUnit : public UserID { size_t GetDebugInfoSize() const; // Size of the CU data incl. header but without initial length. dw_offset_t GetLength() const { return m_header.getLength(); } - uint16_t GetVersion() const { return m_header.getVersion(); } + uint16_t GetVersion() const override { return m_header.getVersion(); } const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; - uint8_t GetAddressByteSize() const { return m_header.getAddressByteSize(); } + uint8_t GetAddressByteSize() const override { + return m_header.getAddressByteSize(); + } dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); } - dw_addr_t GetBaseAddress() const { return m_base_addr; } + dw_addr_t GetBaseAddress() const override { return m_base_addr; } dw_offset_t GetLineTableOffset(); dw_addr_t GetRangesBase() const { return m_ranges_base; } dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; } @@ -131,7 +160,7 @@ class DWARFUnit : public UserID { void SetStrOffsetsBase(dw_offset_t str_offsets_base); virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0; - dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const; + dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override; lldb::ByteOrder GetByteOrder() const; @@ -145,6 +174,9 @@ class DWARFUnit : public UserID { DWARFDIE GetDIE(dw_offset_t die_offset); + llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, + bool &sign) override; + /// Returns the AT_Name of the DIE at `die_offset`, if it exists, without /// parsing the entire compile unit. An empty is string is returned upon /// error or if the attribute is not present. @@ -152,10 +184,6 @@ class DWARFUnit : public UserID { DWARFUnit &GetNonSkeletonUnit(); - static uint8_t GetAddressByteSize(const DWARFUnit *cu); - - static uint8_t GetDefaultAddressSize(); - lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; } void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; } @@ -174,7 +202,7 @@ class DWARFUnit : public UserID { bool Supports_unnamed_objc_bitfields(); - SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; } + SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; } DWARFProducer GetProducer(); @@ -237,7 +265,7 @@ class DWARFUnit : public UserID { /// Return the location table for parsing the given location list data. The /// format is chosen according to the unit type. Never returns null. std::unique_ptr<llvm::DWARFLocationTable> - GetLocationTable(const DataExtractor &data) const; + GetLocationTable(const DataExtractor &data) const override; DWARFDataExtractor GetLocationData() const; >From b5a55922e60719ae252bf62ea9345b83312a4af6 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev <dvassil...@accesssoftek.com> Date: Tue, 18 Mar 2025 20:52:28 +0400 Subject: [PATCH 2/3] Replaced DWARFUnitInterface with DWARFExpression::Delegate. Moved ParseDWARFLocationList to DWARF plugin. --- .../include/lldb/Expression/DWARFExpression.h | 54 ++++++---- lldb/source/Expression/DWARFExpression.cpp | 81 ++++---------- .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 2 +- .../SymbolFile/DWARF/DWARFFormValue.cpp | 6 +- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 100 ++++++++++++++---- .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 55 ++++------ .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- 7 files changed, 159 insertions(+), 141 deletions(-) diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index cf4098f2acc51..e37f9db2cf6cf 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -11,6 +11,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" +#include "lldb/Core/dwarf.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" @@ -21,12 +22,6 @@ namespace lldb_private { -namespace plugin { -namespace dwarf { -class DWARFUnitInterface; -} // namespace dwarf -} // namespace plugin - /// \class DWARFExpression DWARFExpression.h /// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location /// expression and interprets it. @@ -40,6 +35,31 @@ class DWARFUnitInterface; /// location expression or a location list and interprets it. class DWARFExpression { public: + class Delegate { + public: + Delegate() = default; + virtual ~Delegate() = default; + + virtual uint16_t GetVersion() const = 0; + virtual dw_addr_t GetBaseAddress() const = 0; + virtual uint8_t GetAddressByteSize() const = 0; + virtual llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset, + uint64_t &bit_size, + bool &sign) = 0; + virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0; + virtual lldb::offset_t + GetVendorDWARFOpcodeSize(const DataExtractor &data, + const lldb::offset_t data_offset, + const uint8_t op) const = 0; + virtual bool ParseVendorDWARFOpcode(uint8_t op, + const DataExtractor &opcodes, + lldb::offset_t &offset, + std::vector<Value> &stack) const = 0; + + Delegate(const Delegate &) = delete; + Delegate &operator=(const Delegate &) = delete; + }; + DWARFExpression(); /// Constructor @@ -65,20 +85,18 @@ class DWARFExpression { /// \return /// The address specified by the operation, if the operation exists, or /// an llvm::Error otherwise. - llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr( - const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const; + llvm::Expected<lldb::addr_t> + GetLocation_DW_OP_addr(const Delegate *dwarf_cu) const; - bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu, - lldb::addr_t file_addr); + bool Update_DW_OP_addr(const Delegate *dwarf_cu, lldb::addr_t file_addr); void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, uint8_t addr_byte_size); - bool ContainsThreadLocalStorage( - const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const; + bool ContainsThreadLocalStorage(const Delegate *dwarf_cu) const; bool LinkThreadLocalStorage( - const plugin::dwarf::DWARFUnitInterface *dwarf_cu, + const Delegate *dwarf_cu, std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback); @@ -132,14 +150,8 @@ class DWARFExpression { static llvm::Expected<Value> Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, - const plugin::dwarf::DWARFUnitInterface *dwarf_cu, - const lldb::RegisterKind reg_set, const Value *initial_value_ptr, - const Value *object_address_ptr); - - static bool - ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu, - const DataExtractor &data, - DWARFExpressionList *loc_list); + const Delegate *dwarf_cu, const lldb::RegisterKind reg_set, + const Value *initial_value_ptr, const Value *object_address_ptr); bool GetExpressionData(DataExtractor &data) const { data = m_data; diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 41fbca59db60f..b80dea8b66c7c 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -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 DWARFUnitInterface *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,7 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data, // + LEB128 { data.Skip_LEB128(&offset); - return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset - + return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset - data_offset; } @@ -388,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 DWARFUnitInterface *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)); @@ -423,8 +420,8 @@ llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr( return LLDB_INVALID_ADDRESS; } -bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *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)); @@ -482,7 +479,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu, } bool DWARFExpression::ContainsThreadLocalStorage( - const DWARFUnitInterface *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)); @@ -498,7 +495,7 @@ bool DWARFExpression::ContainsThreadLocalStorage( return false; } bool DWARFExpression::LinkThreadLocalStorage( - const DWARFUnitInterface *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(); @@ -784,10 +781,9 @@ enum LocationDescriptionKind { /* Composite*/ }; /// Adjust value's ValueType according to the kind of location description. -void UpdateValueTypeFromLocationDescription(Log *log, - const DWARFUnitInterface *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 @@ -877,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 DWARFUnitInterface *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( @@ -2167,8 +2164,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate( return llvm::createStringError("unspecified architecture"); } else { if (llvm::Error err = - const_cast<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign( - die_offset, bit_size, sign)) + const_cast<DWARFExpression::Delegate *>(dwarf_cu) + ->GetDIEBitSizeAndSign(die_offset, bit_size, sign)) return err; } Scalar &top = stack.back().ResolveValue(exe_ctx); @@ -2293,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; } } @@ -2329,43 +2325,6 @@ llvm::Expected<Value> DWARFExpression::Evaluate( return stack.back(); } -bool DWARFExpression::ParseDWARFLocationList( - const DWARFUnitInterface *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; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 5b23f2e63fe6d..fa3acf04fbbf8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -240,7 +240,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( data = DataExtractor(data, offset, data.GetByteSize() - offset); if (lo_pc != LLDB_INVALID_ADDRESS) { assert(lo_pc >= cu->GetBaseAddress()); - DWARFExpression::ParseDWARFLocationList(cu, data, frame_base); + cu->ParseDWARFLocationList(data, frame_base); frame_base->SetFuncFileAddress(lo_pc); } else set_frame_base_loclist_addr = true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index c2f4cc6a24af7..fd3d45cef4c5e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, switch (m_form) { case DW_FORM_addr: assert(m_unit); - m_value.uval = data.GetMaxU64( - offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit)); + m_value.uval = + data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit)); break; case DW_FORM_block1: m_value.uval = data.GetU8(offset_ptr); @@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // Compile unit address sized values case DW_FORM_addr: - *offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit); + *offset_ptr += DWARFUnit::GetAddressByteSize(unit); return true; case DW_FORM_ref_addr: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 168b134b84e2f..05bd623b48bf3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -672,8 +672,32 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) { return DWARFDIE(); // Not found } -llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset, - uint64_t &bit_size, bool &sign) { +llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { + DWARFDebugInfoEntry die; + if (!die.Extract(GetData(), *this, &die_offset)) + return llvm::StringRef(); + + // Does die contain a DW_AT_Name? + if (const char *name = + die.GetAttributeValueAsString(this, DW_AT_name, nullptr)) + return name; + + // Does its DW_AT_specification or DW_AT_abstract_origin contain an AT_Name? + for (auto attr : {DW_AT_specification, DW_AT_abstract_origin}) { + DWARFFormValue form_value; + if (!die.GetAttributeValue(this, attr, form_value)) + continue; + auto [unit, offset] = form_value.ReferencedUnitAndOffset(); + if (unit) + if (auto name = unit->PeekDIEName(offset); !name.empty()) + return name; + } + + 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(); @@ -703,28 +727,54 @@ llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset, return llvm::Error::success(); } -llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { - DWARFDebugInfoEntry die; - if (!die.Extract(GetData(), *this, &die_offset)) - return llvm::StringRef(); +lldb::offset_t +DWARFUnit::GetVendorDWARFOpcodeSize(const DataExtractor &data, + const lldb::offset_t data_offset, + const uint8_t op) const { + return GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(data, data_offset, op); +} - // Does die contain a DW_AT_Name? - if (const char *name = - die.GetAttributeValueAsString(this, DW_AT_name, nullptr)) - return name; +bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, + lldb::offset_t &offset, + std::vector<Value> &stack) const { + return GetSymbolFileDWARF().ParseVendorDWARFOpcode(op, opcodes, offset, + stack); +} - // Does its DW_AT_specification or DW_AT_abstract_origin contain an AT_Name? - for (auto attr : {DW_AT_specification, DW_AT_abstract_origin}) { - DWARFFormValue form_value; - if (!die.GetAttributeValue(this, attr, form_value)) - continue; - auto [unit, offset] = form_value.ReferencedUnitAndOffset(); - if (unit) - if (auto name = unit->PeekDIEName(offset); !name.empty()) - return name; +bool DWARFUnit::ParseDWARFLocationList( + const DataExtractor &data, DWARFExpressionList *location_list) const { + location_list->Clear(); + std::unique_ptr<llvm::DWARFLocationTable> loctable_up = + GetLocationTable(data); + Log *log = GetLog(DWARFLog::DebugInfo); + auto lookup_addr = + [&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> { + addr_t address = 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{GetBaseAddress()}, lookup_addr, + process_list); + location_list->Sort(); + if (error) { + LLDB_LOG_ERROR(log, std::move(error), "{0}"); + return false; } - - return llvm::StringRef(); + return true; } DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { @@ -734,6 +784,14 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { return *this; } +uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) { + if (cu) + return cu->GetAddressByteSize(); + return DWARFUnit::GetDefaultAddressSize(); +} + +uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } + DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() { if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) { SymbolFileDWARFDwo *dwo = diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 8d0bf51208108..9969ae9b4c09e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -11,6 +11,7 @@ #include "DWARFDIE.h" #include "DWARFDebugInfoEntry.h" +#include "lldb/Expression/DWARFExpression.h" #include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-enumerations.h" #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" @@ -38,34 +39,7 @@ enum DWARFProducer { eProducerOther }; -class DWARFUnitInterface { -public: - DWARFUnitInterface() = default; - virtual ~DWARFUnitInterface() = default; - - virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0; - virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0; - virtual uint16_t GetVersion() const = 0; - virtual std::unique_ptr<llvm::DWARFLocationTable> - GetLocationTable(const DataExtractor &data) const = 0; - virtual dw_addr_t GetBaseAddress() const = 0; - virtual uint8_t GetAddressByteSize() const = 0; - virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, - bool &sign) = 0; - - static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) { - if (cu) - return cu->GetAddressByteSize(); - return GetDefaultAddressSize(); - } - - static uint8_t GetDefaultAddressSize() { return 4; } - - DWARFUnitInterface(const DWARFUnitInterface &) = delete; - DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete; -}; - -class DWARFUnit : public UserID, public DWARFUnitInterface { +class DWARFUnit : public UserID, public DWARFExpression::Delegate { using die_iterator_range = llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>; @@ -174,16 +148,31 @@ class DWARFUnit : public UserID, public DWARFUnitInterface { DWARFDIE GetDIE(dw_offset_t die_offset); - llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, - bool &sign) override; - /// Returns the AT_Name of the DIE at `die_offset`, if it exists, without /// parsing the entire compile unit. An empty is string is returned upon /// error or if the attribute is not present. llvm::StringRef PeekDIEName(dw_offset_t die_offset); + llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, + bool &sign) override; + + lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data, + const lldb::offset_t data_offset, + const uint8_t op) const override; + + bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, + lldb::offset_t &offset, + std::vector<Value> &stack) const override; + + bool ParseDWARFLocationList(const DataExtractor &data, + DWARFExpressionList *loc_list) const; + DWARFUnit &GetNonSkeletonUnit(); + static uint8_t GetAddressByteSize(const DWARFUnit *cu); + + static uint8_t GetDefaultAddressSize(); + lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; } void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; } @@ -202,7 +191,7 @@ class DWARFUnit : public UserID, public DWARFUnitInterface { bool Supports_unnamed_objc_bitfields(); - SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; } + SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; } DWARFProducer GetProducer(); @@ -265,7 +254,7 @@ class DWARFUnit : public UserID, public DWARFUnitInterface { /// Return the location table for parsing the given location list data. The /// format is chosen according to the unit type. Never returns null. std::unique_ptr<llvm::DWARFLocationTable> - GetLocationTable(const DataExtractor &data) const override; + GetLocationTable(const DataExtractor &data) const; DWARFDataExtractor GetLocationData() const; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d1aaf0bd36de4..7600459ac90b3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3296,7 +3296,7 @@ static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value, if (data.ValidOffset(offset)) { data = DataExtractor(data, offset, data.GetByteSize() - offset); const DWARFUnit *dwarf_cu = form_value.GetUnit(); - if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list)) + if (dwarf_cu->ParseDWARFLocationList(data, &location_list)) location_list.SetFuncFileAddress(func_low_pc); } >From 8e6a957eb92505eecd660c42103650a0c46d2eba Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev <dvassil...@accesssoftek.com> Date: Fri, 21 Mar 2025 18:23:00 +0400 Subject: [PATCH 3/3] Updated according to review. --- .../include/lldb/Expression/DWARFExpression.h | 5 ++-- lldb/source/Expression/DWARFExpression.cpp | 14 ++++++----- .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 2 +- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 25 ++++++++++--------- .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 8 +++--- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index e37f9db2cf6cf..0adbe3e8df2ee 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -43,9 +43,8 @@ class DWARFExpression { virtual uint16_t GetVersion() const = 0; virtual dw_addr_t GetBaseAddress() const = 0; virtual uint8_t GetAddressByteSize() const = 0; - virtual llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset, - uint64_t &bit_size, - bool &sign) = 0; + virtual llvm::Expected<std::pair<uint64_t, bool>> + GetDIEBitSizeAndSign(uint64_t relative_die_offset) const = 0; virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0; virtual lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data, diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index b80dea8b66c7c..ae3b634dfda60 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -2149,10 +2149,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate( // DESCRIPTION: Pop the top stack element, convert it to a // different type, and push the result. case DW_OP_convert: { - const uint64_t die_offset = opcodes.GetULEB128(&offset); + const uint64_t relative_die_offset = opcodes.GetULEB128(&offset); uint64_t bit_size; bool sign; - if (die_offset == 0) { + if (relative_die_offset == 0) { // The generic type has the size of an address on the target // machine and an unspecified signedness. Scalar has no // "unspecified signedness", so we use unsigned types. @@ -2163,10 +2163,12 @@ llvm::Expected<Value> DWARFExpression::Evaluate( if (!bit_size) return llvm::createStringError("unspecified architecture"); } else { - if (llvm::Error err = - const_cast<DWARFExpression::Delegate *>(dwarf_cu) - ->GetDIEBitSizeAndSign(die_offset, bit_size, sign)) - return err; + auto bit_size_sign_or_err = + dwarf_cu->GetDIEBitSizeAndSign(relative_die_offset); + if (!bit_size_sign_or_err) + return bit_size_sign_or_err.takeError(); + bit_size = bit_size_sign_or_err->first; + sign = bit_size_sign_or_err->second; } Scalar &top = stack.back().ResolveValue(exe_ctx); top.TruncOrExtendTo(bit_size, sign); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index fa3acf04fbbf8..5196ce89a2c13 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -240,7 +240,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( data = DataExtractor(data, offset, data.GetByteSize() - offset); if (lo_pc != LLDB_INVALID_ADDRESS) { assert(lo_pc >= cu->GetBaseAddress()); - cu->ParseDWARFLocationList(data, frame_base); + cu->ParseDWARFLocationList(data, *frame_base); frame_base->SetFuncFileAddress(lo_pc); } else set_frame_base_loclist_addr = true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 05bd623b48bf3..7d0afc04ac3b6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -696,22 +696,23 @@ 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) { +llvm::Expected<std::pair<uint64_t, bool>> +DWARFUnit::GetDIEBitSizeAndSign(uint64_t relative_die_offset) const { // 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(); + const uint64_t abs_die_offset = relative_die_offset + GetOffset(); // FIXME: the constness has annoying ripple effects. - DWARFDIE die = GetDIE(abs_die_offset); + DWARFDIE die = const_cast<DWARFUnit *>(this)->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; + uint64_t 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"); + bool sign; switch (encoding) { case DW_ATE_signed: case DW_ATE_signed_char: @@ -722,9 +723,9 @@ llvm::Error DWARFUnit::GetDIEBitSizeAndSign(uint64_t die_offset, sign = false; break; default: - return llvm::createStringError("unsupported encoding in DW_OP_convert"); + return llvm::createStringError("unsupported encoding"); } - return llvm::Error::success(); + return std::pair{bit_size, sign}; } lldb::offset_t @@ -742,8 +743,8 @@ bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, } bool DWARFUnit::ParseDWARFLocationList( - const DataExtractor &data, DWARFExpressionList *location_list) const { - location_list->Clear(); + const DataExtractor &data, DWARFExpressionList &location_list) const { + location_list.Clear(); std::unique_ptr<llvm::DWARFLocationTable> loctable_up = GetLocationTable(data); Log *log = GetLog(DWARFLog::DebugInfo); @@ -763,13 +764,13 @@ bool DWARFUnit::ParseDWARFLocationList( 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); + location_list.AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr); return true; }; llvm::Error error = loctable_up->visitAbsoluteLocationList( 0, llvm::object::SectionedAddress{GetBaseAddress()}, lookup_addr, process_list); - location_list->Sort(); + location_list.Sort(); if (error) { LLDB_LOG_ERROR(log, std::move(error), "{0}"); return false; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 9969ae9b4c09e..75a003e0a663c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -39,7 +39,7 @@ enum DWARFProducer { eProducerOther }; -class DWARFUnit : public UserID, public DWARFExpression::Delegate { +class DWARFUnit : public DWARFExpression::Delegate, public UserID { using die_iterator_range = llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>; @@ -153,8 +153,8 @@ class DWARFUnit : public UserID, public DWARFExpression::Delegate { /// error or if the attribute is not present. llvm::StringRef PeekDIEName(dw_offset_t die_offset); - llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size, - bool &sign) override; + llvm::Expected<std::pair<uint64_t, bool>> + GetDIEBitSizeAndSign(uint64_t relative_die_offset) const override; lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data, const lldb::offset_t data_offset, @@ -165,7 +165,7 @@ class DWARFUnit : public UserID, public DWARFExpression::Delegate { std::vector<Value> &stack) const override; bool ParseDWARFLocationList(const DataExtractor &data, - DWARFExpressionList *loc_list) const; + DWARFExpressionList &loc_list) const; DWARFUnit &GetNonSkeletonUnit(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 7600459ac90b3..b95159d882bc7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3296,7 +3296,7 @@ static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value, if (data.ValidOffset(offset)) { data = DataExtractor(data, offset, data.GetByteSize() - offset); const DWARFUnit *dwarf_cu = form_value.GetUnit(); - if (dwarf_cu->ParseDWARFLocationList(data, &location_list)) + if (dwarf_cu->ParseDWARFLocationList(data, location_list)) location_list.SetFuncFileAddress(func_low_pc); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits