diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-02-16 19:10:49 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-02-16 19:10:49 +0000 |
commit | c5bd7e5db0e0dbe86cffb7611e2037c8cc6fe668 (patch) | |
tree | 4ec2bdb272fa200c73283ef5bfd666d15dde799c | |
parent | 168413e17e6af13d756e080b505d1a668f48c0fb (diff) |
Vendor import of lld release_60 branch r325330:vendor/lld/lld-release_60-r325330
Notes
Notes:
svn path=/vendor/lld/dist-release_60/; revision=329402
svn path=/vendor/lld/lld-release_60-r325330/; revision=329403; tag=vendor/lld/lld-release_60-r325330
-rw-r--r-- | COFF/PDB.cpp | 55 | ||||
-rw-r--r-- | ELF/Driver.cpp | 2 | ||||
-rw-r--r-- | ELF/InputFiles.cpp | 8 | ||||
-rw-r--r-- | ELF/Options.td | 4 | ||||
-rw-r--r-- | test/COFF/pdb-type-server-missing.yaml | 7 | ||||
-rw-r--r-- | test/ELF/Inputs/mips-gp-dips-corrupt-ver.s | 14 | ||||
-rwxr-xr-x | test/ELF/Inputs/mips-gp-dips-corrupt-ver.so | bin | 0 -> 2160 bytes | |||
-rw-r--r-- | test/ELF/mips-gp-disp-ver.s | 15 | ||||
-rw-r--r-- | test/ELF/pie.s | 2 |
9 files changed, 83 insertions, 24 deletions
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp index 91a9a01db569..8ca52556ae58 100644 --- a/COFF/PDB.cpp +++ b/COFF/PDB.cpp @@ -96,10 +96,11 @@ public: /// If the object does not use a type server PDB (compiled with /Z7), we merge /// all the type and item records from the .debug$S stream and fill in the /// caller-provided ObjectIndexMap. - const CVIndexMap &mergeDebugT(ObjFile *File, CVIndexMap &ObjectIndexMap); + Expected<const CVIndexMap&> mergeDebugT(ObjFile *File, + CVIndexMap &ObjectIndexMap); - const CVIndexMap &maybeMergeTypeServerPDB(ObjFile *File, - TypeServer2Record &TS); + Expected<const CVIndexMap&> maybeMergeTypeServerPDB(ObjFile *File, + TypeServer2Record &TS); /// Add the section map and section contributions to the PDB. void addSections(ArrayRef<OutputSection *> OutputSections, @@ -140,6 +141,10 @@ private: /// Type index mappings of type server PDBs that we've loaded so far. std::map<GUID, CVIndexMap> TypeServerIndexMappings; + + /// List of TypeServer PDBs which cannot be loaded. + /// Cached to prevent repeated load attempts. + std::set<GUID> MissingTypeServerPDBs; }; } @@ -230,8 +235,8 @@ maybeReadTypeServerRecord(CVTypeArray &Types) { return std::move(TS); } -const CVIndexMap &PDBLinker::mergeDebugT(ObjFile *File, - CVIndexMap &ObjectIndexMap) { +Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File, + CVIndexMap &ObjectIndexMap) { ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T"); if (Data.empty()) return ObjectIndexMap; @@ -304,11 +309,19 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) { return std::move(NS); } -const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, - TypeServer2Record &TS) { - // First, check if we already loaded a PDB with this GUID. Return the type +Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, + TypeServer2Record &TS) { + const GUID& TSId = TS.getGuid(); + StringRef TSPath = TS.getName(); + + // First, check if the PDB has previously failed to load. + if (MissingTypeServerPDBs.count(TSId)) + return make_error<pdb::GenericError>( + pdb::generic_error_code::type_server_not_found, TSPath); + + // Second, check if we already loaded a PDB with this GUID. Return the type // index mapping if we have it. - auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()}); + auto Insertion = TypeServerIndexMappings.insert({TSId, CVIndexMap()}); CVIndexMap &IndexMap = Insertion.first->second; if (!Insertion.second) return IndexMap; @@ -319,18 +332,21 @@ const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, // Check for a PDB at: // 1. The given file path // 2. Next to the object file or archive file - auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName()); + auto ExpectedSession = tryToLoadPDB(TSId, TSPath); if (!ExpectedSession) { consumeError(ExpectedSession.takeError()); StringRef LocalPath = !File->ParentName.empty() ? File->ParentName : File->getName(); SmallString<128> Path = sys::path::parent_path(LocalPath); sys::path::append( - Path, sys::path::filename(TS.getName(), sys::path::Style::windows)); - ExpectedSession = tryToLoadPDB(TS.getGuid(), Path); + Path, sys::path::filename(TSPath, sys::path::Style::windows)); + ExpectedSession = tryToLoadPDB(TSId, Path); + } + if (auto E = ExpectedSession.takeError()) { + TypeServerIndexMappings.erase(TSId); + MissingTypeServerPDBs.emplace(TSId); + return std::move(E); } - if (auto E = ExpectedSession.takeError()) - fatal("Type server PDB was not found: " + toString(std::move(E))); auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream(); if (auto E = ExpectedTpi.takeError()) @@ -707,7 +723,16 @@ void PDBLinker::addObjFile(ObjFile *File) { // the PDB first, so that we can get the map from object file type and item // indices to PDB type and item indices. CVIndexMap ObjectIndexMap; - const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap); + auto IndexMapResult = mergeDebugT(File, ObjectIndexMap); + + // If the .debug$T sections fail to merge, assume there is no debug info. + if (!IndexMapResult) { + warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " + + toString(IndexMapResult.takeError())); + return; + } + + const CVIndexMap &IndexMap = *IndexMapResult; // Now do all live .debug$S sections. for (SectionChunk *DebugChunk : File->getDebugChunks()) { diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp index 326c7bca7122..6de8ed59e5f9 100644 --- a/ELF/Driver.cpp +++ b/ELF/Driver.cpp @@ -638,7 +638,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->Optimize = args::getInteger(Args, OPT_O, 1); Config->OrphanHandling = getOrphanHandling(Args); Config->OutputFile = Args.getLastArgValue(OPT_o); - Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false); + Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false); Config->PrintGcSections = Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); Config->Rpath = getRpath(Args); diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index f514870ca84a..ccf4b3d7673f 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -856,6 +856,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { continue; } + if (Config->EMachine == EM_MIPS) { + // FIXME: MIPS BFD linker puts _gp_disp symbol into DSO files + // and incorrectly assigns VER_NDX_LOCAL to this section global + // symbol. Here is a workaround for this bug. + if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp") + continue; + } + const Elf_Verdef *Ver = nullptr; if (VersymIndex != VER_NDX_GLOBAL) { if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) { diff --git a/ELF/Options.td b/ELF/Options.td index 20027e90aefd..735046728154 100644 --- a/ELF/Options.td +++ b/ELF/Options.td @@ -202,6 +202,8 @@ def no_gnu_unique: F<"no-gnu-unique">, def no_merge_exidx_entries: F<"no-merge-exidx-entries">, HelpText<"Disable merging .ARM.exidx entries">; +def no_pie: F<"no-pie">, HelpText<"Do not create a position independent executable">; + def no_threads: F<"no-threads">, HelpText<"Do not run the linker multi-threaded">; @@ -211,8 +213,6 @@ def no_whole_archive: F<"no-whole-archive">, def noinhibit_exec: F<"noinhibit-exec">, HelpText<"Retain the executable output file whenever it is still usable">; -def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">; - def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">, HelpText<"Do not set the text data sections to be writable">; diff --git a/test/COFF/pdb-type-server-missing.yaml b/test/COFF/pdb-type-server-missing.yaml index 91bb04f5622f..fbbb46f6b4fd 100644 --- a/test/COFF/pdb-type-server-missing.yaml +++ b/test/COFF/pdb-type-server-missing.yaml @@ -1,13 +1,10 @@ # This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an # adjacent type server PDB. Test that LLD fails gracefully on it. -# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug -# info in the object with the missing PDB. - # RUN: yaml2obj %s -o %t.obj -# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s +# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -# CHECK: error: Type server PDB was not found +# CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info. --- !COFF header: diff --git a/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s b/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s new file mode 100644 index 000000000000..42bd32a1e73a --- /dev/null +++ b/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s @@ -0,0 +1,14 @@ +# Source file for mips-gp-dips-corrupt-ver.so +# +# % cat gpdisp.ver +# LLD_1.0.0 { global: foo; }; +# +# % as mips-gp-dips-corrupt-ver.s -o mips-gp-dips-corrupt-ver.o +# % ld -shared -o mips-gp-dips-corrupt-ver.so \ +# --version-script gpdisp.ver mips-gp-dips-corrupt-ver.o + + .global foo + .text +foo: + lui $t0, %hi(_gp_disp) + addi $t0, $t0, %lo(_gp_disp) diff --git a/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so b/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so Binary files differnew file mode 100755 index 000000000000..289ffa538f0c --- /dev/null +++ b/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so diff --git a/test/ELF/mips-gp-disp-ver.s b/test/ELF/mips-gp-disp-ver.s new file mode 100644 index 000000000000..134a056a3620 --- /dev/null +++ b/test/ELF/mips-gp-disp-ver.s @@ -0,0 +1,15 @@ +# MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero +# version definition index to it. This value means 'unversioned local symbol' +# while _gp_disp is a section global symbol. We have to handle this bug +# in the LLD because BFD linker is used for building MIPS toolchain +# libraries. This test checks such handling. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so + +# REQUIRES: mips + + .global __start + .text +__start: + lw $t0, %got(foo)($gp) diff --git a/test/ELF/pie.s b/test/ELF/pie.s index 5964db5c9399..3efd6e337c64 100644 --- a/test/ELF/pie.s +++ b/test/ELF/pie.s @@ -48,7 +48,7 @@ # CHECK: Type: PT_DYNAMIC ## Check -nopie -# RUN: ld.lld -nopie %t1.o -o %t2 +# RUN: ld.lld -no-pie %t1.o -o %t2 # RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE # NOPIE-NOT: Type: SharedObject |