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;
276 Options.KeepFunctionForStatic = KeepFunctionForStatic;
281 Options.Threads = NumThreads;
287 Options.AccelTables.emplace_back(Kind);
295 ObjectContexts.reserve(ObjFilesNum);
302 Options.InputVerificationHandler = Handler;
307 Options.ParseableSwiftInterfaces = Map;
312 Options.ObjectPrefixMap = Map;
317 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
319 "unsupported DWARF version: %d",
322 Options.TargetDWARFVersion = TargetDWARFVersion;
328 enum TraversalFlags {
330 TF_InFunctionScope = 1 << 1,
331 TF_DependencyWalk = 1 << 2,
332 TF_ParentWalk = 1 << 3,
338 enum class WorklistItemType {
342 LookForChildDIEsToKeep,
344 LookForRefDIEsToKeep,
346 LookForParentDIEsToKeep,
349 UpdateChildIncompleteness,
352 UpdateRefIncompleteness,
360 struct WorklistItem {
362 WorklistItemType
Type;
366 const unsigned AncestorIdx;
370 WorklistItem(DWARFDie Die, CompileUnit &
CU,
unsigned Flags,
371 WorklistItemType
T = WorklistItemType::LookForDIEsToKeep)
372 : Die(Die), Type(
T),
CU(
CU), Flags(Flags), AncestorIdx(0) {}
374 WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType
T,
375 CompileUnit::DIEInfo *OtherInfo =
nullptr)
376 : Die(Die),
Type(
T), CU(CU),
Flags(0), OtherInfo(OtherInfo) {}
378 WorklistItem(
unsigned AncestorIdx, CompileUnit &CU,
unsigned Flags)
379 :
Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
Flags(
Flags),
380 AncestorIdx(AncestorIdx) {}
384 void verifyInput(
const DWARFFile &File);
387 bool needToTranslateStrings() {
return StringsTranslator !=
nullptr; }
389 void reportWarning(
const Twine &Warning,
const DWARFFile &File,
390 const DWARFDie *DIE =
nullptr)
const {
391 if (WarningHandler !=
nullptr)
392 WarningHandler(Warning,
File.FileName, DIE);
395 void reportError(
const Twine &Warning,
const DWARFFile &File,
396 const DWARFDie *DIE =
nullptr)
const {
401 void copyInvariantDebugSection(DWARFContext &Dwarf);
405 struct RefModuleUnit {
406 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
408 RefModuleUnit(RefModuleUnit &&Other)
410 RefModuleUnit(
const RefModuleUnit &) =
delete;
413 std::unique_ptr<CompileUnit>
Unit;
415 using ModuleUnitListTy = std::vector<RefModuleUnit>;
421 ModuleUnitListTy ModuleUnits;
424 LinkContext(DWARFFile &File) :
File(
File) {}
429 CompileUnits.clear();
436 void cleanupAuxiliarryData(LinkContext &
Context);
440 void lookForParentDIEsToKeep(
unsigned AncestorIdx, CompileUnit &CU,
442 SmallVectorImpl<WorklistItem> &Worklist);
446 void lookForChildDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
448 SmallVectorImpl<WorklistItem> &Worklist);
452 void lookForRefDIEsToKeep(
const DWARFDie &Die, CompileUnit &CU,
453 unsigned Flags,
const UnitListTy &Units,
454 const DWARFFile &File,
455 SmallVectorImpl<WorklistItem> &Worklist);
459 void markODRCanonicalDie(
const DWARFDie &Die, CompileUnit &CU);
468 void lookForDIEsToKeep(AddressesMap &RelocMgr,
const UnitListTy &Units,
469 const DWARFDie &DIE,
const DWARFFile &File,
470 CompileUnit &CU,
unsigned Flags);
476 std::pair<bool, bool> isClangModuleRef(
const DWARFDie &CUDie,
477 std::string &PCMFile,
478 LinkContext &
Context,
unsigned Indent,
487 bool registerModuleReference(
const DWARFDie &CUDie, LinkContext &
Context,
488 ObjFileLoaderTy Loader,
489 CompileUnitHandlerTy OnCUDieLoaded,
490 unsigned Indent = 0);
495 Error loadClangModule(ObjFileLoaderTy Loader,
const DWARFDie &CUDie,
496 const std::string &PCMFile, LinkContext &
Context,
497 CompileUnitHandlerTy OnCUDieLoaded,
498 unsigned Indent = 0);
501 Error cloneModuleUnit(LinkContext &
Context, RefModuleUnit &Unit,
502 DeclContextTree &ODRContexts,
503 OffsetsStringPool &DebugStrPool,
504 OffsetsStringPool &DebugLineStrPool,
505 DebugDieValuePool &StringOffsetPool,
506 unsigned Indent = 0);
508 unsigned shouldKeepDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
509 const DWARFFile &File, CompileUnit &Unit,
510 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
518 std::pair<bool, std::optional<int64_t>>
519 getVariableRelocAdjustment(AddressesMap &RelocMgr,
const DWARFDie &DIE);
523 unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
524 CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
526 unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr,
const DWARFDie &DIE,
527 const DWARFFile &File, CompileUnit &Unit,
528 CompileUnit::DIEInfo &MyInfo,
535 DWARFDie resolveDIEReference(
const DWARFFile &File,
const UnitListTy &Units,
536 const DWARFFormValue &RefValue,
537 const DWARFDie &DIE, CompileUnit *&RefCU);
545 struct DWARFLinkerOptions;
559 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
568 DIECloner(DWARFLinker &Linker, DwarfEmitter *
Emitter, DWARFFile &ObjFile,
569 BumpPtrAllocator &DIEAlloc,
570 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
571 bool Update, OffsetsStringPool &DebugStrPool,
572 OffsetsStringPool &DebugLineStrPool,
573 DebugDieValuePool &StringOffsetPool)
575 DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
576 StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
577 CompileUnits(CompileUnits), Update(Update) {}
590 LLVM_ABI DIE *cloneDIE(
const DWARFDie &InputDIE,
const DWARFFile &File,
591 CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
592 unsigned Flags,
bool IsLittleEndian,
598 LLVM_ABI uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
599 const DWARFFile &File,
600 bool IsLittleEndian);
603 LLVM_ABI void emitDebugAddrSection(CompileUnit &Unit,
604 const uint16_t DwarfVersion)
const;
606 using ExpressionHandlerRef = function_ref<void(
607 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
608 int64_t AddrRelocAdjustment)>;
612 LLVM_ABI void generateUnitLocations(CompileUnit &Unit,
613 const DWARFFile &File,
614 ExpressionHandlerRef ExprHandler);
617 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
621 struct AttributesInfo {
623 DwarfStringPoolEntryRef
Name, MangledName, NameWithoutTemplate;
626 uint32_t NameOffset = 0;
627 uint32_t MangledNameOffset = 0;
630 int64_t PCOffset = 0;
633 bool HasLowPc =
false;
636 bool HasRanges =
false;
639 bool IsDeclaration =
false;
642 bool AttrStrOffsetBaseSeen =
false;
645 bool HasAppleOrigin =
false;
647 AttributesInfo() =
default;
651 unsigned cloneAttribute(DIE &Die,
const DWARFDie &InputDIE,
652 const DWARFFile &File, CompileUnit &U,
653 const DWARFFormValue &Val,
654 const AttributeSpec AttrSpec,
unsigned AttrSize,
655 AttributesInfo &AttrInfo,
bool IsLittleEndian);
660 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
661 const DWARFFormValue &Val,
const DWARFUnit &U,
662 AttributesInfo &
Info);
667 unsigned cloneDieReferenceAttribute(DIE &Die,
const DWARFDie &InputDIE,
668 AttributeSpec AttrSpec,
670 const DWARFFormValue &Val,
671 const DWARFFile &File,
675 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
676 const DWARFFile &File, CompileUnit &Unit,
677 SmallVectorImpl<uint8_t> &OutputBuffer,
678 int64_t AddrRelocAdjustment,
bool IsLittleEndian);
683 unsigned cloneBlockAttribute(DIE &Die,
const DWARFDie &InputDIE,
684 const DWARFFile &File, CompileUnit &Unit,
685 AttributeSpec AttrSpec,
686 const DWARFFormValue &Val,
687 bool IsLittleEndian);
692 unsigned cloneAddressAttribute(DIE &Die,
const DWARFDie &InputDIE,
693 AttributeSpec AttrSpec,
unsigned AttrSize,
694 const DWARFFormValue &Val,
695 const CompileUnit &Unit,
696 AttributesInfo &
Info);
700 unsigned cloneScalarAttribute(DIE &Die,
const DWARFDie &InputDIE,
701 const DWARFFile &File, CompileUnit &U,
702 AttributeSpec AttrSpec,
703 const DWARFFormValue &Val,
unsigned AttrSize,
704 AttributesInfo &
Info);
710 bool getDIENames(
const DWARFDie &Die, AttributesInfo &
Info,
711 OffsetsStringPool &StringPool,
bool StripTemplate =
false);
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 void generateLineTableForUnit(CompileUnit &Unit);
731 void assignAbbrev(DIEAbbrev &Abbrev);
735 void 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;