diff options
| author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-10-26 11:07:09 +0000 |
|---|---|---|
| committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-10-26 11:07:09 +0000 |
| commit | b380b24e6edc83030ea6bcc815763b77cbbf9a75 (patch) | |
| tree | f3aa289b7b0d575daf4cefc57534e406532c4728 /lld/ELF/InputFiles.cpp | |
| parent | 9bcb064f1928264a7b8f1bc0352f101e418d04e4 (diff) | |
| download | bcm5719-llvm-b380b24e6edc83030ea6bcc815763b77cbbf9a75.tar.gz bcm5719-llvm-b380b24e6edc83030ea6bcc815763b77cbbf9a75.zip | |
[ELF] Better error reporting for undefined symbols
This patch make lld show following details for undefined symbol errors:
- file (line)
- file (function name)
- file (section name + offset)
Differential revision: https://reviews.llvm.org/D25826
llvm-svn: 285186
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index f03a5bdf05f..2dd34f0d5d8 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/Analysis.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/LTO/LTO.h" @@ -35,6 +36,39 @@ using namespace lld::elf; std::vector<InputFile *> InputFile::Pool; +template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) { + Expected<std::unique_ptr<object::ObjectFile>> Obj = + object::ObjectFile::createObjectFile(F->MB); + if (!Obj) + return; + + DWARFContextInMemory Dwarf(*Obj.get()); + DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs)); + 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> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) { + if (!DwarfLine) + return ""; + + DILineInfo LineInfo; + DILineInfoSpecifier Spec; + // The offset to CU is 0 (see DIHelper constructor). + const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0); + if (!LineTbl) + return ""; + LineTbl->getFileLineInfoForAddress(Offset, nullptr, Spec.FLIKind, LineInfo); + return LineInfo.Line != 0 + ? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")" + : ""; +} + // Deletes all InputFile instances created so far. void InputFile::freePool() { // Files are freed in reverse order so that files created @@ -132,6 +166,13 @@ ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() { 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; @@ -432,6 +473,8 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { int Binding = Sym->getBinding(); InputSectionBase<ELFT> *Sec = getSection(*Sym); if (Binding == STB_LOCAL) { + if (Sym->getType() == STT_FILE) + SourceFile = check(Sym->getName(this->StringTable)); if (Sym->st_shndx == SHN_UNDEF) return new (this->Alloc) Undefined(Sym->st_name, Sym->st_other, Sym->getType(), this); @@ -897,3 +940,8 @@ template InputFile *BinaryFile::createELF<ELF32LE>(); template InputFile *BinaryFile::createELF<ELF32BE>(); template InputFile *BinaryFile::createELF<ELF64LE>(); template InputFile *BinaryFile::createELF<ELF64BE>(); + +template class elf::DIHelper<ELF32LE>; +template class elf::DIHelper<ELF32BE>; +template class elf::DIHelper<ELF64LE>; +template class elf::DIHelper<ELF64BE>; |

