summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputFiles.cpp
diff options
context:
space:
mode:
authorEugene Leviant <evgeny.leviant@gmail.com>2016-10-26 11:07:09 +0000
committerEugene Leviant <evgeny.leviant@gmail.com>2016-10-26 11:07:09 +0000
commitb380b24e6edc83030ea6bcc815763b77cbbf9a75 (patch)
treef3aa289b7b0d575daf4cefc57534e406532c4728 /lld/ELF/InputFiles.cpp
parent9bcb064f1928264a7b8f1bc0352f101e418d04e4 (diff)
downloadbcm5719-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.cpp48
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>;
OpenPOWER on IntegriCloud