@@ -65,10 +65,10 @@ struct llvm::gsym::CUInfo {
6565 // / the first client that asks for a compile unit file index will end up
6666 // / doing the conversion, and subsequent clients will get the cached GSYM
6767 // / index.
68- uint32_t DWARFToGSYMFileIndex (GsymCreator &Gsym, uint32_t DwarfFileIdx) {
69- if (!LineTable)
70- return 0 ;
71- assert (DwarfFileIdx < FileCache. size ()) ;
68+ std::optional< uint32_t > DWARFToGSYMFileIndex (GsymCreator &Gsym,
69+ uint32_t DwarfFileIdx) {
70+ if (!LineTable || DwarfFileIdx >= FileCache. size ())
71+ return std:: nullopt ;
7272 uint32_t &GsymFileIdx = FileCache[DwarfFileIdx];
7373 if (GsymFileIdx != UINT32_MAX)
7474 return GsymFileIdx;
@@ -272,14 +272,24 @@ static void parseInlineInfo(GsymCreator &Gsym, raw_ostream *Log, CUInfo &CUI,
272272
273273 if (auto NameIndex = getQualifiedNameIndex (Die, CUI.Language , Gsym))
274274 II.Name = *NameIndex;
275- II.CallFile = CUI.DWARFToGSYMFileIndex (
276- Gsym, dwarf::toUnsigned (Die.find (dwarf::DW_AT_call_file), 0 ));
277- II.CallLine = dwarf::toUnsigned (Die.find (dwarf::DW_AT_call_line), 0 );
278- // parse all children and append to parent
279- for (DWARFDie ChildDie : Die.children ())
280- parseInlineInfo (Gsym, Log, CUI, ChildDie, Depth + 1 , FI, II,
281- AllInlineRanges, WarnIfEmpty);
282- Parent.Children .emplace_back (std::move (II));
275+ const uint64_t DwarfFileIdx = dwarf::toUnsigned (
276+ Die.findRecursively (dwarf::DW_AT_call_file), UINT32_MAX);
277+ std::optional<uint32_t > OptGSymFileIdx =
278+ CUI.DWARFToGSYMFileIndex (Gsym, DwarfFileIdx);
279+ if (OptGSymFileIdx) {
280+ II.CallFile = OptGSymFileIdx.value ();
281+ II.CallLine = dwarf::toUnsigned (Die.find (dwarf::DW_AT_call_line), 0 );
282+ // parse all children and append to parent
283+ for (DWARFDie ChildDie : Die.children ())
284+ parseInlineInfo (Gsym, Log, CUI, ChildDie, Depth + 1 , FI, II,
285+ AllInlineRanges, WarnIfEmpty);
286+ Parent.Children .emplace_back (std::move (II));
287+ } else if (Log) {
288+ *Log << " error: inlined function DIE at " << HEX32 (Die.getOffset ())
289+ << " has an invalid file index " << DwarfFileIdx
290+ << " in its DW_AT_call_file attribute, this inline entry and all "
291+ << " children will be removed.\n " ;
292+ }
283293 return ;
284294 }
285295 if (Tag == dwarf::DW_TAG_subprogram || Tag == dwarf::DW_TAG_lexical_block) {
@@ -306,8 +316,20 @@ static void convertFunctionLineTable(raw_ostream *Log, CUInfo &CUI,
306316 // the DW_AT_decl_file an d DW_AT_decl_line if we have both attributes.
307317 std::string FilePath = Die.getDeclFile (
308318 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);
309- if (FilePath.empty ())
319+ if (FilePath.empty ()) {
320+ // If we had a DW_AT_decl_file, but got no file then we need to emit a
321+ // warning.
322+ if (Log) {
323+ const uint64_t DwarfFileIdx = dwarf::toUnsigned (
324+ Die.findRecursively (dwarf::DW_AT_decl_file), UINT32_MAX);
325+ *Log << " error: function DIE at " << HEX32 (Die.getOffset ())
326+ << " has an invalid file index " << DwarfFileIdx
327+ << " in its DW_AT_decl_file attribute, unable to create a single "
328+ << " line entry from the DW_AT_decl_file/DW_AT_decl_line "
329+ << " attributes.\n " ;
330+ }
310331 return ;
332+ }
311333 if (auto Line =
312334 dwarf::toUnsigned (Die.findRecursively ({dwarf::DW_AT_decl_line}))) {
313335 LineEntry LE (StartAddress, Gsym.insertFile (FilePath), *Line);
@@ -322,7 +344,20 @@ static void convertFunctionLineTable(raw_ostream *Log, CUInfo &CUI,
322344 for (uint32_t RowIndex : RowVector) {
323345 // Take file number and line/column from the row.
324346 const DWARFDebugLine::Row &Row = CUI.LineTable ->Rows [RowIndex];
325- const uint32_t FileIdx = CUI.DWARFToGSYMFileIndex (Gsym, Row.File );
347+ std::optional<uint32_t > OptFileIdx =
348+ CUI.DWARFToGSYMFileIndex (Gsym, Row.File );
349+ if (!OptFileIdx) {
350+ if (Log) {
351+ *Log << " error: function DIE at " << HEX32 (Die.getOffset ()) << " has "
352+ << " a line entry with invalid DWARF file index, this entry will "
353+ << " be removed:\n " ;
354+ Row.dumpTableHeader (*Log, /* Indent=*/ 0 );
355+ Row.dump (*Log);
356+ *Log << " \n " ;
357+ }
358+ continue ;
359+ }
360+ const uint32_t FileIdx = OptFileIdx.value ();
326361 uint64_t RowAddress = Row.Address .Address ;
327362 // Watch out for a RowAddress that is in the middle of a line table entry
328363 // in the DWARF. If we pass an address in between two line table entries
0 commit comments