Skip to content

Commit a241f56

Browse files
Merge pull request #8172 from felipepiovezan/felipe/cherry-pickdwarf-verifier-debug-str-offsets-v2
[CherryPick][DWARFVerifier] Fi x debug_str_offsets DWARF version detection (llvm#81303)
2 parents aaebcbf + 7113333 commit a241f56

File tree

4 files changed

+94
-31
lines changed

4 files changed

+94
-31
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,9 @@ class DWARFVerifier {
346346
///
347347
/// \returns true if the .debug_line verifies successfully, false otherwise.
348348
bool handleDebugStrOffsets();
349-
bool verifyDebugStrOffsets(
350-
StringRef SectionName, const DWARFSection &Section, StringRef StrData,
351-
void (DWARFObject::*)(function_ref<void(const DWARFSection &)>) const);
349+
bool verifyDebugStrOffsets(std::optional<dwarf::DwarfFormat> LegacyFormat,
350+
StringRef SectionName, const DWARFSection &Section,
351+
StringRef StrData);
352352
};
353353

354354
static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,

llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,42 +1697,47 @@ bool DWARFVerifier::handleDebugStrOffsets() {
16971697
OS << "Verifying .debug_str_offsets...\n";
16981698
const DWARFObject &DObj = DCtx.getDWARFObj();
16991699
bool Success = true;
1700+
1701+
// dwo sections may contain the legacy debug_str_offsets format (and they
1702+
// can't be mixed with dwarf 5's format). This section format contains no
1703+
// header.
1704+
// As such, check the version from debug_info and, if we are in the legacy
1705+
// mode (Dwarf <= 4), extract Dwarf32/Dwarf64.
1706+
std::optional<DwarfFormat> DwoLegacyDwarf4Format;
1707+
DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
1708+
if (DwoLegacyDwarf4Format)
1709+
return;
1710+
DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
1711+
uint64_t Offset = 0;
1712+
DwarfFormat InfoFormat = DebugInfoData.getInitialLength(&Offset).second;
1713+
if (uint16_t InfoVersion = DebugInfoData.getU16(&Offset); InfoVersion <= 4)
1714+
DwoLegacyDwarf4Format = InfoFormat;
1715+
});
1716+
17001717
Success &= verifyDebugStrOffsets(
1701-
".debug_str_offsets.dwo", DObj.getStrOffsetsDWOSection(),
1702-
DObj.getStrDWOSection(), &DWARFObject::forEachInfoDWOSections);
1718+
DwoLegacyDwarf4Format, ".debug_str_offsets.dwo",
1719+
DObj.getStrOffsetsDWOSection(), DObj.getStrDWOSection());
17031720
Success &= verifyDebugStrOffsets(
1704-
".debug_str_offsets", DObj.getStrOffsetsSection(), DObj.getStrSection(),
1705-
&DWARFObject::forEachInfoSections);
1721+
/*LegacyFormat=*/std::nullopt, ".debug_str_offsets",
1722+
DObj.getStrOffsetsSection(), DObj.getStrSection());
17061723
return Success;
17071724
}
17081725

