@@ -496,111 +496,107 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
496496}
497497
498498Error DWARFUnit::tryExtractDIEsIfNeeded (bool CUDieOnly) {
499- return Context.doWorkThreadSafely ([&]() -> Error {
500- if ((CUDieOnly && !DieArray.empty ()) || DieArray.size () > 1 )
501- return Error::success (); // Already parsed.
502-
503- bool HasCUDie = !DieArray.empty ();
504- extractDIEsToVector (!HasCUDie, !CUDieOnly, DieArray);
505-
506- if (DieArray.empty ())
507- return Error::success ();
508-
509- // If CU DIE was just parsed, copy several attribute values from it.
510- if (HasCUDie)
511- return Error::success ();
512-
513- DWARFDie UnitDie (this , &DieArray[0 ]);
514- if (std::optional<uint64_t > DWOId =
515- toUnsigned (UnitDie.find (DW_AT_GNU_dwo_id)))
516- Header.setDWOId (*DWOId);
517- if (!IsDWO) {
518- assert (AddrOffsetSectionBase == std::nullopt );
519- assert (RangeSectionBase == 0 );
520- assert (LocSectionBase == 0 );
521- AddrOffsetSectionBase = toSectionOffset (UnitDie.find (DW_AT_addr_base));
522- if (!AddrOffsetSectionBase)
523- AddrOffsetSectionBase =
524- toSectionOffset (UnitDie.find (DW_AT_GNU_addr_base));
525- RangeSectionBase = toSectionOffset (UnitDie.find (DW_AT_rnglists_base), 0 );
526- LocSectionBase = toSectionOffset (UnitDie.find (DW_AT_loclists_base), 0 );
527- }
499+ if ((CUDieOnly && !DieArray.empty ()) || DieArray.size () > 1 )
500+ return Error::success (); // Already parsed.
528501
529- // In general, in DWARF v5 and beyond we derive the start of the unit's
530- // contribution to the string offsets table from the unit DIE's
531- // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
532- // attribute, so we assume that there is a contribution to the string
533- // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
534- // In both cases we need to determine the format of the contribution,
535- // which may differ from the unit's format.
536- DWARFDataExtractor DA (Context.getDWARFObj (), StringOffsetSection,
537- IsLittleEndian, 0 );
538- if (IsDWO || getVersion () >= 5 ) {
539- auto StringOffsetOrError =
540- IsDWO ? determineStringOffsetsTableContributionDWO (DA)
541- : determineStringOffsetsTableContribution (DA);
542- if (!StringOffsetOrError) {
543- return createStringError (errc::invalid_argument,
544- " invalid reference to or invalid content in "
545- " .debug_str_offsets[.dwo]: " +
546- toString (StringOffsetOrError.takeError ()));
547- }
502+ bool HasCUDie = !DieArray.empty ();
503+ extractDIEsToVector (!HasCUDie, !CUDieOnly, DieArray);
548504
549- StringOffsetsTableContribution = *StringOffsetOrError;
550- }
505+ if (DieArray. empty ())
506+ return Error::success ();
551507
552- // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
553- // describe address ranges.
554- if (getVersion () >= 5 ) {
555- // In case of DWP, the base offset from the index has to be added.
556- if (IsDWO) {
557- uint64_t ContributionBaseOffset = 0 ;
558- if (auto *IndexEntry = Header.getIndexEntry ())
559- if (auto *Contrib = IndexEntry->getContribution (DW_SECT_RNGLISTS))
560- ContributionBaseOffset = Contrib->getOffset ();
561- setRangesSection (
562- &Context.getDWARFObj ().getRnglistsDWOSection (),
563- ContributionBaseOffset +
564- DWARFListTableHeader::getHeaderSize (Header.getFormat ()));
565- } else
566- setRangesSection (&Context.getDWARFObj ().getRnglistsSection (),
567- toSectionOffset (UnitDie.find (DW_AT_rnglists_base),
568- DWARFListTableHeader::getHeaderSize (
569- Header.getFormat ())));
570- }
508+ // If CU DIE was just parsed, copy several attribute values from it.
509+ if (HasCUDie)
510+ return Error::success ();
511+
512+ DWARFDie UnitDie (this , &DieArray[0 ]);
513+ if (std::optional<uint64_t > DWOId =
514+ toUnsigned (UnitDie.find (DW_AT_GNU_dwo_id)))
515+ Header.setDWOId (*DWOId);
516+ if (!IsDWO) {
517+ assert (AddrOffsetSectionBase == std::nullopt );
518+ assert (RangeSectionBase == 0 );
519+ assert (LocSectionBase == 0 );
520+ AddrOffsetSectionBase = toSectionOffset (UnitDie.find (DW_AT_addr_base));
521+ if (!AddrOffsetSectionBase)
522+ AddrOffsetSectionBase =
523+ toSectionOffset (UnitDie.find (DW_AT_GNU_addr_base));
524+ RangeSectionBase = toSectionOffset (UnitDie.find (DW_AT_rnglists_base), 0 );
525+ LocSectionBase = toSectionOffset (UnitDie.find (DW_AT_loclists_base), 0 );
526+ }
527+
528+ // In general, in DWARF v5 and beyond we derive the start of the unit's
529+ // contribution to the string offsets table from the unit DIE's
530+ // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
531+ // attribute, so we assume that there is a contribution to the string
532+ // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
533+ // In both cases we need to determine the format of the contribution,
534+ // which may differ from the unit's format.
535+ DWARFDataExtractor DA (Context.getDWARFObj (), StringOffsetSection,
536+ IsLittleEndian, 0 );
537+ if (IsDWO || getVersion () >= 5 ) {
538+ auto StringOffsetOrError =
539+ IsDWO ? determineStringOffsetsTableContributionDWO (DA)
540+ : determineStringOffsetsTableContribution (DA);
541+ if (!StringOffsetOrError)
542+ return createStringError (errc::invalid_argument,
543+ " invalid reference to or invalid content in "
544+ " .debug_str_offsets[.dwo]: " +
545+ toString (StringOffsetOrError.takeError ()));
546+
547+ StringOffsetsTableContribution = *StringOffsetOrError;
548+ }
571549
550+ // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
551+ // describe address ranges.
552+ if (getVersion () >= 5 ) {
553+ // In case of DWP, the base offset from the index has to be added.
572554 if (IsDWO) {
573- // If we are reading a package file, we need to adjust the location list
574- // data based on the index entries.
575- StringRef Data = Header.getVersion () >= 5
576- ? Context.getDWARFObj ().getLoclistsDWOSection ().Data
577- : Context.getDWARFObj ().getLocDWOSection ().Data ;
555+ uint64_t ContributionBaseOffset = 0 ;
578556 if (auto *IndexEntry = Header.getIndexEntry ())
579- if (const auto *C = IndexEntry->getContribution (
580- Header.getVersion () >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
581- Data = Data.substr (C->getOffset (), C->getLength ());
582-
583- DWARFDataExtractor DWARFData (Data, IsLittleEndian, getAddressByteSize ());
584- LocTable =
585- std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion ());
586- LocSectionBase = DWARFListTableHeader::getHeaderSize (Header.getFormat ());
587- } else if (getVersion () >= 5 ) {
588- LocTable = std::make_unique<DWARFDebugLoclists>(
589- DWARFDataExtractor (Context.getDWARFObj (),
590- Context.getDWARFObj ().getLoclistsSection (),
591- IsLittleEndian, getAddressByteSize ()),
592- getVersion ());
593- } else {
594- LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor (
595- Context.getDWARFObj (), Context.getDWARFObj ().getLocSection (),
596- IsLittleEndian, getAddressByteSize ()));
597- }
557+ if (auto *Contrib = IndexEntry->getContribution (DW_SECT_RNGLISTS))
558+ ContributionBaseOffset = Contrib->getOffset ();
559+ setRangesSection (
560+ &Context.getDWARFObj ().getRnglistsDWOSection (),
561+ ContributionBaseOffset +
562+ DWARFListTableHeader::getHeaderSize (Header.getFormat ()));
563+ } else
564+ setRangesSection (&Context.getDWARFObj ().getRnglistsSection (),
565+ toSectionOffset (UnitDie.find (DW_AT_rnglists_base),
566+ DWARFListTableHeader::getHeaderSize (
567+ Header.getFormat ())));
568+ }
598569
599- // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
600- // skeleton CU DIE, so that DWARF users not aware of it are not broken.
570+ if (IsDWO) {
571+ // If we are reading a package file, we need to adjust the location list
572+ // data based on the index entries.
573+ StringRef Data = Header.getVersion () >= 5
574+ ? Context.getDWARFObj ().getLoclistsDWOSection ().Data
575+ : Context.getDWARFObj ().getLocDWOSection ().Data ;
576+ if (auto *IndexEntry = Header.getIndexEntry ())
577+ if (const auto *C = IndexEntry->getContribution (
578+ Header.getVersion () >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
579+ Data = Data.substr (C->getOffset (), C->getLength ());
580+
581+ DWARFDataExtractor DWARFData (Data, IsLittleEndian, getAddressByteSize ());
582+ LocTable =
583+ std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion ());
584+ LocSectionBase = DWARFListTableHeader::getHeaderSize (Header.getFormat ());
585+ } else if (getVersion () >= 5 ) {
586+ LocTable = std::make_unique<DWARFDebugLoclists>(
587+ DWARFDataExtractor (Context.getDWARFObj (),
588+ Context.getDWARFObj ().getLoclistsSection (),
589+ IsLittleEndian, getAddressByteSize ()),
590+ getVersion ());
591+ } else {
592+ LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor (
593+ Context.getDWARFObj (), Context.getDWARFObj ().getLocSection (),
594+ IsLittleEndian, getAddressByteSize ()));
595+ }
601596
602- return Error::success ();
603- });
597+ // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
598+ // skeleton CU DIE, so that DWARF users not aware of it are not broken.
599+ return Error::success ();
604600}
605601
606602bool DWARFUnit::parseDWO (StringRef DWOAlternativeLocation) {
@@ -655,26 +651,15 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
655651 return true ;
656652}
657653
658- void DWARFUnit::clearDIEs (bool KeepCUDie, bool KeepDWODies) {
659- cantFail (Context.doWorkThreadSafely ([&] {
660- if (!KeepDWODies && DWO) {
661- DWO->clearDIEs (KeepCUDie, KeepDWODies);
662- }
663- if (!IsDWO) {
664- RangeSectionBase = 0 ;
665- LocSectionBase = 0 ;
666- AddrOffsetSectionBase = std::nullopt ;
667- }
668- // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
669- // shrink_to_fit() is a *non-binding* request to reduce capacity() to
670- // size(). It depends on the implementation whether the request is
671- // fulfilled. Create a new vector with a small capacity and assign it to the
672- // DieArray to have previous contents freed.
673- DieArray = (KeepCUDie && !DieArray.empty ())
674- ? std::vector<DWARFDebugInfoEntry>({DieArray[0 ]})
675- : std::vector<DWARFDebugInfoEntry>();
676- return Error::success ();
677- }));
654+ void DWARFUnit::clearDIEs (bool KeepCUDie) {
655+ // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
656+ // shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
657+ // It depends on the implementation whether the request is fulfilled.
658+ // Create a new vector with a small capacity and assign it to the DieArray to
659+ // have previous contents freed.
660+ DieArray = (KeepCUDie && !DieArray.empty ())
661+ ? std::vector<DWARFDebugInfoEntry>({DieArray[0 ]})
662+ : std::vector<DWARFDebugInfoEntry>();
678663}
679664
680665Expected<DWARFAddressRangesVector>
0 commit comments