diff options
| author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-11-01 09:17:50 +0000 |
|---|---|---|
| committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-11-01 09:17:50 +0000 |
| commit | c4681203e1f643550ae2fa66d354ebe3d8584307 (patch) | |
| tree | bb0a08d38091fccc5a52a91e1497ea3a5b7a3a8d /lld/ELF/InputFiles.cpp | |
| parent | 251f6dd93d035cd7f5ca9fbdc097851776cc7dc8 (diff) | |
| download | bcm5719-llvm-c4681203e1f643550ae2fa66d354ebe3d8584307.tar.gz bcm5719-llvm-c4681203e1f643550ae2fa66d354ebe3d8584307.zip | |
Allow fetching source line, when multiple "AX" sections present
Differential revision: https://reviews.llvm.org/D26070
llvm-svn: 285680
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index e3e97ea588b..dadf3bbebc4 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/Module.h" #include "llvm/LTO/LTO.h" #include "llvm/MC/StringTableBuilder.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -36,13 +37,31 @@ using namespace lld::elf; std::vector<InputFile *> InputFile::Pool; -template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) { +namespace { +// In ELF object file all section addresses are zero. If we have multiple +// .text sections (when using -ffunction-section or comdat group) then +// LLVM DWARF parser will not be able to parse .debug_line correctly, unless +// we assign each section some unique address. This callback method assigns +// each section an address equal to its offset in ELF object file. +class ObjectInfo : public LoadedObjectInfo { +public: + uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override { + return static_cast<const ELFSectionRef &>(Sec).getOffset(); + } + std::unique_ptr<LoadedObjectInfo> clone() const override { + return std::unique_ptr<LoadedObjectInfo>(); + } +}; +} + +template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) { Expected<std::unique_ptr<object::ObjectFile>> Obj = object::ObjectFile::createObjectFile(F->MB); if (!Obj) return; - DWARFContextInMemory Dwarf(*Obj.get()); + ObjectInfo ObjInfo; + DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo); DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs)); DataExtractor LineData(Dwarf.getLineSection().Data, ELFT::TargetEndianness == support::little, @@ -55,7 +74,9 @@ template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) { template <class ELFT> DIHelper<ELFT>::~DIHelper() {} -template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) { +template <class ELFT> +std::string DIHelper<ELFT>::getLineInfo(InputSectionBase<ELFT> *S, + uintX_t Offset) { if (!DwarfLine) return ""; @@ -65,7 +86,12 @@ template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) { const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0); if (!LineTbl) return ""; - LineTbl->getFileLineInfoForAddress(Offset, nullptr, Spec.FLIKind, LineInfo); + + // 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) + ")" : ""; |

