[lldb] Update the String table offset based on the DWARF format (#147054)

This PR is updating the string table offset (DW_AT_str_offsets_base
which is introduced in `DWARF5`) based on the DWARF format, as per the
DWARF specification; For the 32-bit DWARF format, each offset is 4 bytes
long; for the 64-bit DWARF format, each offset is 8 bytes long.
This commit is contained in:
Hemang Gadhavi 2025-07-14 15:25:45 +05:30 committed by GitHub
parent 6d4a50272f
commit 0a357e92ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 101 additions and 2 deletions

View File

@ -1077,8 +1077,10 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); }
std::optional<uint64_t>
DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
lldb::offset_t offset = GetStrOffsetsBase() + index * 4;
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset);
lldb::offset_t offset =
GetStrOffsetsBase() + index * m_header.getDwarfOffsetByteSize();
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
&offset, m_header.getDwarfOffsetByteSize());
}
llvm::Expected<llvm::DWARFAddressRangesVector>

View File

@ -84,3 +84,100 @@ DWARF:
ASSERT_TRUE(declaration.IsValid());
ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);
}
TEST(DWARF64UnitTest, DWARF5StrTable) {
const char *yamldata = R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2MSB
Type: ET_EXEC
Machine: EM_PPC64
DWARF:
debug_str:
- 'clang version 18.1.8 (clang-18.1.8-1)'
- 'main.c'
- 'foo'
- 'main'
debug_abbrev:
- Table:
- Code: 0x1
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_producer
Form: DW_FORM_strx1
- Attribute: DW_AT_language
Form: DW_FORM_data2
- Attribute: DW_AT_name
Form: DW_FORM_strx1
- Attribute: DW_AT_str_offsets_base
Form: DW_FORM_sec_offset
- Code: 0x2
Tag: DW_TAG_subprogram
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_name
Form: DW_FORM_strx1
debug_info:
- Format: DWARF64
Version: 0x05
UnitType: DW_UT_compile
AbbrOffset: 0x0
AddrSize: 0x08
Entries:
- AbbrCode: 0x1
Values:
- Value: 0x0
- Value: 0x04
- Value: 0x1
- Value: 0x00000010
- AbbrCode: 0x2
Values:
- Value: 0x2
- AbbrCode: 0x2
Values:
- Value: 0x3
- AbbrCode: 0x0
debug_str_offsets:
- Format: DWARF64
Version: "0x05"
Offsets:
- 0x00000000
- 0x00000026
- 0x0000002d
- 0x00000031
)";
YAMLModuleTester t(yamldata);
auto *symbol_file =
llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());
DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);
ASSERT_TRUE(unit);
ASSERT_EQ(unit->GetFormParams().Format, DwarfFormat::DWARF64);
ASSERT_EQ(unit->GetVersion(), 5);
ASSERT_EQ(unit->GetAddressByteSize(), 8);
DWARFFormValue form_value;
const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
ASSERT_EQ(unit->GetProducer(), eProducerClang);
ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
auto attrs = cu_entry->GetAttributes(unit, DWARFDebugInfoEntry::Recurse::yes);
attrs.ExtractFormValueAtIndex(3,
form_value); // Validate DW_AT_str_offsets_bae
ASSERT_EQ(form_value.Unsigned(), 0x00000010UL);
DWARFDIE cu_die(unit, cu_entry);
ASSERT_EQ(ConstString(cu_die.GetName()), "main.c");
auto func_foo = cu_die.GetFirstChild();
ASSERT_TRUE(func_foo.IsValid());
ASSERT_EQ(func_foo.Tag(), DW_TAG_subprogram);
ASSERT_EQ(ConstString(func_foo.GetName()), "foo");
auto func_main = func_foo.GetSibling();
ASSERT_TRUE(func_main.IsValid());
ASSERT_EQ(func_main.Tag(), DW_TAG_subprogram);
ASSERT_EQ(ConstString(func_main.GetName()), "main");
}