Skip to content

Commit 464460d

Browse files
committed
[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.
1 parent 83356f3 commit 464460d

File tree

5 files changed

+101
-72
lines changed

5 files changed

+101
-72
lines changed

lldb/include/lldb/Expression/DWARFExpression.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace lldb_private {
2323

2424
namespace plugin {
2525
namespace dwarf {
26-
class DWARFUnit;
26+
class DWARFUnitInterface;
2727
} // namespace dwarf
2828
} // namespace plugin
2929

@@ -65,20 +65,20 @@ class DWARFExpression {
6565
/// \return
6666
/// The address specified by the operation, if the operation exists, or
6767
/// an llvm::Error otherwise.
68-
llvm::Expected<lldb::addr_t>
69-
GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
68+
llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr(
69+
const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
7070

71-
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
71+
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
7272
lldb::addr_t file_addr);
7373

7474
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
7575
uint8_t addr_byte_size);
7676

77-
bool
78-
ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
77+
bool ContainsThreadLocalStorage(
78+
const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
7979

8080
bool LinkThreadLocalStorage(
81-
const plugin::dwarf::DWARFUnit *dwarf_cu,
81+
const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
8282
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
8383
&link_address_callback);
8484

@@ -132,13 +132,14 @@ class DWARFExpression {
132132
static llvm::Expected<Value>
133133
Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
134134
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
135-
const plugin::dwarf::DWARFUnit *dwarf_cu,
135+
const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
136136
const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
137137
const Value *object_address_ptr);
138138

139-
static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu,
140-
const DataExtractor &data,
141-
DWARFExpressionList *loc_list);
139+
static bool
140+
ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
141+
const DataExtractor &data,
142+
DWARFExpressionList *loc_list);
142143

143144
bool GetExpressionData(DataExtractor &data) const {
144145
data = m_data;

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
133133
static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
134134
const lldb::offset_t data_offset,
135135
const LocationAtom op,
136-
const DWARFUnit *dwarf_cu) {
136+
const DWARFUnitInterface *dwarf_cu) {
137137
lldb::offset_t offset = data_offset;
138138
switch (op) {
139139
// Only used in LLVM metadata.
@@ -362,7 +362,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
362362
// + LEB128
363363
{
364364
data.Skip_LEB128(&offset);
365-
return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset;
365+
return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset -
366+
data_offset;
366367
}
367368

368369
case DW_OP_GNU_entry_value:
@@ -393,8 +394,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
393394
return LLDB_INVALID_OFFSET;
394395
}
395396

396-
llvm::Expected<lldb::addr_t>
397-
DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
397+
llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
398+
const DWARFUnitInterface *dwarf_cu) const {
398399
lldb::offset_t offset = 0;
399400
while (m_data.ValidOffset(offset)) {
400401
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -422,7 +423,7 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
422423
return LLDB_INVALID_ADDRESS;
423424
}
424425

425-
bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
426+
bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu,
426427
lldb::addr_t file_addr) {
427428
lldb::offset_t offset = 0;
428429
while (m_data.ValidOffset(offset)) {
@@ -481,7 +482,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
481482
}
482483

483484
bool DWARFExpression::ContainsThreadLocalStorage(
484-
const DWARFUnit *dwarf_cu) const {
485+
const DWARFUnitInterface *dwarf_cu) const {
485486
lldb::offset_t offset = 0;
486487
while (m_data.ValidOffset(offset)) {
487488
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -497,7 +498,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
497498
return false;
498499
}
499500
bool DWARFExpression::LinkThreadLocalStorage(
500-
const DWARFUnit *dwarf_cu,
501+
const DWARFUnitInterface *dwarf_cu,
501502
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
502503
&link_address_callback) {
503504
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
@@ -783,7 +784,8 @@ enum LocationDescriptionKind {
783784
/* Composite*/
784785
};
785786
/// Adjust value's ValueType according to the kind of location description.
786-
void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,
787+
void UpdateValueTypeFromLocationDescription(Log *log,
788+
const DWARFUnitInterface *dwarf_cu,
787789
LocationDescriptionKind kind,
788790
Value *value = nullptr) {
789791
// Note that this function is conflating DWARF expressions with
@@ -875,7 +877,7 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
875877
llvm::Expected<Value> DWARFExpression::Evaluate(
876878
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
877879
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
878-
const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
880+
const DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_kind,
879881
const Value *initial_value_ptr, const Value *object_address_ptr) {
880882

881883
if (opcodes.GetByteSize() == 0)
@@ -2164,35 +2166,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
21642166
if (!bit_size)
21652167
return llvm::createStringError("unspecified architecture");
21662168
} else {
2167-
// Retrieve the type DIE that the value is being converted to. This
2168-
// offset is compile unit relative so we need to fix it up.
2169-
const uint64_t abs_die_offset = die_offset + dwarf_cu->GetOffset();
2170-
// FIXME: the constness has annoying ripple effects.
2171-
DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
2172-
if (!die)
2173-
return llvm::createStringError(
2174-
"cannot resolve DW_OP_convert type DIE");
2175-
uint64_t encoding =
2176-
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
2177-
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
2178-
if (!bit_size)
2179-
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
2180-
if (!bit_size)
2181-
return llvm::createStringError(
2182-
"unsupported type size in DW_OP_convert");
2183-
switch (encoding) {
2184-
case DW_ATE_signed:
2185-
case DW_ATE_signed_char:
2186-
sign = true;
2187-
break;
2188-
case DW_ATE_unsigned:
2189-
case DW_ATE_unsigned_char:
2190-
sign = false;
2191-
break;
2192-
default:
2193-
return llvm::createStringError(
2194-
"unsupported encoding in DW_OP_convert");
2195-
}
2169+
if (llvm::Error err =
2170+
const_cast<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign(
2171+
die_offset, bit_size, sign))
2172+
return err;
21962173
}
21972174
Scalar &top = stack.back().ResolveValue(exe_ctx);
21982175
top.TruncOrExtendTo(bit_size, sign);
@@ -2353,7 +2330,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
23532330
}
23542331

23552332
bool DWARFExpression::ParseDWARFLocationList(
2356-
const DWARFUnit *dwarf_cu, const DataExtractor &data,
2333+
const DWARFUnitInterface *dwarf_cu, const DataExtractor &data,
23572334
DWARFExpressionList *location_list) {
23582335
location_list->Clear();
23592336
std::unique_ptr<llvm::DWARFLocationTable> loctable_up =

lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
4444
switch (m_form) {
4545
case DW_FORM_addr:
4646
assert(m_unit);
47-
m_value.uval =
48-
data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit));
47+
m_value.uval = data.GetMaxU64(
48+
offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit));
4949
break;
5050
case DW_FORM_block1:
5151
m_value.uval = data.GetU8(offset_ptr);
@@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
242242

243243
// Compile unit address sized values
244244
case DW_FORM_addr:
245-
*offset_ptr += DWARFUnit::GetAddressByteSize(unit);
245+
*offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit);
246246
return true;
247247

248248
case DW_FORM_ref_addr:

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,37 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
672672
return DWARFDIE(); // Not found
673673
}
674674

675+
llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset,
676+
uint64_t &bit_size, bool &sign) {
677+
// Retrieve the type DIE that the value is being converted to. This
678+
// offset is compile unit relative so we need to fix it up.
679+
const uint64_t abs_die_offset = die_offset + GetOffset();
680+
// FIXME: the constness has annoying ripple effects.
681+
DWARFDIE die = GetDIE(abs_die_offset);
682+
if (!die)
683+
return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
684+
uint64_t encoding =
685+
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
686+
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
687+
if (!bit_size)
688+
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
689+
if (!bit_size)
690+
return llvm::createStringError("unsupported type size in DW_OP_convert");
691+
switch (encoding) {
692+
case DW_ATE_signed:
693+
case DW_ATE_signed_char:
694+
sign = true;
695+
break;
696+
case DW_ATE_unsigned:
697+
case DW_ATE_unsigned_char:
698+
sign = false;
699+
break;
700+
default:
701+
return llvm::createStringError("unsupported encoding in DW_OP_convert");
702+
}
703+
return llvm::Error::success();
704+
}
705+
675706
llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
676707
DWARFDebugInfoEntry die;
677708
if (!die.Extract(GetData(), *this, &die_offset))
@@ -703,14 +734,6 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
703734
return *this;
704735
}
705736

