@@ -65,10 +65,10 @@ struct llvm::gsym::CUInfo {
65
65
// / the first client that asks for a compile unit file index will end up
66
66
// / doing the conversion, and subsequent clients will get the cached GSYM
67
67
// / 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 ;
72
72
uint32_t &GsymFileIdx = FileCache[DwarfFileIdx];
73
73
if (GsymFileIdx != UINT32_MAX)
74
74
return GsymFileIdx;
@@ -272,14 +272,24 @@ static void parseInlineInfo(GsymCreator &Gsym, raw_ostream *Log, CUInfo &CUI,
272
272
273
273
if (auto NameIndex = getQualifiedNameIndex (Die, CUI.Language , Gsym))
274
274
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
+ }
283
293
return ;
284
294
}
285
295
if (Tag == dwarf::DW_TAG_subprogram || Tag == dwarf::DW_TAG_lexical_block) {
@@ -306,8 +316,20 @@ static void convertFunctionLineTable(raw_ostream *Log, CUInfo &CUI,
306
316
// the DW_AT_decl_file an d DW_AT_decl_line if we have both attributes.
307
317
std::string FilePath = Die.getDeclFile (
308
318
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
+ }
310
331
return ;
332
+ }
311
333
if (auto Line =
312
334
dwarf::toUnsigned (Die.findRecursively ({dwarf::DW_AT_decl_line}))) {
313
335
LineEntry LE (StartAddress, Gsym.insertFile (FilePath), *Line);
@@ -322,7 +344,20 @@ static void convertFunctionLineTable(raw_ostream *Log, CUInfo &CUI,
322
344
for (uint32_t RowIndex : RowVector) {
323
345
// Take file number and line/column from the row.
324
346
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 ();
326
361
uint64_t RowAddress = Row.Address .Address ;
327
362
// Watch out for a RowAddress that is in the middle of a line table entry
328
363
// in the DWARF. If we pass an address in between two line table entries
0 commit comments