DWARF standard claims that each compilation/type unit header in
.debug_info/.debug_types section must be followed by corresponding
compile/type unit DIE, possibly with its children. Two situations
are possible:
* compile/type unit DIE is missing because DWARF producer failed to
emit it.
* DWARF parser failed to parse unit DIE correctly, for instance if it
contains some unsupported attributes (see r237721, for instance).
In either of these cases, the library, and the tools that use it
(llvm-dwarfdump, llvm-symbolizer) should not crash. Insert appropriate
checks to protect against this.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237733
91177308-0d34-0410-b5e6-
96231b3b80d8
BaseAddr = base_addr;
}
- const DWARFDebugInfoEntryMinimal *
- getCompileUnitDIE(bool extract_cu_die_only = true) {
- extractDIEsIfNeeded(extract_cu_die_only);
+ const DWARFDebugInfoEntryMinimal *getUnitDIE(bool ExtractUnitDIEOnly = true) {
+ extractDIEsIfNeeded(ExtractUnitDIEOnly);
return DieArray.empty() ? nullptr : &DieArray[0];
}
/// It is illegal to call this method with a DIE that hasn't be
/// created by this unit. In other word, it's illegal to call this
/// method on a DIE that isn't accessible by following
- /// children/sibling links starting from this unit's
- /// getCompileUnitDIE().
+ /// children/sibling links starting from this unit's getUnitDIE().
uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE) {
assert(!DieArray.empty() && DIE >= &DieArray[0] &&
DIE < &DieArray[0] + DieArray.size());
<< " (next unit at " << format("0x%08x", getNextUnitOffset())
<< ")\n";
- const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
- assert(CU && "Null Compile Unit?");
- CU->dump(OS, this, -1U);
+ if (const DWARFDebugInfoEntryMinimal *CU = getUnitDIE(false))
+ CU->dump(OS, this, -1U);
+ else
+ OS << "<compile unit can't be parsed!>\n\n";
}
// VTable anchor.
OS << "\n.debug_line contents:\n";
for (const auto &CU : compile_units()) {
savedAddressByteSize = CU->getAddressByteSize();
- unsigned stmtOffset =
- CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
- CU.get(), DW_AT_stmt_list, -1U);
+ const auto *CUDIE = CU->getUnitDIE();
+ if (CUDIE == nullptr)
+ continue;
+ unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
+ CU.get(), DW_AT_stmt_list, -1U);
if (stmtOffset != -1U) {
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
savedAddressByteSize);
}
const DWARFLineTable *
-DWARFContext::getLineTableForUnit(DWARFUnit *cu) {
+DWARFContext::getLineTableForUnit(DWARFUnit *U) {
if (!Line)
Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
-
+ const auto *UnitDIE = U->getUnitDIE();
+ if (UnitDIE == nullptr)
+ return nullptr;
unsigned stmtOffset =
- cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
- cu, DW_AT_stmt_list, -1U);
+ UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
if (stmtOffset == -1U)
return nullptr; // No line table for this compile unit.
// We have to parse it first.
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
- cu->getAddressByteSize());
+ U->getAddressByteSize());
return Line->getOrParseLineTable(lineData, stmtOffset);
}
<< " (next unit at " << format("0x%08x", getNextUnitOffset())
<< ")\n";
- const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
- assert(CU && "Null Compile Unit?");
- CU->dump(OS, this, -1U);
+ if (const DWARFDebugInfoEntryMinimal *TU = getUnitDIE(false))
+ TU->dump(OS, this, -1U);
+ else
+ OS << "<type unit can't be parsed!>\n\n";
}
}
void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
- // First, check if CU DIE describes address ranges for the unit.
- const auto &CUDIERanges = getCompileUnitDIE()->getAddressRanges(this);
+ const auto *U = getUnitDIE();
+ if (U == nullptr)
+ return;
+ // First, check if unit DIE describes address ranges for the whole unit.
+ const auto &CUDIERanges = U->getAddressRanges(this);
if (!CUDIERanges.empty()) {
CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
return;
const DWARFSection &InputSec = Dwarf.getLocSection();
DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
DWARFUnit &OrigUnit = Unit.getOrigUnit();
- const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false);
+ const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
int64_t UnitPcOffset = 0;
uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
&OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
OrigDwarf.isLittleEndian(), AddressSize);
auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
DWARFUnit &OrigUnit = Unit.getOrigUnit();
- const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false);
+ const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
&OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
// Ranges addresses are based on the unit's low_pc. Compute the
void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
DWARFContext &OrigDwarf) {
const DWARFDebugInfoEntryMinimal *CUDie =
- Unit.getOrigUnit().getCompileUnitDIE();
+ Unit.getOrigUnit().getUnitDIE();
uint64_t StmtList = CUDie->getAttributeValueAsSectionOffset(
&Unit.getOrigUnit(), dwarf::DW_AT_stmt_list, -1ULL);
if (StmtList == -1ULL)
// In a first phase, just read in the debug info and store the DIE
// parent links that we will use during the next phase.
for (const auto &CU : DwarfContext.compile_units()) {
- auto *CUDie = CU->getCompileUnitDIE(false);
+ auto *CUDie = CU->getUnitDIE(false);
if (Options.Verbose) {
outs() << "Input compilation unit:";
CUDie->dump(outs(), CU.get(), 0);
// references require the ParentIdx to be setup for every CU in
// the object file before calling this.
for (auto &CurrentUnit : Units)
- lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getCompileUnitDIE(), *Obj,
+ lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getUnitDIE(), *Obj,
CurrentUnit, 0);
// The calls to applyValidRelocs inside cloneDIE will walk the
// to clone/emit.
if (!ValidRelocs.empty())
for (auto &CurrentUnit : Units) {
- const auto *InputDIE = CurrentUnit.getOrigUnit().getCompileUnitDIE();
+ const auto *InputDIE = CurrentUnit.getOrigUnit().getUnitDIE();
CurrentUnit.setStartOffset(OutputDebugInfoSize);
DIE *OutputDIE = cloneDIE(*InputDIE, CurrentUnit, 0 /* PCOffset */,
11 /* Unit Header size */);