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. @@ -282,8 +285,8 @@ // 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. - DWARFCache *dwarf; - llvm::once_flag initDwarfLine; + std::unique_ptr dwarf; + 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 @@ -265,8 +265,12 @@ } template void ObjFile::initializeDwarf() { - dwarf = make(std::make_unique( - std::make_unique>(this))); + dwarf = std::make_unique(std::make_unique( + std::make_unique>(this), "", + [&](Error Err) { warn(getName() + ": " + toString(std::move(Err))); }, + [&](Error Warning) { + warn(getName() + ": " + toString(std::move(Warning))); + })); } // Returns the pair of file name and line number describing location of data @@ -274,7 +278,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 +288,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 +305,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 @@ -2668,12 +2668,12 @@ uint32_t cuIdx = 0; for (std::unique_ptr &cu : dwarf.compile_units()) { if (Error e = cu->tryExtractDIEsIfNeeded(false)) { - error(toString(sec) + ": " + toString(std::move(e))); + warn(toString(sec) + ": " + toString(std::move(e))); return {}; } Expected ranges = cu->collectAddressRanges(); if (!ranges) { - error(toString(sec) + ": " + toString(ranges.takeError())); + warn(toString(sec) + ": " + toString(ranges.takeError())); return {}; } @@ -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/test/ELF/gdb-index-invalid-ranges.s b/lld/test/ELF/gdb-index-invalid-ranges.s --- a/lld/test/ELF/gdb-index-invalid-ranges.s +++ b/lld/test/ELF/gdb-index-invalid-ranges.s @@ -1,12 +1,12 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: not ld.lld --gdb-index -e main %t.o -o /dev/null 2>&1 | FileCheck %s +# RUN: ld.lld --gdb-index -e main %t.o -o /dev/null 2>&1 | FileCheck %s # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index-invalid-ranges.obj.s -o %t2.o # RUN: llvm-ar rc %t.a %t.o -# RUN: not ld.lld --gdb-index -e main %t2.o %t.a -o /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE %s +# RUN: ld.lld --gdb-index -e main %t2.o %t.a -o /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE %s -# CHECK: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10 -# ARCHIVE: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10 +# CHECK: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10 +# ARCHIVE: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10 .section .text.foo1,"ax",@progbits .globl f1 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: warning: {{.*}}:{{(\(\.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