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
};
}
-template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) {
- Expected<std::unique_ptr<object::ObjectFile>> Obj =
- object::ObjectFile::createObjectFile(F->MB);
- if (!Obj)
- return;
+template <class ELFT> void ObjectFile<ELFT>::initializeDwarfLine() {
+ std::unique_ptr<object::ObjectFile> Obj =
+ check(object::ObjectFile::createObjectFile(this->MB),
+ "createObjectFile failed");
ObjectInfo ObjInfo;
DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
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 <class ELFT> DIHelper<ELFT>::~DIHelper() {}
-
+// Returns source line information for a given offset
+// using DWARF debug info.
template <class ELFT>
-std::string DIHelper<ELFT>::getLineInfo(InputSectionBase<ELFT> *S,
- uintX_t Offset) {
+std::string ObjectFile<ELFT>::getLineInfo(InputSectionBase<ELFT> *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".
return makeArrayRef(this->SymbolBodies).slice(1);
}
-template <class ELFT> DIHelper<ELFT> *elf::ObjectFile<ELFT>::getDIHelper() {
- if (!DIH)
- DIH.reset(new DIHelper<ELFT>(this));
-
- return DIH.get();
-}
-
template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const {
if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo)
return MipsOptions->Reginfo->ri_gp_value;
template void BinaryFile::parse<ELF32BE>();
template void BinaryFile::parse<ELF64LE>();
template void BinaryFile::parse<ELF64BE>();
-
-template class elf::DIHelper<ELF32LE>;
-template class elf::DIHelper<ELF32BE>;
-template class elf::DIHelper<ELF64LE>;
-template class elf::DIHelper<ELF64BE>;
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 ELFT> class DIHelper {
- typedef typename ELFT::uint uintX_t;
-
-public:
- DIHelper(InputFile *F);
- ~DIHelper();
- std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
-
-private:
- std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
-};
-
// The root class of input files.
class InputFile {
public:
const Elf_Shdr *getSymbolTable() const { return this->Symtab; };
- // DI helper allows manipilating debugging information for this
- // object file. Used for error reporting.
- DIHelper<ELFT> *getDIHelper();
+ // Returns source line information for a given offset.
+ // If no information is available, returns "".
+ std::string getLineInfo(InputSectionBase<ELFT> *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
initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
void initializeSymbols();
void initializeReverseDependencies();
+ void initializeDwarfLine();
InputSectionBase<ELFT> *getRelocTarget(const Elf_Shdr &Sec);
InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec,
StringRef SectionStringTable);
// MIPS .MIPS.abiflags section defined by this file.
std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags;
- std::unique_ptr<DIHelper<ELFT>> 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<llvm::DWARFDebugLine> DwarfLine;
};
// LazyObjectFile is analogous to ArchiveFile in the sense that