diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -98,10 +98,8 @@ /// Emit DIE containing warnings. virtual void emitPaperTrailWarningsDie(DIE &Die) = 0; - /// Emit section named SecName with content equals to - /// corresponding section in Obj. - virtual void emitSectionContents(const object::ObjectFile &Obj, - StringRef SecName) = 0; + /// Emit section named SecName with data SecData. + virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0; /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. virtual void @@ -202,19 +200,21 @@ using UnitListTy = std::vector>; -/// this class represents Object File and it`s additional info. -class DwarfLinkerObjFile { +/// this class represents DWARF information for source file +/// and it`s address map. +class DwarfFile { public: - DwarfLinkerObjFile(StringRef Name, const object::ObjectFile *File, - const std::vector &Warnings) - : FileName(Name), ObjFile(File), Warnings(Warnings) {} + DwarfFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses, + const std::vector &Warnings) + : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) { + } /// object file name. StringRef FileName; - /// object file. - const object::ObjectFile *ObjFile; + /// source DWARF information. + DWARFContext *Dwarf = nullptr; /// helpful address information(list of valid address ranges, relocations). - std::unique_ptr Addresses; + AddressesMap *Addresses = nullptr; /// warnings for object file. const std::vector &Warnings; }; @@ -222,8 +222,8 @@ typedef std::function messageHandler; -typedef std::function(StringRef ContainerName, - StringRef Path)> +typedef std::function(StringRef ContainerName, + StringRef Path)> objFileLoader; typedef std::map swiftInterfacesMap; @@ -248,7 +248,7 @@ : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {} /// Add object file to be linked. - void addObjectFile(DwarfLinkerObjFile &ObjFile); + void addObjectFile(DwarfFile &File); /// Link debug info for added objFiles. Object /// files are linked all together. @@ -367,13 +367,13 @@ /// returns true if we need to translate strings. bool needToTranslateStrings() { return StringsTranslator != nullptr; } - void reportWarning(const Twine &Warning, const DwarfLinkerObjFile &OF, + void reportWarning(const Twine &Warning, const DwarfFile &OF, const DWARFDie *DIE = nullptr) const { if (Options.WarningHandler != nullptr) Options.WarningHandler(Warning, OF.FileName, DIE); } - void reportError(const Twine &Warning, const DwarfLinkerObjFile &OF, + void reportError(const Twine &Warning, const DwarfFile &OF, const DWARFDie *DIE = nullptr) const { if (Options.ErrorHandler != nullptr) Options.ErrorHandler(Warning, OF.FileName, DIE); @@ -389,30 +389,24 @@ void updateAccelKind(DWARFContext &Dwarf); /// Emit warnings as Dwarf compile units to leave a trail after linking. - bool emitPaperTrailWarnings(const DwarfLinkerObjFile &OF, + bool emitPaperTrailWarnings(const DwarfFile &OF, OffsetsStringPool &StringPool); - void copyInvariantDebugSection(const object::ObjectFile &Obj); + void copyInvariantDebugSection(DWARFContext &Dwarf); /// Keeps track of data associated with one object during linking. struct LinkContext { - DwarfLinkerObjFile &ObjectFile; - std::unique_ptr DwarfContext; + DwarfFile &File; UnitListTy CompileUnits; bool Skip = false; - LinkContext(DwarfLinkerObjFile &objFile) : ObjectFile(objFile) { - - if (ObjectFile.ObjFile) - DwarfContext = DWARFContext::create(*ObjectFile.ObjFile); - } + 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() { - DwarfContext.reset(nullptr); CompileUnits.clear(); - ObjectFile.Addresses->clear(); + File.Addresses->clear(); } }; @@ -435,7 +429,7 @@ /// kept. All DIEs referenced though attributes should be kept. void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, unsigned Flags, const UnitListTy &Units, - const DwarfLinkerObjFile &OF, + const DwarfFile &OF, SmallVectorImpl &Worklist); /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries. @@ -447,8 +441,7 @@ /// The return value indicates whether the DIE is incomplete. void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges, const UnitListTy &Units, const DWARFDie &DIE, - const DwarfLinkerObjFile &OF, CompileUnit &CU, - unsigned Flags); + const DwarfFile &OF, CompileUnit &CU, unsigned Flags); /// If this compile unit is really a skeleton CU that points to a /// clang module, register it in ClangModules and return true. @@ -457,7 +450,7 @@ /// pointing to the module, and a DW_AT_gnu_dwo_id with the module /// hash. bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit, - const DwarfLinkerObjFile &OF, + const DwarfFile &OF, OffsetsStringPool &OffsetsStringPool, UniquingStringPool &UniquingStringPoolStringPool, DeclContextTree &ODRContexts, @@ -470,7 +463,7 @@ /// to Units. Error loadClangModule(DWARFDie CUDie, StringRef FilePath, StringRef ModuleName, uint64_t DwoId, - const DwarfLinkerObjFile &OF, + const DwarfFile &OF, OffsetsStringPool &OffsetsStringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, @@ -480,12 +473,11 @@ /// Mark the passed DIE as well as all the ones it depends on as kept. void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges, const UnitListTy &Units, const DWARFDie &DIE, - CompileUnit::DIEInfo &MyInfo, - const DwarfLinkerObjFile &OF, CompileUnit &CU, - bool UseODR); + CompileUnit::DIEInfo &MyInfo, const DwarfFile &OF, + CompileUnit &CU, bool UseODR); unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, const DwarfLinkerObjFile &OF, + const DWARFDie &DIE, const DwarfFile &OF, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags); @@ -496,8 +488,7 @@ CompileUnit::DIEInfo &MyInfo, unsigned Flags); unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, - const DwarfLinkerObjFile &OF, + const DWARFDie &DIE, const DwarfFile &OF, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags); @@ -506,8 +497,7 @@ /// 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 DwarfLinkerObjFile &OF, - const UnitListTy &Units, + DWARFDie resolveDIEReference(const DwarfFile &OF, const UnitListTy &Units, const DWARFFormValue &RefValue, const DWARFDie &DIE, CompileUnit *&RefCU); @@ -522,7 +512,7 @@ class DIECloner { DWARFLinker &Linker; DwarfEmitter *Emitter; - DwarfLinkerObjFile &ObjFile; + DwarfFile &ObjFile; /// Allocator used for all the DIEValue objects. BumpPtrAllocator &DIEAlloc; @@ -532,8 +522,8 @@ bool Update; public: - DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, - DwarfLinkerObjFile &ObjFile, BumpPtrAllocator &DIEAlloc, + DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DwarfFile &ObjFile, + BumpPtrAllocator &DIEAlloc, std::vector> &CompileUnits, bool Update) : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile), @@ -550,16 +540,15 @@ /// 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 DwarfLinkerObjFile &OF, - CompileUnit &U, OffsetsStringPool &StringPool, - int64_t PCOffset, uint32_t OutOffset, unsigned Flags, - bool IsLittleEndian, DIE *Die = nullptr); + DIE *cloneDIE(const DWARFDie &InputDIE, const DwarfFile &OF, CompileUnit &U, + OffsetsStringPool &StringPool, int64_t PCOffset, + uint32_t OutOffset, unsigned Flags, bool IsLittleEndian, + DIE *Die = nullptr); /// Construct the output DIE tree by cloning the DIEs we /// chose to keep above. If there are no valid relocs, then there's /// nothing to clone/emit. - void cloneAllCompileUnits(DWARFContext &DwarfContext, - const DwarfLinkerObjFile &OF, + void cloneAllCompileUnits(DWARFContext &DwarfContext, const DwarfFile &OF, OffsetsStringPool &StringPool, bool IsLittleEndian); @@ -602,7 +591,7 @@ /// Helper for cloneDIE. unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE, - const DwarfLinkerObjFile &OF, CompileUnit &U, + const DwarfFile &OF, CompileUnit &U, OffsetsStringPool &StringPool, const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize, @@ -623,18 +612,17 @@ AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val, - const DwarfLinkerObjFile &OF, - CompileUnit &Unit); + const DwarfFile &OF, CompileUnit &Unit); /// Clone a DWARF expression that may be referencing another DIE. void cloneExpression(DataExtractor &Data, DWARFExpression Expression, - const DwarfLinkerObjFile &OF, CompileUnit &Unit, + const DwarfFile &OF, CompileUnit &Unit, SmallVectorImpl &OutputBuffer); /// Clone an attribute referencing another DIE and add /// it to \p Die. /// \returns the size of the new attribute. - unsigned cloneBlockAttribute(DIE &Die, const DwarfLinkerObjFile &OF, + unsigned cloneBlockAttribute(DIE &Die, const DwarfFile &OF, CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, bool IsLittleEndian); @@ -650,7 +638,7 @@ /// 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 DwarfLinkerObjFile &OF, CompileUnit &U, + const DwarfFile &OF, CompileUnit &U, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, AttributesInfo &Info); @@ -666,8 +654,7 @@ void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR); uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, - const DwarfLinkerObjFile &OF, - int RecurseDepth = 0); + const DwarfFile &OF, int RecurseDepth = 0); /// Helper for cloneDIE. void addObjCAccelerator(CompileUnit &Unit, const DIE *Die, @@ -681,7 +668,7 @@ /// Compute and emit debug_ranges section for \p Unit, and /// patch the attributes referencing it. void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf, - const DwarfLinkerObjFile &OF) const; + const DwarfFile &OF) const; /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had /// one. @@ -691,7 +678,7 @@ /// parts according to the linked function ranges and emit the result in the /// debug_line section. void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfLinkerObjFile &OF); + const DwarfFile &OF); /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); @@ -699,7 +686,7 @@ void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit); /// Patch the frame info for an object file and emit it. - void patchFrameInfoForObject(const DwarfLinkerObjFile &, RangesTy &Ranges, + void patchFrameInfoForObject(const DwarfFile &, RangesTy &Ranges, DWARFContext &, unsigned AddressSize); /// FoldingSet that uniques the abbreviations. diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -21,7 +21,6 @@ #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -47,7 +46,7 @@ /// 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 DWARFLinker::resolveDIEReference(const DwarfLinkerObjFile &OF, +DWARFDie DWARFLinker::resolveDIEReference(const DwarfFile &OF, const UnitListTy &Units, const DWARFFormValue &RefValue, const DWARFDie &DIE, @@ -367,8 +366,8 @@ /// \returns updated TraversalFlags. unsigned DWARFLinker::shouldKeepSubprogramDIE( AddressesMap &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE, - const DwarfLinkerObjFile &OF, CompileUnit &Unit, - CompileUnit::DIEInfo &MyInfo, unsigned Flags) { + const DwarfFile &OF, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, + unsigned Flags) { const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); Flags |= TF_InFunctionScope; @@ -429,8 +428,7 @@ /// Check if a DIE should be kept. /// \returns updated TraversalFlags. unsigned DWARFLinker::shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, - const DwarfLinkerObjFile &OF, + const DWARFDie &DIE, const DwarfFile &OF, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags) { @@ -538,7 +536,7 @@ /// kept. All DIEs referenced though attributes should be kept. void DWARFLinker::lookForRefDIEsToKeep( const DWARFDie &Die, CompileUnit &CU, unsigned Flags, - const UnitListTy &Units, const DwarfLinkerObjFile &OF, + const UnitListTy &Units, const DwarfFile &OF, SmallVectorImpl &Worklist) { bool UseOdr = (Flags & DWARFLinker::TF_DependencyWalk) ? (Flags & DWARFLinker::TF_ODR) @@ -647,8 +645,7 @@ /// The return value indicates whether the DIE is incomplete. void DWARFLinker::lookForDIEsToKeep(AddressesMap &AddressesMap, RangesTy &Ranges, const UnitListTy &Units, - const DWARFDie &Die, - const DwarfLinkerObjFile &OF, + const DWARFDie &Die, const DwarfFile &OF, CompileUnit &Cu, unsigned Flags) { // LIFO work list. SmallVector Worklist; @@ -786,7 +783,7 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute( DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec, - unsigned AttrSize, const DWARFFormValue &Val, const DwarfLinkerObjFile &OF, + unsigned AttrSize, const DWARFFormValue &Val, const DwarfFile &OF, CompileUnit &Unit) { const DWARFUnit &U = Unit.getOrigUnit(); uint64_t Ref = *Val.getAsReference(); @@ -858,9 +855,8 @@ } void DWARFLinker::DIECloner::cloneExpression( - DataExtractor &Data, DWARFExpression Expression, - const DwarfLinkerObjFile &OF, CompileUnit &Unit, - SmallVectorImpl &OutputBuffer) { + DataExtractor &Data, DWARFExpression Expression, const DwarfFile &OF, + CompileUnit &Unit, SmallVectorImpl &OutputBuffer) { using Encoding = DWARFExpression::Operation::Encoding; uint64_t OpOffset = 0; @@ -919,9 +915,8 @@ } unsigned DWARFLinker::DIECloner::cloneBlockAttribute( - DIE &Die, const DwarfLinkerObjFile &OF, CompileUnit &Unit, - AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, - bool IsLittleEndian) { + DIE &Die, const DwarfFile &OF, CompileUnit &Unit, AttributeSpec AttrSpec, + const DWARFFormValue &Val, unsigned AttrSize, bool IsLittleEndian) { DIEValueList *Attr; DIEValue Value; DIELoc *Loc = nullptr; @@ -1027,9 +1022,9 @@ } unsigned DWARFLinker::DIECloner::cloneScalarAttribute( - DIE &Die, const DWARFDie &InputDIE, const DwarfLinkerObjFile &OF, - CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, - unsigned AttrSize, AttributesInfo &Info) { + DIE &Die, const DWARFDie &InputDIE, const DwarfFile &OF, CompileUnit &Unit, + AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, + AttributesInfo &Info) { uint64_t Value; if (LLVM_UNLIKELY(Linker.Options.Update)) { @@ -1095,8 +1090,8 @@ /// value \p Val, and add it to \p Die. /// \returns the size of the cloned attribute. unsigned DWARFLinker::DIECloner::cloneAttribute( - DIE &Die, const DWARFDie &InputDIE, const DwarfLinkerObjFile &OF, - CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val, + DIE &Die, const DWARFDie &InputDIE, const DwarfFile &OF, CompileUnit &Unit, + OffsetsStringPool &StringPool, const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info, bool IsLittleEndian) { const DWARFUnit &U = Unit.getOrigUnit(); @@ -1212,10 +1207,12 @@ } } -DIE *DWARFLinker::DIECloner::cloneDIE( - const DWARFDie &InputDIE, const DwarfLinkerObjFile &OF, CompileUnit &Unit, - OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset, - unsigned Flags, bool IsLittleEndian, DIE *Die) { +DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE, + const DwarfFile &OF, CompileUnit &Unit, + OffsetsStringPool &StringPool, + int64_t PCOffset, uint32_t OutOffset, + unsigned Flags, bool IsLittleEndian, + DIE *Die) { DWARFUnit &U = Unit.getOrigUnit(); unsigned Idx = U.getDIEIndex(InputDIE); CompileUnit::DIEInfo &Info = Unit.getInfo(Idx); @@ -1419,7 +1416,7 @@ /// to point at the new entries. void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfLinkerObjFile &OF) const { + const DwarfFile &OF) const { DWARFDebugRangeList RangeList; const auto &FunctionRanges = Unit.getFunctionRanges(); unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); @@ -1526,7 +1523,7 @@ /// are present in the binary. void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfLinkerObjFile &OF) { + const DwarfFile &OF) { DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list)); if (!StmtList) @@ -1726,8 +1723,7 @@ /// This is actually pretty easy as the data of the CIEs and FDEs can /// be considered as black boxes and moved as is. The only thing to do /// is to patch the addresses in the headers. -void DWARFLinker::patchFrameInfoForObject(const DwarfLinkerObjFile &OF, - RangesTy &Ranges, +void DWARFLinker::patchFrameInfoForObject(const DwarfFile &OF, RangesTy &Ranges, DWARFContext &OrigDwarf, unsigned AddrSize) { StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data; @@ -1821,10 +1817,10 @@ Linker.assignAbbrev(Copy); } -uint32_t -DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, - const DwarfLinkerObjFile &OF, - int ChildRecurseDepth) { +uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, + CompileUnit &U, + const DwarfFile &OF, + int ChildRecurseDepth) { const char *Name = nullptr; DWARFUnit *OrigUnit = &U.getOrigUnit(); CompileUnit *CU = &U; @@ -1876,7 +1872,7 @@ } bool DWARFLinker::registerModuleReference( - DWARFDie CUDie, const DWARFUnit &Unit, const DwarfLinkerObjFile &OF, + DWARFDie CUDie, const DWARFUnit &Unit, const DwarfFile &OF, OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian, unsigned Indent, bool Quiet) { @@ -1933,7 +1929,7 @@ Error DWARFLinker::loadClangModule( DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId, - const DwarfLinkerObjFile &OF, OffsetsStringPool &StringPool, + const DwarfFile &OF, OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian, unsigned Indent, bool Quiet) { @@ -1954,10 +1950,7 @@ std::unique_ptr Unit; - // Setup access to the debug info. - auto DwarfContext = DWARFContext::create(*ErrOrObj->ObjFile); - - for (const auto &CU : DwarfContext->compile_units()) { + for (const auto &CU : ErrOrObj->Dwarf->compile_units()) { updateDwarfVersion(CU->getVersion()); // Recursively get all modules imported by this one. auto CUDie = CU->getUnitDIE(false); @@ -2015,12 +2008,12 @@ assert(TheDwarfEmitter); DIECloner(*this, TheDwarfEmitter, *ErrOrObj, DIEAlloc, CompileUnits, Options.Update) - .cloneAllCompileUnits(*DwarfContext, OF, StringPool, IsLittleEndian); + .cloneAllCompileUnits(*(ErrOrObj->Dwarf), OF, StringPool, IsLittleEndian); return Error::success(); } void DWARFLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext, - const DwarfLinkerObjFile &OF, + const DwarfFile &OF, OffsetsStringPool &StringPool, bool IsLittleEndian) { uint64_t OutputDebugInfoSize = @@ -2110,11 +2103,10 @@ } } -bool DWARFLinker::emitPaperTrailWarnings(const DwarfLinkerObjFile &OF, +bool DWARFLinker::emitPaperTrailWarnings(const DwarfFile &OF, OffsetsStringPool &StringPool) { - if (OF.Warnings.empty() || (OF.ObjFile && (OF.ObjFile->symbols().begin() != - OF.ObjFile->symbols().end()))) + if (OF.Warnings.empty()) return false; DIE *CUDie = DIE::get(DIEAlloc, dwarf::DW_TAG_compile_unit); @@ -2174,20 +2166,25 @@ return true; } -void DWARFLinker::copyInvariantDebugSection(const object::ObjectFile &Obj) { +void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) { if (!needToTranslateStrings()) - TheDwarfEmitter->emitSectionContents(Obj, "debug_line"); - TheDwarfEmitter->emitSectionContents(Obj, "debug_loc"); - TheDwarfEmitter->emitSectionContents(Obj, "debug_ranges"); - TheDwarfEmitter->emitSectionContents(Obj, "debug_frame"); - TheDwarfEmitter->emitSectionContents(Obj, "debug_aranges"); + TheDwarfEmitter->emitSectionContents( + Dwarf.getDWARFObj().getLineSection().Data, "debug_line"); + TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data, + "debug_loc"); + TheDwarfEmitter->emitSectionContents( + Dwarf.getDWARFObj().getRangesSection().Data, "debug_ranges"); + TheDwarfEmitter->emitSectionContents( + Dwarf.getDWARFObj().getFrameSection().Data, "debug_frame"); + TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(), + "debug_aranges"); } -void DWARFLinker::addObjectFile(DwarfLinkerObjFile &ObjFile) { - ObjectContexts.emplace_back(LinkContext(ObjFile)); +void DWARFLinker::addObjectFile(DwarfFile &File) { + ObjectContexts.emplace_back(LinkContext(File)); - if (ObjectContexts.back().DwarfContext) - updateAccelKind(*ObjectContexts.back().DwarfContext); + if (ObjectContexts.back().File.Dwarf) + updateAccelKind(*ObjectContexts.back().File.Dwarf); } bool DWARFLinker::link() { @@ -2228,23 +2225,22 @@ for (LinkContext &OptContext : ObjectContexts) { if (Options.Verbose) { if (DwarfLinkerClientID == DwarfLinkerClient::Dsymutil) - outs() << "DEBUG MAP OBJECT: " << OptContext.ObjectFile.FileName - << "\n"; + outs() << "DEBUG MAP OBJECT: " << OptContext.File.FileName << "\n"; else - outs() << "OBJECT FILE: " << OptContext.ObjectFile.FileName << "\n"; + outs() << "OBJECT FILE: " << OptContext.File.FileName << "\n"; } - if (emitPaperTrailWarnings(OptContext.ObjectFile, OffsetsStringPool)) + if (emitPaperTrailWarnings(OptContext.File, OffsetsStringPool)) continue; - if (!OptContext.ObjectFile.ObjFile) + if (!OptContext.File.Dwarf) continue; // Look for relocations that correspond to address map entries. // there was findvalidrelocations previously ... probably we need to gather // info here if (LLVM_LIKELY(!Options.Update) && - !OptContext.ObjectFile.Addresses->hasValidRelocs()) { + !OptContext.File.Addresses->hasValidRelocs()) { if (Options.Verbose) outs() << "No valid relocations found. Skipping.\n"; @@ -2255,14 +2251,14 @@ } // Setup access to the debug info. - if (!OptContext.DwarfContext) + if (!OptContext.File.Dwarf) continue; // In a first phase, just read in the debug info and load all clang modules. OptContext.CompileUnits.reserve( - OptContext.DwarfContext->getNumCompileUnits()); + OptContext.File.Dwarf->getNumCompileUnits()); - for (const auto &CU : OptContext.DwarfContext->compile_units()) { + for (const auto &CU : OptContext.File.Dwarf->compile_units()) { updateDwarfVersion(CU->getVersion()); auto CUDie = CU->getUnitDIE(false); if (Options.Verbose) { @@ -2273,10 +2269,9 @@ CUDie.dump(outs(), 0, DumpOpts); } if (CUDie && !LLVM_UNLIKELY(Options.Update)) - registerModuleReference(CUDie, *CU, OptContext.ObjectFile, - OffsetsStringPool, UniquingStringPool, - ODRContexts, 0, UnitID, - OptContext.DwarfContext->isLittleEndian()); + registerModuleReference(CUDie, *CU, OptContext.File, OffsetsStringPool, + UniquingStringPool, ODRContexts, 0, UnitID, + OptContext.File.Dwarf->isLittleEndian()); } } @@ -2303,10 +2298,10 @@ auto AnalyzeLambda = [&](size_t I) { auto &Context = ObjectContexts[I]; - if (Context.Skip || !Context.DwarfContext) + if (Context.Skip || !Context.File.Dwarf) return; - for (const auto &CU : Context.DwarfContext->compile_units()) { + for (const auto &CU : Context.File.Dwarf->compile_units()) { updateDwarfVersion(CU->getVersion()); // The !registerModuleReference() condition effectively skips // over fully resolved skeleton units. This second pass of @@ -2316,10 +2311,9 @@ bool Quiet = true; auto CUDie = CU->getUnitDIE(false); if (!CUDie || LLVM_UNLIKELY(Options.Update) || - !registerModuleReference(CUDie, *CU, Context.ObjectFile, - OffsetsStringPool, UniquingStringPool, - ODRContexts, ModulesEndOffset, UnitID, - Quiet)) { + !registerModuleReference(CUDie, *CU, Context.File, OffsetsStringPool, + UniquingStringPool, ODRContexts, + ModulesEndOffset, UnitID, Quiet)) { Context.CompileUnits.push_back(std::make_unique( *CU, UnitID++, !Options.NoODR && !Options.Update, "")); } @@ -2335,7 +2329,7 @@ UniquingStringPool, ODRContexts, ModulesEndOffset, Options.ParseableSwiftInterfaces, [&](const Twine &Warning, const DWARFDie &DIE) { - reportWarning(Warning, Context.ObjectFile, &DIE); + reportWarning(Warning, Context.File, &DIE); }); } }; @@ -2346,7 +2340,7 @@ // than those processed by analyzeContextInfo. auto CloneLambda = [&](size_t I) { auto &OptContext = ObjectContexts[I]; - if (OptContext.Skip || !OptContext.ObjectFile.ObjFile) + if (OptContext.Skip || !OptContext.File.Dwarf) return; // Then mark all the DIEs that need to be present in the generated output @@ -2357,33 +2351,32 @@ if (LLVM_UNLIKELY(Options.Update)) { for (auto &CurrentUnit : OptContext.CompileUnits) CurrentUnit->markEverythingAsKept(); - copyInvariantDebugSection(*OptContext.ObjectFile.ObjFile); + copyInvariantDebugSection(*OptContext.File.Dwarf); } else { for (auto &CurrentUnit : OptContext.CompileUnits) - lookForDIEsToKeep( - *OptContext.ObjectFile.Addresses, - OptContext.ObjectFile.Addresses->getValidAddressRanges(), - OptContext.CompileUnits, CurrentUnit->getOrigUnit().getUnitDIE(), - OptContext.ObjectFile, *CurrentUnit, 0); + lookForDIEsToKeep(*OptContext.File.Addresses, + OptContext.File.Addresses->getValidAddressRanges(), + OptContext.CompileUnits, + CurrentUnit->getOrigUnit().getUnitDIE(), + OptContext.File, *CurrentUnit, 0); } // The calls to applyValidRelocs inside cloneDIE will walk the reloc // array again (in the same way findValidRelocsInDebugInfo() did). We // need to reset the NextValidReloc index to the beginning. - if (OptContext.ObjectFile.Addresses->hasValidRelocs() || + if (OptContext.File.Addresses->hasValidRelocs() || LLVM_UNLIKELY(Options.Update)) { - DIECloner(*this, TheDwarfEmitter, OptContext.ObjectFile, DIEAlloc, + DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc, OptContext.CompileUnits, Options.Update) - .cloneAllCompileUnits(*OptContext.DwarfContext, OptContext.ObjectFile, + .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File, OffsetsStringPool, - OptContext.DwarfContext->isLittleEndian()); + OptContext.File.Dwarf->isLittleEndian()); } if (!Options.NoOutput && !OptContext.CompileUnits.empty() && LLVM_LIKELY(!Options.Update)) patchFrameInfoForObject( - OptContext.ObjectFile, - OptContext.ObjectFile.Addresses->getValidAddressRanges(), - *OptContext.DwarfContext, + OptContext.File, OptContext.File.Addresses->getValidAddressRanges(), + *OptContext.File.Dwarf, OptContext.CompileUnits[0]->getOrigUnit().getAddressByteSize()); // Clean-up before starting working on the next object. diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.h b/llvm/tools/dsymutil/DwarfLinkerForBinary.h --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.h +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.h @@ -167,15 +167,18 @@ /// Attempt to load a debug object from disk. ErrorOr loadObject(const DebugMapObject &Obj, const Triple &triple); - ErrorOr loadObject(const DebugMapObject &Obj, - const DebugMap &DebugMap, - remarks::RemarkLinker &RL); + ErrorOr loadObject(const DebugMapObject &Obj, + const DebugMap &DebugMap, + remarks::RemarkLinker &RL); raw_fd_ostream &OutFile; BinaryHolder &BinHolder; LinkOptions Options; std::unique_ptr Streamer; - std::vector> ObjectsForLinking; + std::vector> ObjectsForLinking; + std::vector> ContextForLinking; + std::vector> AddressMapForLinking; + std::vector EmptyWarnings; /// A list of all .swiftinterface files referenced by the debug /// info, mapping Module name to path on disk. The entries need to diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -252,21 +252,24 @@ return Error::success(); } -ErrorOr +ErrorOr DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, const DebugMap &DebugMap, remarks::RemarkLinker &RL) { auto ErrorOrObj = loadObject(Obj, DebugMap.getTriple()); if (ErrorOrObj) { - ObjectsForLinking.push_back( - std::unique_ptr(new DwarfLinkerObjFile( - Obj.getObjectFilename(), &*ErrorOrObj, Obj.getWarnings()))); + ContextForLinking.push_back( + std::unique_ptr(DWARFContext::create(*ErrorOrObj))); + AddressMapForLinking.push_back( + std::make_unique(*this, *ErrorOrObj, Obj)); - ObjectsForLinking.back()->Addresses.reset( - new AddressManager(*this, *ErrorOrObj, Obj)); + ObjectsForLinking.push_back(std::make_unique( + Obj.getObjectFilename(), ContextForLinking.back().get(), + AddressMapForLinking.back().get(), + Obj.empty() ? Obj.getWarnings() : EmptyWarnings)); - Error E = RL.link(*ObjectsForLinking.back()->ObjFile); + Error E = RL.link(*ErrorOrObj); if (Error NewE = handleErrors( std::move(E), [&](std::unique_ptr EC) -> Error { return remarksErrorHandler(Obj, *this, std::move(EC)); @@ -284,6 +287,8 @@ return false; ObjectsForLinking.clear(); + ContextForLinking.clear(); + AddressMapForLinking.clear(); DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath()); @@ -317,7 +322,7 @@ }); GeneralLinker.setObjFileLoader( [&DebugMap, &RL, this](StringRef ContainerName, - StringRef Path) -> ErrorOr { + StringRef Path) -> ErrorOr { auto &Obj = DebugMap.addDebugMapObject( Path, sys::TimePoint(), MachO::N_OSO); @@ -412,9 +417,9 @@ if (auto ErrorOrObj = loadObject(*Obj, Map, RL)) GeneralLinker.addObjectFile(*ErrorOrObj); else { - ObjectsForLinking.push_back( - std::unique_ptr(new DwarfLinkerObjFile( - Obj->getObjectFilename(), nullptr, Obj->getWarnings()))); + ObjectsForLinking.push_back(std::make_unique( + Obj->getObjectFilename(), nullptr, nullptr, + Obj->empty() ? Obj->getWarnings() : EmptyWarnings)); GeneralLinker.addObjectFile(*ObjectsForLinking.back()); } } diff --git a/llvm/tools/dsymutil/DwarfStreamer.h b/llvm/tools/dsymutil/DwarfStreamer.h --- a/llvm/tools/dsymutil/DwarfStreamer.h +++ b/llvm/tools/dsymutil/DwarfStreamer.h @@ -76,8 +76,7 @@ void emitPaperTrailWarningsDie(DIE &Die) override; /// Emit contents of section SecName From Obj. - void emitSectionContents(const object::ObjectFile &Obj, - StringRef SecName) override; + void emitSectionContents(StringRef SecData, StringRef SecName) override; /// Emit the string table described by \p Pool. void emitStrings(const NonRelocatableStringpool &Pool) override; @@ -118,9 +117,6 @@ /// file names and directories. void translateLineTable(DataExtractor LineData, uint64_t Offset) override; - /// Copy over the debug sections that are not modified when updating. - void copyInvariantDebugSection(const object::ObjectFile &Obj); - uint64_t getLineSectionSize() const override { return LineSectionSize; } /// Emit the .debug_pubnames contribution for \p Unit. diff --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/tools/dsymutil/DwarfStreamer.cpp --- a/llvm/tools/dsymutil/DwarfStreamer.cpp +++ b/llvm/tools/dsymutil/DwarfStreamer.cpp @@ -194,8 +194,7 @@ } /// Emit contents of section SecName From Obj. -void DwarfStreamer::emitSectionContents(const object::ObjectFile &Obj, - StringRef SecName) { +void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) { MCSection *Section = StringSwitch(SecName) .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection()) @@ -210,12 +209,7 @@ if (Section) { MS->SwitchSection(Section); - if (auto Sec = getSectionByName(Obj, SecName)) { - if (Expected E = Sec->getContents()) - MS->emitBytes(*E); - else - consumeError(E.takeError()); - } + MS->emitBytes(SecData); } } @@ -721,25 +715,6 @@ Offset = UnitEnd; } -void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj) { - if (!Options.Translator) { - MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection()); - emitSectionContents(Obj, "debug_line"); - } - - MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection()); - emitSectionContents(Obj, "debug_loc"); - - MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); - emitSectionContents(Obj, "debug_ranges"); - - MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); - emitSectionContents(Obj, "debug_frame"); - - MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); - emitSectionContents(Obj, "debug_aranges"); -} - /// Emit the pubnames or pubtypes section contribution for \p /// Unit into \p Sec. The data is provided in \p Names. void DwarfStreamer::emitPubSectionForUnit(