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;
286 Options.AccelTables.emplace_back(Kind);
294 ObjectContexts.reserve(ObjFilesNum);
301 Options.InputVerificationHandler = Handler;
306 Options.ParseableSwiftInterfaces = Map;
311 Options.ObjectPrefixMap = Map;
316 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
318 "unsupported DWARF version: %d",
321 Options.TargetDWARFVersion = TargetDWARFVersion;
327 enum TraversalFlags {
329 TF_InFunctionScope = 1 << 1,
330 TF_DependencyWalk = 1 << 2,
331 TF_ParentWalk = 1 << 3,
337 enum class WorklistItemType {
341 LookForChildDIEsToKeep,
343 LookForRefDIEsToKeep,
345 LookForParentDIEsToKeep,
348 UpdateChildIncompleteness,
351 UpdateRefIncompleteness,
359 struct WorklistItem {
361 WorklistItemType
Type;
365 const unsigned AncestorIdx;
369 WorklistItem(DWARFDie Die, CompileUnit &
CU,
unsigned Flags,
370 WorklistItemType
T = WorklistItemType::LookForDIEsToKeep)
371 : Die(Die), Type(
T),
CU(
CU), Flags(Flags), AncestorIdx(0) {}
373 WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType
T,
374 CompileUnit::DIEInfo *OtherInfo =
nullptr)
375 : Die(Die),
Type(
T), CU(CU),
Flags(0), OtherInfo(OtherInfo) {}
377 WorklistItem(
unsigned AncestorIdx, CompileUnit &CU,
unsigned Flags)
378 :
Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
Flags(
Flags),
379 AncestorIdx(AncestorIdx) {}
383 void verifyInput(
const DWARFFile &File);
386 bool needToTranslateStrings() {
return StringsTranslator !=
nullptr; }
388 void reportWarning(
const Twine &Warning,
const DWARFFile &File,
389 const DWARFDie *DIE =
nullptr)
const {
390 if (WarningHandler !=
nullptr)
391 WarningHandler(Warning,
File.FileName, DIE);
394 void reportError(
const Twine &Warning,
const DWARFFile &File,
395 const DWARFDie *DIE =
nullptr)
const {
400 void copyInvariantDebugSection(DWARFContext &Dwarf);
404 struct RefModuleUnit {
405 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
407 RefModuleUnit(RefModuleUnit &&Other)
409 RefModuleUnit(
const RefModuleUnit &) =
delete;
412 std::unique_ptr<CompileUnit>
Unit;
414 using ModuleUnitListTy = std::vector<RefModuleUnit>;
420 ModuleUnitListTy ModuleUnits;
423 LinkContext(DWARFFile &File) :
File(
File) {}
428 CompileUnits.clear();
435 void cleanupAuxiliarryData(LinkContext &
Context);
439 void lookForParentDIEsToKeep(
unsigned AncestorIdx, CompileUnit &CU,
441 SmallVectorImpl<WorklistItem> &Worklist);
445 void lookForChildDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
447 SmallVectorImpl<WorklistItem> &Worklist);
451 void lookForRefDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
452 unsigned Flags,
const UnitListTy &Units,
453 const DWARFFile &File,
454 SmallVectorImpl<WorklistItem> &Worklist);
458 void markODRCanonicalDie(
const DWARFDie &Die, CompileUnit &CU);
467 void lookForDIEsToKeep(AddressesMap &RelocMgr,
const UnitListTy &Units,
468 const DWARFDie &DIE,
const DWARFFile &File,
469 CompileUnit &CU,
unsigned Flags);
475 std::pair<bool, bool> isClangModuleRef(
const DWARFDie &CUDie,
476 std::string &PCMFile,
477 LinkContext &
Context,
unsigned Indent,
486 bool registerModuleReference(
const DWARFDie &CUDie, LinkContext &
Context,
487 ObjFileLoaderTy Loader,
488 CompileUnitHandlerTy OnCUDieLoaded,
489 unsigned Indent = 0);
494 Error loadClangModule(ObjFileLoaderTy Loader,
const DWARFDie &CUDie,
495 const std::string &PCMFile, LinkContext &
Context,
496 CompileUnitHandlerTy OnCUDieLoaded,
497 unsigned Indent = 0);
500 Error cloneModuleUnit(LinkContext &
Context, RefModuleUnit &Unit,
501 DeclContextTree &ODRContexts,
502 OffsetsStringPool &DebugStrPool,
503 OffsetsStringPool &DebugLineStrPool,
504 DebugDieValuePool &StringOffsetPool,
505 unsigned Indent = 0);
507 unsigned shouldKeepDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
508 const DWARFFile &File, CompileUnit &Unit,
509 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
517 std::pair<bool, std::optional<int64_t>>
518 getVariableRelocAdjustment(AddressesMap &RelocMgr,
const DWARFDie &DIE);
522 unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
523 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
525 unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
526 const DWARFFile &File, CompileUnit &Unit,
527 CompileUnit::DIEInfo &MyInfo,
534 DWARFDie resolveDIEReference(
const DWARFFile &File,
const UnitListTy &Units,
535 const DWARFFormValue &RefValue,
536 const DWARFDie &DIE, CompileUnit *&RefCU);
544 struct DWARFLinkerOptions;
558 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
567 DIECloner(DWARFLinker &Linker, DwarfEmitter *
Emitter, DWARFFile &ObjFile,
568 BumpPtrAllocator &DIEAlloc,
569 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
570 bool Update, OffsetsStringPool &DebugStrPool,
571 OffsetsStringPool &DebugLineStrPool,
572 DebugDieValuePool &StringOffsetPool)
574 DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
575 StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
576 CompileUnits(CompileUnits), Update(Update) {}
589 LLVM_ABI DIE *cloneDIE(
const DWARFDie &InputDIE,
const DWARFFile &File,
590 CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
591 unsigned Flags,
bool IsLittleEndian,
597 LLVM_ABI Expected<uint64_t> cloneAllCompileUnits(DWARFContext &DwarfContext,
598 const DWARFFile &File,
599 bool IsLittleEndian);
603 const uint16_t DwarfVersion)
const;
605 using ExpressionHandlerRef = function_ref<void(
606 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
607 int64_t AddrRelocAdjustment)>;
612 const DWARFFile &File,
613 ExpressionHandlerRef ExprHandler);
616 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
620 struct AttributesInfo {
622 DwarfStringPoolEntryRef
Name, MangledName, NameWithoutTemplate;
625 uint32_t NameOffset = 0;
626 uint32_t MangledNameOffset = 0;
629 int64_t PCOffset = 0;
632 bool HasLowPc =
false;
635 bool HasRanges =
false;
638 bool IsDeclaration =
false;
641 bool AttrStrOffsetBaseSeen =
false;
644 bool HasAppleOrigin =
false;
646 AttributesInfo() =
default;
650 unsigned cloneAttribute(DIE &Die,
const DWARFDie &InputDIE,
651 const DWARFFile &File, CompileUnit &U,
652 const DWARFFormValue &Val,
653 const AttributeSpec AttrSpec,
unsigned AttrSize,
654 AttributesInfo &AttrInfo,
bool IsLittleEndian);
659 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
660 const DWARFFormValue &Val,
const DWARFUnit &U,
661 AttributesInfo &Info);
666 unsigned cloneDieReferenceAttribute(DIE &Die,
const DWARFDie &InputDIE,
667 AttributeSpec AttrSpec,
669 const DWARFFormValue &Val,
670 const DWARFFile &File,
674 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
675 const DWARFFile &File, CompileUnit &Unit,
676 SmallVectorImpl<uint8_t> &OutputBuffer,
677 int64_t AddrRelocAdjustment,
bool IsLittleEndian);
682 unsigned cloneBlockAttribute(DIE &Die,
const DWARFDie &InputDIE,
683 const DWARFFile &File, CompileUnit &Unit,
684 AttributeSpec AttrSpec,
685 const DWARFFormValue &Val,
686 bool IsLittleEndian);
691 unsigned cloneAddressAttribute(DIE &Die,
const DWARFDie &InputDIE,
692 AttributeSpec AttrSpec,
unsigned AttrSize,
693 const DWARFFormValue &Val,
694 const CompileUnit &Unit,
695 AttributesInfo &Info);
699 unsigned cloneScalarAttribute(DIE &Die,
const DWARFDie &InputDIE,
700 const DWARFFile &File, CompileUnit &U,
701 AttributeSpec AttrSpec,
702 const DWARFFormValue &Val,
unsigned AttrSize,
703 AttributesInfo &Info);
709 bool getDIENames(
const DWARFDie &Die, AttributesInfo &Info,
710 OffsetsStringPool &StringPool,
const DWARFFile &File,
711 CompileUnit &Unit,
bool StripTemplate =
false);
713 llvm::StringRef getCanonicalDIEName(DWARFDie Die,
const DWARFFile &File,
717 const DWARFFile &File,
718 int RecurseDepth = 0);
721 void addObjCAccelerator(CompileUnit &Unit,
const DIE *Die,
722 DwarfStringPoolEntryRef Name,
723 OffsetsStringPool &StringPool,
bool SkipPubSection);
725 void rememberUnitForMacroOffset(CompileUnit &Unit);
730 Error generateLineTableForUnit(CompileUnit &Unit);
734 void assignAbbrev(DIEAbbrev &Abbrev);
738 Error generateUnitRanges(CompileUnit &Unit,
const DWARFFile &File,
739 DebugDieValuePool &AddrPool)
const;
742 void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
745 void patchFrameInfoForObject(LinkContext &
Context);
748 FoldingSet<DIEAbbrev> AbbreviationsSet;
753 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
756 std::vector<DIELoc *> DIELocs;
759 std::vector<DIEBlock *> DIEBlocks;
765 DwarfEmitter *TheDwarfEmitter =
nullptr;
766 std::vector<LinkContext> ObjectContexts;
771 StringMap<uint32_t> EmittedCIEs;
775 uint32_t LastCIEOffset = 0;
779 AccelTable<AppleAccelTableStaticOffsetData>
AppleNames;
781 AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
782 AccelTable<AppleAccelTableStaticTypeData>
AppleTypes;
785 StringMap<uint64_t> ClangModules;
787 std::function<StringRef(StringRef)> StringsTranslator =
nullptr;
790 unsigned UniqueUnitID = 0;
799 struct DWARFLinkerOptions {
801 uint16_t TargetDWARFVersion = 0;
807 bool Statistics =
false;
810 bool VerifyInputDWARF =
false;
820 bool KeepFunctionForStatic =
false;
823 unsigned Threads = 1;
829 std::string PrependPath;
832 InputVerificationHandlerTy InputVerificationHandler =
nullptr;
839 SwiftInterfacesMapTy *ParseableSwiftInterfaces =
nullptr;
842 ObjectPrefixMapTy *ObjectPrefixMap =
nullptr;