Skip to content

Commit 55906e0

Browse files
[DWARFVerifier] Verify that DW_AT_LLVM_stmt_sequence is set correctly (#152807)
Sometimes DW_AT_LLVM_stmt_sequence won't point to the correct offset. This feature helps us debug when/where it went wrong. Added a new test and manually tempered with the value to show the intended verification result. --------- Signed-off-by: Peter Rong <[email protected]>
1 parent f6ded0b commit 55906e0

File tree

2 files changed

+1736
-0
lines changed

2 files changed

+1736
-0
lines changed

llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,86 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
851851
}
852852
break;
853853
}
854+
case DW_AT_LLVM_stmt_sequence: {
855+
// Make sure the offset in the DW_AT_LLVM_stmt_sequence attribute is valid
856+
// and points to a valid sequence offset in the line table.
857+
auto SectionOffset = AttrValue.Value.getAsSectionOffset();
858+
if (!SectionOffset) {
859+
ReportError("Invalid DW_AT_LLVM_stmt_sequence encoding",
860+
"DIE has invalid DW_AT_LLVM_stmt_sequence encoding");
861+
break;
862+
}
863+
if (*SectionOffset >= U->getLineSection().Data.size()) {
864+
ReportError(
865+
"DW_AT_LLVM_stmt_sequence offset out of bounds",
866+
"DW_AT_LLVM_stmt_sequence offset is beyond .debug_line bounds: " +
867+
llvm::formatv("{0:x8}", *SectionOffset));
868+
break;
869+
}
870+
871+
// Get the line table for this unit to validate bounds
872+
const auto *LineTable = DCtx.getLineTableForUnit(U);
873+
if (!LineTable) {
874+
ReportError("DW_AT_LLVM_stmt_sequence without line table",
875+
"DIE has DW_AT_LLVM_stmt_sequence but compile unit has no "
876+
"line table");
877+
break;
878+
}
879+
880+
// Get the DW_AT_stmt_list offset from the compile unit DIE
881+
DWARFDie CUDie = U->getUnitDIE();
882+
auto StmtListOffset = toSectionOffset(CUDie.find(DW_AT_stmt_list));
883+
if (!StmtListOffset) {
884+
ReportError("DW_AT_LLVM_stmt_sequence without DW_AT_stmt_list",
885+
"DIE has DW_AT_LLVM_stmt_sequence but compile unit has no "
886+
"DW_AT_stmt_list");
887+
break;
888+
}
889+
890+
const int8_t DwarfOffset =
891+
LineTable->Prologue.getFormParams().getDwarfOffsetByteSize();
892+
// Calculate the bounds of this specific line table
893+
uint64_t LineTableStart = *StmtListOffset;
894+
uint64_t PrologueLength = LineTable->Prologue.PrologueLength;
895+
uint64_t TotalLength = LineTable->Prologue.TotalLength;
896+
uint64_t LineTableEnd = LineTableStart + TotalLength + DwarfOffset;
897+
898+
// See DWARF definition for this, the following three do not
899+
// count toward prologue length. Calculate SequencesStart correctly
900+
// according to DWARF specification:
901+
uint64_t InitialLengthSize = DwarfOffset;
902+
// Version field is always 2 bytes
903+
uint64_t VersionSize = 2;
904+
uint64_t PrologueLengthSize = DwarfOffset;
905+
uint64_t SequencesStart = LineTableStart + InitialLengthSize + VersionSize +
906+
PrologueLengthSize + PrologueLength;
907+
908+
// Check if the offset is within the bounds of this specific line table
909+
if (*SectionOffset < SequencesStart || *SectionOffset >= LineTableEnd) {
910+
ReportError("DW_AT_LLVM_stmt_sequence offset out of line table bounds",
911+
"DW_AT_LLVM_stmt_sequence offset " +
912+
llvm::formatv("{0:x8}", *SectionOffset) +
913+
" is not within the line table bounds [" +
914+
llvm::formatv("{0:x8}", SequencesStart) + ", " +
915+
llvm::formatv("{0:x8}", LineTableEnd) + ")");
916+
break;
917+
}
918+
919+
// Check if the offset matches any of the sequence offset.
920+
auto It =
921+
std::find_if(LineTable->Sequences.begin(), LineTable->Sequences.end(),
922+
[SectionOffset](const auto &Sequence) {
923+
return Sequence.StmtSeqOffset == *SectionOffset;
924+
});
925+
926+
if (It == LineTable->Sequences.end())
927+
ReportError(
928+
"Invalid DW_AT_LLVM_stmt_sequence offset",
929+
"DW_AT_LLVM_stmt_sequence offset " +
930+
llvm::formatv("{0:x8}", *SectionOffset) +
931+
" does not point to a valid sequence offset in the line table");
932+
break;
933+
}
854934
default:
855935
break;
856936
}

0 commit comments

Comments
 (0)