219 : StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
220 WarningHandler(WarningHandler) {}
225 return std::make_unique<DWARFLinker>(ErrorHandler, WarningHandler,
241 DWARFFile &File, ObjFileLoaderTy Loader =
nullptr,
242 CompileUnitHandlerTy OnCUDieLoaded = [](
const DWARFUnit &) {})
override;
245 Error link()
override;
254 Options.Statistics = Statistics;
259 Options.VerifyInputDWARF =
Verify;
263 void setNoODR(
bool NoODR)
override { Options.NoODR = NoODR; }
267 Options.Update = Update;
272 Options.KeepFunctionForStatic = KeepFunctionForStatic;
277 Options.Threads = NumThreads;
283 Options.AccelTables.emplace_back(Kind);
291 ObjectContexts.reserve(ObjFilesNum);
298 Options.InputVerificationHandler = Handler;
303 Options.ParseableSwiftInterfaces = Map;
308 Options.ObjectPrefixMap = Map;
313 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
315 "unsupported DWARF version: %d",
318 Options.TargetDWARFVersion = TargetDWARFVersion;
324 enum TraversalFlags {
326 TF_InFunctionScope = 1 << 1,
327 TF_DependencyWalk = 1 << 2,
328 TF_ParentWalk = 1 << 3,
334 enum class WorklistItemType {
338 LookForChildDIEsToKeep,
340 LookForRefDIEsToKeep,
342 LookForParentDIEsToKeep,
345 UpdateChildIncompleteness,
348 UpdateRefIncompleteness,
356 struct WorklistItem {
358 WorklistItemType
Type;
362 const unsigned AncestorIdx;
366 WorklistItem(DWARFDie Die, CompileUnit &
CU,
unsigned Flags,
367 WorklistItemType
T = WorklistItemType::LookForDIEsToKeep)
368 : Die(Die), Type(
T),
CU(
CU), Flags(Flags), AncestorIdx(0) {}
370 WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType
T,
371 CompileUnit::DIEInfo *OtherInfo =
nullptr)
372 : Die(Die),
Type(
T), CU(CU),
Flags(0), OtherInfo(OtherInfo) {}
374 WorklistItem(
unsigned AncestorIdx, CompileUnit &CU,
unsigned Flags)
375 :
Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
Flags(
Flags),
376 AncestorIdx(AncestorIdx) {}
380 void verifyInput(
const DWARFFile &File);
383 bool needToTranslateStrings() {
return StringsTranslator !=
nullptr; }
385 void reportWarning(
const Twine &Warning,
const DWARFFile &File,
386 const DWARFDie *DIE =
nullptr)
const {
387 if (WarningHandler !=
nullptr)
388 WarningHandler(Warning,
File.FileName, DIE);
391 void reportError(
const Twine &Warning,
const DWARFFile &File,
392 const DWARFDie *DIE =
nullptr)
const {
397 void copyInvariantDebugSection(DWARFContext &Dwarf);
401 struct RefModuleUnit {
402 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
404 RefModuleUnit(RefModuleUnit &&Other)
406 RefModuleUnit(
const RefModuleUnit &) =
delete;
409 std::unique_ptr<CompileUnit>
Unit;
411 using ModuleUnitListTy = std::vector<RefModuleUnit>;
417 ModuleUnitListTy ModuleUnits;
420 LinkContext(DWARFFile &File) :
File(
File) {}
425 CompileUnits.clear();
432 void cleanupAuxiliarryData(LinkContext &
Context);
436 void lookForParentDIEsToKeep(
unsigned AncestorIdx, CompileUnit &CU,
438 SmallVectorImpl<WorklistItem> &Worklist);
442 void lookForChildDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
444 SmallVectorImpl<WorklistItem> &Worklist);
448 void lookForRefDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
449 unsigned Flags,
const UnitListTy &Units,
450 const DWARFFile &File,
451 SmallVectorImpl<WorklistItem> &Worklist);
455 void markODRCanonicalDie(
const DWARFDie &Die, CompileUnit &CU);
464 void lookForDIEsToKeep(AddressesMap &RelocMgr,
const UnitListTy &Units,
465 const DWARFDie &DIE,
const DWARFFile &File,
466 CompileUnit &CU,
unsigned Flags);
472 std::pair<bool, bool> isClangModuleRef(
const DWARFDie &CUDie,
473 std::string &PCMFile,
474 LinkContext &
Context,
unsigned Indent,
483 bool registerModuleReference(
const DWARFDie &CUDie, LinkContext &
Context,
484 ObjFileLoaderTy Loader,
485 CompileUnitHandlerTy OnCUDieLoaded,
486 unsigned Indent = 0);
491 Error loadClangModule(ObjFileLoaderTy Loader,
const DWARFDie &CUDie,
492 const std::string &PCMFile, LinkContext &
Context,
493 CompileUnitHandlerTy OnCUDieLoaded,
494 unsigned Indent = 0);
497 Error cloneModuleUnit(LinkContext &
Context, RefModuleUnit &Unit,
498 DeclContextTree &ODRContexts,
499 OffsetsStringPool &DebugStrPool,
500 OffsetsStringPool &DebugLineStrPool,
501 DebugDieValuePool &StringOffsetPool,
502 unsigned Indent = 0);
504 unsigned shouldKeepDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
505 const DWARFFile &File, CompileUnit &Unit,
506 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
514 std::pair<bool, std::optional<int64_t>>
515 getVariableRelocAdjustment(AddressesMap &RelocMgr,
const DWARFDie &DIE);
519 unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
520 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
522 unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
523 const DWARFFile &File, CompileUnit &Unit,
524 CompileUnit::DIEInfo &MyInfo,
531 DWARFDie resolveDIEReference(
const DWARFFile &File,
const UnitListTy &Units,
532 const DWARFFormValue &RefValue,
533 const DWARFDie &DIE, CompileUnit *&RefCU);
541 struct DWARFLinkerOptions;
555 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
564 DIECloner(DWARFLinker &Linker, DwarfEmitter *
Emitter, DWARFFile &ObjFile,
565 BumpPtrAllocator &DIEAlloc,
566 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
567 bool Update, OffsetsStringPool &DebugStrPool,
568 OffsetsStringPool &DebugLineStrPool,
569 DebugDieValuePool &StringOffsetPool)
571 DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
572 StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
573 CompileUnits(CompileUnits), Update(Update) {}
586 LLVM_ABI DIE *cloneDIE(
const DWARFDie &InputDIE,
const DWARFFile &File,
587 CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
588 unsigned Flags,
bool IsLittleEndian,
594 LLVM_ABI Expected<uint64_t> cloneAllCompileUnits(DWARFContext &DwarfContext,
595 const DWARFFile &File,
596 bool IsLittleEndian);
600 const uint16_t DwarfVersion)
const;
602 using ExpressionHandlerRef = function_ref<void(
603 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
604 int64_t AddrRelocAdjustment)>;
609 const DWARFFile &File,
610 ExpressionHandlerRef ExprHandler);
613 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
617 struct AttributesInfo {
619 DwarfStringPoolEntryRef
Name, MangledName, NameWithoutTemplate;
622 uint32_t NameOffset = 0;
623 uint32_t MangledNameOffset = 0;
626 int64_t PCOffset = 0;
629 bool HasLowPc =
false;
632 bool HasRanges =
false;
635 bool IsDeclaration =
false;
638 bool AttrStrOffsetBaseSeen =
false;
641 bool HasAppleOrigin =
false;
643 AttributesInfo() =
default;
647 unsigned cloneAttribute(DIE &Die,
const DWARFDie &InputDIE,
648 const DWARFFile &File, CompileUnit &U,
649 const DWARFFormValue &Val,
650 const AttributeSpec AttrSpec,
unsigned AttrSize,
651 AttributesInfo &AttrInfo,
bool IsLittleEndian);
656 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
657 const DWARFFormValue &Val,
const DWARFUnit &U,
658 AttributesInfo &Info);
663 unsigned cloneDieReferenceAttribute(DIE &Die,
const DWARFDie &InputDIE,
664 AttributeSpec AttrSpec,
666 const DWARFFormValue &Val,
667 const DWARFFile &File,
671 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
672 const DWARFFile &File, CompileUnit &Unit,
673 SmallVectorImpl<uint8_t> &OutputBuffer,
674 int64_t AddrRelocAdjustment,
bool IsLittleEndian);
679 unsigned cloneBlockAttribute(DIE &Die,
const DWARFDie &InputDIE,
680 const DWARFFile &File, CompileUnit &Unit,
681 AttributeSpec AttrSpec,
682 const DWARFFormValue &Val,
683 bool IsLittleEndian);
688 unsigned cloneAddressAttribute(DIE &Die,
const DWARFDie &InputDIE,
689 AttributeSpec AttrSpec,
unsigned AttrSize,
690 const DWARFFormValue &Val,
691 const CompileUnit &Unit,
692 AttributesInfo &Info);
696 unsigned cloneScalarAttribute(DIE &Die,
const DWARFDie &InputDIE,
697 const DWARFFile &File, CompileUnit &U,
698 AttributeSpec AttrSpec,
699 const DWARFFormValue &Val,
unsigned AttrSize,
700 AttributesInfo &Info);
706 bool getDIENames(
const DWARFDie &Die, AttributesInfo &Info,
707 OffsetsStringPool &StringPool,
const DWARFFile &File,
708 CompileUnit &Unit,
bool StripTemplate =
false);
710 llvm::StringRef getCanonicalDIEName(DWARFDie Die,
const DWARFFile &File,
714 const DWARFFile &File,
715 int RecurseDepth = 0);
718 void addObjCAccelerator(CompileUnit &Unit,
const DIE *Die,
719 DwarfStringPoolEntryRef Name,
720 OffsetsStringPool &StringPool,
bool SkipPubSection);
722 void rememberUnitForMacroOffset(CompileUnit &Unit);
727 Error generateLineTableForUnit(CompileUnit &Unit);
731 void assignAbbrev(DIEAbbrev &Abbrev);
735 Error generateUnitRanges(CompileUnit &Unit,
const DWARFFile &File,
736 DebugDieValuePool &AddrPool)
const;
739 void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
742 void patchFrameInfoForObject(LinkContext &
Context);
745 FoldingSet<DIEAbbrev> AbbreviationsSet;
750 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
753 std::vector<DIELoc *> DIELocs;
756 std::vector<DIEBlock *> DIEBlocks;
762 DwarfEmitter *TheDwarfEmitter =
nullptr;
763 std::vector<LinkContext> ObjectContexts;
768 StringMap<uint32_t> EmittedCIEs;
772 uint32_t LastCIEOffset = 0;
776 AccelTable<AppleAccelTableStaticOffsetData>
AppleNames;
778 AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
779 AccelTable<AppleAccelTableStaticTypeData>
AppleTypes;
782 StringMap<uint64_t> ClangModules;
784 std::function<StringRef(StringRef)> StringsTranslator =
nullptr;
787 unsigned UniqueUnitID = 0;
796 struct DWARFLinkerOptions {
798 uint16_t TargetDWARFVersion = 0;
804 bool Statistics =
false;
807 bool VerifyInputDWARF =
false;
817 bool KeepFunctionForStatic =
false;
820 unsigned Threads = 1;
826 std::string PrependPath;
829 InputVerificationHandlerTy InputVerificationHandler =
nullptr;
836 SwiftInterfacesMapTy *ParseableSwiftInterfaces =
nullptr;
839 ObjectPrefixMapTy *ObjectPrefixMap =
nullptr;