Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -43,23 +43,6 @@ class Lazy; class SymbolBody; -// Debugging information helper class. The main purpose is to -// retrieve source file and line for error reporting. Linker may -// find reasonable number of errors in a single object file, so -// we cache debugging information in order to parse it only once -// for each object file we link. -template class DIHelper { - typedef typename ELFT::uint uintX_t; - -public: - DIHelper(InputFile *F); - ~DIHelper(); - std::string getLineInfo(InputSectionBase *S, uintX_t Offset); - -private: - std::unique_ptr DwarfLine; -}; - // The root class of input files. class InputFile { public: @@ -175,9 +158,9 @@ const Elf_Shdr *getSymbolTable() const { return this->Symtab; }; - // DI helper allows manipilating debugging information for this - // object file. Used for error reporting. - DIHelper *getDIHelper(); + // Returns source line information for a given offset. + // If no information is available, returns "". + std::string getLineInfo(InputSectionBase *S, uintX_t Offset); // Get MIPS GP0 value defined by this file. This value represents the gp value // used to create the relocatable object and required to support @@ -198,6 +181,7 @@ initializeSections(llvm::DenseSet &ComdatGroups); void initializeSymbols(); void initializeReverseDependencies(); + void initializeDwarfLine(); InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); InputSectionBase *createInputSection(const Elf_Shdr &Sec, StringRef SectionStringTable); @@ -218,7 +202,11 @@ // MIPS .MIPS.abiflags section defined by this file. std::unique_ptr> MipsAbiFlags; - std::unique_ptr> DIH; + // Debugging information to retrieve source file and line for error + // reporting. Linker may find reasonable number of errors in a + // single object file, so we cache debugging information in order to + // parse it only once for each object file we link. + std::unique_ptr DwarfLine; }; // LazyObjectFile is analogous to ArchiveFile in the sense that Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -35,7 +35,6 @@ using namespace lld; using namespace lld::elf; - namespace { // In ELF object file all section addresses are zero. If we have multiple // .text sections (when using -ffunction-section or comdat group) then @@ -53,11 +52,10 @@ }; } -template DIHelper::DIHelper(InputFile *F) { - Expected> Obj = - object::ObjectFile::createObjectFile(F->MB); - if (!Obj) - return; +template void ObjectFile::initializeDwarfLine() { + std::unique_ptr Obj = + check(object::ObjectFile::createObjectFile(this->MB), + "createObjectFile failed"); ObjectInfo ObjInfo; DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo); @@ -65,35 +63,35 @@ DataExtractor LineData(Dwarf.getLineSection().Data, ELFT::TargetEndianness == support::little, ELFT::Is64Bits ? 8 : 4); + // The second parameter is offset in .debug_line section // for compilation unit (CU) of interest. We have only one // CU (object file), so offset is always 0. DwarfLine->getOrParseLineTable(LineData, 0); } -template DIHelper::~DIHelper() {} - +// Returns source line information for a given offset +// using DWARF debug info. template -std::string DIHelper::getLineInfo(InputSectionBase *S, - uintX_t Offset) { +std::string ObjectFile::getLineInfo(InputSectionBase *S, + uintX_t Offset) { if (!DwarfLine) - return ""; + initializeDwarfLine(); - DILineInfo LineInfo; - DILineInfoSpecifier Spec; - // The offset to CU is 0 (see DIHelper constructor). - const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0); - if (!LineTbl) + // The offset to CU is 0. + const DWARFDebugLine::LineTable *Tbl = DwarfLine->getLineTable(0); + if (!Tbl) return ""; // Use fake address calcuated by adding section file offset and offset in - // section. - // See comments for ObjectInfo class - LineTbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind, - LineInfo); - return LineInfo.Line != 0 - ? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")" - : ""; + // section. See comments for ObjectInfo class. + DILineInfo Info; + DILineInfoSpecifier Spec; + Tbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind, + Info); + if (Info.Line == 0) + return ""; + return Info.FileName + " (" + std::to_string(Info.Line) + ")"; } // Returns "(internal)", "foo.a(bar.o)" or "baz.o". @@ -185,13 +183,6 @@ return makeArrayRef(this->SymbolBodies).slice(1); } -template DIHelper *elf::ObjectFile::getDIHelper() { - if (!DIH) - DIH.reset(new DIHelper(this)); - - return DIH.get(); -} - template uint32_t elf::ObjectFile::getMipsGp0() const { if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo) return MipsOptions->Reginfo->ri_gp_value; @@ -968,8 +959,3 @@ template void BinaryFile::parse(); template void BinaryFile::parse(); template void BinaryFile::parse(); - -template class elf::DIHelper; -template class elf::DIHelper; -template class elf::DIHelper; -template class elf::DIHelper; Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -544,7 +544,7 @@ ObjectFile *File = S.getFile(); // First check if we can get desired values from debugging information. - std::string LineInfo = File->getDIHelper()->getLineInfo(&S, Offset); + std::string LineInfo = File->getLineInfo(&S, Offset); if (!LineInfo.empty()) return LineInfo;