Skip to content

Commit 2c784f7

Browse files
committed
[BOLT][DWARF] Fix handling of invalid DIE references
Compiler can generate DIE References that are invalid. Previously BOLT could assert when writing out IR to .debug_info. Changed where DIE offsets are changed so that it's always done. Thus making sure that assert is not triggered. Added more specific warnings, and ability to print out invalid referenced DIE offset when verbosity >=1. Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D157746
1 parent bce5743 commit 2c784f7

5 files changed

+1257
-8
lines changed

bolt/include/bolt/Core/DIEBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
2222
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
2323
#include "llvm/Support/Allocator.h"
24-
#include "llvm/Support/ErrorHandling.h"
2524

2625
#include <list>
2726
#include <memory>
2827
#include <optional>
2928
#include <unordered_map>
29+
#include <unordered_set>
3030
#include <vector>
3131

3232
namespace llvm {
@@ -113,6 +113,7 @@ class DIEBuilder {
113113
std::vector<LocWithReference> LocWithReferencesToProcess;
114114
BumpPtrAllocator DIEAlloc;
115115
ProcessingType Type;
116+
std::unordered_set<uint64_t> DWARFDieAddressesParsed;
116117
};
117118

118119
std::unique_ptr<State> BuilderState;

bolt/lib/Core/DIEBuilder.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939

4040
#undef DEBUG_TYPE
4141
#define DEBUG_TYPE "bolt"
42+
namespace opts {
43+
extern cl::opt<unsigned> Verbosity;
44+
}
4245
namespace llvm {
4346
namespace bolt {
4447

@@ -105,6 +108,14 @@ uint32_t DIEBuilder::allocDIE(const DWARFUnit &DU, const DWARFDie &DDie,
105108
return DWARFUnitInfo.DIEIDMap[DDieOffset];
106109

107110
DIE *Die = DIE::get(Alloc, dwarf::Tag(DDie.getTag()));
111+
// This handles the case where there is a DIE ref which points to
112+
// invalid DIE. This prevents assert when IR is written out.
113+
// Also it makes debugging easier.
114+
// DIE dump is not very useful.
115+
// It's nice to know original offset from which this DIE was constructed.
116+
Die->setOffset(DDie.getOffset());
117+
if (opts::Verbosity >= 1)
118+
getState().DWARFDieAddressesParsed.insert(DDie.getOffset());
108119
const uint32_t DId = DWARFUnitInfo.DieInfoVector.size();
109120
DWARFUnitInfo.DIEIDMap[DDieOffset] = DId;
110121
DWARFUnitInfo.DieInfoVector.emplace_back(
@@ -290,10 +301,6 @@ DIE *DIEBuilder::constructDIEFast(DWARFDie &DDie, DWARFUnit &U,
290301
DIEInfo &DieInfo = getDIEInfo(UnitId, *Idx);
291302

292303
uint64_t Offset = DDie.getOffset();
293-
// Just for making debugging easier.
294-
// DIE dump is not very useful.
295-
// It's nice to know original offset from which this DIE was constructed.
296-
DieInfo.Die->setOffset(Offset);
297304
uint64_t NextOffset = Offset;
298305
DWARFDataExtractor Data = U.getDebugInfoExtractor();
299306
DWARFDebugInfoEntry DDIEntry;
@@ -369,6 +376,7 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx,
369376

370377
uint32_t DIEBuilder::computeDIEOffset(const DWARFUnit &CU, DIE &Die,
371378
uint32_t &CurOffset) {
379+
getState().DWARFDieAddressesParsed.erase(Die.getOffset());
372380
uint32_t CurSize = 0;
373381
Die.setOffset(CurOffset);
374382
for (DIEValue &Val : Die.values())
@@ -421,6 +429,13 @@ void DIEBuilder::finish() {
421429
continue;
422430
computeOffset(*CU, UnitSize);
423431
}
432+
if (opts::Verbosity >= 1) {
433+
if (!getState().DWARFDieAddressesParsed.empty())
434+
dbgs() << "Referenced DIE offsets not in .debug_info\n";
435+
for (const uint64_t Address : getState().DWARFDieAddressesParsed) {
436+
dbgs() << Twine::utohexstr(Address) << "\n";
437+
}
438+
}
424439
updateReferences();
425440
}
426441

@@ -457,11 +472,20 @@ DWARFDie DIEBuilder::resolveDIEReference(
457472
allocDIE(*RefCU, RefDie, getState().DIEAlloc, *UnitId);
458473
return RefDie;
459474
}
475+
errs() << "BOLT-WARNING: [internal-dwarf-error]: invalid referenced DIE "
476+
"at offset: "
477+
<< Twine::utohexstr(RefOffset) << ".\n";
478+
479+
} else {
480+
errs() << "BOLT-WARNING: [internal-dwarf-error]: could not parse "
481+
"referenced DIE at offset: "
482+
<< Twine::utohexstr(RefOffset) << ".\n";
460483
}
484+
} else {
485+
errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
486+
"CU. Referenced DIE offset: "
487+
<< Twine::utohexstr(RefOffset) << ".\n";
461488
}
462-
463-
errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
464-
"CU.\n";
465489
return DWARFDie();
466490
}
467491

0 commit comments

Comments
 (0)