9#ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
10#define LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
31template <
typename T>
class SmallVectorImpl;
33namespace dwarf_linker {
51 emitAbbrevs(
const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
52 unsigned DwarfVersion) = 0;
132 std::vector<uint64_t> *RowOffsets =
nullptr) = 0;
153 unsigned DwarfVersion) = 0;
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;
276 Options.KeepFunctionForStatic = KeepFunctionForStatic;
287 Options.AccelTables.emplace_back(Kind);
295 ObjectContexts.reserve(ObjFilesNum);
302 Options.InputVerificationHandler = Handler;
307 Options.ParseableSwiftInterfaces = Map;
317 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
319 "unsupported DWARF version: %d",
322 Options.TargetDWARFVersion = TargetDWARFVersion;
323 return Error::success();
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)
378 WorklistItem(
unsigned AncestorIdx, CompileUnit &
CU,
unsigned 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,
599 const DWARFFile &File,
600 bool IsLittleEndian);
603 LLVM_ABI void emitDebugAddrSection(CompileUnit &Unit,
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;
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,
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;
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 {
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;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains support for writing accelerator tables.
static uint32_t hashFullyQualifiedName(CompileUnit &InputCU, DWARFDie &InputDIE, int ChildRecurseDepth=0)
static Error reportError(StringRef Message)
Analysis containing CSE Info
dxil DXContainer Global Emitter
This file defines the DenseMap class.
static cl::opt< AccelTableKind > AccelTables("accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."), cl::values(clEnumValN(AccelTableKind::Default, "Default", "Default for platform"), clEnumValN(AccelTableKind::None, "Disable", "Disabled."), clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), cl::init(AccelTableKind::Default))
std::optional< std::vector< StOtherPiece > > Other
static fatal_error_handler_t ErrorHandler
ppc ctr loops PowerPC CTR Loops Verify
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
The AddressRanges class helps normalize address range collections.
A structured debug information entry.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Lightweight error class with error context and mandatory checking.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
A string table that doesn't need relocations.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Helper for making strong types.
This class represents DWARF information for source file and it's address map.
The base interface for DWARFLinker implementations.
std::map< std::string, std::string > ObjectPrefixMapTy
AccelTableKind
The kind of accelerator tables to be emitted.
std::function< void(const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
std::function< void(const DWARFFile &File, llvm::StringRef Output)> InputVerificationHandlerTy
std::map< std::string, std::string > SwiftInterfacesMapTy
Stores all information relating to a compile unit, be it in its original instance in the object file ...
The core of the Dwarf linking logic.
void setStatistics(bool Statistics) override
Print statistics to standard output.
void setInputVerificationHandler(InputVerificationHandlerTy Handler) override
Set verification handler which would be used to report verification errors.
void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override
Set map for Swift interfaces.
void setNumThreads(unsigned NumThreads) override
Use specified number of threads for parallel files linking.
void setAllowNonDeterministicOutput(bool) override
Allow generating valid, but non-deterministic output.
void setObjectPrefixMap(ObjectPrefixMapTy *Map) override
Set prefix map for objects.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) override
Set whether to keep the enclosing function for a static variable.
DWARFLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, std::function< StringRef(StringRef)> StringsTranslator)
void setVerifyInputDWARF(bool Verify) override
Verify the input DWARF.
void addAccelTableKind(AccelTableKind Kind) override
Add kind of accelerator tables to be generated.
static std::unique_ptr< DWARFLinker > createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, std::function< StringRef(StringRef)> StringsTranslator=nullptr)
void setNoODR(bool NoODR) override
Do not unique types according to ODR.
void setPrependPath(StringRef Ppath) override
Set prepend path for clang modules.
Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override
Set target DWARF version.
void setOutputDWARFEmitter(DwarfEmitter *Emitter)
Set output DWARF emitter.
void setUpdateIndexTablesOnly(bool Update) override
Update index tables only(do not modify rest of DWARF).
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override
Set estimated objects files amount, for preliminary data allocation.
void setVerbosity(bool Verbose) override
A number of methods setting various linking options:
DwarfEmitter presents interface to generate all debug info tables.
virtual void emitDwarfDebugAddrs(const SmallVector< uint64_t > &Addrs, uint8_t AddrSize)=0
Emit the addresses described by Addrs into the .debug_addr section.
virtual uint64_t getDebugAddrSectionSize() const =0
Returns size of generated .debug_addr section.
virtual void emitPubTypesForUnit(const CompileUnit &Unit)=0
Emit the .debug_pubtypes contribution for Unit.
virtual void emitSectionContents(StringRef SecData, DebugSectionKind SecKind)=0
Emit section named SecName with data SecData.
virtual uint64_t getDebugMacroSectionSize() const =0
Returns size of generated .debug_macro section.
virtual void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool)=0
Emit debug ranges (.debug_ranges, .debug_rnglists) fragment.
virtual void emitDwarfDebugArangesTable(const CompileUnit &Unit, const AddressRanges &LinkedRanges)=0
Emit .debug_aranges entries for Unit.
virtual uint64_t getDebugInfoSectionSize() const =0
Returns size of generated .debug_info section.
virtual ~DwarfEmitter()=default
virtual void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion)=0
Emit the compilation unit header for Unit in the .debug_info section.
virtual void emitCIE(StringRef CIEBytes)=0
Emit a CIE.
virtual uint64_t getFrameSectionSize() const =0
Returns size of generated .debug_frame section.
virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address, StringRef Bytes)=0
Emit an FDE with data Bytes.
virtual void emitAppleNamespaces(AccelTable< AppleAccelTableStaticOffsetData > &Table)=0
Emit Apple namespaces accelerator table.
virtual uint64_t getRngListsSectionSize() const =0
Returns size of generated .debug_rnglists section.
virtual void emitAppleObjc(AccelTable< AppleAccelTableStaticOffsetData > &Table)=0
Emit Apple Objective-C accelerator table.
virtual void emitMacroTables(DWARFContext *Context, const Offset2UnitMap &UnitMacroMap, OffsetsStringPool &StringPool)=0
Emit all available macro tables(DWARFv4 and DWARFv5).
virtual void emitDwarfDebugLocListFragment(const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool)=0
Emit debug locations (.debug_loc, .debug_loclists) fragment.
virtual void emitDebugNames(DWARF5AccelTable &Table)=0
Emit DWARF debug names.
virtual void emitAppleTypes(AccelTable< AppleAccelTableStaticTypeData > &Table)=0
Emit Apple type accelerator table.
virtual MCSymbol * emitDwarfDebugAddrsHeader(const CompileUnit &Unit)=0
Emit .debug_addr header.
virtual MCSymbol * emitDwarfDebugLocListHeader(const CompileUnit &Unit)=0
Emit debug locations (.debug_loc, .debug_loclists) header.
virtual void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit, OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool, std::vector< uint64_t > *RowOffsets=nullptr)=0
Emit specified LineTable into .debug_line table.
virtual void emitDIE(DIE &Die)=0
Recursively emit the DIE tree rooted at Die.
virtual uint64_t getDebugMacInfoSectionSize() const =0
Returns size of generated .debug_macinfo section.
virtual void emitPubNamesForUnit(const CompileUnit &Unit)=0
Emit the .debug_pubnames contribution for Unit.
virtual void emitAppleNames(AccelTable< AppleAccelTableStaticOffsetData > &Table)=0
Emit Apple names accelerator table.
virtual void emitAbbrevs(const std::vector< std::unique_ptr< DIEAbbrev > > &Abbrevs, unsigned DwarfVersion)=0
Emit the abbreviation table Abbrevs to the .debug_abbrev section.
virtual uint64_t getLocListsSectionSize() const =0
Returns size of generated .debug_loclists section.
virtual uint64_t getLineSectionSize() const =0
Returns size of generated .debug_line section.
virtual MCSymbol * emitDwarfDebugRangeListHeader(const CompileUnit &Unit)=0
Emit debug ranges (.debug_ranges, .debug_rnglists) header.
virtual void emitStrings(const NonRelocatableStringpool &Pool)=0
Emit the string table described by Pool into .debug_str table.
virtual void finish()=0
Dump the file to the disk.
virtual void emitDwarfDebugAddrsFooter(const CompileUnit &Unit, MCSymbol *EndLabel)=0
Emit .debug_addr footer.
virtual uint64_t getRangesSectionSize() const =0
Returns size of generated .debug_ranges section.
virtual void emitLineStrings(const NonRelocatableStringpool &Pool)=0
Emit the string table described by Pool into .debug_line_str table.
virtual void emitDwarfDebugLocListFooter(const CompileUnit &Unit, MCSymbol *EndLabel)=0
Emit debug locations (.debug_loc, .debug_loclists) footer.
virtual void emitStringOffsets(const SmallVector< uint64_t > &StringOffsets, uint16_t TargetDWARFVersion)=0
Emit the debug string offset table described by StringOffsets into the .debug_str_offsets table.
virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, MCSymbol *EndLabel)=0
Emit debug ranges (.debug_ranges, .debug_rnglists) footer.
User of DwarfStreamer should call initialization code for AsmPrinter:
DenseMap< uint64_t, CompileUnit * > Offset2UnitMap
IndexedValuesMap< uint64_t > DebugDieValuePool
std::vector< std::unique_ptr< CompileUnit > > UnitListTy
std::function< void(const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
DebugSectionKind
List of tracked debug tables.
DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
StrongType< NonRelocatableStringpool, OffsetsTag > OffsetsStringPool
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Implement std::hash so that hash_code can be used in STL containers.
Information gathered about a DIE in the object file.