Skip to content

Commit

Permalink
[BOLT][DWARF] Fix handling of invalid DIE references
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ayermolo committed Aug 15, 2023
1 parent bce5743 commit 2c784f7
Show file tree
Hide file tree
Showing 5 changed files with 1,257 additions and 8 deletions.
3 changes: 2 additions & 1 deletion bolt/include/bolt/Core/DIEBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"

#include <list>
#include <memory>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace llvm {
Expand Down Expand Up @@ -113,6 +113,7 @@ class DIEBuilder {
std::vector<LocWithReference> LocWithReferencesToProcess;
BumpPtrAllocator DIEAlloc;
ProcessingType Type;
std::unordered_set<uint64_t> DWARFDieAddressesParsed;
};

std::unique_ptr<State> BuilderState;
Expand Down
38 changes: 31 additions & 7 deletions bolt/lib/Core/DIEBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@

#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
namespace opts {
extern cl::opt<unsigned> Verbosity;
}
namespace llvm {
namespace bolt {

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

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

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

uint32_t DIEBuilder::computeDIEOffset(const DWARFUnit &CU, DIE &Die,
uint32_t &CurOffset) {
getState().DWARFDieAddressesParsed.erase(Die.getOffset());
uint32_t CurSize = 0;
Die.setOffset(CurOffset);
for (DIEValue &Val : Die.values())
Expand Down Expand Up @@ -421,6 +429,13 @@ void DIEBuilder::finish() {
continue;
computeOffset(*CU, UnitSize);
}
if (opts::Verbosity >= 1) {
if (!getState().DWARFDieAddressesParsed.empty())
dbgs() << "Referenced DIE offsets not in .debug_info\n";
for (const uint64_t Address : getState().DWARFDieAddressesParsed) {
dbgs() << Twine::utohexstr(Address) << "\n";
}
}
updateReferences();
}

Expand Down Expand Up @@ -457,11 +472,20 @@ DWARFDie DIEBuilder::resolveDIEReference(
allocDIE(*RefCU, RefDie, getState().DIEAlloc, *UnitId);
return RefDie;
}
errs() << "BOLT-WARNING: [internal-dwarf-error]: invalid referenced DIE "
"at offset: "
<< Twine::utohexstr(RefOffset) << ".\n";

} else {
errs() << "BOLT-WARNING: [internal-dwarf-error]: could not parse "
"referenced DIE at offset: "
<< Twine::utohexstr(RefOffset) << ".\n";
}
} else {
errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
"CU. Referenced DIE offset: "
<< Twine::utohexstr(RefOffset) << ".\n";
}

errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
"CU.\n";
return DWARFDie();
}

Expand Down
Loading

0 comments on commit 2c784f7

Please sign in to comment.