summaryrefslogtreecommitdiff
path: root/llvm/include/llvm/DWARFLinker/DWARFLinker.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/DWARFLinker/DWARFLinker.h')
-rw-r--r--llvm/include/llvm/DWARFLinker/DWARFLinker.h619
1 files changed, 614 insertions, 5 deletions
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
index 80df01ca0539..be3c5ebcadae 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
@@ -21,6 +21,13 @@ namespace llvm {
enum class DwarfLinkerClient { Dsymutil, LLD, General };
+/// The kind of accelerator tables we should emit.
+enum class AccelTableKind {
+ Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
+ Dwarf, ///< DWARF v5 .debug_names.
+ Default, ///< Dwarf for DWARF5 or later, Apple otherwise.
+};
+
/// Partial address range. Besides an offset, only the
/// HighPC is stored. The structure is stored in a map where the LowPC is the
/// key.
@@ -89,12 +96,10 @@ public:
virtual ~DwarfEmitter();
/// Emit DIE containing warnings.
- virtual void emitPaperTrailWarningsDie(const Triple &Triple, DIE &Die) = 0;
+ virtual void emitPaperTrailWarningsDie(DIE &Die) = 0;
- /// Emit section named SecName with content equals to
- /// corresponding section in Obj.
- virtual void emitSectionContents(const object::ObjectFile &Obj,
- StringRef SecName) = 0;
+ /// Emit section named SecName with data SecData.
+ virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
/// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
virtual void
@@ -193,6 +198,610 @@ public:
virtual uint64_t getDebugInfoSectionSize() const = 0;
};
+using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
+
+/// this class represents DWARF information for source file
+/// and it`s address map.
+class DwarfFile {
+public:
+ DwarfFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
+ const std::vector<std::string> &Warnings)
+ : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
+ }
+
+ /// object file name.
+ StringRef FileName;
+ /// source DWARF information.
+ DWARFContext *Dwarf = nullptr;
+ /// helpful address information(list of valid address ranges, relocations).
+ AddressesMap *Addresses = nullptr;
+ /// warnings for object file.
+ const std::vector<std::string> &Warnings;
+};
+
+typedef std::function<void(const Twine &Warning, StringRef Context,
+ const DWARFDie *DIE)>
+ messageHandler;
+typedef std::function<ErrorOr<DwarfFile &>(StringRef ContainerName,
+ StringRef Path)>
+ objFileLoader;
+typedef std::map<std::string, std::string> swiftInterfacesMap;
+typedef std::map<std::string, std::string> objectPrefixMap;
+
+/// The core of the Dwarf linking logic.
+///
+/// The generation of the dwarf information from the object files will be
+/// driven by the selection of 'root DIEs', which are DIEs that
+/// describe variables or functions that resolves to the corresponding
+/// code section(and thus have entries in the Addresses map). All the debug
+/// information that will be generated(the DIEs, but also the line
+/// tables, ranges, ...) is derived from that set of root DIEs.
+///
+/// The root DIEs are identified because they contain relocations that
+/// points to code section(the low_pc for a function, the location for
+/// a variable). These relocations are called ValidRelocs in the
+/// AddressesInfo and are gathered as a very first step when we start
+/// processing a object file.
+class DWARFLinker {
+public:
+ DWARFLinker(DwarfEmitter *Emitter,
+ DwarfLinkerClient ClientID = DwarfLinkerClient::General)
+ : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
+
+ /// Add object file to be linked.
+ void addObjectFile(DwarfFile &File);
+
+ /// Link debug info for added objFiles. Object
+ /// files are linked all together.
+ bool link();
+
+ /// A number of methods setting various linking options:
+
+ /// Allows to generate log of linking process to the standard output.
+ void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
+
+ /// Print statistics to standard output.
+ void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
+
+ /// Do not emit linked dwarf info.
+ void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
+
+ /// Do not unique types according to ODR.
+ void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
+
+ /// update existing DWARF info(for the linked binary).
+ void setUpdate(bool Update) { Options.Update = Update; }
+
+ /// Use specified number of threads for parallel files linking.
+ void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
+
+ /// Set kind of accelerator tables to be generated.
+ void setAccelTableKind(AccelTableKind Kind) {
+ Options.TheAccelTableKind = Kind;
+ }
+
+ /// Set prepend path for clang modules.
+ void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
+
+ /// Set translator which would be used for strings.
+ void
+ setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
+ this->StringsTranslator = StringsTranslator;
+ }
+
+ /// Set estimated objects files amount, for preliminary data allocation.
+ void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
+ ObjectContexts.reserve(ObjFilesNum);
+ }
+
+ /// Set warning handler which would be used to report warnings.
+ void setWarningHandler(messageHandler Handler) {
+ Options.WarningHandler = Handler;
+ }
+
+ /// Set error handler which would be used to report errors.
+ void setErrorHandler(messageHandler Handler) {
+ Options.ErrorHandler = Handler;
+ }
+
+ /// Set object files loader which would be used to load
+ /// additional objects for splitted dwarf.
+ void setObjFileLoader(objFileLoader Loader) {
+ Options.ObjFileLoader = Loader;
+ }
+
+ /// Set map for Swift interfaces.
+ void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
+ Options.ParseableSwiftInterfaces = Map;
+ }
+
+ /// Set prefix map for objects.
+ void setObjectPrefixMap(objectPrefixMap *Map) {
+ Options.ObjectPrefixMap = Map;
+ }
+
+private:
+ /// Flags passed to DwarfLinker::lookForDIEsToKeep
+ enum TraversalFlags {
+ TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
+ TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
+ TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
+ TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
+ TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
+ TF_SkipPC = 1 << 5, ///< Skip all location attributes.
+ };
+
+ /// The distinct types of work performed by the work loop.
+ enum class WorklistItemType {
+ /// Given a DIE, look for DIEs to be kept.
+ LookForDIEsToKeep,
+ /// Given a DIE, look for children of this DIE to be kept.
+ LookForChildDIEsToKeep,
+ /// Given a DIE, look for DIEs referencing this DIE to be kept.
+ LookForRefDIEsToKeep,
+ /// Given a DIE, look for parent DIEs to be kept.
+ LookForParentDIEsToKeep,
+ /// Given a DIE, update its incompleteness based on whether its children are
+ /// incomplete.
+ UpdateChildIncompleteness,
+ /// Given a DIE, update its incompleteness based on whether the DIEs it
+ /// references are incomplete.
+ UpdateRefIncompleteness,
+ };
+
+ /// This class represents an item in the work list. The type defines what kind
+ /// of work needs to be performed when processing the current item. The flags
+ /// and info fields are optional based on the type.
+ struct WorklistItem {
+ WorklistItemType Type;
+ DWARFDie Die;
+ CompileUnit &CU;
+ unsigned Flags;
+ unsigned AncestorIdx = 0;
+ CompileUnit::DIEInfo *OtherInfo = nullptr;
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
+ WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
+ : Type(T), Die(Die), CU(CU), Flags(Flags) {}
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
+ CompileUnit::DIEInfo *OtherInfo = nullptr)
+ : Type(T), Die(Die), CU(CU), OtherInfo(OtherInfo) {}
+
+ WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
+ : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
+ AncestorIdx(AncestorIdx) {}
+ };
+
+ /// returns true if we need to translate strings.
+ bool needToTranslateStrings() { return StringsTranslator != nullptr; }
+
+ void reportWarning(const Twine &Warning, const DwarfFile &File,
+ const DWARFDie *DIE = nullptr) const {
+ if (Options.WarningHandler != nullptr)
+ Options.WarningHandler(Warning, File.FileName, DIE);
+ }
+
+ void reportError(const Twine &Warning, const DwarfFile &File,
+ const DWARFDie *DIE = nullptr) const {
+ if (Options.ErrorHandler != nullptr)
+ Options.ErrorHandler(Warning, File.FileName, DIE);
+ }
+
+ /// Remembers the oldest and newest DWARF version we've seen in a unit.
+ void updateDwarfVersion(unsigned Version) {
+ MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
+ MinDwarfVersion = std::min(MinDwarfVersion, Version);
+ }
+
+ /// Remembers the kinds of accelerator tables we've seen in a unit.
+ void updateAccelKind(DWARFContext &Dwarf);
+
+ /// Emit warnings as Dwarf compile units to leave a trail after linking.
+ bool emitPaperTrailWarnings(const DwarfFile &File,
+ OffsetsStringPool &StringPool);
+
+ void copyInvariantDebugSection(DWARFContext &Dwarf);
+
+ /// Keeps track of data associated with one object during linking.
+ struct LinkContext {
+ DwarfFile &File;
+ UnitListTy CompileUnits;
+ bool Skip = false;
+
+ LinkContext(DwarfFile &File) : File(File) {}
+
+ /// Clear part of the context that's no longer needed when we're done with
+ /// the debug object.
+ void clear() {
+ CompileUnits.clear();
+ File.Addresses->clear();
+ }
+ };
+
+ /// Called before emitting object data
+ void cleanupAuxiliarryData(LinkContext &Context);
+
+ /// Look at the parent of the given DIE and decide whether they should be
+ /// kept.
+ void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
+ unsigned Flags,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// Look at the children of the given DIE and decide whether they should be
+ /// kept.
+ void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
+ unsigned Flags,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// Look at DIEs referenced by the given DIE and decide whether they should be
+ /// kept. All DIEs referenced though attributes should be kept.
+ void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
+ unsigned Flags, const UnitListTy &Units,
+ const DwarfFile &File,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
+ ///
+ /// @{
+ /// Recursively walk the \p DIE tree and look for DIEs to
+ /// keep. Store that information in \p CU's DIEInfo.
+ ///
+ /// The return value indicates whether the DIE is incomplete.
+ void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const UnitListTy &Units, const DWARFDie &DIE,
+ const DwarfFile &File, CompileUnit &CU,
+ unsigned Flags);
+
+ /// If this compile unit is really a skeleton CU that points to a
+ /// clang module, register it in ClangModules and return true.
+ ///
+ /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
+ /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
+ /// hash.
+ bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
+ const DwarfFile &File,
+ OffsetsStringPool &OffsetsStringPool,
+ UniquingStringPool &UniquingStringPoolStringPool,
+ DeclContextTree &ODRContexts,
+ uint64_t ModulesEndOffset, unsigned &UnitID,
+ bool IsLittleEndian, unsigned Indent = 0,
+ bool Quiet = false);
+
+ /// Recursively add the debug info in this clang module .pcm
+ /// file (and all the modules imported by it in a bottom-up fashion)
+ /// to Units.
+ Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
+ StringRef ModuleName, uint64_t DwoId,
+ const DwarfFile &File,
+ OffsetsStringPool &OffsetsStringPool,
+ UniquingStringPool &UniquingStringPool,
+ DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
+ unsigned &UnitID, bool IsLittleEndian,
+ unsigned Indent = 0, bool Quiet = false);
+
+ /// Mark the passed DIE as well as all the ones it depends on as kept.
+ void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const UnitListTy &Units, const DWARFDie &DIE,
+ CompileUnit::DIEInfo &MyInfo,
+ const DwarfFile &File, CompileUnit &CU,
+ bool UseODR);
+
+ unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const DWARFDie &DIE, const DwarfFile &File,
+ CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
+ unsigned Flags);
+
+ /// Check if a variable describing DIE should be kept.
+ /// \returns updated TraversalFlags.
+ unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
+ CompileUnit &Unit,
+ CompileUnit::DIEInfo &MyInfo, unsigned Flags);
+
+ unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const DWARFDie &DIE, const DwarfFile &File,
+ CompileUnit &Unit,
+ CompileUnit::DIEInfo &MyInfo,
+ unsigned Flags);
+
+ /// Resolve the DIE attribute reference that has been extracted in \p
+ /// RefValue. The resulting DIE might be in another CompileUnit which is
+ /// stored into \p ReferencedCU. \returns null if resolving fails for any
+ /// reason.
+ DWARFDie resolveDIEReference(const DwarfFile &File, const UnitListTy &Units,
+ const DWARFFormValue &RefValue,
+ const DWARFDie &DIE, CompileUnit *&RefCU);
+
+ /// @}
+
+ /// \defgroup Methods used to link the debug information
+ ///
+ /// @{
+
+ struct DWARFLinkerOptions;
+
+ class DIECloner {
+ DWARFLinker &Linker;
+ DwarfEmitter *Emitter;
+ DwarfFile &ObjFile;
+
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator &DIEAlloc;
+
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
+
+ bool Update;
+
+ public:
+ DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DwarfFile &ObjFile,
+ BumpPtrAllocator &DIEAlloc,
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
+ bool Update)
+ : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
+ DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
+
+ /// Recursively clone \p InputDIE into an tree of DIE objects
+ /// where useless (as decided by lookForDIEsToKeep()) bits have been
+ /// stripped out and addresses have been rewritten according to the
+ /// address map.
+ ///
+ /// \param OutOffset is the offset the cloned DIE in the output
+ /// compile unit.
+ /// \param PCOffset (while cloning a function scope) is the offset
+ /// applied to the entry point of the function to get the linked address.
+ /// \param Die the output DIE to use, pass NULL to create one.
+ /// \returns the root of the cloned tree or null if nothing was selected.
+ DIE *cloneDIE(const DWARFDie &InputDIE, const DwarfFile &File,
+ CompileUnit &U, OffsetsStringPool &StringPool,
+ int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
+ bool IsLittleEndian, DIE *Die = nullptr);
+
+ /// Construct the output DIE tree by cloning the DIEs we
+ /// chose to keep above. If there are no valid relocs, then there's
+ /// nothing to clone/emit.
+ uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
+ const DwarfFile &File,
+ OffsetsStringPool &StringPool,
+ bool IsLittleEndian);
+
+ private:
+ using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
+
+ /// Information gathered and exchanged between the various
+ /// clone*Attributes helpers about the attributes of a particular DIE.
+ struct AttributesInfo {
+ /// Names.
+ DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
+
+ /// Offsets in the string pool.
+ uint32_t NameOffset = 0;
+ uint32_t MangledNameOffset = 0;
+
+ /// Value of AT_low_pc in the input DIE
+ uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
+
+ /// Value of AT_high_pc in the input DIE
+ uint64_t OrigHighPc = 0;
+
+ /// Value of DW_AT_call_return_pc in the input DIE
+ uint64_t OrigCallReturnPc = 0;
+
+ /// Value of DW_AT_call_pc in the input DIE
+ uint64_t OrigCallPc = 0;
+
+ /// Offset to apply to PC addresses inside a function.
+ int64_t PCOffset = 0;
+
+ /// Does the DIE have a low_pc attribute?
+ bool HasLowPc = false;
+
+ /// Does the DIE have a ranges attribute?
+ bool HasRanges = false;
+
+ /// Is this DIE only a declaration?
+ bool IsDeclaration = false;
+
+ AttributesInfo() = default;
+ };
+
+ /// Helper for cloneDIE.
+ unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DwarfFile &File, CompileUnit &U,
+ OffsetsStringPool &StringPool,
+ const DWARFFormValue &Val,
+ const AttributeSpec AttrSpec, unsigned AttrSize,
+ AttributesInfo &AttrInfo, bool IsLittleEndian);
+
+ /// Clone a string attribute described by \p AttrSpec and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, const DWARFUnit &U,
+ OffsetsStringPool &StringPool,
+ AttributesInfo &Info);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
+ AttributeSpec AttrSpec,
+ unsigned AttrSize,
+ const DWARFFormValue &Val,
+ const DwarfFile &File,
+ CompileUnit &Unit);
+
+ /// Clone a DWARF expression that may be referencing another DIE.
+ void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
+ const DwarfFile &File, CompileUnit &Unit,
+ SmallVectorImpl<uint8_t> &OutputBuffer);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneBlockAttribute(DIE &Die, const DwarfFile &File,
+ CompileUnit &Unit, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, unsigned AttrSize,
+ bool IsLittleEndian);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val,
+ const CompileUnit &Unit,
+ AttributesInfo &Info);
+
+ /// Clone a scalar attribute and add it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DwarfFile &File, CompileUnit &U,
+ AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, unsigned AttrSize,
+ AttributesInfo &Info);
+
+ /// Get the potential name and mangled name for the entity
+ /// described by \p Die and store them in \Info if they are not
+ /// already there.
+ /// \returns is a name was found.
+ bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
+ OffsetsStringPool &StringPool, bool StripTemplate = false);
+
+ /// Create a copy of abbreviation Abbrev.
+ void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
+
+ uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
+ const DwarfFile &File,
+ int RecurseDepth = 0);
+
+ /// Helper for cloneDIE.
+ void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
+ DwarfStringPoolEntryRef Name,
+ OffsetsStringPool &StringPool, bool SkipPubSection);
+ };
+
+ /// Assign an abbreviation number to \p Abbrev
+ void assignAbbrev(DIEAbbrev &Abbrev);
+
+ /// Compute and emit debug_ranges section for \p Unit, and
+ /// patch the attributes referencing it.
+ void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
+ const DwarfFile &File) const;
+
+ /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
+ /// one.
+ void generateUnitRanges(CompileUnit &Unit) const;
+
+ /// Extract the line tables from the original dwarf, extract the relevant
+ /// parts according to the linked function ranges and emit the result in the
+ /// debug_line section.
+ void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
+ const DwarfFile &File);
+
+ /// Emit the accelerator entries for \p Unit.
+ void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
+ void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
+ void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
+
+ /// Patch the frame info for an object file and emit it.
+ void patchFrameInfoForObject(const DwarfFile &, RangesTy &Ranges,
+ DWARFContext &, unsigned AddressSize);
+
+ /// FoldingSet that uniques the abbreviations.
+ FoldingSet<DIEAbbrev> AbbreviationsSet;
+
+ /// Storage for the unique Abbreviations.
+ /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
+ /// changed to a vector of unique_ptrs.
+ std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
+
+ /// DIELoc objects that need to be destructed (but not freed!).
+ std::vector<DIELoc *> DIELocs;
+
+ /// DIEBlock objects that need to be destructed (but not freed!).
+ std::vector<DIEBlock *> DIEBlocks;
+
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator DIEAlloc;
+ /// @}
+
+ DwarfEmitter *TheDwarfEmitter;
+ std::vector<LinkContext> ObjectContexts;
+
+ unsigned MaxDwarfVersion = 0;
+ unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
+
+ bool AtLeastOneAppleAccelTable = false;
+ bool AtLeastOneDwarfAccelTable = false;
+
+ /// The CIEs that have been emitted in the output section. The actual CIE
+ /// data serves a the key to this StringMap, this takes care of comparing the
+ /// semantics of CIEs defined in different object files.
+ StringMap<uint32_t> EmittedCIEs;
+
+ /// Offset of the last CIE that has been emitted in the output
+ /// debug_frame section.
+ uint32_t LastCIEOffset = 0;
+
+ /// Apple accelerator tables.
+ AccelTable<DWARF5AccelTableStaticData> DebugNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
+ AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
+
+ /// Mapping the PCM filename to the DwoId.
+ StringMap<uint64_t> ClangModules;
+
+ DwarfLinkerClient DwarfLinkerClientID;
+
+ std::function<StringRef(StringRef)> StringsTranslator = nullptr;
+
+ /// linking options
+ struct DWARFLinkerOptions {
+ /// Generate processing log to the standard output.
+ bool Verbose = false;
+
+ /// Print statistics.
+ bool Statistics = false;
+
+ /// Skip emitting output
+ bool NoOutput = false;
+
+ /// Do not unique types according to ODR
+ bool NoODR = false;
+
+ /// Update
+ bool Update = false;
+
+ /// Number of threads.
+ unsigned Threads = 1;
+
+ /// The accelerator table kind
+ AccelTableKind TheAccelTableKind = AccelTableKind::Default;
+
+ /// Prepend path for the clang modules.
+ std::string PrependPath;
+
+ // warning handler
+ messageHandler WarningHandler = nullptr;
+
+ // error handler
+ messageHandler ErrorHandler = nullptr;
+
+ objFileLoader ObjFileLoader = nullptr;
+
+ /// A list of all .swiftinterface files referenced by the debug
+ /// info, mapping Module name to path on disk. The entries need to
+ /// be uniqued and sorted and there are only few entries expected
+ /// per compile unit, which is why this is a std::map.
+ /// this is dsymutil specific fag.
+ swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
+
+ /// A list of remappings to apply to file paths.
+ objectPrefixMap *ObjectPrefixMap = nullptr;
+ } Options;
+};
+
} // end namespace llvm
#endif // LLVM_DWARFLINKER_DWARFLINKER_H