@@ -496,107 +496,111 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
496496}
497497
498498Error DWARFUnit::tryExtractDIEsIfNeeded (bool  CUDieOnly) {
499-   if  ((CUDieOnly && !DieArray.empty ()) || DieArray.size () > 1 )
500-     return  Error::success (); //  Already parsed.
501- 
502-   bool  HasCUDie = !DieArray.empty ();
503-   extractDIEsToVector (!HasCUDie, !CUDieOnly, DieArray);
504- 
505-   if  (DieArray.empty ())
506-     return  Error::success ();
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+     }
507528
508-   //  If CU DIE was just parsed, copy several attribute values from it.
509-   if  (HasCUDie)
510-     return  Error::success ();
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+       }
511548
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-   }
549+       StringOffsetsTableContribution = *StringOffsetOrError;
550+     }
527551
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-   }
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+     }
549571
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.
554572    if  (IsDWO) {
555-       uint64_t  ContributionBaseOffset = 0 ;
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 ;
556578      if  (auto  *IndexEntry = Header.getIndexEntry ())
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-   }
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+     }
569598
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-   }
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.
596601
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 ();
602+     return  Error::success ();
603+   });
600604}
601605
602606bool  DWARFUnit::parseDWO (StringRef DWOAlternativeLocation) {
@@ -651,15 +655,26 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
651655  return  true ;
652656}
653657
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>();
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+   }));
663678}
664679
665680Expected<DWARFAddressRangesVector>
0 commit comments