[llvm] r237733 - [DWARF parser] Make DWARF parser more robust against missing compile/type units.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Tue May 26 07:06:15 PDT 2015


testcase?

On 19 May 2015 at 17:54, Alexey Samsonov <vonosmas at gmail.com> wrote:
> Author: samsonov
> Date: Tue May 19 16:54:32 2015
> New Revision: 237733
>
> URL: http://llvm.org/viewvc/llvm-project?rev=237733&view=rev
> Log:
> [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.
>
> Modified:
>     llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
>     llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
>     llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
>     llvm/trunk/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
>     llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
>     llvm/trunk/tools/dsymutil/DwarfLinker.cpp
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Tue May 19 16:54:32 2015
> @@ -195,9 +195,8 @@ public:
>      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];
>    }
>
> @@ -226,8 +225,7 @@ public:
>    /// 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());
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp Tue May 19 16:54:32 2015
> @@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream
>       << " (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.
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Tue May 19 16:54:32 2015
> @@ -140,9 +140,11 @@ void DWARFContext::dump(raw_ostream &OS,
>      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::get
>  }
>
>  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(DWARFU
>
>    // We have to parse it first.
>    DataExtractor lineData(getLineSection().Data, isLittleEndian(),
> -                         cu->getAddressByteSize());
> +                         U->getAddressByteSize());
>    return Line->getOrParseLineTable(lineData, stmtOffset);
>  }
>
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp Tue May 19 16:54:32 2015
> @@ -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";
>  }
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Tue May 19 16:54:32 2015
> @@ -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;
>
> Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=237733&r1=237732&r2=237733&view=diff
> ==============================================================================
> --- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
> +++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Tue May 19 16:54:32 2015
> @@ -729,7 +729,7 @@ void DwarfStreamer::emitLocationsForUnit
>    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);
> @@ -2203,7 +2203,7 @@ void DwarfLinker::patchRangesForUnit(con
>                                 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
> @@ -2287,7 +2287,7 @@ static void insertLineSequence(std::vect
>  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)
> @@ -2461,7 +2461,7 @@ bool DwarfLinker::link(const DebugMap &M
>      // 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);
> @@ -2476,7 +2476,7 @@ bool DwarfLinker::link(const DebugMap &M
>      // 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
> @@ -2489,7 +2489,7 @@ bool DwarfLinker::link(const DebugMap &M
>      // 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 */);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list