aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic')
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h867
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h336
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h193
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h324
4 files changed, 1720 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
new file mode 100644
index 000000000000..d3aaa3baadc4
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -0,0 +1,867 @@
+//===- DWARFLinker.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
+#define LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
+
+#include "llvm/ADT/AddressRanges.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/AccelTable.h"
+#include "llvm/CodeGen/NonRelocatableStringpool.h"
+#include "llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h"
+#include "llvm/DWARFLinker/DWARFLinkerBase.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include <map>
+
+namespace llvm {
+class DWARFExpression;
+class DWARFUnit;
+class DataExtractor;
+template <typename T> class SmallVectorImpl;
+
+namespace dwarf_linker {
+namespace classic {
+class DeclContextTree;
+
+using Offset2UnitMap = DenseMap<uint64_t, CompileUnit *>;
+
+struct DebugDieValuePool {
+ DenseMap<uint64_t, uint64_t> DieValueMap;
+ SmallVector<uint64_t> DieValues;
+
+ uint64_t getValueIndex(uint64_t Value) {
+ DenseMap<uint64_t, uint64_t>::iterator It = DieValueMap.find(Value);
+ if (It == DieValueMap.end()) {
+ It = DieValueMap.insert(std::make_pair(Value, DieValues.size())).first;
+ DieValues.push_back(Value);
+ }
+ return It->second;
+ }
+
+ void clear() {
+ DieValueMap.clear();
+ DieValues.clear();
+ }
+};
+
+/// DwarfEmitter presents interface to generate all debug info tables.
+class DwarfEmitter {
+public:
+ virtual ~DwarfEmitter() = default;
+
+ /// 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
+ emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
+ unsigned DwarfVersion) = 0;
+
+ /// Emit the string table described by \p Pool into .debug_str table.
+ virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
+
+ /// Emit the debug string offset table described by \p StringOffsets into the
+ /// .debug_str_offsets table.
+ virtual void emitStringOffsets(const SmallVector<uint64_t> &StringOffsets,
+ uint16_t TargetDWARFVersion) = 0;
+
+ /// Emit the string table described by \p Pool into .debug_line_str table.
+ virtual void emitLineStrings(const NonRelocatableStringpool &Pool) = 0;
+
+ /// Emit DWARF debug names.
+ virtual void emitDebugNames(DWARF5AccelTable &Table) = 0;
+
+ /// Emit Apple namespaces accelerator table.
+ virtual void
+ emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
+
+ /// Emit Apple names accelerator table.
+ virtual void
+ emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
+
+ /// Emit Apple Objective-C accelerator table.
+ virtual void
+ emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
+
+ /// Emit Apple type accelerator table.
+ virtual void
+ emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
+
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) header.
+ virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0;
+
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) fragment.
+ virtual void emitDwarfDebugRangeListFragment(
+ const CompileUnit &Unit, const AddressRanges &LinkedRanges,
+ PatchLocation Patch, DebugDieValuePool &AddrPool) = 0;
+
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) footer.
+ virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) = 0;
+
+ /// Emit debug locations (.debug_loc, .debug_loclists) header.
+ virtual MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) = 0;
+
+ /// Emit debug locations (.debug_loc, .debug_loclists) fragment.
+ virtual void emitDwarfDebugLocListFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch, DebugDieValuePool &AddrPool) = 0;
+
+ /// Emit debug locations (.debug_loc, .debug_loclists) footer.
+ virtual void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) = 0;
+
+ /// Emit .debug_addr header.
+ virtual MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) = 0;
+
+ /// Emit the addresses described by \p Addrs into the .debug_addr section.
+ virtual void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
+ uint8_t AddrSize) = 0;
+
+ /// Emit .debug_addr footer.
+ virtual void emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) = 0;
+
+ /// Emit .debug_aranges entries for \p Unit
+ virtual void
+ emitDwarfDebugArangesTable(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges) = 0;
+
+ /// Emit specified \p LineTable into .debug_line table.
+ virtual void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
+ const CompileUnit &Unit,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool) = 0;
+
+ /// Emit the .debug_pubnames contribution for \p Unit.
+ virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
+
+ /// Emit the .debug_pubtypes contribution for \p Unit.
+ virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
+
+ /// Emit a CIE.
+ virtual void emitCIE(StringRef CIEBytes) = 0;
+
+ /// Emit an FDE with data \p Bytes.
+ virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
+ StringRef Bytes) = 0;
+
+ /// Emit the compilation unit header for \p Unit in the
+ /// .debug_info section.
+ ///
+ /// As a side effect, this also switches the current Dwarf version
+ /// of the MC layer to the one of U.getOrigUnit().
+ virtual void emitCompileUnitHeader(CompileUnit &Unit,
+ unsigned DwarfVersion) = 0;
+
+ /// Recursively emit the DIE tree rooted at \p Die.
+ virtual void emitDIE(DIE &Die) = 0;
+
+ /// Emit all available macro tables(DWARFv4 and DWARFv5).
+ /// Use \p UnitMacroMap to get compilation unit by macro table offset.
+ /// Side effects: Fill \p StringPool with macro strings, update
+ /// DW_AT_macro_info, DW_AT_macros attributes for corresponding compile
+ /// units.
+ virtual void emitMacroTables(DWARFContext *Context,
+ const Offset2UnitMap &UnitMacroMap,
+ OffsetsStringPool &StringPool) = 0;
+
+ /// Returns size of generated .debug_line section.
+ virtual uint64_t getLineSectionSize() const = 0;
+
+ /// Returns size of generated .debug_frame section.
+ virtual uint64_t getFrameSectionSize() const = 0;
+
+ /// Returns size of generated .debug_ranges section.
+ virtual uint64_t getRangesSectionSize() const = 0;
+
+ /// Returns size of generated .debug_rnglists section.
+ virtual uint64_t getRngListsSectionSize() const = 0;
+
+ /// Returns size of generated .debug_info section.
+ virtual uint64_t getDebugInfoSectionSize() const = 0;
+
+ /// Returns size of generated .debug_macinfo section.
+ virtual uint64_t getDebugMacInfoSectionSize() const = 0;
+
+ /// Returns size of generated .debug_macro section.
+ virtual uint64_t getDebugMacroSectionSize() const = 0;
+
+ /// Returns size of generated .debug_loclists section.
+ virtual uint64_t getLocListsSectionSize() const = 0;
+
+ /// Returns size of generated .debug_addr section.
+ virtual uint64_t getDebugAddrSectionSize() const = 0;
+
+ /// Dump the file to the disk.
+ virtual void finish() = 0;
+
+ /// Emit the swift_ast section stored in \p Buffer.
+ virtual void emitSwiftAST(StringRef Buffer) = 0;
+
+ /// Emit the swift reflection section stored in \p Buffer.
+ virtual void emitSwiftReflectionSection(
+ llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
+ StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
+
+ /// Returns underlying AsmPrinter.
+ virtual AsmPrinter &getAsmPrinter() const = 0;
+};
+
+class DwarfStreamer;
+using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
+
+/// 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 DWARFLinkerBase {
+public:
+ DWARFLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
+ std::function<StringRef(StringRef)> StringsTranslator)
+ : StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
+ WarningHandler(WarningHandler) {}
+
+ static std::unique_ptr<DWARFLinker> createLinker(
+ MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
+ std::function<StringRef(StringRef)> StringsTranslator = nullptr) {
+ return std::make_unique<DWARFLinker>(ErrorHandler, WarningHandler,
+ StringsTranslator);
+ }
+
+ Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
+ raw_pwrite_stream &OutFile);
+
+ DwarfEmitter *getEmitter();
+
+ /// Add object file to be linked. Pre-load compile unit die. Call
+ /// \p OnCUDieLoaded for each compile unit die. If specified \p File
+ /// has reference to the Clang module then such module would be
+ /// pre-loaded by \p Loader for !Update case.
+ ///
+ /// \pre NoODR, Update options should be set before call to addObjectFile.
+ void addObjectFile(
+ DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
+ CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
+
+ /// Link debug info for added objFiles. Object files are linked all together.
+ Error link() override;
+
+ /// A number of methods setting various linking options:
+
+ /// Allows to generate log of linking process to the standard output.
+ void setVerbosity(bool Verbose) override { Options.Verbose = Verbose; }
+
+ /// Print statistics to standard output.
+ void setStatistics(bool Statistics) override {
+ Options.Statistics = Statistics;
+ }
+
+ /// Verify the input DWARF.
+ void setVerifyInputDWARF(bool Verify) override {
+ Options.VerifyInputDWARF = Verify;
+ }
+
+ /// Do not unique types according to ODR.
+ void setNoODR(bool NoODR) override { Options.NoODR = NoODR; }
+
+ /// Update index tables only(do not modify rest of DWARF).
+ void setUpdateIndexTablesOnly(bool Update) override {
+ Options.Update = Update;
+ }
+
+ /// Allow generating valid, but non-deterministic output.
+ void setAllowNonDeterministicOutput(bool) override { /* Nothing to do. */
+ }
+
+ /// Set whether to keep the enclosing function for a static variable.
+ void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
+ Options.KeepFunctionForStatic = KeepFunctionForStatic;
+ }
+
+ /// Use specified number of threads for parallel files linking.
+ void setNumThreads(unsigned NumThreads) override {
+ Options.Threads = NumThreads;
+ }
+
+ /// Add kind of accelerator tables to be generated.
+ void addAccelTableKind(AccelTableKind Kind) override {
+ assert(!llvm::is_contained(Options.AccelTables, Kind));
+ Options.AccelTables.emplace_back(Kind);
+ }
+
+ /// Set prepend path for clang modules.
+ void setPrependPath(StringRef Ppath) override { Options.PrependPath = Ppath; }
+
+ /// Set estimated objects files amount, for preliminary data allocation.
+ void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override {
+ ObjectContexts.reserve(ObjFilesNum);
+ }
+
+ /// Set verification handler which would be used to report verification
+ /// errors.
+ void
+ setInputVerificationHandler(InputVerificationHandlerTy Handler) override {
+ Options.InputVerificationHandler = Handler;
+ }
+
+ /// Set map for Swift interfaces.
+ void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override {
+ Options.ParseableSwiftInterfaces = Map;
+ }
+
+ /// Set prefix map for objects.
+ void setObjectPrefixMap(ObjectPrefixMapTy *Map) override {
+ Options.ObjectPrefixMap = Map;
+ }
+
+ /// Set target DWARF version.
+ Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
+ if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
+ return createStringError(std::errc::invalid_argument,
+ "unsupported DWARF version: %d",
+ TargetDWARFVersion);
+
+ Options.TargetDWARFVersion = TargetDWARFVersion;
+ return Error::success();
+ }
+
+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,
+ /// Given a DIE, mark it as ODR Canonical if applicable.
+ MarkODRCanonicalDie,
+ };
+
+ /// 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 {
+ DWARFDie Die;
+ WorklistItemType Type;
+ CompileUnit &CU;
+ unsigned Flags;
+ union {
+ const unsigned AncestorIdx;
+ CompileUnit::DIEInfo *OtherInfo;
+ };
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
+ WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
+ : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
+ CompileUnit::DIEInfo *OtherInfo = nullptr)
+ : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
+
+ WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
+ : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
+ AncestorIdx(AncestorIdx) {}
+ };
+
+ /// Verify the given DWARF file.
+ void verifyInput(const DWARFFile &File);
+
+ /// 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 (WarningHandler != nullptr)
+ WarningHandler(Warning, File.FileName, DIE);
+ }
+
+ void reportError(const Twine &Warning, const DWARFFile &File,
+ const DWARFDie *DIE = nullptr) const {
+ if (ErrorHandler != nullptr)
+ ErrorHandler(Warning, File.FileName, DIE);
+ }
+
+ void copyInvariantDebugSection(DWARFContext &Dwarf);
+
+ /// Keep information for referenced clang module: already loaded DWARF info
+ /// of the clang module and a CompileUnit of the module.
+ struct RefModuleUnit {
+ RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
+ : File(File), Unit(std::move(Unit)) {}
+ RefModuleUnit(RefModuleUnit &&Other)
+ : File(Other.File), Unit(std::move(Other.Unit)) {}
+ RefModuleUnit(const RefModuleUnit &) = delete;
+
+ DWARFFile &File;
+ std::unique_ptr<CompileUnit> Unit;
+ };
+ using ModuleUnitListTy = std::vector<RefModuleUnit>;
+
+ /// Keeps track of data associated with one object during linking.
+ struct LinkContext {
+ DWARFFile &File;
+ UnitListTy CompileUnits;
+ ModuleUnitListTy ModuleUnits;
+ 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();
+ ModuleUnits.clear();
+ File.unload();
+ }
+ };
+
+ /// 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);
+
+ /// Mark context corresponding to the specified \p Die as having canonical
+ /// die, if applicable.
+ void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
+
+ /// \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, const UnitListTy &Units,
+ const DWARFDie &DIE, const DWARFFile &File,
+ CompileUnit &CU, unsigned Flags);
+
+ /// Check whether specified \p CUDie is a Clang module reference.
+ /// if \p Quiet is false then display error messages.
+ /// \return first == true if CUDie is a Clang module reference.
+ /// second == true if module is already loaded.
+ std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
+ std::string &PCMFile,
+ LinkContext &Context, unsigned Indent,
+ bool Quiet);
+
+ /// 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(const DWARFDie &CUDie, LinkContext &Context,
+ ObjFileLoaderTy Loader,
+ CompileUnitHandlerTy OnCUDieLoaded,
+ unsigned Indent = 0);
+
+ /// Recursively add the debug info in this clang module .pcm
+ /// file (and all the modules imported by it in a bottom-up fashion)
+ /// to ModuleUnits.
+ Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
+ const std::string &PCMFile, LinkContext &Context,
+ CompileUnitHandlerTy OnCUDieLoaded,
+ unsigned Indent = 0);
+
+ /// Clone specified Clang module unit \p Unit.
+ Error cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
+ DeclContextTree &ODRContexts,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool,
+ DebugDieValuePool &StringOffsetPool,
+ unsigned Indent = 0);
+
+ unsigned shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
+ const DWARFFile &File, CompileUnit &Unit,
+ CompileUnit::DIEInfo &MyInfo, unsigned Flags);
+
+ /// This function checks whether variable has DWARF expression containing
+ /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...).
+ /// \returns first is true if the expression has an operation referencing an
+ /// address.
+ /// second is the relocation adjustment value if the live address is
+ /// referenced.
+ std::pair<bool, std::optional<int64_t>>
+ getVariableRelocAdjustment(AddressesMap &RelocMgr, const DWARFDie &DIE);
+
+ /// Check if a variable describing DIE should be kept.
+ /// \returns updated TraversalFlags.
+ unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
+ CompileUnit::DIEInfo &MyInfo, unsigned Flags);
+
+ unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, 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;
+ OffsetsStringPool &DebugStrPool;
+ OffsetsStringPool &DebugLineStrPool;
+ DebugDieValuePool &StringOffsetPool;
+ DebugDieValuePool AddrPool;
+
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator &DIEAlloc;
+
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
+
+ /// Keeps mapping from offset of the macro table to corresponding
+ /// compile unit.
+ Offset2UnitMap UnitMacroMap;
+
+ bool Update;
+
+ public:
+ DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
+ BumpPtrAllocator &DIEAlloc,
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
+ bool Update, OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool,
+ DebugDieValuePool &StringOffsetPool)
+ : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
+ DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
+ StringOffsetPool(StringOffsetPool), 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, 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, bool IsLittleEndian);
+
+ /// Emit the .debug_addr section for the \p Unit.
+ void emitDebugAddrSection(CompileUnit &Unit,
+ const uint16_t DwarfVersion) const;
+
+ using ExpressionHandlerRef = function_ref<void(
+ SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
+ int64_t AddrRelocAdjustment)>;
+
+ /// Compute and emit debug locations (.debug_loc, .debug_loclists)
+ /// for \p Unit, patch the attributes referencing it.
+ void generateUnitLocations(CompileUnit &Unit, const DWARFFile &File,
+ ExpressionHandlerRef ExprHandler);
+
+ 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;
+
+ /// 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;
+
+ /// Is there a DW_AT_str_offsets_base in the CU?
+ bool AttrStrOffsetBaseSeen = false;
+
+ /// Is there a DW_AT_APPLE_origin in the CU?
+ bool HasAppleOrigin = false;
+
+ AttributesInfo() = default;
+ };
+
+ /// Helper for cloneDIE.
+ unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DWARFFile &File, CompileUnit &U,
+ 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,
+ 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,
+ int64_t AddrRelocAdjustment, bool IsLittleEndian);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneBlockAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DWARFFile &File, CompileUnit &Unit,
+ AttributeSpec AttrSpec,
+ const DWARFFormValue &Val,
+ 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, const DWARFDie &InputDIE,
+ AttributeSpec AttrSpec, unsigned AttrSize,
+ 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);
+
+ 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);
+
+ void rememberUnitForMacroOffset(CompileUnit &Unit);
+
+ /// Clone and emit the line table for the specified \p Unit.
+ /// Translate directories and file names if necessary.
+ /// Relocate address ranges.
+ void generateLineTableForUnit(CompileUnit &Unit);
+ };
+
+ /// Assign an abbreviation number to \p Abbrev
+ void assignAbbrev(DIEAbbrev &Abbrev);
+
+ /// Compute and emit debug ranges(.debug_aranges, .debug_ranges,
+ /// .debug_rnglists) for \p Unit, patch the attributes referencing it.
+ void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
+ DebugDieValuePool &AddrPool) const;
+
+ /// Emit the accelerator entries for \p Unit.
+ void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
+
+ /// Patch the frame info for an object file and emit it.
+ void patchFrameInfoForObject(LinkContext &Context);
+
+ /// 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;
+ /// @}
+
+ std::unique_ptr<DwarfStreamer> TheDwarfEmitter;
+ std::vector<LinkContext> ObjectContexts;
+
+ /// 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.
+ DWARF5AccelTable DebugNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
+ AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
+
+ /// Mapping the PCM filename to the DwoId.
+ StringMap<uint64_t> ClangModules;
+
+ std::function<StringRef(StringRef)> StringsTranslator = nullptr;
+
+ /// A unique ID that identifies each compile unit.
+ unsigned UniqueUnitID = 0;
+
+ // error handler
+ MessageHandlerTy ErrorHandler = nullptr;
+
+ // warning handler
+ MessageHandlerTy WarningHandler = nullptr;
+
+ /// linking options
+ struct DWARFLinkerOptions {
+ /// DWARF version for the output.
+ uint16_t TargetDWARFVersion = 0;
+
+ /// Generate processing log to the standard output.
+ bool Verbose = false;
+
+ /// Print statistics.
+ bool Statistics = false;
+
+ /// Verify the input DWARF.
+ bool VerifyInputDWARF = false;
+
+ /// Do not unique types according to ODR
+ bool NoODR = false;
+
+ /// Update
+ bool Update = false;
+
+ /// Whether we want a static variable to force us to keep its enclosing
+ /// function.
+ bool KeepFunctionForStatic = false;
+
+ /// Number of threads.
+ unsigned Threads = 1;
+
+ /// The accelerator table kinds
+ SmallVector<AccelTableKind, 1> AccelTables;
+
+ /// Prepend path for the clang modules.
+ std::string PrependPath;
+
+ // input verification handler
+ InputVerificationHandlerTy InputVerificationHandler = 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.
+ SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
+
+ /// A list of remappings to apply to file paths.
+ ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
+ } Options;
+};
+
+} // end of namespace classic
+} // end of namespace dwarf_linker
+} // end of namespace llvm
+
+#endif // LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h
new file mode 100644
index 000000000000..bfe544946fd9
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h
@@ -0,0 +1,336 @@
+//===- DWARFLinkerCompileUnit.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKERCOMPILEUNIT_H
+#define LLVM_DWARFLINKER_CLASSIC_DWARFLINKERCOMPILEUNIT_H
+
+#include "llvm/ADT/AddressRanges.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/DIE.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include <optional>
+
+namespace llvm {
+namespace dwarf_linker {
+namespace classic {
+
+class DeclContext;
+
+/// Mapped value in the address map is the offset to apply to the
+/// linked address.
+using RangesTy = AddressRangesMap;
+
+// This structure keeps patch for the attribute and, optionally,
+// the value of relocation which should be applied. Currently,
+// only location attribute needs to have relocation: either to the
+// function ranges if location attribute is of type 'loclist',
+// either to the operand of DW_OP_addr/DW_OP_addrx if location attribute
+// is of type 'exprloc'.
+// ASSUMPTION: Location attributes of 'loclist' type containing 'exprloc'
+// with address expression operands are not supported yet.
+struct PatchLocation {
+ DIE::value_iterator I;
+ int64_t RelocAdjustment = 0;
+
+ PatchLocation() = default;
+ PatchLocation(DIE::value_iterator I) : I(I) {}
+ PatchLocation(DIE::value_iterator I, int64_t Reloc)
+ : I(I), RelocAdjustment(Reloc) {}
+
+ void set(uint64_t New) const {
+ assert(I);
+ const auto &Old = *I;
+ assert(Old.getType() == DIEValue::isInteger);
+ *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New));
+ }
+
+ uint64_t get() const {
+ assert(I);
+ return I->getDIEInteger().getValue();
+ }
+};
+
+using RngListAttributesTy = SmallVector<PatchLocation>;
+using LocListAttributesTy = SmallVector<PatchLocation>;
+
+/// Stores all information relating to a compile unit, be it in its original
+/// instance in the object file to its brand new cloned and generated DIE tree.
+class CompileUnit {
+public:
+ /// Information gathered about a DIE in the object file.
+ struct DIEInfo {
+ /// Address offset to apply to the described entity.
+ int64_t AddrAdjust;
+
+ /// ODR Declaration context.
+ DeclContext *Ctxt;
+
+ /// Cloned version of that DIE.
+ DIE *Clone;
+
+ /// The index of this DIE's parent.
+ uint32_t ParentIdx;
+
+ /// Is the DIE part of the linked output?
+ bool Keep : 1;
+
+ /// Was this DIE's entity found in the map?
+ bool InDebugMap : 1;
+
+ /// Is this a pure forward declaration we can strip?
+ bool Prune : 1;
+
+ /// Does DIE transitively refer an incomplete decl?
+ bool Incomplete : 1;
+
+ /// Is DIE in the clang module scope?
+ bool InModuleScope : 1;
+
+ /// Is ODR marking done?
+ bool ODRMarkingDone : 1;
+
+ /// Is this a reference to a DIE that hasn't been cloned yet?
+ bool UnclonedReference : 1;
+
+ /// Is this a variable with a location attribute referencing address?
+ bool HasLocationExpressionAddr : 1;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump();
+#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ };
+
+ CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,
+ StringRef ClangModuleName)
+ : OrigUnit(OrigUnit), ID(ID), ClangModuleName(ClangModuleName) {
+ Info.resize(OrigUnit.getNumDIEs());
+
+ auto CUDie = OrigUnit.getUnitDIE(false);
+ if (!CUDie) {
+ HasODR = false;
+ return;
+ }
+ if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language)))
+ HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus ||
+ *Lang == dwarf::DW_LANG_C_plus_plus_03 ||
+ *Lang == dwarf::DW_LANG_C_plus_plus_11 ||
+ *Lang == dwarf::DW_LANG_C_plus_plus_14 ||
+ *Lang == dwarf::DW_LANG_ObjC_plus_plus);
+ else
+ HasODR = false;
+ }
+
+ DWARFUnit &getOrigUnit() const { return OrigUnit; }
+
+ unsigned getUniqueID() const { return ID; }
+
+ void createOutputDIE() { NewUnit.emplace(OrigUnit.getUnitDIE().getTag()); }
+
+ DIE *getOutputUnitDIE() const {
+ if (NewUnit)
+ return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie();
+ return nullptr;
+ }
+
+ bool hasODR() const { return HasODR; }
+ bool isClangModule() const { return !ClangModuleName.empty(); }
+ uint16_t getLanguage();
+ /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
+ StringRef getSysRoot();
+
+ const std::string &getClangModuleName() const { return ClangModuleName; }
+
+ DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
+ const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
+
+ DIEInfo &getInfo(const DWARFDie &Die) {
+ unsigned Idx = getOrigUnit().getDIEIndex(Die);
+ return Info[Idx];
+ }
+
+ uint64_t getStartOffset() const { return StartOffset; }
+ uint64_t getNextUnitOffset() const { return NextUnitOffset; }
+ void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
+
+ std::optional<uint64_t> getLowPc() const { return LowPc; }
+ uint64_t getHighPc() const { return HighPc; }
+ bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
+
+ const RangesTy &getFunctionRanges() const { return Ranges; }
+
+ const RngListAttributesTy &getRangesAttributes() { return RangeAttributes; }
+
+ std::optional<PatchLocation> getUnitRangesAttribute() const {
+ return UnitRangeAttribute;
+ }
+
+ const LocListAttributesTy &getLocationAttributes() const {
+ return LocationAttributes;
+ }
+
+ /// Mark every DIE in this unit as kept. This function also
+ /// marks variables as InDebugMap so that they appear in the
+ /// reconstructed accelerator tables.
+ void markEverythingAsKept();
+
+ /// Compute the end offset for this unit. Must be called after the CU's DIEs
+ /// have been cloned. \returns the next unit offset (which is also the
+ /// current debug_info section size).
+ uint64_t computeNextUnitOffset(uint16_t DwarfVersion);
+
+ /// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p
+ /// Attr. The attribute should be fixed up later to point to the absolute
+ /// offset of \p Die in the debug_info section or to the canonical offset of
+ /// \p Ctxt if it is non-null.
+ void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
+ DeclContext *Ctxt, PatchLocation Attr);
+
+ /// Apply all fixups recorded by noteForwardReference().
+ void fixupForwardReferences();
+
+ /// Add the low_pc of a label that is relocated by applying
+ /// offset \p PCOffset.
+ void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);
+
+ /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying
+ /// offset \p PCOffset.
+ void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
+
+ /// Keep track of a DW_AT_range attribute that we will need to patch up later.
+ void noteRangeAttribute(const DIE &Die, PatchLocation Attr);
+
+ /// Keep track of a location attribute pointing to a location list in the
+ /// debug_loc section.
+ void noteLocationAttribute(PatchLocation Attr);
+
+ /// Add a name accelerator entry for \a Die with \a Name.
+ void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name);
+
+ /// Add a name accelerator entry for \a Die with \a Name.
+ void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
+ bool SkipPubnamesSection = false);
+
+ /// Add various accelerator entries for \p Die with \p Name which is stored
+ /// in the string table at \p Offset. \p Name must be an Objective-C
+ /// selector.
+ void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
+ bool SkipPubnamesSection = false);
+
+ /// Add a type accelerator entry for \p Die with \p Name which is stored in
+ /// the string table at \p Offset.
+ void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name,
+ bool ObjcClassImplementation,
+ uint32_t QualifiedNameHash);
+
+ struct AccelInfo {
+ /// Name of the entry.
+ DwarfStringPoolEntryRef Name;
+
+ /// DIE this entry describes.
+ const DIE *Die;
+
+ /// Hash of the fully qualified name.
+ uint32_t QualifiedNameHash;
+
+ /// Emit this entry only in the apple_* sections.
+ bool SkipPubSection;
+
+ /// Is this an ObjC class implementation?
+ bool ObjcClassImplementation;
+
+ AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
+ bool SkipPubSection = false)
+ : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {}
+
+ AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die,
+ uint32_t QualifiedNameHash, bool ObjCClassIsImplementation)
+ : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash),
+ SkipPubSection(false),
+ ObjcClassImplementation(ObjCClassIsImplementation) {}
+ };
+
+ const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }
+ const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }
+ const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; }
+ const std::vector<AccelInfo> &getObjC() const { return ObjC; }
+
+ MCSymbol *getLabelBegin() { return LabelBegin; }
+ void setLabelBegin(MCSymbol *S) { LabelBegin = S; }
+
+private:
+ DWARFUnit &OrigUnit;
+ unsigned ID;
+ std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
+ std::optional<BasicDIEUnit> NewUnit;
+ MCSymbol *LabelBegin = nullptr;
+
+ uint64_t StartOffset;
+ uint64_t NextUnitOffset;
+
+ std::optional<uint64_t> LowPc;
+ uint64_t HighPc = 0;
+
+ /// A list of attributes to fixup with the absolute offset of
+ /// a DIE in the debug_info section.
+ ///
+ /// The offsets for the attributes in this array couldn't be set while
+ /// cloning because for cross-cu forward references the target DIE's offset
+ /// isn't known you emit the reference attribute.
+ std::vector<
+ std::tuple<DIE *, const CompileUnit *, DeclContext *, PatchLocation>>
+ ForwardDIEReferences;
+
+ /// The ranges in that map are the PC ranges for functions in this unit,
+ /// associated with the PC offset to apply to the addresses to get
+ /// the linked address.
+ RangesTy Ranges;
+
+ /// The DW_AT_low_pc of each DW_TAG_label.
+ SmallDenseMap<uint64_t, uint64_t, 1> Labels;
+
+ /// 'rnglist'(DW_AT_ranges, DW_AT_start_scope) attributes to patch after
+ /// we have gathered all the unit's function addresses.
+ /// @{
+ RngListAttributesTy RangeAttributes;
+ std::optional<PatchLocation> UnitRangeAttribute;
+ /// @}
+
+ /// Location attributes that need to be transferred from the
+ /// original debug_loc section to the linked one. They are stored
+ /// along with the PC offset that is to be applied to their
+ /// function's address or to be applied to address operands of
+ /// location expression.
+ LocListAttributesTy LocationAttributes;
+
+ /// Accelerator entries for the unit, both for the pub*
+ /// sections and the apple* ones.
+ /// @{
+ std::vector<AccelInfo> Pubnames;
+ std::vector<AccelInfo> Pubtypes;
+ std::vector<AccelInfo> Namespaces;
+ std::vector<AccelInfo> ObjC;
+ /// @}
+
+ /// Is this unit subject to the ODR rule?
+ bool HasODR;
+
+ /// The DW_AT_language of this unit.
+ uint16_t Language = 0;
+
+ /// The DW_AT_LLVM_sysroot of this unit.
+ std::string SysRoot;
+
+ /// If this is a Clang module, this holds the module's name.
+ std::string ClangModuleName;
+};
+
+} // end of namespace classic
+} // end of namespace dwarf_linker
+} // end of namespace llvm
+
+#endif // LLVM_DWARFLINKER_CLASSIC_DWARFLINKERCOMPILEUNIT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h
new file mode 100644
index 000000000000..b00f68c3be84
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h
@@ -0,0 +1,193 @@
+//===- DWARFLinkerDeclContext.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKERDECLCONTEXT_H
+#define LLVM_DWARFLINKER_CLASSIC_DWARFLINKERDECLCONTEXT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/NonRelocatableStringpool.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <atomic>
+
+namespace llvm {
+namespace dwarf_linker {
+namespace classic {
+
+class CompileUnit;
+struct DeclMapInfo;
+
+/// Small helper that resolves and caches file paths. This helps reduce the
+/// number of calls to realpath which is expensive. We assume the input are
+/// files, and cache the realpath of their parent. This way we can quickly
+/// resolve different files under the same path.
+class CachedPathResolver {
+public:
+ /// Resolve a path by calling realpath and cache its result. The returned
+ /// StringRef is interned in the given \p StringPool.
+ StringRef resolve(const std::string &Path,
+ NonRelocatableStringpool &StringPool) {
+ StringRef FileName = sys::path::filename(Path);
+ StringRef ParentPath = sys::path::parent_path(Path);
+
+ // If the ParentPath has not yet been resolved, resolve and cache it for
+ // future look-ups.
+ if (!ResolvedPaths.count(ParentPath)) {
+ SmallString<256> RealPath;
+ sys::fs::real_path(ParentPath, RealPath);
+ ResolvedPaths.insert(
+ {ParentPath, std::string(RealPath.c_str(), RealPath.size())});
+ }
+
+ // Join the file name again with the resolved path.
+ SmallString<256> ResolvedPath(ResolvedPaths[ParentPath]);
+ sys::path::append(ResolvedPath, FileName);
+ return StringPool.internString(ResolvedPath);
+ }
+
+private:
+ StringMap<std::string> ResolvedPaths;
+};
+
+/// A DeclContext is a named program scope that is used for ODR uniquing of
+/// types.
+///
+/// The set of DeclContext for the ODR-subject parts of a Dwarf link is
+/// expanded (and uniqued) with each new object file processed. We need to
+/// determine the context of each DIE in an linked object file to see if the
+/// corresponding type has already been emitted.
+///
+/// The contexts are conceptually organized as a tree (eg. a function scope is
+/// contained in a namespace scope that contains other scopes), but
+/// storing/accessing them in an actual tree is too inefficient: we need to be
+/// able to very quickly query a context for a given child context by name.
+/// Storing a StringMap in each DeclContext would be too space inefficient.
+///
+/// The solution here is to give each DeclContext a link to its parent (this
+/// allows to walk up the tree), but to query the existence of a specific
+/// DeclContext using a separate DenseMap keyed on the hash of the fully
+/// qualified name of the context.
+class DeclContext {
+public:
+ using Map = DenseSet<DeclContext *, DeclMapInfo>;
+
+ DeclContext() : DefinedInClangModule(0), Parent(*this) {}
+
+ DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
+ StringRef Name, StringRef File, const DeclContext &Parent,
+ DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
+ : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
+ DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
+ LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
+
+ uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
+
+ bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die);
+
+ void setHasCanonicalDIE() { HasCanonicalDIE = true; }
+
+ bool hasCanonicalDIE() const { return HasCanonicalDIE; }
+
+ uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
+ void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
+
+ bool isDefinedInClangModule() const { return DefinedInClangModule; }
+ void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
+
+ uint16_t getTag() const { return Tag; }
+
+private:
+ friend DeclMapInfo;
+
+ unsigned QualifiedNameHash = 0;
+ uint32_t Line = 0;
+ uint32_t ByteSize = 0;
+ uint16_t Tag = dwarf::DW_TAG_compile_unit;
+ unsigned DefinedInClangModule : 1;
+ StringRef Name;
+ StringRef File;
+ const DeclContext &Parent;
+ DWARFDie LastSeenDIE;
+ uint32_t LastSeenCompileUnitID = 0;
+ std::atomic<uint32_t> CanonicalDIEOffset = {0};
+ bool HasCanonicalDIE = false;
+};
+
+/// This class gives a tree-like API to the DenseMap that stores the
+/// DeclContext objects. It holds the BumpPtrAllocator where these objects will
+/// be allocated.
+class DeclContextTree {
+public:
+ /// Get the child of \a Context described by \a DIE in \a Unit. The
+ /// required strings will be interned in \a StringPool.
+ /// \returns The child DeclContext along with one bit that is set if
+ /// this context is invalid.
+ ///
+ /// An invalid context means it shouldn't be considered for uniquing, but its
+ /// not returning null, because some children of that context might be
+ /// uniquing candidates.
+ ///
+ /// FIXME: The invalid bit along the return value is to emulate some
+ /// dsymutil-classic functionality.
+ PointerIntPair<DeclContext *, 1> getChildDeclContext(DeclContext &Context,
+ const DWARFDie &DIE,
+ CompileUnit &Unit,
+ bool InClangModule);
+
+ DeclContext &getRoot() { return Root; }
+
+private:
+ BumpPtrAllocator Allocator;
+ DeclContext Root;
+ DeclContext::Map Contexts;
+
+ /// Cached resolved paths from the line table.
+ /// The key is <UniqueUnitID, FileIdx>.
+ using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>;
+ ResolvedPathsMap ResolvedPaths;
+
+ /// Helper that resolves and caches fragments of file paths.
+ CachedPathResolver PathResolver;
+
+ /// String pool keeping real path bodies.
+ NonRelocatableStringpool StringPool;
+
+ StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum,
+ const DWARFDebugLine::LineTable &LineTable);
+};
+
+/// Info type for the DenseMap storing the DeclContext pointers.
+struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
+ using DenseMapInfo<DeclContext *>::getEmptyKey;
+ using DenseMapInfo<DeclContext *>::getTombstoneKey;
+
+ static unsigned getHashValue(const DeclContext *Ctxt) {
+ return Ctxt->QualifiedNameHash;
+ }
+
+ static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey())
+ return RHS == LHS;
+ return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
+ LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
+ LHS->Name.data() == RHS->Name.data() &&
+ LHS->File.data() == RHS->File.data() &&
+ LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
+ }
+};
+
+} // end of namespace classic
+} // end of namespace dwarf_linker
+} // end of namespace llvm
+
+#endif // LLVM_DWARFLINKER_CLASSIC_DWARFLINKERDECLCONTEXT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
new file mode 100644
index 000000000000..f010c348f121
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
@@ -0,0 +1,324 @@
+//===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
+#define LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
+
+#include "DWARFLinker.h"
+#include "llvm/BinaryFormat/Swift.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+template <typename DataT> class AccelTable;
+
+class MCCodeEmitter;
+class DWARFDebugMacro;
+
+namespace dwarf_linker {
+namespace classic {
+
+/// User of DwarfStreamer should call initialization code
+/// for AsmPrinter:
+///
+/// InitializeAllTargetInfos();
+/// InitializeAllTargetMCs();
+/// InitializeAllTargets();
+/// InitializeAllAsmPrinters();
+
+/// The Dwarf streaming logic.
+///
+/// All interactions with the MC layer that is used to build the debug
+/// information binary representation are handled in this class.
+class DwarfStreamer : public DwarfEmitter {
+public:
+ DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType,
+ raw_pwrite_stream &OutFile,
+ std::function<StringRef(StringRef Input)> Translator,
+ DWARFLinkerBase::MessageHandlerTy Warning)
+ : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
+ WarningHandler(Warning) {}
+ virtual ~DwarfStreamer() = default;
+
+ Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
+
+ /// Dump the file to the disk.
+ void finish() override;
+
+ AsmPrinter &getAsmPrinter() const override { return *Asm; }
+
+ /// Set the current output section to debug_info and change
+ /// the MC Dwarf version to \p DwarfVersion.
+ void switchToDebugInfoSection(unsigned DwarfVersion);
+
+ /// Emit the compilation unit header for \p Unit in the
+ /// debug_info section.
+ ///
+ /// As a side effect, this also switches the current Dwarf version
+ /// of the MC layer to the one of U.getOrigUnit().
+ void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
+
+ /// Recursively emit the DIE tree rooted at \p Die.
+ void emitDIE(DIE &Die) override;
+
+ /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
+ void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
+ unsigned DwarfVersion) override;
+
+ /// Emit contents of section SecName From Obj.
+ void emitSectionContents(StringRef SecData, StringRef SecName) override;
+
+ /// Emit the string table described by \p Pool into .debug_str table.
+ void emitStrings(const NonRelocatableStringpool &Pool) override;
+
+ /// Emit the debug string offset table described by \p StringOffsets into the
+ /// .debug_str_offsets table.
+ void emitStringOffsets(const SmallVector<uint64_t> &StringOffset,
+ uint16_t TargetDWARFVersion) override;
+
+ /// Emit the string table described by \p Pool into .debug_line_str table.
+ void emitLineStrings(const NonRelocatableStringpool &Pool) override;
+
+ /// Emit the swift_ast section stored in \p Buffer.
+ void emitSwiftAST(StringRef Buffer) override;
+
+ /// Emit the swift reflection section stored in \p Buffer.
+ void emitSwiftReflectionSection(
+ llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
+ StringRef Buffer, uint32_t Alignment, uint32_t Size) override;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
+ MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
+ void emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch,
+ DebugDieValuePool &AddrPool) override;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
+ void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) override;
+
+ /// Emit debug locations(.debug_loc, .debug_loclists) header.
+ MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override;
+
+ /// Emit .debug_addr header.
+ MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override;
+
+ /// Emit the addresses described by \p Addrs into .debug_addr table.
+ void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
+ uint8_t AddrSize) override;
+
+ /// Emit .debug_addr footer.
+ void emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) override;
+
+ /// Emit debug ranges(.debug_loc, .debug_loclists) fragment.
+ void emitDwarfDebugLocListFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch, DebugDieValuePool &AddrPool) override;
+
+ /// Emit debug ranges(.debug_loc, .debug_loclists) footer.
+ void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) override;
+
+ /// Emit .debug_aranges entries for \p Unit
+ void emitDwarfDebugArangesTable(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges) override;
+
+ uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
+
+ uint64_t getRngListsSectionSize() const override {
+ return RngListsSectionSize;
+ }
+
+ /// Emit .debug_line table entry for specified \p LineTable
+ void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
+ const CompileUnit &Unit,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool) override;
+
+ uint64_t getLineSectionSize() const override { return LineSectionSize; }
+
+ /// Emit the .debug_pubnames contribution for \p Unit.
+ void emitPubNamesForUnit(const CompileUnit &Unit) override;
+
+ /// Emit the .debug_pubtypes contribution for \p Unit.
+ void emitPubTypesForUnit(const CompileUnit &Unit) override;
+
+ /// Emit a CIE.
+ void emitCIE(StringRef CIEBytes) override;
+
+ /// Emit an FDE with data \p Bytes.
+ void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
+ StringRef Bytes) override;
+
+ /// Emit DWARF debug names.
+ void emitDebugNames(DWARF5AccelTable &Table) override;
+
+ /// Emit Apple namespaces accelerator table.
+ void emitAppleNamespaces(
+ AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple names accelerator table.
+ void
+ emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple Objective-C accelerator table.
+ void
+ emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple type accelerator table.
+ void
+ emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
+
+ uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
+
+ uint64_t getDebugInfoSectionSize() const override {
+ return DebugInfoSectionSize;
+ }
+
+ uint64_t getDebugMacInfoSectionSize() const override {
+ return MacInfoSectionSize;
+ }
+
+ uint64_t getDebugMacroSectionSize() const override {
+ return MacroSectionSize;
+ }
+
+ uint64_t getLocListsSectionSize() const override {
+ return LocListsSectionSize;
+ }
+
+ uint64_t getDebugAddrSectionSize() const override { return AddrSectionSize; }
+
+ void emitMacroTables(DWARFContext *Context,
+ const Offset2UnitMap &UnitMacroMap,
+ OffsetsStringPool &StringPool) override;
+
+private:
+ inline void warn(const Twine &Warning, StringRef Context = "") {
+ if (WarningHandler)
+ WarningHandler(Warning, Context, nullptr);
+ }
+
+ void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
+ const Offset2UnitMap &UnitMacroMap,
+ OffsetsStringPool &StringPool, uint64_t &OutOffset);
+
+ /// Emit piece of .debug_ranges for \p LinkedRanges.
+ void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch);
+
+ /// Emit piece of .debug_rnglists for \p LinkedRanges.
+ void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch,
+ DebugDieValuePool &AddrPool);
+
+ /// Emit piece of .debug_loc for \p LinkedRanges.
+ void emitDwarfDebugLocTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch);
+
+ /// Emit piece of .debug_loclists for \p LinkedRanges.
+ void emitDwarfDebugLocListsTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch, DebugDieValuePool &AddrPool);
+
+ /// \defgroup Line table emission
+ /// @{
+ void emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool);
+ void emitLineTableString(const DWARFDebugLine::Prologue &P,
+ const DWARFFormValue &String,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool);
+ void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,
+ OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool);
+ void emitLineTablePrologueV2IncludeAndFileTable(
+ const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool);
+ void emitLineTablePrologueV5IncludeAndFileTable(
+ const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool);
+ void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
+ MCSymbol *LineEndSym, unsigned AddressByteSize);
+ void emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
+ uint64_t &SectionSize);
+ void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
+ dwarf::DwarfFormat Format, uint64_t &SectionSize);
+ /// @}
+
+ /// \defgroup MCObjects MC layer objects constructed by the streamer
+ /// @{
+ std::unique_ptr<MCRegisterInfo> MRI;
+ std::unique_ptr<MCAsmInfo> MAI;
+ std::unique_ptr<MCObjectFileInfo> MOFI;
+ std::unique_ptr<MCContext> MC;
+ MCAsmBackend *MAB; // Owned by MCStreamer
+ std::unique_ptr<MCInstrInfo> MII;
+ std::unique_ptr<MCSubtargetInfo> MSTI;
+ MCInstPrinter *MIP; // Owned by AsmPrinter
+ MCCodeEmitter *MCE; // Owned by MCStreamer
+ MCStreamer *MS; // Owned by AsmPrinter
+ std::unique_ptr<TargetMachine> TM;
+ std::unique_ptr<AsmPrinter> Asm;
+ /// @}
+
+ /// The output file we stream the linked Dwarf to.
+ raw_pwrite_stream &OutFile;
+ DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
+ std::function<StringRef(StringRef Input)> Translator;
+
+ uint64_t RangesSectionSize = 0;
+ uint64_t RngListsSectionSize = 0;
+ uint64_t LocSectionSize = 0;
+ uint64_t LocListsSectionSize = 0;
+ uint64_t LineSectionSize = 0;
+ uint64_t FrameSectionSize = 0;
+ uint64_t DebugInfoSectionSize = 0;
+ uint64_t MacInfoSectionSize = 0;
+ uint64_t MacroSectionSize = 0;
+ uint64_t AddrSectionSize = 0;
+ uint64_t StrOffsetSectionSize = 0;
+
+ /// Keep track of emitted CUs and their Unique ID.
+ struct EmittedUnit {
+ unsigned ID;
+ MCSymbol *LabelBegin;
+ };
+ std::vector<EmittedUnit> EmittedUnits;
+
+ /// Emit the pubnames or pubtypes section contribution for \p
+ /// Unit into \p Sec. The data is provided in \p Names.
+ void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
+ const CompileUnit &Unit,
+ const std::vector<CompileUnit::AccelInfo> &Names);
+
+ DWARFLinkerBase::MessageHandlerTy WarningHandler = nullptr;
+};
+
+} // end of namespace classic
+} // end of namespace dwarf_linker
+} // end of namespace llvm
+
+#endif // LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H