mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237733 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user