Beispiel #1
0
void DWARFUnitVector::addUnitsImpl(
    DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
    const DWARFDebugAbbrev *DA, const DWARFSection *RS,
    const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
    const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
    bool Lazy, DWARFSectionKind SectionKind) {
  DWARFDataExtractor Data(Obj, Section, LE, 0);
  // Lazy initialization of Parser, now that we have all section info.
  if (!Parser) {
    Parser = [=, &Context, &Obj, &Section, &SOS, &LS](
                 uint32_t Offset, DWARFSectionKind SectionKind,
                 const DWARFSection *CurSection) -> std::unique_ptr<DWARFUnit> {
      const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
      DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
      if (!Data.isValidOffset(Offset))
        return nullptr;
      const DWARFUnitIndex *Index = nullptr;
      if (IsDWO)
        Index = &getDWARFUnitIndex(Context, SectionKind);
      DWARFUnitHeader Header;
      if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
        return nullptr;
      std::unique_ptr<DWARFUnit> U;
      if (Header.isTypeUnit())
        U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
                                             RS, LocSection, SS, SOS, AOS, LS,
                                             LE, IsDWO, *this);
      else
        U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
                                                DA, RS, LocSection, SS, SOS,
                                                AOS, LS, LE, IsDWO, *this);
      return U;
    };
  }
  if (Lazy)
    return;
  // Find a reasonable insertion point within the vector.  We skip over
  // (a) units from a different section, (b) units from the same section
  // but with lower offset-within-section.  This keeps units in order
  // within a section, although not necessarily within the object file,
  // even if we do lazy parsing.
  auto I = this->begin();
  uint32_t Offset = 0;
  while (Data.isValidOffset(Offset)) {
    if (I != this->end() &&
        (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
      ++I;
      continue;
    }
    auto U = Parser(Offset, SectionKind, &Section);
    // If parsing failed, we're done with this section.
    if (!U)
      break;
    Offset = U->getNextUnitOffset();
    I = std::next(this->insert(I, std::move(U)));
  }
}
Beispiel #2
0
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
                     const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
                     const DWARFSection *RS, const DWARFSection *LocSection,
                     StringRef SS, const DWARFSection &SOS,
                     const DWARFSection *AOS, const DWARFSection &LS, bool LE,
                     bool IsDWO, const DWARFUnitVector &UnitVector)
    : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
      RangeSection(RS), LocSection(LocSection), LineSection(LS),
      StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
      isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) {
  clear();
  // For split DWARF we only need to keep track of the location list section's
  // data (no relocations), and if we are reading a package file, we need to
  // adjust the location list data based on the index entries.
  if (IsDWO) {
    LocSectionData = LocSection->Data;
    if (auto *IndexEntry = Header.getIndexEntry())
      if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
        LocSectionData = LocSectionData.substr(C->Offset, C->Length);
  }
}
Beispiel #3
0
unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
                                          DWARFSectionKind SectionKind) {
  const DWARFObject &DObj = DCtx.getDWARFObj();
  DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
  unsigned NumDebugInfoErrors = 0;
  uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
  uint8_t UnitType = 0;
  bool isUnitDWARF64 = false;
  bool isHeaderChainValid = true;
  bool hasDIE = DebugInfoData.isValidOffset(Offset);
  DWARFUnitVector UnitVector{};
  while (hasDIE) {
    OffsetStart = Offset;
    if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
                          isUnitDWARF64)) {
      isHeaderChainValid = false;
      if (isUnitDWARF64)
        break;
    } else {
      DWARFUnitHeader Header;
      Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind);
      std::unique_ptr<DWARFUnit> Unit;
      switch (UnitType) {
      case dwarf::DW_UT_type:
      case dwarf::DW_UT_split_type: {
        Unit.reset(new DWARFTypeUnit(
            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
            DObj.getStringSection(), DObj.getStringOffsetSection(),
            &DObj.getAppleObjCSection(), DObj.getLineSection(),
            DCtx.isLittleEndian(), false, UnitVector));
        break;
      }
      case dwarf::DW_UT_skeleton:
      case dwarf::DW_UT_split_compile:
      case dwarf::DW_UT_compile:
      case dwarf::DW_UT_partial:
      // UnitType = 0 means that we are
      // verifying a compile unit in DWARF v4.
      case 0: {
        Unit.reset(new DWARFCompileUnit(
            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
            DObj.getStringSection(), DObj.getStringOffsetSection(),
            &DObj.getAppleObjCSection(), DObj.getLineSection(),
            DCtx.isLittleEndian(), false, UnitVector));
        break;
      }
      default: { llvm_unreachable("Invalid UnitType."); }
      }
      NumDebugInfoErrors += verifyUnitContents(*Unit, UnitType);
    }
    hasDIE = DebugInfoData.isValidOffset(Offset);
    ++UnitIdx;
  }
  if (UnitIdx == 0 && !hasDIE) {
    warn() << "Section is empty.\n";
    isHeaderChainValid = true;
  }
  if (!isHeaderChainValid)
    ++NumDebugInfoErrors;
  NumDebugInfoErrors += verifyDebugInfoReferences();
  return NumDebugInfoErrors;
}