LLVM: include/llvm/DWARFLinker/Classic/DWARFLinker.h Source File (original) (raw)
42public:
44
45
48
49
50 virtual void
51 emitAbbrevs(const std::vector<std::unique_ptr> &Abbrevs,
52 unsigned DwarfVersion) = 0;
53
54
56
57
58
60 uint16_t TargetDWARFVersion) = 0;
61
62
64
65
67
68
69 virtual void
71
72
73 virtual void
75
76
77 virtual void
79
80
81 virtual void
83
84
86
87
91
92
95
96
98
99
104
105
108
109
111
112
115
116
119
120
121 virtual void
124
125
126
127
128 virtual void
132 std::vector<uint64_t> *RowOffsets = nullptr) = 0;
133
134
136
137
139
140
142
143
146
147
148
149
150
151
153 unsigned DwarfVersion) = 0;
154
155
157
158
159
160
161
162
166
167
169
170
172
173
175
176
178
179
181
182
184
185
187
188
190
191
193
194
196};
216public:
219 : StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
220 WarningHandler(WarningHandler) {}
221
225 return std::make_unique(ErrorHandler, WarningHandler,
226 StringsTranslator);
227 }
228
229
231 TheDwarfEmitter = Emitter;
232 }
233
234
235
236
237
238
239
240 void addObjectFile(
241 DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
242 CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
243
244
245 Error link() override;
246
247
248
249
251
252
254 Options.Statistics = Statistics;
255 }
256
257
259 Options.VerifyInputDWARF = Verify;
260 }
261
262
263 void setNoODR(bool NoODR) override { Options.NoODR = NoODR; }
264
265
267 Options.Update = Update;
268 }
269
270
273
274
276 Options.KeepFunctionForStatic = KeepFunctionForStatic;
277 }
278
279
281 Options.Threads = NumThreads;
282 }
283
284
287 Options.AccelTables.emplace_back(Kind);
288 }
289
290
292
293
295 ObjectContexts.reserve(ObjFilesNum);
296 }
297
298
299
300 void
302 Options.InputVerificationHandler = Handler;
303 }
304
305
307 Options.ParseableSwiftInterfaces = Map;
308 }
309
310
312 Options.ObjectPrefixMap = Map;
313 }
314
315
317 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
319 "unsupported DWARF version: %d",
320 TargetDWARFVersion);
321
322 Options.TargetDWARFVersion = TargetDWARFVersion;
324 }
325
326private:
327
328 enum TraversalFlags {
329 TF_Keep = 1 << 0,
330 TF_InFunctionScope = 1 << 1,
331 TF_DependencyWalk = 1 << 2,
332 TF_ParentWalk = 1 << 3,
333 TF_ODR = 1 << 4,
334 TF_SkipPC = 1 << 5,
335 };
336
337
338 enum class WorklistItemType {
339
340 LookForDIEsToKeep,
341
342 LookForChildDIEsToKeep,
343
344 LookForRefDIEsToKeep,
345
346 LookForParentDIEsToKeep,
347
348
349 UpdateChildIncompleteness,
350
351
352 UpdateRefIncompleteness,
353
354 MarkODRCanonicalDie,
355 };
356
357
358
359
360 struct WorklistItem {
362 WorklistItemType Type;
364 unsigned Flags;
365 union {
366 const unsigned AncestorIdx;
368 };
369
370 WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
371 WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
372 : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
373
374 WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
375 CompileUnit::DIEInfo *OtherInfo = nullptr)
376 : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
377
378 WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
379 : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
380 AncestorIdx(AncestorIdx) {}
381 };
382
383
384 void verifyInput(const DWARFFile &File);
385
386
387 bool needToTranslateStrings() { return StringsTranslator != nullptr; }
388
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);
393 }
394
395 void reportError(const Twine &Warning, const DWARFFile &File,
396 const DWARFDie *DIE = nullptr) const {
399 }
400
401 void copyInvariantDebugSection(DWARFContext &Dwarf);
402
403
404
405 struct RefModuleUnit {
406 RefModuleUnit(DWARFFile &File, std::unique_ptr Unit)
408 RefModuleUnit(RefModuleUnit &&Other)
410 RefModuleUnit(const RefModuleUnit &) = delete;
411
412 DWARFFile &File;
413 std::unique_ptr Unit;
414 };
415 using ModuleUnitListTy = std::vector;
416
417
418 struct LinkContext {
419 DWARFFile &File;
421 ModuleUnitListTy ModuleUnits;
422 bool Skip = false;
423
424 LinkContext(DWARFFile &File) : File(File) {}
425
426
427
428 void clear() {
429 CompileUnits.clear();
430 ModuleUnits.clear();
431 File.unload();
432 }
433 };
434
435
436 void cleanupAuxiliarryData(LinkContext &Context);
437
438
439
440 void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
441 unsigned Flags,
442 SmallVectorImpl &Worklist);
443
444
445
446 void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
447 unsigned Flags,
448 SmallVectorImpl &Worklist);
449
450
451
452 void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
453 unsigned Flags, const UnitListTy &Units,
454 const DWARFFile &File,
455 SmallVectorImpl &Worklist);
456
457
458
459 void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
460
461
462
463
464
465
466
467
468 void lookForDIEsToKeep(AddressesMap &RelocMgr, const UnitListTy &Units,
469 const DWARFDie &DIE, const DWARFFile &File,
470 CompileUnit &CU, unsigned Flags);
471
472
473
474
475
476 std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
477 std::string &PCMFile,
478 LinkContext &Context, unsigned Indent,
479 bool Quiet);
480
481
482
483
484
485
486
487 bool registerModuleReference(const DWARFDie &CUDie, LinkContext &Context,
488 ObjFileLoaderTy Loader,
489 CompileUnitHandlerTy OnCUDieLoaded,
490 unsigned Indent = 0);
491
492
493
494
495 Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
496 const std::string &PCMFile, LinkContext &Context,
497 CompileUnitHandlerTy OnCUDieLoaded,
498 unsigned Indent = 0);
499
500
501 Error cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
502 DeclContextTree &ODRContexts,
503 OffsetsStringPool &DebugStrPool,
504 OffsetsStringPool &DebugLineStrPool,
505 DebugDieValuePool &StringOffsetPool,
506 unsigned Indent = 0);
507
508 unsigned shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
509 const DWARFFile &File, CompileUnit &Unit,
510 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
511
512
513
514
515
516
517
518 std::pair<bool, std::optional<int64_t>>
519 getVariableRelocAdjustment(AddressesMap &RelocMgr, const DWARFDie &DIE);
520
521
522
523 unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
524 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
525
526 unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
527 const DWARFFile &File, CompileUnit &Unit,
528 CompileUnit::DIEInfo &MyInfo,
529 unsigned Flags);
530
531
532
533
534
535 DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
536 const DWARFFormValue &RefValue,
537 const DWARFDie &DIE, CompileUnit *&RefCU);
538
539
540
541
542
543
544
545 struct DWARFLinkerOptions;
546
547 class DIECloner {
548 DWARFLinker &Linker;
550 DWARFFile &ObjFile;
555
556
558
559 std::vector<std::unique_ptr> &CompileUnits;
560
561
562
564
565 bool Update;
566
567 public:
568 DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
569 BumpPtrAllocator &DIEAlloc,
570 std::vector<std::unique_ptr> &CompileUnits,
571 bool Update, OffsetsStringPool &DebugStrPool,
572 OffsetsStringPool &DebugLineStrPool,
573 DebugDieValuePool &StringOffsetPool)
574 : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
575 DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
576 StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
577 CompileUnits(CompileUnits), Update(Update) {}
578
579
580
581
582
583
584
585
586
587
588
589
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,
593 DIE *Die = nullptr);
594
595
596
597
598 LLVM_ABI uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
599 const DWARFFile &File,
600 bool IsLittleEndian);
601
602
603 LLVM_ABI void emitDebugAddrSection(CompileUnit &Unit,
604 const uint16_t DwarfVersion) const;
605
606 using ExpressionHandlerRef = function_ref<void(
607 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
608 int64_t AddrRelocAdjustment)>;
609
610
611
612 LLVM_ABI void generateUnitLocations(CompileUnit &Unit,
613 const DWARFFile &File,
614 ExpressionHandlerRef ExprHandler);
615
616 private:
617 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
618
619
620
621 struct AttributesInfo {
622
623 DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
624
625
626 uint32_t NameOffset = 0;
627 uint32_t MangledNameOffset = 0;
628
629
630 int64_t PCOffset = 0;
631
632
633 bool HasLowPc = false;
634
635
636 bool HasRanges = false;
637
638
639 bool IsDeclaration = false;
640
641
642 bool AttrStrOffsetBaseSeen = false;
643
644
645 bool HasAppleOrigin = false;
646
647 AttributesInfo() = default;
648 };
649
650
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);
656
657
658
659
660 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
661 const DWARFFormValue &Val, const DWARFUnit &U,
662 AttributesInfo &Info);
663
664
665
666
667 unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
668 AttributeSpec AttrSpec,
669 unsigned AttrSize,
670 const DWARFFormValue &Val,
671 const DWARFFile &File,
672 CompileUnit &Unit);
673
674
675 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
676 const DWARFFile &File, CompileUnit &Unit,
677 SmallVectorImpl<uint8_t> &OutputBuffer,
678 int64_t AddrRelocAdjustment, bool IsLittleEndian);
679
680
681
682
683 unsigned cloneBlockAttribute(DIE &Die, const DWARFDie &InputDIE,
684 const DWARFFile &File, CompileUnit &Unit,
685 AttributeSpec AttrSpec,
686 const DWARFFormValue &Val,
687 bool IsLittleEndian);
688
689
690
691
692 unsigned cloneAddressAttribute(DIE &Die, const DWARFDie &InputDIE,
693 AttributeSpec AttrSpec, unsigned AttrSize,
694 const DWARFFormValue &Val,
695 const CompileUnit &Unit,
696 AttributesInfo &Info);
697
698
699
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);
705
706
707
708
709
710 bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
711 OffsetsStringPool &StringPool, const DWARFFile &File,
712 CompileUnit &Unit, bool StripTemplate = false);
713
714 llvm::StringRef getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
715 CompileUnit *Unit);
716
718 const DWARFFile &File,
719 int RecurseDepth = 0);
720
721
722 void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
723 DwarfStringPoolEntryRef Name,
724 OffsetsStringPool &StringPool, bool SkipPubSection);
725
726 void rememberUnitForMacroOffset(CompileUnit &Unit);
727
728
729
730
731 void generateLineTableForUnit(CompileUnit &Unit);
732 };
733
734
735 void assignAbbrev(DIEAbbrev &Abbrev);
736
737
738
739 void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
740 DebugDieValuePool &AddrPool) const;
741
742
743 void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
744
745
746 void patchFrameInfoForObject(LinkContext &Context);
747
748
749 FoldingSet AbbreviationsSet;
750
751
752
753
754 std::vector<std::unique_ptr> Abbreviations;
755
756
757 std::vector<DIELoc *> DIELocs;
758
759
760 std::vector<DIEBlock *> DIEBlocks;
761
762
764
765
766 DwarfEmitter *TheDwarfEmitter = nullptr;
767 std::vector ObjectContexts;
768
769
770
771
772 StringMap<uint32_t> EmittedCIEs;
773
774
775
776 uint32_t LastCIEOffset = 0;
777
778
780 AccelTable AppleNames;
781 AccelTable AppleNamespaces;
782 AccelTable AppleObjc;
783 AccelTable AppleTypes;
784
785
786 StringMap<uint64_t> ClangModules;
787
788 std::function<StringRef(StringRef)> StringsTranslator = nullptr;
789
790
791 unsigned UniqueUnitID = 0;
792
793
795
796
798
799
800 struct DWARFLinkerOptions {
801
802 uint16_t TargetDWARFVersion = 0;
803
804
806
807
808 bool Statistics = false;
809
810
811 bool VerifyInputDWARF = false;
812
813
814 bool NoODR = false;
815
816
817 bool Update = false;
818
819
820
821 bool KeepFunctionForStatic = false;
822
823
824 unsigned Threads = 1;
825
826
827 SmallVector<AccelTableKind, 1> AccelTables;
828
829
830 std::string PrependPath;
831
832
833 InputVerificationHandlerTy InputVerificationHandler = nullptr;
834
835
836
837
838
839
840 SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
841
842
843 ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
845};