Skip to content

Commit

Permalink
[lldb][DWARFUnit] Implement PeekDIEName query
Browse files Browse the repository at this point in the history
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
  • Loading branch information
felipepiovezan committed Jan 17, 2024
1 parent 2d5cc1c commit b0a3348
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,10 @@ DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset());
return DWARFDIE(); // Not found
}

llvm::StringRef
DWARFDebugInfo::PeekDIEName(const DIERef &die_ref) {
if(DWARFUnit *cu = GetUnit(die_ref))
return cu->GetNonSkeletonUnit().PeekDIEName(die_ref.die_offset());
return llvm::StringRef();
}
5 changes: 5 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ class DWARFDebugInfo {
bool ContainsTypeUnits();
DWARFDIE GetDIE(const DIERef &die_ref);

/// Returns the AT_Name of this DIE, 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(const DIERef &die_ref);

enum {
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,14 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
return DWARFDIE(); // Not found
}

llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
const DWARFDataExtractor &data = GetData();
DWARFDebugInfoEntry die;
if (!die.Extract(data, this, &die_offset))
return llvm::StringRef();
return die.GetName(this);
}

DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
ExtractUnitDIEIfNeeded();
if (m_dwo)
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ class DWARFUnit : public UserID {

DWARFDIE GetDIE(dw_offset_t die_offset);

/// 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);

DWARFUnit &GetNonSkeletonUnit();

static uint8_t GetAddressByteSize(const DWARFUnit *cu);
Expand Down
59 changes: 59 additions & 0 deletions lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "TestingSupport/Symbol/YAMLModuleTester.h"
#include "llvm/ADT/STLExtras.h"
#include "gmock/gmock.h"
Expand Down Expand Up @@ -104,3 +105,61 @@ TEST(DWARFDIETest, ChildIteration) {
DWARFDIE no_children_die(unit, die_child0);
EXPECT_TRUE(no_children_die.children().empty());
}

TEST(DWARFDIETest, PeekName) {
const char *yamldata = R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_386
DWARF:
debug_str:
- 'NameType1'
- 'NameType2'
debug_abbrev:
- Table:
- Code: 0x00000001
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_language
Form: DW_FORM_data2
- Code: 0x00000002
Tag: DW_TAG_base_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_name
Form: DW_FORM_strp
debug_info:
- Version: 4
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
Values:
- Value: 0x000000000000000C
- AbbrCode: 0x00000002
Values:
- Value: 0x0000000000000000 # Name = NameType1
- AbbrCode: 0x00000002
Values:
- Value: 0x000000000000000a # Name = NameType2
- AbbrCode: 0x00000000
)";

YAMLModuleTester t(yamldata);
auto *symbol_file =
llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());
auto &debug_info = symbol_file->DebugInfo();

DIERef first_die(std::nullopt, DIERef::Section::DebugInfo,
11 /*FirstDIEOffset*/);
EXPECT_EQ(debug_info.PeekDIEName(first_die), "");

DIERef second_die(std::nullopt, DIERef::Section::DebugInfo, 14);
EXPECT_EQ(debug_info.PeekDIEName(second_die), "NameType1");

DIERef third_die(std::nullopt, DIERef::Section::DebugInfo, 19);
EXPECT_EQ(debug_info.PeekDIEName(third_die), "NameType2");
}

0 comments on commit b0a3348

Please sign in to comment.