+ class DIECloner {
+ DwarfLinker &Linker;
+ RelocationManager &RelocMgr;
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator &DIEAlloc;
+ MutableArrayRef<CompileUnit> CompileUnits;
+ LinkOptions Options;
+
+ public:
+ DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
+ BumpPtrAllocator &DIEAlloc,
+ MutableArrayRef<CompileUnit> CompileUnits, LinkOptions &Options)
+ : Linker(Linker), RelocMgr(RelocMgr), DIEAlloc(DIEAlloc),
+ CompileUnits(CompileUnits), Options(Options) {}
+
+ /// 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
+ /// debug 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.
+ ///
+ /// \returns the root of the cloned tree or null if nothing was selected.
+ DIE *cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &U,
+ int64_t PCOffset, uint32_t OutOffset, unsigned Flags);
+
+ /// 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.
+ void cloneAllCompileUnits(DWARFContextInMemory &DwarfContext);
+
+ private:
+ typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
+
+ /// Information gathered and exchanged between the various
+ /// clone*Attributes helpers about the attributes of a particular DIE.
+ struct AttributesInfo {
+ const char *Name, *MangledName; ///< Names.
+ uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool.
+
+ uint64_t OrigLowPc; ///< Value of AT_low_pc in the input DIE
+ uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE
+ int64_t PCOffset; ///< Offset to apply to PC addresses inside a function.
+
+ bool HasLowPc; ///< Does the DIE have a low_pc attribute?
+ bool IsDeclaration; ///< Is this DIE only a declaration?
+
+ AttributesInfo()
+ : Name(nullptr), MangledName(nullptr), NameOffset(0),
+ MangledNameOffset(0), OrigLowPc(UINT64_MAX), OrigHighPc(0),
+ PCOffset(0), HasLowPc(false), IsDeclaration(false) {}
+ };
+
+ /// Helper for cloneDIE.
+ unsigned cloneAttribute(DIE &Die,
+ const DWARFDebugInfoEntryMinimal &InputDIE,
+ CompileUnit &U, const DWARFFormValue &Val,
+ const AttributeSpec AttrSpec, unsigned AttrSize,
+ AttributesInfo &AttrInfo);
+
+ /// 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);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned
+ cloneDieReferenceAttribute(DIE &Die,
+ const DWARFDebugInfoEntryMinimal &InputDIE,
+ AttributeSpec AttrSpec, unsigned AttrSize,
+ const DWARFFormValue &Val, CompileUnit &Unit);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, unsigned AttrSize);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val,
+ const CompileUnit &Unit,
+ AttributesInfo &Info);
+
+ /// Clone a scalar attribute and add it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneScalarAttribute(DIE &Die,
+ const DWARFDebugInfoEntryMinimal &InputDIE,
+ 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 DWARFDebugInfoEntryMinimal &Die, DWARFUnit &U,
+ AttributesInfo &Info);
+
+ /// Create a copy of abbreviation Abbrev.
+ void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);