Skip to content

Commit b0a3348

Browse files
[lldb][DWARFUnit] Implement PeekDIEName query
This allows us to query the AT_Name of a DIE without parsing the entire CU. Part of the ongoing effort to support IDX_Parent in accelerator tables [1]. [1]: https://discourse.llvm.org/t/rfc-improve-dwarf-5-debug-names-type-lookup-parsing-speed/74151/44
1 parent 2d5cc1c commit b0a3348

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,10 @@ DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
191191
return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset());
192192
return DWARFDIE(); // Not found
193193
}
194+
195+
llvm::StringRef
196+
DWARFDebugInfo::PeekDIEName(const DIERef &die_ref) {
197+
if(DWARFUnit *cu = GetUnit(die_ref))
198+
return cu->GetNonSkeletonUnit().PeekDIEName(die_ref.die_offset());
199+
return llvm::StringRef();
200+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class DWARFDebugInfo {
4343
bool ContainsTypeUnits();
4444
DWARFDIE GetDIE(const DIERef &die_ref);
4545

46+
/// Returns the AT_Name of this DIE, if it exists, without parsing the entire
47+
/// compile unit. An empty is string is returned upon error or if the
48+
/// attribute is not present.
49+
llvm::StringRef PeekDIEName(const DIERef &die_ref);
50+
4651
enum {
4752
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
4853
eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,14 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
663663
return DWARFDIE(); // Not found
664664
}
665665

666+
llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
667+
const DWARFDataExtractor &data = GetData();
668+
DWARFDebugInfoEntry die;
669+
if (!die.Extract(data, this, &die_offset))
670+
return llvm::StringRef();
671+
return die.GetName(this);
672+
}
673+
666674
DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
667675
ExtractUnitDIEIfNeeded();
668676
if (m_dwo)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ class DWARFUnit : public UserID {
187187

188188
DWARFDIE GetDIE(dw_offset_t die_offset);
189189

190+
/// Returns the AT_Name of the DIE at `die_offset`, if it exists, without
191+
/// parsing the entire compile unit. An empty is string is returned upon
192+
/// error or if the attribute is not present.
193+
llvm::StringRef PeekDIEName(dw_offset_t die_offset);
194+
190195
DWARFUnit &GetNonSkeletonUnit();
191196

192197
static uint8_t GetAddressByteSize(const DWARFUnit *cu);

lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
10+
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
1011
#include "TestingSupport/Symbol/YAMLModuleTester.h"
1112
#include "llvm/ADT/STLExtras.h"
1213
#include "gmock/gmock.h"
@@ -104,3 +105,61 @@ TEST(DWARFDIETest, ChildIteration) {
104105
DWARFDIE no_children_die(unit, die_child0);
105106
EXPECT_TRUE(no_children_die.children().empty());
106107
}
108+
109+
TEST(DWARFDIETest, PeekName) {
110+
const char *yamldata = R"(
111+
--- !ELF
112+
FileHeader:
113+
Class: ELFCLASS64
114+
Data: ELFDATA2LSB
115+
Type: ET_EXEC
116+
Machine: EM_386
117+
DWARF:
118+
debug_str:
119+
- 'NameType1'
120+
- 'NameType2'
121+
debug_abbrev:
122+
- Table:
123+
- Code: 0x00000001
124+
Tag: DW_TAG_compile_unit
125+
Children: DW_CHILDREN_yes
126+
Attributes:
127+
- Attribute: DW_AT_language
128+
Form: DW_FORM_data2
129+
- Code: 0x00000002
130+
Tag: DW_TAG_base_type
131+
Children: DW_CHILDREN_no
132+
Attributes:
133+
- Attribute: DW_AT_name
134+
Form: DW_FORM_strp
135+
debug_info:
136+
- Version: 4
137+
AddrSize: 8
138+
Entries:
139+
- AbbrCode: 0x00000001
140+
Values:
141+
- Value: 0x000000000000000C
142+
- AbbrCode: 0x00000002
143+
Values:
144+
- Value: 0x0000000000000000 # Name = NameType1
145+
- AbbrCode: 0x00000002
146+
Values:
147+
- Value: 0x000000000000000a # Name = NameType2
148+
- AbbrCode: 0x00000000
149+
)";
150+
151+
YAMLModuleTester t(yamldata);
152+
auto *symbol_file =
153+
llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());
154+
auto &debug_info = symbol_file->DebugInfo();
155+
156+
DIERef first_die(std::nullopt, DIERef::Section::DebugInfo,
157+
11 /*FirstDIEOffset*/);
158+
EXPECT_EQ(debug_info.PeekDIEName(first_die), "");
159+
160+
DIERef second_die(std::nullopt, DIERef::Section::DebugInfo, 14);
161+
EXPECT_EQ(debug_info.PeekDIEName(second_die), "NameType1");
162+
163+
DIERef third_die(std::nullopt, DIERef::Section::DebugInfo, 19);
164+
EXPECT_EQ(debug_info.PeekDIEName(third_die), "NameType2");
165+
}

0 commit comments

Comments
 (0)