diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2015-05-19 21:54:32 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2015-05-19 21:54:32 +0000 |
| commit | 7a18c0612802b7380aca8f90cf3f342cc3df9aea (patch) | |
| tree | 22d3e689ac470d79b6796c526e4c2bd51e071646 /llvm/lib/DebugInfo | |
| parent | b868ec1c2f4e36033fd67f99a76d4d9d0d68da46 (diff) | |
| download | bcm5719-llvm-7a18c0612802b7380aca8f90cf3f342cc3df9aea.tar.gz bcm5719-llvm-7a18c0612802b7380aca8f90cf3f342cc3df9aea.zip | |
[DWARF parser] Make DWARF parser more robust against missing compile/type units.
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.
llvm-svn: 237733
Diffstat (limited to 'llvm/lib/DebugInfo')
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 7 |
4 files changed, 24 insertions, 16 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 01e724799ab..39a7c772dc7 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS) { << " (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. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 3b427007e59..1faa2ba5921 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -140,9 +140,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { 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); @@ -321,13 +323,14 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { } 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. @@ -337,7 +340,7 @@ DWARFContext::getLineTableForUnit(DWARFUnit *cu) { // We have to parse it first. DataExtractor lineData(getLineSection().Data, isLittleEndian(), - cu->getAddressByteSize()); + U->getAddressByteSize()); return Line->getOrParseLineTable(lineData, stmtOffset); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index 65c7bff0990..766e8ac16f0 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -33,7 +33,8 @@ void DWARFTypeUnit::dump(raw_ostream &OS) { << " (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"; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 406915a9e4c..63a99855551 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -310,8 +310,11 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) { } 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; |

