Skip to content

Commit 0a357e9

Browse files
[lldb] Update the String table offset based on the DWARF format (llvm#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.
1 parent 6d4a502 commit 0a357e9

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,8 +1077,10 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); }
10771077

10781078
std::optional<uint64_t>
10791079
DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
1080-
lldb::offset_t offset = GetStrOffsetsBase() + index * 4;
1081-
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset);
1080+
lldb::offset_t offset =
1081+
GetStrOffsetsBase() + index * m_header.getDwarfOffsetByteSize();
1082+
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
1083+
&offset, m_header.getDwarfOffsetByteSize());
10821084
}
10831085

10841086
llvm::Expected<llvm::DWARFAddressRangesVector>

lldb/unittests/SymbolFile/DWARF/DWARF64UnitTest.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,100 @@ TEST(DWARF64UnitTest, DWARF64DebugInfoAndCU) {
8484
ASSERT_TRUE(declaration.IsValid());
8585
ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);
8686
}
87+
88+
TEST(DWARF64UnitTest, DWARF5StrTable) {
89+
const char *yamldata = R"(
90+
--- !ELF
91+
FileHeader:
92+
Class: ELFCLASS64
93+
Data: ELFDATA2MSB
94+
Type: ET_EXEC
95+
Machine: EM_PPC64
96+
DWARF:
97+
debug_str:
98+
- 'clang version 18.1.8 (clang-18.1.8-1)'
99+
- 'main.c'
100+
- 'foo'
101+
- 'main'
102+
debug_abbrev:
103+
- Table:
104+
- Code: 0x1
105+
Tag: DW_TAG_compile_unit
106+
Children: DW_CHILDREN_yes
107+
Attributes:
108+
- Attribute: DW_AT_producer
109+
Form: DW_FORM_strx1
110+
- Attribute: DW_AT_language
111+
Form: DW_FORM_data2
112+
- Attribute: DW_AT_name
113+
Form: DW_FORM_strx1
114+
- Attribute: DW_AT_str_offsets_base
115+
Form: DW_FORM_sec_offset
116+
- Code: 0x2
117+
Tag: DW_TAG_subprogram
118+
Children: DW_CHILDREN_no
119+
Attributes:
120+
- Attribute: DW_AT_name
121+
Form: DW_FORM_strx1
122+
debug_info:
123+
- Format: DWARF64
124+
Version: 0x05
125+
UnitType: DW_UT_compile
126+
AbbrOffset: 0x0
127+
AddrSize: 0x08
128+
Entries:
129+
- AbbrCode: 0x1
130+
Values:
131+
- Value: 0x0
132+
- Value: 0x04
133+
- Value: 0x1
134+
- Value: 0x00000010
135+
- AbbrCode: 0x2
136+
Values:
137+
- Value: 0x2
138+
- AbbrCode: 0x2
139+
Values:
140+
- Value: 0x3
141+
- AbbrCode: 0x0
142+
143+
debug_str_offsets:
144+
- Format: DWARF64
145+
Version: "0x05"
146+
Offsets:
147+
- 0x00000000
148+
- 0x00000026
149+
- 0x0000002d
150+
- 0x00000031
151+
)";
152+
153+
YAMLModuleTester t(yamldata);
154+
auto *symbol_file =
155+
llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());
156+
DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);
157+
ASSERT_TRUE(unit);
158+
ASSERT_EQ(unit->GetFormParams().Format, DwarfFormat::DWARF64);
159+
ASSERT_EQ(unit->GetVersion(), 5);
160+
ASSERT_EQ(unit->GetAddressByteSize(), 8);
161+
162+
DWARFFormValue form_value;
163+
const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
164+
ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
165+
ASSERT_EQ(unit->GetProducer(), eProducerClang);
166+
ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
167+
auto attrs = cu_entry->GetAttributes(unit, DWARFDebugInfoEntry::Recurse::yes);
168+
attrs.ExtractFormValueAtIndex(3,
169+
form_value); // Validate DW_AT_str_offsets_bae
170+
ASSERT_EQ(form_value.Unsigned(), 0x00000010UL);
171+
DWARFDIE cu_die(unit, cu_entry);
172+
ASSERT_EQ(ConstString(cu_die.GetName()), "main.c");
173+
174+
auto func_foo = cu_die.GetFirstChild();
175+
ASSERT_TRUE(func_foo.IsValid());
176+
ASSERT_EQ(func_foo.Tag(), DW_TAG_subprogram);
177+
ASSERT_EQ(ConstString(func_foo.GetName()), "foo");
178+
179+
auto func_main = func_foo.GetSibling();
180+
ASSERT_TRUE(func_main.IsValid());
181+
ASSERT_EQ(func_main.Tag(), DW_TAG_subprogram);
182+
ASSERT_EQ(ConstString(func_main.GetName()), "main");
183+
}

0 commit comments

Comments
 (0)