aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-02-16 19:10:49 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-02-16 19:10:49 +0000
commitc5bd7e5db0e0dbe86cffb7611e2037c8cc6fe668 (patch)
tree4ec2bdb272fa200c73283ef5bfd666d15dde799c
parent168413e17e6af13d756e080b505d1a668f48c0fb (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.cpp55
-rw-r--r--ELF/Driver.cpp2
-rw-r--r--ELF/InputFiles.cpp8
-rw-r--r--ELF/Options.td4
-rw-r--r--test/COFF/pdb-type-server-missing.yaml7
-rw-r--r--test/ELF/Inputs/mips-gp-dips-corrupt-ver.s14
-rwxr-xr-xtest/ELF/Inputs/mips-gp-dips-corrupt-ver.sobin0 -> 2160 bytes
-rw-r--r--test/ELF/mips-gp-disp-ver.s15
-rw-r--r--test/ELF/pie.s2
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
new file mode 100755
index 000000000000..289ffa538f0c
--- /dev/null
+++ b/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so
Binary files differ
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