17091726
bool DWARFVerifier::verifyDebugStrOffsets(
1710-
StringRef SectionName, const DWARFSection &Section, StringRef StrData,
1711-
void (DWARFObject::*VisitInfoSections)(
1712-
function_ref<void(const DWARFSection &)>) const) {
1727+
std::optional<DwarfFormat> LegacyFormat, StringRef SectionName,
1728+
const DWARFSection &Section, StringRef StrData) {
17131729
const DWARFObject &DObj = DCtx.getDWARFObj();
1714-
uint16_t InfoVersion = 0;
1715-
DwarfFormat InfoFormat = DwarfFormat::DWARF32;
1716-
(DObj.*VisitInfoSections)([&](const DWARFSection &S) {
1717-
if (InfoVersion)
1718-
return;
1719-
DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
1720-
uint64_t Offset = 0;
1721-
InfoFormat = DebugInfoData.getInitialLength(&Offset).second;
1722-
InfoVersion = DebugInfoData.getU16(&Offset);
1723-
});
17241730

17251731
DWARFDataExtractor DA(DObj, Section, DCtx.isLittleEndian(), 0);
1726-
17271732
DataExtractor::Cursor C(0);
17281733
uint64_t NextUnit = 0;
17291734
bool Success = true;
17301735
while (C.seek(NextUnit), C.tell() < DA.getData().size()) {
17311736
DwarfFormat Format;
17321737
uint64_t Length;
17331738
uint64_t StartOffset = C.tell();
1734-
if (InfoVersion == 4) {
1735-
Format = InfoFormat;
1739+
if (LegacyFormat) {
1740+
Format = *LegacyFormat;
17361741
Length = DA.getData().size();
17371742
NextUnit = C.tell() + Length;
17381743
} else {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: llvm-dwarfdump -debug-str-offsets -verify %t.o | FileCheck %s
3+
4+
# CHECK: Verifying .debug_str_offsets...
5+
# CHECK: No errors
6+
7+
# Check that when mixing standard DWARF 4 debug information with standard DWARF
8+
# 5 debug information, the verifier correctly interprets the debug_str_offsets
9+
# section as a standards-conforming DWARF 5 section.
10+
11+
--- !ELF
12+
FileHeader:
13+
Class: ELFCLASS64
14+
Data: ELFDATA2LSB
15+
Type: ET_EXEC
16+
DWARF:
17+
debug_str:
18+
- 'cu1'
19+
- 'cu2'
20+
debug_str_offsets:
21+
- Offsets:
22+
- 0x0
23+
debug_abbrev:
24+
- Table:
25+
- Code: 0x1
26+
Tag: DW_TAG_compile_unit
27+
Children: DW_CHILDREN_no
28+
Attributes:
29+
- Attribute: DW_AT_name
30+
Form: DW_FORM_strp
31+
- Code: 0x2
32+
Tag: DW_TAG_compile_unit
33+
Children: DW_CHILDREN_no
34+
Attributes:
35+
- Attribute: DW_AT_name
36+
Form: DW_FORM_strx1
37+
- Attribute: DW_AT_str_offsets_base
38+
Form: DW_FORM_sec_offset
39+
debug_info:
40+
- Version: 4
41+
AbbrevTableID: 0
42+
AbbrOffset: 0x0
43+
AddrSize: 8
44+
Entries:
45+
- AbbrCode: 0x1
46+
Values:
47+
- Value: 0x4
48+
- Version: 5
49+
UnitType: DW_UT_compile
50+
AbbrOffset: 0x0
51+
AddrSize: 8
52+
AbbrevTableID: 0
53+
Entries:
54+
- AbbrCode: 0x2
55+
Values:
56+
- Value: 0x0
57+
- Value: 0x8 # str offsets base

llvm/test/tools/llvm-dwarfdump/X86/verify_invalid_str_offsets.yaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# CHECK-NEXT: error: .debug_str_offsets: contribution 0x29: length exceeds available space (contribution offset (0x29) + length field space (0x4) + length (0x5000000) == 0x500002D > section size 0x30)
1414
# Errors detected.
1515

16-
# V4: error: .debug_str_offsets: contribution 0x0: index 0x2: invalid string offset *0x8 == 0x2, is neither zero nor immediately following a null character
16+
# V4: error: .debug_str_offsets.dwo: contribution 0x0: index 0x2: invalid string offset *0x8 == 0x2, is neither zero nor immediately following a null character
1717

1818

1919
#--- v4.yaml
@@ -23,16 +23,17 @@ FileHeader:
2323
Data: ELFDATA2LSB
2424
Type: ET_EXEC
2525
DWARF:
26-
debug_str:
27-
- 'foo'
28-
- 'bar'
29-
debug_info:
30-
- Version: 4
31-
AddrSize: 4
3226
Sections:
33-
- Name: '.debug_str_offsets'
27+
- Name: '.debug_info.dwo'
28+
Type: SHT_PROGBITS
29+
Content: "0700000004000000000004"
30+
- Name: '.debug_str_offsets.dwo'
3431
Type: SHT_PROGBITS
3532
Content: "000000000400000002000000"
33+
- Name: 'debug_str.dwo'
34+
Type: SHT_PROGBITS
35+
Content: "666F6F0062617200"
36+
3637

3738
#--- v5.yaml
3839
--- !ELF

0 commit comments

Comments
 (0)