[Lldb-commits] [lldb] [LLDB][NFC] Added the interface DWARFExpression::Delegate to break dependencies and reduce lldb-server size (PR #131645)
Dmitry Vasilyev via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 24 04:44:10 PDT 2025
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 <dvassiliev at accesssoftek.com>
Date: Mon, 17 Mar 2025 19:13:20 +0400
Subject: [PATCH 1/4] [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 <dvassiliev at accesssoftek.com>
Date: Tue, 18 Mar 2025 20:52:28 +0400
Subject: [PATCH 2/4] 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 <dvassiliev at accesssoftek.com>
Date: Fri, 21 Mar 2025 18:23:00 +0400
Subject: [PATCH 3/4] 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);
}
>From 42692267a9c200aadc7ce0c24d463e3c76821b08 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Mon, 24 Mar 2025 15:43:56 +0400
Subject: [PATCH 4/4] Removed #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
from DWARFExpression.cpp Moved DW_OP_value_to_name() from DWARFDefines.cpp to
DWARFExpression.cpp
---
lldb/source/Expression/DWARFExpression.cpp | 12 ++++++++++--
.../source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp | 10 ----------
lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h | 2 --
3 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index ae3b634dfda60..4b2b111e08e6d 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -38,8 +38,6 @@
#include "lldb/Target/Thread.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
-
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::dwarf;
@@ -391,6 +389,16 @@ GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset,
return LLDB_INVALID_OFFSET;
}
+static const char *DW_OP_value_to_name(uint32_t val) {
+ static char invalid[100];
+ llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
+ if (llvmstr.empty()) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr.data();
+}
+
llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
const DWARFExpression::Delegate *dwarf_cu) const {
lldb::offset_t offset = 0;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 2fb0c224bf8e8..53a9a1227337f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -23,15 +23,5 @@ llvm::StringRef DW_TAG_value_to_name(dw_tag_t tag) {
return s_unknown_tag_name;
}
-const char *DW_OP_value_to_name(uint32_t val) {
- static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
- if (llvmstr.empty()) {
- snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
- return invalid;
- }
- return llvmstr.data();
-}
-
} // namespace dwarf
} // namespace lldb_private::plugin
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index be81cb0f5df1e..6e33371c34854 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -17,8 +17,6 @@ namespace dwarf {
llvm::StringRef DW_TAG_value_to_name(dw_tag_t tag);
-const char *DW_OP_value_to_name(uint32_t val);
-
} // namespace dwarf
} // namespace lldb_private::plugin
More information about the lldb-commits
mailing list