Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:48

0001 //===- DWARFLinker.h --------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
0010 #define LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H
0011 
0012 #include "llvm/ADT/AddressRanges.h"
0013 #include "llvm/ADT/DenseMap.h"
0014 #include "llvm/CodeGen/AccelTable.h"
0015 #include "llvm/CodeGen/NonRelocatableStringpool.h"
0016 #include "llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h"
0017 #include "llvm/DWARFLinker/DWARFLinkerBase.h"
0018 #include "llvm/DWARFLinker/IndexedValuesMap.h"
0019 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
0020 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
0021 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
0022 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
0023 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
0024 #include <map>
0025 
0026 namespace llvm {
0027 class DWARFExpression;
0028 class DWARFUnit;
0029 class DataExtractor;
0030 template <typename T> class SmallVectorImpl;
0031 
0032 namespace dwarf_linker {
0033 namespace classic {
0034 class DeclContextTree;
0035 
0036 using Offset2UnitMap = DenseMap<uint64_t, CompileUnit *>;
0037 using DebugDieValuePool = IndexedValuesMap<uint64_t>;
0038 
0039 /// DwarfEmitter presents interface to generate all debug info tables.
0040 class DwarfEmitter {
0041 public:
0042   virtual ~DwarfEmitter() = default;
0043 
0044   /// Emit section named SecName with data SecData.
0045   virtual void emitSectionContents(StringRef SecData,
0046                                    DebugSectionKind SecKind) = 0;
0047 
0048   /// Emit the abbreviation table \p Abbrevs to the .debug_abbrev section.
0049   virtual void
0050   emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
0051               unsigned DwarfVersion) = 0;
0052 
0053   /// Emit the string table described by \p Pool into .debug_str table.
0054   virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
0055 
0056   /// Emit the debug string offset table described by \p StringOffsets into the
0057   /// .debug_str_offsets table.
0058   virtual void emitStringOffsets(const SmallVector<uint64_t> &StringOffsets,
0059                                  uint16_t TargetDWARFVersion) = 0;
0060 
0061   /// Emit the string table described by \p Pool into .debug_line_str table.
0062   virtual void emitLineStrings(const NonRelocatableStringpool &Pool) = 0;
0063 
0064   /// Emit DWARF debug names.
0065   virtual void emitDebugNames(DWARF5AccelTable &Table) = 0;
0066 
0067   /// Emit Apple namespaces accelerator table.
0068   virtual void
0069   emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
0070 
0071   /// Emit Apple names accelerator table.
0072   virtual void
0073   emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
0074 
0075   /// Emit Apple Objective-C accelerator table.
0076   virtual void
0077   emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
0078 
0079   /// Emit Apple type accelerator table.
0080   virtual void
0081   emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
0082 
0083   /// Emit debug ranges (.debug_ranges, .debug_rnglists) header.
0084   virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0;
0085 
0086   /// Emit debug ranges (.debug_ranges, .debug_rnglists) fragment.
0087   virtual void emitDwarfDebugRangeListFragment(
0088       const CompileUnit &Unit, const AddressRanges &LinkedRanges,
0089       PatchLocation Patch, DebugDieValuePool &AddrPool) = 0;
0090 
0091   /// Emit debug ranges (.debug_ranges, .debug_rnglists) footer.
0092   virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
0093                                              MCSymbol *EndLabel) = 0;
0094 
0095   /// Emit debug locations (.debug_loc, .debug_loclists) header.
0096   virtual MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) = 0;
0097 
0098   /// Emit debug locations (.debug_loc, .debug_loclists) fragment.
0099   virtual void emitDwarfDebugLocListFragment(
0100       const CompileUnit &Unit,
0101       const DWARFLocationExpressionsVector &LinkedLocationExpression,
0102       PatchLocation Patch, DebugDieValuePool &AddrPool) = 0;
0103 
0104   /// Emit debug locations (.debug_loc, .debug_loclists) footer.
0105   virtual void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
0106                                            MCSymbol *EndLabel) = 0;
0107 
0108   /// Emit .debug_addr header.
0109   virtual MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) = 0;
0110 
0111   /// Emit the addresses described by \p Addrs into the .debug_addr section.
0112   virtual void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
0113                                    uint8_t AddrSize) = 0;
0114 
0115   /// Emit .debug_addr footer.
0116   virtual void emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
0117                                          MCSymbol *EndLabel) = 0;
0118 
0119   /// Emit .debug_aranges entries for \p Unit
0120   virtual void
0121   emitDwarfDebugArangesTable(const CompileUnit &Unit,
0122                              const AddressRanges &LinkedRanges) = 0;
0123 
0124   /// Emit specified \p LineTable into .debug_line table.
0125   virtual void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
0126                                     const CompileUnit &Unit,
0127                                     OffsetsStringPool &DebugStrPool,
0128                                     OffsetsStringPool &DebugLineStrPool) = 0;
0129 
0130   /// Emit the .debug_pubnames contribution for \p Unit.
0131   virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
0132 
0133   /// Emit the .debug_pubtypes contribution for \p Unit.
0134   virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
0135 
0136   /// Emit a CIE.
0137   virtual void emitCIE(StringRef CIEBytes) = 0;
0138 
0139   /// Emit an FDE with data \p Bytes.
0140   virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
0141                        StringRef Bytes) = 0;
0142 
0143   /// Emit the compilation unit header for \p Unit in the
0144   /// .debug_info section.
0145   ///
0146   /// As a side effect, this also switches the current Dwarf version
0147   /// of the MC layer to the one of U.getOrigUnit().
0148   virtual void emitCompileUnitHeader(CompileUnit &Unit,
0149                                      unsigned DwarfVersion) = 0;
0150 
0151   /// Recursively emit the DIE tree rooted at \p Die.
0152   virtual void emitDIE(DIE &Die) = 0;
0153 
0154   /// Emit all available macro tables(DWARFv4 and DWARFv5).
0155   /// Use \p UnitMacroMap to get compilation unit by macro table offset.
0156   /// Side effects: Fill \p StringPool with macro strings, update
0157   /// DW_AT_macro_info, DW_AT_macros attributes for corresponding compile
0158   /// units.
0159   virtual void emitMacroTables(DWARFContext *Context,
0160                                const Offset2UnitMap &UnitMacroMap,
0161                                OffsetsStringPool &StringPool) = 0;
0162 
0163   /// Returns size of generated .debug_line section.
0164   virtual uint64_t getLineSectionSize() const = 0;
0165 
0166   /// Returns size of generated .debug_frame section.
0167   virtual uint64_t getFrameSectionSize() const = 0;
0168 
0169   /// Returns size of generated .debug_ranges section.
0170   virtual uint64_t getRangesSectionSize() const = 0;
0171 
0172   /// Returns size of generated .debug_rnglists section.
0173   virtual uint64_t getRngListsSectionSize() const = 0;
0174 
0175   /// Returns size of generated .debug_info section.
0176   virtual uint64_t getDebugInfoSectionSize() const = 0;
0177 
0178   /// Returns size of generated .debug_macinfo section.
0179   virtual uint64_t getDebugMacInfoSectionSize() const = 0;
0180 
0181   /// Returns size of generated .debug_macro section.
0182   virtual uint64_t getDebugMacroSectionSize() const = 0;
0183 
0184   /// Returns size of generated .debug_loclists section.
0185   virtual uint64_t getLocListsSectionSize() const = 0;
0186 
0187   /// Returns size of generated .debug_addr section.
0188   virtual uint64_t getDebugAddrSectionSize() const = 0;
0189 
0190   /// Dump the file to the disk.
0191   virtual void finish() = 0;
0192 };
0193 
0194 class DwarfStreamer;
0195 using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
0196 
0197 /// The core of the Dwarf linking logic.
0198 ///
0199 /// The generation of the dwarf information from the object files will be
0200 /// driven by the selection of 'root DIEs', which are DIEs that
0201 /// describe variables or functions that resolves to the corresponding
0202 /// code section(and thus have entries in the Addresses map). All the debug
0203 /// information that will be generated(the DIEs, but also the line
0204 /// tables, ranges, ...) is derived from that set of root DIEs.
0205 ///
0206 /// The root DIEs are identified because they contain relocations that
0207 /// points to code section(the low_pc for a function, the location for
0208 /// a variable). These relocations are called ValidRelocs in the
0209 /// AddressesInfo and are gathered as a very first step when we start
0210 /// processing a object file.
0211 class DWARFLinker : public DWARFLinkerBase {
0212 public:
0213   DWARFLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
0214               std::function<StringRef(StringRef)> StringsTranslator)
0215       : StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
0216         WarningHandler(WarningHandler) {}
0217 
0218   static std::unique_ptr<DWARFLinker> createLinker(
0219       MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
0220       std::function<StringRef(StringRef)> StringsTranslator = nullptr) {
0221     return std::make_unique<DWARFLinker>(ErrorHandler, WarningHandler,
0222                                          StringsTranslator);
0223   }
0224 
0225   /// Set output DWARF emitter.
0226   void setOutputDWARFEmitter(DwarfEmitter *Emitter) {
0227     TheDwarfEmitter = Emitter;
0228   }
0229 
0230   /// Add object file to be linked. Pre-load compile unit die. Call
0231   /// \p OnCUDieLoaded for each compile unit die. If specified \p File
0232   /// has reference to the Clang module then such module would be
0233   /// pre-loaded by \p Loader for !Update case.
0234   ///
0235   /// \pre NoODR, Update options should be set before call to addObjectFile.
0236   void addObjectFile(
0237       DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
0238       CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
0239 
0240   /// Link debug info for added objFiles. Object files are linked all together.
0241   Error link() override;
0242 
0243   /// A number of methods setting various linking options:
0244 
0245   /// Allows to generate log of linking process to the standard output.
0246   void setVerbosity(bool Verbose) override { Options.Verbose = Verbose; }
0247 
0248   /// Print statistics to standard output.
0249   void setStatistics(bool Statistics) override {
0250     Options.Statistics = Statistics;
0251   }
0252 
0253   /// Verify the input DWARF.
0254   void setVerifyInputDWARF(bool Verify) override {
0255     Options.VerifyInputDWARF = Verify;
0256   }
0257 
0258   /// Do not unique types according to ODR.
0259   void setNoODR(bool NoODR) override { Options.NoODR = NoODR; }
0260 
0261   /// Update index tables only(do not modify rest of DWARF).
0262   void setUpdateIndexTablesOnly(bool Update) override {
0263     Options.Update = Update;
0264   }
0265 
0266   /// Allow generating valid, but non-deterministic output.
0267   void setAllowNonDeterministicOutput(bool) override { /* Nothing to do. */
0268   }
0269 
0270   /// Set whether to keep the enclosing function for a static variable.
0271   void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
0272     Options.KeepFunctionForStatic = KeepFunctionForStatic;
0273   }
0274 
0275   /// Use specified number of threads for parallel files linking.
0276   void setNumThreads(unsigned NumThreads) override {
0277     Options.Threads = NumThreads;
0278   }
0279 
0280   /// Add kind of accelerator tables to be generated.
0281   void addAccelTableKind(AccelTableKind Kind) override {
0282     assert(!llvm::is_contained(Options.AccelTables, Kind));
0283     Options.AccelTables.emplace_back(Kind);
0284   }
0285 
0286   /// Set prepend path for clang modules.
0287   void setPrependPath(StringRef Ppath) override { Options.PrependPath = Ppath; }
0288 
0289   /// Set estimated objects files amount, for preliminary data allocation.
0290   void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override {
0291     ObjectContexts.reserve(ObjFilesNum);
0292   }
0293 
0294   /// Set verification handler which would be used to report verification
0295   /// errors.
0296   void
0297   setInputVerificationHandler(InputVerificationHandlerTy Handler) override {
0298     Options.InputVerificationHandler = Handler;
0299   }
0300 
0301   /// Set map for Swift interfaces.
0302   void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override {
0303     Options.ParseableSwiftInterfaces = Map;
0304   }
0305 
0306   /// Set prefix map for objects.
0307   void setObjectPrefixMap(ObjectPrefixMapTy *Map) override {
0308     Options.ObjectPrefixMap = Map;
0309   }
0310 
0311   /// Set target DWARF version.
0312   Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
0313     if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
0314       return createStringError(std::errc::invalid_argument,
0315                                "unsupported DWARF version: %d",
0316                                TargetDWARFVersion);
0317 
0318     Options.TargetDWARFVersion = TargetDWARFVersion;
0319     return Error::success();
0320   }
0321 
0322 private:
0323   /// Flags passed to DwarfLinker::lookForDIEsToKeep
0324   enum TraversalFlags {
0325     TF_Keep = 1 << 0,            ///< Mark the traversed DIEs as kept.
0326     TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
0327     TF_DependencyWalk = 1 << 2,  ///< Walking the dependencies of a kept DIE.
0328     TF_ParentWalk = 1 << 3,      ///< Walking up the parents of a kept DIE.
0329     TF_ODR = 1 << 4,             ///< Use the ODR while keeping dependents.
0330     TF_SkipPC = 1 << 5,          ///< Skip all location attributes.
0331   };
0332 
0333   /// The  distinct types of work performed by the work loop.
0334   enum class WorklistItemType {
0335     /// Given a DIE, look for DIEs to be kept.
0336     LookForDIEsToKeep,
0337     /// Given a DIE, look for children of this DIE to be kept.
0338     LookForChildDIEsToKeep,
0339     /// Given a DIE, look for DIEs referencing this DIE to be kept.
0340     LookForRefDIEsToKeep,
0341     /// Given a DIE, look for parent DIEs to be kept.
0342     LookForParentDIEsToKeep,
0343     /// Given a DIE, update its incompleteness based on whether its children are
0344     /// incomplete.
0345     UpdateChildIncompleteness,
0346     /// Given a DIE, update its incompleteness based on whether the DIEs it
0347     /// references are incomplete.
0348     UpdateRefIncompleteness,
0349     /// Given a DIE, mark it as ODR Canonical if applicable.
0350     MarkODRCanonicalDie,
0351   };
0352 
0353   /// This class represents an item in the work list. The type defines what kind
0354   /// of work needs to be performed when processing the current item. The flags
0355   /// and info fields are optional based on the type.
0356   struct WorklistItem {
0357     DWARFDie Die;
0358     WorklistItemType Type;
0359     CompileUnit &CU;
0360     unsigned Flags;
0361     union {
0362       const unsigned AncestorIdx;
0363       CompileUnit::DIEInfo *OtherInfo;
0364     };
0365 
0366     WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
0367                  WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
0368         : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
0369 
0370     WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
0371                  CompileUnit::DIEInfo *OtherInfo = nullptr)
0372         : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
0373 
0374     WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
0375         : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
0376           AncestorIdx(AncestorIdx) {}
0377   };
0378 
0379   /// Verify the given DWARF file.
0380   void verifyInput(const DWARFFile &File);
0381 
0382   /// returns true if we need to translate strings.
0383   bool needToTranslateStrings() { return StringsTranslator != nullptr; }
0384 
0385   void reportWarning(const Twine &Warning, const DWARFFile &File,
0386                      const DWARFDie *DIE = nullptr) const {
0387     if (WarningHandler != nullptr)
0388       WarningHandler(Warning, File.FileName, DIE);
0389   }
0390 
0391   void reportError(const Twine &Warning, const DWARFFile &File,
0392                    const DWARFDie *DIE = nullptr) const {
0393     if (ErrorHandler != nullptr)
0394       ErrorHandler(Warning, File.FileName, DIE);
0395   }
0396 
0397   void copyInvariantDebugSection(DWARFContext &Dwarf);
0398 
0399   /// Keep information for referenced clang module: already loaded DWARF info
0400   /// of the clang module and a CompileUnit of the module.
0401   struct RefModuleUnit {
0402     RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
0403         : File(File), Unit(std::move(Unit)) {}
0404     RefModuleUnit(RefModuleUnit &&Other)
0405         : File(Other.File), Unit(std::move(Other.Unit)) {}
0406     RefModuleUnit(const RefModuleUnit &) = delete;
0407 
0408     DWARFFile &File;
0409     std::unique_ptr<CompileUnit> Unit;
0410   };
0411   using ModuleUnitListTy = std::vector<RefModuleUnit>;
0412 
0413   /// Keeps track of data associated with one object during linking.
0414   struct LinkContext {
0415     DWARFFile &File;
0416     UnitListTy CompileUnits;
0417     ModuleUnitListTy ModuleUnits;
0418     bool Skip = false;
0419 
0420     LinkContext(DWARFFile &File) : File(File) {}
0421 
0422     /// Clear part of the context that's no longer needed when we're done with
0423     /// the debug object.
0424     void clear() {
0425       CompileUnits.clear();
0426       ModuleUnits.clear();
0427       File.unload();
0428     }
0429   };
0430 
0431   /// Called before emitting object data
0432   void cleanupAuxiliarryData(LinkContext &Context);
0433 
0434   /// Look at the parent of the given DIE and decide whether they should be
0435   /// kept.
0436   void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
0437                                unsigned Flags,
0438                                SmallVectorImpl<WorklistItem> &Worklist);
0439 
0440   /// Look at the children of the given DIE and decide whether they should be
0441   /// kept.
0442   void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
0443                               unsigned Flags,
0444                               SmallVectorImpl<WorklistItem> &Worklist);
0445 
0446   /// Look at DIEs referenced by the given DIE and decide whether they should be
0447   /// kept. All DIEs referenced though attributes should be kept.
0448   void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
0449                             unsigned Flags, const UnitListTy &Units,
0450                             const DWARFFile &File,
0451                             SmallVectorImpl<WorklistItem> &Worklist);
0452 
0453   /// Mark context corresponding to the specified \p Die as having canonical
0454   /// die, if applicable.
0455   void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
0456 
0457   /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
0458   ///
0459   /// @{
0460   /// Recursively walk the \p DIE tree and look for DIEs to
0461   /// keep. Store that information in \p CU's DIEInfo.
0462   ///
0463   /// The return value indicates whether the DIE is incomplete.
0464   void lookForDIEsToKeep(AddressesMap &RelocMgr, const UnitListTy &Units,
0465                          const DWARFDie &DIE, const DWARFFile &File,
0466                          CompileUnit &CU, unsigned Flags);
0467 
0468   /// Check whether specified \p CUDie is a Clang module reference.
0469   /// if \p Quiet is false then display error messages.
0470   /// \return first == true if CUDie is a Clang module reference.
0471   ///         second == true if module is already loaded.
0472   std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
0473                                          std::string &PCMFile,
0474                                          LinkContext &Context, unsigned Indent,
0475                                          bool Quiet);
0476 
0477   /// If this compile unit is really a skeleton CU that points to a
0478   /// clang module, register it in ClangModules and return true.
0479   ///
0480   /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
0481   /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
0482   /// hash.
0483   bool registerModuleReference(const DWARFDie &CUDie, LinkContext &Context,
0484                                ObjFileLoaderTy Loader,
0485                                CompileUnitHandlerTy OnCUDieLoaded,
0486                                unsigned Indent = 0);
0487 
0488   /// Recursively add the debug info in this clang module .pcm
0489   /// file (and all the modules imported by it in a bottom-up fashion)
0490   /// to ModuleUnits.
0491   Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
0492                         const std::string &PCMFile, LinkContext &Context,
0493                         CompileUnitHandlerTy OnCUDieLoaded,
0494                         unsigned Indent = 0);
0495 
0496   /// Clone specified Clang module unit \p Unit.
0497   Error cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
0498                         DeclContextTree &ODRContexts,
0499                         OffsetsStringPool &DebugStrPool,
0500                         OffsetsStringPool &DebugLineStrPool,
0501                         DebugDieValuePool &StringOffsetPool,
0502                         unsigned Indent = 0);
0503 
0504   unsigned shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
0505                          const DWARFFile &File, CompileUnit &Unit,
0506                          CompileUnit::DIEInfo &MyInfo, unsigned Flags);
0507 
0508   /// This function checks whether variable has DWARF expression containing
0509   /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...).
0510   /// \returns first is true if the expression has an operation referencing an
0511   /// address.
0512   ///          second is the relocation adjustment value if the live address is
0513   ///          referenced.
0514   std::pair<bool, std::optional<int64_t>>
0515   getVariableRelocAdjustment(AddressesMap &RelocMgr, const DWARFDie &DIE);
0516 
0517   /// Check if a variable describing DIE should be kept.
0518   /// \returns updated TraversalFlags.
0519   unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
0520                                  CompileUnit::DIEInfo &MyInfo, unsigned Flags);
0521 
0522   unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
0523                                    const DWARFFile &File, CompileUnit &Unit,
0524                                    CompileUnit::DIEInfo &MyInfo,
0525                                    unsigned Flags);
0526 
0527   /// Resolve the DIE attribute reference that has been extracted in \p
0528   /// RefValue. The resulting DIE might be in another CompileUnit which is
0529   /// stored into \p ReferencedCU. \returns null if resolving fails for any
0530   /// reason.
0531   DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
0532                                const DWARFFormValue &RefValue,
0533                                const DWARFDie &DIE, CompileUnit *&RefCU);
0534 
0535   /// @}
0536 
0537   /// \defgroup Methods used to link the debug information
0538   ///
0539   /// @{
0540 
0541   struct DWARFLinkerOptions;
0542 
0543   class DIECloner {
0544     DWARFLinker &Linker;
0545     DwarfEmitter *Emitter;
0546     DWARFFile &ObjFile;
0547     OffsetsStringPool &DebugStrPool;
0548     OffsetsStringPool &DebugLineStrPool;
0549     DebugDieValuePool &StringOffsetPool;
0550     DebugDieValuePool AddrPool;
0551 
0552     /// Allocator used for all the DIEValue objects.
0553     BumpPtrAllocator &DIEAlloc;
0554 
0555     std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
0556 
0557     /// Keeps mapping from offset of the macro table to corresponding
0558     /// compile unit.
0559     Offset2UnitMap UnitMacroMap;
0560 
0561     bool Update;
0562 
0563   public:
0564     DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
0565               BumpPtrAllocator &DIEAlloc,
0566               std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
0567               bool Update, OffsetsStringPool &DebugStrPool,
0568               OffsetsStringPool &DebugLineStrPool,
0569               DebugDieValuePool &StringOffsetPool)
0570         : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
0571           DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
0572           StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
0573           CompileUnits(CompileUnits), Update(Update) {}
0574 
0575     /// Recursively clone \p InputDIE into an tree of DIE objects
0576     /// where useless (as decided by lookForDIEsToKeep()) bits have been
0577     /// stripped out and addresses have been rewritten according to the
0578     /// address map.
0579     ///
0580     /// \param OutOffset is the offset the cloned DIE in the output
0581     /// compile unit.
0582     /// \param PCOffset (while cloning a function scope) is the offset
0583     /// applied to the entry point of the function to get the linked address.
0584     /// \param Die the output DIE to use, pass NULL to create one.
0585     /// \returns the root of the cloned tree or null if nothing was selected.
0586     DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
0587                   CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
0588                   unsigned Flags, bool IsLittleEndian, DIE *Die = nullptr);
0589 
0590     /// Construct the output DIE tree by cloning the DIEs we
0591     /// chose to keep above. If there are no valid relocs, then there's
0592     /// nothing to clone/emit.
0593     uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
0594                                   const DWARFFile &File, bool IsLittleEndian);
0595 
0596     /// Emit the .debug_addr section for the \p Unit.
0597     void emitDebugAddrSection(CompileUnit &Unit,
0598                               const uint16_t DwarfVersion) const;
0599 
0600     using ExpressionHandlerRef = function_ref<void(
0601         SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
0602         int64_t AddrRelocAdjustment)>;
0603 
0604     /// Compute and emit debug locations (.debug_loc, .debug_loclists)
0605     /// for \p Unit, patch the attributes referencing it.
0606     void generateUnitLocations(CompileUnit &Unit, const DWARFFile &File,
0607                                ExpressionHandlerRef ExprHandler);
0608 
0609   private:
0610     using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
0611 
0612     /// Information gathered and exchanged between the various
0613     /// clone*Attributes helpers about the attributes of a particular DIE.
0614     struct AttributesInfo {
0615       /// Names.
0616       DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
0617 
0618       /// Offsets in the string pool.
0619       uint32_t NameOffset = 0;
0620       uint32_t MangledNameOffset = 0;
0621 
0622       /// Offset to apply to PC addresses inside a function.
0623       int64_t PCOffset = 0;
0624 
0625       /// Does the DIE have a low_pc attribute?
0626       bool HasLowPc = false;
0627 
0628       /// Does the DIE have a ranges attribute?
0629       bool HasRanges = false;
0630 
0631       /// Is this DIE only a declaration?
0632       bool IsDeclaration = false;
0633 
0634       /// Is there a DW_AT_str_offsets_base in the CU?
0635       bool AttrStrOffsetBaseSeen = false;
0636 
0637       /// Is there a DW_AT_APPLE_origin in the CU?
0638       bool HasAppleOrigin = false;
0639 
0640       AttributesInfo() = default;
0641     };
0642 
0643     /// Helper for cloneDIE.
0644     unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
0645                             const DWARFFile &File, CompileUnit &U,
0646                             const DWARFFormValue &Val,
0647                             const AttributeSpec AttrSpec, unsigned AttrSize,
0648                             AttributesInfo &AttrInfo, bool IsLittleEndian);
0649 
0650     /// Clone a string attribute described by \p AttrSpec and add
0651     /// it to \p Die.
0652     /// \returns the size of the new attribute.
0653     unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
0654                                   const DWARFFormValue &Val, const DWARFUnit &U,
0655                                   AttributesInfo &Info);
0656 
0657     /// Clone an attribute referencing another DIE and add
0658     /// it to \p Die.
0659     /// \returns the size of the new attribute.
0660     unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
0661                                         AttributeSpec AttrSpec,
0662                                         unsigned AttrSize,
0663                                         const DWARFFormValue &Val,
0664                                         const DWARFFile &File,
0665                                         CompileUnit &Unit);
0666 
0667     /// Clone a DWARF expression that may be referencing another DIE.
0668     void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
0669                          const DWARFFile &File, CompileUnit &Unit,
0670                          SmallVectorImpl<uint8_t> &OutputBuffer,
0671                          int64_t AddrRelocAdjustment, bool IsLittleEndian);
0672 
0673     /// Clone an attribute referencing another DIE and add
0674     /// it to \p Die.
0675     /// \returns the size of the new attribute.
0676     unsigned cloneBlockAttribute(DIE &Die, const DWARFDie &InputDIE,
0677                                  const DWARFFile &File, CompileUnit &Unit,
0678                                  AttributeSpec AttrSpec,
0679                                  const DWARFFormValue &Val,
0680                                  bool IsLittleEndian);
0681 
0682     /// Clone an attribute referencing another DIE and add
0683     /// it to \p Die.
0684     /// \returns the size of the new attribute.
0685     unsigned cloneAddressAttribute(DIE &Die, const DWARFDie &InputDIE,
0686                                    AttributeSpec AttrSpec, unsigned AttrSize,
0687                                    const DWARFFormValue &Val,
0688                                    const CompileUnit &Unit,
0689                                    AttributesInfo &Info);
0690 
0691     /// Clone a scalar attribute  and add it to \p Die.
0692     /// \returns the size of the new attribute.
0693     unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
0694                                   const DWARFFile &File, CompileUnit &U,
0695                                   AttributeSpec AttrSpec,
0696                                   const DWARFFormValue &Val, unsigned AttrSize,
0697                                   AttributesInfo &Info);
0698 
0699     /// Get the potential name and mangled name for the entity
0700     /// described by \p Die and store them in \Info if they are not
0701     /// already there.
0702     /// \returns is a name was found.
0703     bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
0704                      OffsetsStringPool &StringPool, bool StripTemplate = false);
0705 
0706     uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
0707                                     const DWARFFile &File,
0708                                     int RecurseDepth = 0);
0709 
0710     /// Helper for cloneDIE.
0711     void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
0712                             DwarfStringPoolEntryRef Name,
0713                             OffsetsStringPool &StringPool, bool SkipPubSection);
0714 
0715     void rememberUnitForMacroOffset(CompileUnit &Unit);
0716 
0717     /// Clone and emit the line table for the specified \p Unit.
0718     /// Translate directories and file names if necessary.
0719     /// Relocate address ranges.
0720     void generateLineTableForUnit(CompileUnit &Unit);
0721   };
0722 
0723   /// Assign an abbreviation number to \p Abbrev
0724   void assignAbbrev(DIEAbbrev &Abbrev);
0725 
0726   /// Compute and emit debug ranges(.debug_aranges, .debug_ranges,
0727   /// .debug_rnglists) for \p Unit, patch the attributes referencing it.
0728   void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
0729                           DebugDieValuePool &AddrPool) const;
0730 
0731   /// Emit the accelerator entries for \p Unit.
0732   void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
0733 
0734   /// Patch the frame info for an object file and emit it.
0735   void patchFrameInfoForObject(LinkContext &Context);
0736 
0737   /// FoldingSet that uniques the abbreviations.
0738   FoldingSet<DIEAbbrev> AbbreviationsSet;
0739 
0740   /// Storage for the unique Abbreviations.
0741   /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
0742   /// changed to a vector of unique_ptrs.
0743   std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
0744 
0745   /// DIELoc objects that need to be destructed (but not freed!).
0746   std::vector<DIELoc *> DIELocs;
0747 
0748   /// DIEBlock objects that need to be destructed (but not freed!).
0749   std::vector<DIEBlock *> DIEBlocks;
0750 
0751   /// Allocator used for all the DIEValue objects.
0752   BumpPtrAllocator DIEAlloc;
0753   /// @}
0754 
0755   DwarfEmitter *TheDwarfEmitter = nullptr;
0756   std::vector<LinkContext> ObjectContexts;
0757 
0758   /// The CIEs that have been emitted in the output section. The actual CIE
0759   /// data serves a the key to this StringMap, this takes care of comparing the
0760   /// semantics of CIEs defined in different object files.
0761   StringMap<uint32_t> EmittedCIEs;
0762 
0763   /// Offset of the last CIE that has been emitted in the output
0764   /// .debug_frame section.
0765   uint32_t LastCIEOffset = 0;
0766 
0767   /// Apple accelerator tables.
0768   DWARF5AccelTable DebugNames;
0769   AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
0770   AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
0771   AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
0772   AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
0773 
0774   /// Mapping the PCM filename to the DwoId.
0775   StringMap<uint64_t> ClangModules;
0776 
0777   std::function<StringRef(StringRef)> StringsTranslator = nullptr;
0778 
0779   /// A unique ID that identifies each compile unit.
0780   unsigned UniqueUnitID = 0;
0781 
0782   // error handler
0783   MessageHandlerTy ErrorHandler = nullptr;
0784 
0785   // warning handler
0786   MessageHandlerTy WarningHandler = nullptr;
0787 
0788   /// linking options
0789   struct DWARFLinkerOptions {
0790     /// DWARF version for the output.
0791     uint16_t TargetDWARFVersion = 0;
0792 
0793     /// Generate processing log to the standard output.
0794     bool Verbose = false;
0795 
0796     /// Print statistics.
0797     bool Statistics = false;
0798 
0799     /// Verify the input DWARF.
0800     bool VerifyInputDWARF = false;
0801 
0802     /// Do not unique types according to ODR
0803     bool NoODR = false;
0804 
0805     /// Update
0806     bool Update = false;
0807 
0808     /// Whether we want a static variable to force us to keep its enclosing
0809     /// function.
0810     bool KeepFunctionForStatic = false;
0811 
0812     /// Number of threads.
0813     unsigned Threads = 1;
0814 
0815     /// The accelerator table kinds
0816     SmallVector<AccelTableKind, 1> AccelTables;
0817 
0818     /// Prepend path for the clang modules.
0819     std::string PrependPath;
0820 
0821     // input verification handler
0822     InputVerificationHandlerTy InputVerificationHandler = nullptr;
0823 
0824     /// A list of all .swiftinterface files referenced by the debug
0825     /// info, mapping Module name to path on disk. The entries need to
0826     /// be uniqued and sorted and there are only few entries expected
0827     /// per compile unit, which is why this is a std::map.
0828     /// this is dsymutil specific fag.
0829     SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
0830 
0831     /// A list of remappings to apply to file paths.
0832     ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
0833   } Options;
0834 };
0835 
0836 } // end of namespace classic
0837 } // end of namespace dwarf_linker
0838 } // end of namespace llvm
0839 
0840 #endif // LLVM_DWARFLINKER_CLASSIC_DWARFLINKER_H