@@ -851,6 +851,86 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
851
851
}
852
852
break ;
853
853
}
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
+ }
854
934
default :
855
935
break ;
856
936
}
0 commit comments