706-
uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
707-
if (cu)
708-
return cu->GetAddressByteSize();
709-
return DWARFUnit::GetDefaultAddressSize();
710-
}
711-
712-
uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
713-
714737
DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() {
715738
if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) {
716739
SymbolFileDWARFDwo *dwo =

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,34 @@ enum DWARFProducer {
3838
eProducerOther
3939
};
4040

41-
class DWARFUnit : public UserID {
41+
class DWARFUnitInterface {
42+
public:
43+
DWARFUnitInterface() = default;
44+
virtual ~DWARFUnitInterface() = default;
45+
46+
virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0;
47+
virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
48+
virtual uint16_t GetVersion() const = 0;
49+
virtual std::unique_ptr<llvm::DWARFLocationTable>
50+
GetLocationTable(const DataExtractor &data) const = 0;
51+
virtual dw_addr_t GetBaseAddress() const = 0;
52+
virtual uint8_t GetAddressByteSize() const = 0;
53+
virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
54+
bool &sign) = 0;
55+
56+
static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) {
57+
if (cu)
58+
return cu->GetAddressByteSize();
59+
return GetDefaultAddressSize();
60+
}
61+
62+
static uint8_t GetDefaultAddressSize() { return 4; }
63+
64+
DWARFUnitInterface(const DWARFUnitInterface &) = delete;
65+
DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete;
66+
};
67+
68+
class DWARFUnit : public UserID, public DWARFUnitInterface {
4269
using die_iterator_range =
4370
llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
4471

@@ -116,12 +143,14 @@ class DWARFUnit : public UserID {
116143
size_t GetDebugInfoSize() const;
117144
// Size of the CU data incl. header but without initial length.
118145
dw_offset_t GetLength() const { return m_header.getLength(); }
119-
uint16_t GetVersion() const { return m_header.getVersion(); }
146+
uint16_t GetVersion() const override { return m_header.getVersion(); }
120147
const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
121148
dw_offset_t GetAbbrevOffset() const;
122-
uint8_t GetAddressByteSize() const { return m_header.getAddressByteSize(); }
149+
uint8_t GetAddressByteSize() const override {
150+
return m_header.getAddressByteSize();
151+
}
123152
dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); }
124-
dw_addr_t GetBaseAddress() const { return m_base_addr; }
153+
dw_addr_t GetBaseAddress() const override { return m_base_addr; }
125154
dw_offset_t GetLineTableOffset();
126155
dw_addr_t GetRangesBase() const { return m_ranges_base; }
127156
dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
@@ -131,7 +160,7 @@ class DWARFUnit : public UserID {
131160
void SetStrOffsetsBase(dw_offset_t str_offsets_base);
132161
virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;
133162

134-
dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const;
163+
dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override;
135164

136165
lldb::ByteOrder GetByteOrder() const;
137166

@@ -145,17 +174,16 @@ class DWARFUnit : public UserID {
145174

146175
DWARFDIE GetDIE(dw_offset_t die_offset);
147176

177+
llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
178+
bool &sign) override;
179+
148180
/// Returns the AT_Name of the DIE at `die_offset`, if it exists, without
149181
/// parsing the entire compile unit. An empty is string is returned upon
150182
/// error or if the attribute is not present.
151183
llvm::StringRef PeekDIEName(dw_offset_t die_offset);
152184

153185
DWARFUnit &GetNonSkeletonUnit();
154186

155-
static uint8_t GetAddressByteSize(const DWARFUnit *cu);
156-
157-
static uint8_t GetDefaultAddressSize();
158-
159187
lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; }
160188

161189
void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; }
@@ -174,7 +202,7 @@ class DWARFUnit : public UserID {
174202

175203
bool Supports_unnamed_objc_bitfields();
176204

177-
SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
205+
SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; }
178206

179207
DWARFProducer GetProducer();
180208

@@ -237,7 +265,7 @@ class DWARFUnit : public UserID {
237265
/// Return the location table for parsing the given location list data. The
238266
/// format is chosen according to the unit type. Never returns null.
239267
std::unique_ptr<llvm::DWARFLocationTable>
240-
GetLocationTable(const DataExtractor &data) const;
268+
GetLocationTable(const DataExtractor &data) const override;
241269

242270
DWARFDataExtractor GetLocationData() const;
243271

0 commit comments

Comments
 (0)