-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DWARFVerifier] Verify that DW_AT_LLVM_stmt_sequence is set correctly #152807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
cedce21
e1a4ed7
c8f2305
5715526
01a59eb
8fc1a3b
41a9fbf
dc053bc
c7461d3
25bbe1a
c463b7e
03f6b8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -851,6 +851,86 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, | |
} | ||
break; | ||
} | ||
case DW_AT_LLVM_stmt_sequence: { | ||
// Make sure the offset in the DW_AT_LLVM_stmt_sequence attribute is valid | ||
// and points to a valid sequence offset in the line table. | ||
auto SectionOffset = AttrValue.Value.getAsSectionOffset(); | ||
if (!SectionOffset) { | ||
ReportError("Invalid DW_AT_LLVM_stmt_sequence encoding", | ||
"DIE has invalid DW_AT_LLVM_stmt_sequence encoding"); | ||
break; | ||
} | ||
if (*SectionOffset >= U->getLineSection().Data.size()) { | ||
ReportError( | ||
"DW_AT_LLVM_stmt_sequence offset out of bounds", | ||
"DW_AT_LLVM_stmt_sequence offset is beyond .debug_line bounds: " + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably check if the DW_AT_LLVM_stmt_sequence is inside the current line table only? The .debug_line section conttains multiple line tables, each one has a prologue and then N sequences. We want to make sure the
The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a test for out of range (of the intended line table) test |
||
llvm::formatv("{0:x8}", *SectionOffset)); | ||
break; | ||
} | ||
|
||
// Get the line table for this unit to validate bounds | ||
const auto *LineTable = DCtx.getLineTableForUnit(U); | ||
if (!LineTable) { | ||
ReportError("DW_AT_LLVM_stmt_sequence without line table", | ||
"DIE has DW_AT_LLVM_stmt_sequence but compile unit has no " | ||
"line table"); | ||
break; | ||
} | ||
|
||
// Get the DW_AT_stmt_list offset from the compile unit DIE | ||
DWARFDie CUDie = U->getUnitDIE(); | ||
auto StmtListOffset = toSectionOffset(CUDie.find(DW_AT_stmt_list)); | ||
if (!StmtListOffset) { | ||
ReportError("DW_AT_LLVM_stmt_sequence without DW_AT_stmt_list", | ||
"DIE has DW_AT_LLVM_stmt_sequence but compile unit has no " | ||
"DW_AT_stmt_list"); | ||
break; | ||
} | ||
|
||
const int8_t DwarfOffset = | ||
LineTable->Prologue.getFormParams().getDwarfOffsetByteSize(); | ||
// Calculate the bounds of this specific line table | ||
uint64_t LineTableStart = *StmtListOffset; | ||
uint64_t PrologueLength = LineTable->Prologue.PrologueLength; | ||
uint64_t TotalLength = LineTable->Prologue.TotalLength; | ||
uint64_t LineTableEnd = LineTableStart + TotalLength + DwarfOffset; | ||
|
||
// See DWARF definition for this, the following three do not | ||
// count toward prologue length. Calculate SequencesStart correctly | ||
// according to DWARF specification: | ||
uint64_t InitialLengthSize = DwarfOffset; | ||
// Version field is always 2 bytes | ||
uint64_t VersionSize = 2; | ||
uint64_t PrologueLengthSize = DwarfOffset; | ||
uint64_t SequencesStart = LineTableStart + InitialLengthSize + VersionSize + | ||
PrologueLengthSize + PrologueLength; | ||
|
||
// Check if the offset is within the bounds of this specific line table | ||
if (*SectionOffset < SequencesStart || *SectionOffset >= LineTableEnd) { | ||
ReportError("DW_AT_LLVM_stmt_sequence offset out of line table bounds", | ||
"DW_AT_LLVM_stmt_sequence offset " + | ||
llvm::formatv("{0:x8}", *SectionOffset) + | ||
" is not within the line table bounds [" + | ||
llvm::formatv("{0:x8}", SequencesStart) + ", " + | ||
llvm::formatv("{0:x8}", LineTableEnd) + ")"); | ||
break; | ||
} | ||
|
||
// Check if the offset matches any of the sequence offset. | ||
auto It = | ||
std::find_if(LineTable->Sequences.begin(), LineTable->Sequences.end(), | ||
[SectionOffset](const auto &Sequence) { | ||
return Sequence.StmtSeqOffset == *SectionOffset; | ||
}); | ||
|
||
if (It == LineTable->Sequences.end()) | ||
ReportError( | ||
"Invalid DW_AT_LLVM_stmt_sequence offset", | ||
"DW_AT_LLVM_stmt_sequence offset " + | ||
llvm::formatv("{0:x8}", *SectionOffset) + | ||
" does not point to a valid sequence offset in the line table"); | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a test for this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a test for " invalid DW_AT_LLVM_stmt_sequence encoding"