diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp --- a/lld/Common/ErrorHandler.cpp +++ b/lld/Common/ErrorHandler.cpp @@ -177,7 +177,7 @@ sep = getSeparator(msg); } -void ErrorHandler::error(const Twine &msg) { +void ErrorHandler::error(const Twine &msg, bool isRecoverableError) { // If Visual Studio-style error message mode is enabled, // this particular error is printed out as two errors. if (vsDiagnostics) { @@ -209,7 +209,9 @@ } sep = getSeparator(msg); - ++errorCount; + + if (!isRecoverableError) + ++errorCount; } if (exit) diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -16,6 +16,7 @@ #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/IR/Comdat.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ELF.h" @@ -224,6 +225,8 @@ llvm::Optional getDILineInfo(InputSectionBase *, uint64_t); llvm::Optional> getVariableLoc(StringRef name); + llvm::DWARFContext *getDWARFContext(); + // MIPS GP0 value defined by this file. This value represents the gp value // used to create the relocatable object and required to support // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. @@ -283,7 +286,7 @@ // single object file, so we cache debugging information in order to // parse it only once for each object file we link. DWARFCache *dwarf; - llvm::once_flag initDwarfLine; + llvm::once_flag initDwarf; }; // LazyObjFile is analogous to ArchiveFile in the sense that diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -266,7 +266,13 @@ template void ObjFile::initializeDwarf() { dwarf = make(std::make_unique( - std::make_unique>(this))); + std::make_unique>(this), "", + [&](Error Err) { + error(getName() + ": " + toString(std::move(Err)), true); + }, + [&](Error Warning) { + warn(getName() + ": " + toString(std::move(Warning))); + })); } // Returns the pair of file name and line number describing location of data @@ -274,7 +280,7 @@ template Optional> ObjFile::getVariableLoc(StringRef name) { - llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); }); + llvm::call_once(initDwarf, [this]() { initializeDwarf(); }); return dwarf->getVariableLoc(name); } @@ -284,7 +290,7 @@ template Optional ObjFile::getDILineInfo(InputSectionBase *s, uint64_t offset) { - llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); }); + llvm::call_once(initDwarf, [this]() { initializeDwarf(); }); // Detect SectionIndex for specified section. uint64_t sectionIndex = object::SectionedAddress::UndefSection; @@ -301,6 +307,12 @@ return dwarf->getDILineInfo(s->getOffsetInFile() + offset, sectionIndex); } +template llvm::DWARFContext *ObjFile::getDWARFContext() { + llvm::call_once(initDwarf, [this]() { initializeDwarf(); }); + + return dwarf->getContext(); +} + ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) { ekind = getELFKind(mb, ""); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2820,14 +2820,13 @@ std::vector> nameAttrs(sections.size()); parallelForEachN(0, sections.size(), [&](size_t i) { - ObjFile *file = sections[i]->getFile(); - DWARFContext dwarf(std::make_unique>(file)); + DWARFContext *dwarf = sections[i]->getFile()->getDWARFContext(); chunks[i].sec = sections[i]; - chunks[i].compilationUnits = readCuList(dwarf); - chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]); + chunks[i].compilationUnits = readCuList(*dwarf); + chunks[i].addressAreas = readAddressAreas(*dwarf, sections[i]); nameAttrs[i] = readPubNamesAndTypes( - static_cast &>(dwarf.getDWARFObj()), + static_cast &>(dwarf->getDWARFObj()), chunks[i].compilationUnits); }); diff --git a/lld/include/lld/Common/DWARF.h b/lld/include/lld/Common/DWARF.h --- a/lld/include/lld/Common/DWARF.h +++ b/lld/include/lld/Common/DWARF.h @@ -31,6 +31,8 @@ llvm::Optional> getVariableLoc(StringRef name); + llvm::DWARFContext *getContext() { return dwarf.get(); } + private: std::unique_ptr dwarf; std::vector lineTables; diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h --- a/lld/include/lld/Common/ErrorHandler.h +++ b/lld/include/lld/Common/ErrorHandler.h @@ -100,7 +100,7 @@ bool verbose = false; bool vsDiagnostics = false; - void error(const Twine &msg); + void error(const Twine &msg, bool isRecoverableError = false); LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg); void log(const Twine &msg); void message(const Twine &msg); @@ -117,7 +117,9 @@ /// Returns the default error handler. ErrorHandler &errorHandler(); -inline void error(const Twine &msg) { errorHandler().error(msg); } +inline void error(const Twine &msg, bool isRecoverableError = false) { + errorHandler().error(msg, isRecoverableError); +} inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg) { errorHandler().fatal(msg); } diff --git a/lld/test/ELF/gdb-index-parse-fail.s b/lld/test/ELF/gdb-index-parse-fail.s --- a/lld/test/ELF/gdb-index-parse-fail.s +++ b/lld/test/ELF/gdb-index-parse-fail.s @@ -1,8 +1,8 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o -# RUN: not ld.lld --gdb-index %t1.o -o /dev/null 2>&1 | FileCheck %s +# RUN: ld.lld --gdb-index %t1.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: error: {{.*}}:(.debug_info): invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix +# CHECK: error: {{.*}}:{{(\(\.debug_info\):)?}} invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix .section .debug_abbrev,"",@progbits .byte 1 # Abbreviation Code