llvm.org GIT mirror llvm / 05f725e
[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 Alexey Samsonov 4 years ago
6 changed file(s) with 33 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
194194 BaseAddr = base_addr;
195195 }
196196
197 const DWARFDebugInfoEntryMinimal *
198 getCompileUnitDIE(bool extract_cu_die_only = true) {
199 extractDIEsIfNeeded(extract_cu_die_only);
197 const DWARFDebugInfoEntryMinimal *getUnitDIE(bool ExtractUnitDIEOnly = true) {
198 extractDIEsIfNeeded(ExtractUnitDIEOnly);
200199 return DieArray.empty() ? nullptr : &DieArray[0];
201200 }
202201
225224 /// It is illegal to call this method with a DIE that hasn't be
226225 /// created by this unit. In other word, it's illegal to call this
227226 /// method on a DIE that isn't accessible by following
228 /// children/sibling links starting from this unit's
229 /// getCompileUnitDIE().
227 /// children/sibling links starting from this unit's getUnitDIE().
230228 uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE) {
231229 assert(!DieArray.empty() && DIE >= &DieArray[0] &&
232230 DIE < &DieArray[0] + DieArray.size());
2121 << " (next unit at " << format("0x%08x", getNextUnitOffset())
2222 << ")\n";
2323
24 const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
25 assert(CU && "Null Compile Unit?");
26 CU->dump(OS, this, -1U);
24 if (const DWARFDebugInfoEntryMinimal *CU = getUnitDIE(false))
25 CU->dump(OS, this, -1U);
26 else
27 OS << "\n\n";
2728 }
2829
2930 // VTable anchor.
139139 OS << "\n.debug_line contents:\n";
140140 for (const auto &CU : compile_units()) {
141141 savedAddressByteSize = CU->getAddressByteSize();
142 unsigned stmtOffset =
143 CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
144 CU.get(), DW_AT_stmt_list, -1U);
142 const auto *CUDIE = CU->getUnitDIE();
143 if (CUDIE == nullptr)
144 continue;
145 unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
146 CU.get(), DW_AT_stmt_list, -1U);
145147 if (stmtOffset != -1U) {
146148 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
147149 savedAddressByteSize);
320322 }
321323
322324 const DWARFLineTable *
323 DWARFContext::getLineTableForUnit(DWARFUnit *cu) {
325 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
324326 if (!Line)
325327 Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
326
328 const auto *UnitDIE = U->getUnitDIE();
329 if (UnitDIE == nullptr)
330 return nullptr;
327331 unsigned stmtOffset =
328 cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
329 cu, DW_AT_stmt_list, -1U);
332 UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
330333 if (stmtOffset == -1U)
331334 return nullptr; // No line table for this compile unit.
332335
336339
337340 // We have to parse it first.
338341 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
339 cu->getAddressByteSize());
342 U->getAddressByteSize());
340343 return Line->getOrParseLineTable(lineData, stmtOffset);
341344 }
342345
3232 << " (next unit at " << format("0x%08x", getNextUnitOffset())
3333 << ")\n";
3434
35 const DWARFDebugInfoEntryMinimal *CU = getCompileUnitDIE(false);
36 assert(CU && "Null Compile Unit?");
37 CU->dump(OS, this, -1U);
35 if (const DWARFDebugInfoEntryMinimal *TU = getUnitDIE(false))
36 TU->dump(OS, this, -1U);
37 else
38 OS << "\n\n";
3839 }
309309 }
310310
311311 void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
312 // First, check if CU DIE describes address ranges for the unit.
313 const auto &CUDIERanges = getCompileUnitDIE()->getAddressRanges(this);
312 const auto *U = getUnitDIE();
313 if (U == nullptr)
314 return;
315 // First, check if unit DIE describes address ranges for the whole unit.
316 const auto &CUDIERanges = U->getAddressRanges(this);
314317 if (!CUDIERanges.empty()) {
315318 CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
316319 return;
728728 const DWARFSection &InputSec = Dwarf.getLocSection();
729729 DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
730730 DWARFUnit &OrigUnit = Unit.getOrigUnit();
731 const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false);
731 const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
732732 int64_t UnitPcOffset = 0;
733733 uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
734734 &OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
22022202 OrigDwarf.isLittleEndian(), AddressSize);
22032203 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
22042204 DWARFUnit &OrigUnit = Unit.getOrigUnit();
2205 const auto *OrigUnitDie = OrigUnit.getCompileUnitDIE(false);
2205 const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
22062206 uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
22072207 &OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
22082208 // Ranges addresses are based on the unit's low_pc. Compute the
22862286 void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
22872287 DWARFContext &OrigDwarf) {
22882288 const DWARFDebugInfoEntryMinimal *CUDie =
2289 Unit.getOrigUnit().getCompileUnitDIE();
2289 Unit.getOrigUnit().getUnitDIE();
22902290 uint64_t StmtList = CUDie->getAttributeValueAsSectionOffset(
22912291 &Unit.getOrigUnit(), dwarf::DW_AT_stmt_list, -1ULL);
22922292 if (StmtList == -1ULL)
24602460 // In a first phase, just read in the debug info and store the DIE
24612461 // parent links that we will use during the next phase.
24622462 for (const auto &CU : DwarfContext.compile_units()) {
2463 auto *CUDie = CU->getCompileUnitDIE(false);
2463 auto *CUDie = CU->getUnitDIE(false);
24642464 if (Options.Verbose) {
24652465 outs() << "Input compilation unit:";
24662466 CUDie->dump(outs(), CU.get(), 0);
24752475 // references require the ParentIdx to be setup for every CU in
24762476 // the object file before calling this.
24772477 for (auto &CurrentUnit : Units)
2478 lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getCompileUnitDIE(), *Obj,
2478 lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getUnitDIE(), *Obj,
24792479 CurrentUnit, 0);
24802480
24812481 // The calls to applyValidRelocs inside cloneDIE will walk the
24882488 // to clone/emit.
24892489 if (!ValidRelocs.empty())
24902490 for (auto &CurrentUnit : Units) {
2491 const auto *InputDIE = CurrentUnit.getOrigUnit().getCompileUnitDIE();
2491 const auto *InputDIE = CurrentUnit.getOrigUnit().getUnitDIE();
24922492 CurrentUnit.setStartOffset(OutputDebugInfoSize);
24932493 DIE *OutputDIE = cloneDIE(*InputDIE, CurrentUnit, 0 /* PCOffset */,
24942494 11 /* Unit Header size */);