summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Richardson <arichardson.kde@gmail.com>2017-11-20 15:43:20 +0000
committerAlexander Richardson <arichardson.kde@gmail.com>2017-11-20 15:43:20 +0000
commit1de78471f524e79dc77ecacbe09fada47bfd7418 (patch)
treeb9fdcb325bdaf2133ff38f4a93cacd40666101af
parent24194525057b73ecc1d78b7853ce1bbd6ceaf9c2 (diff)
downloadbcm5719-llvm-1de78471f524e79dc77ecacbe09fada47bfd7418.tar.gz
bcm5719-llvm-1de78471f524e79dc77ecacbe09fada47bfd7418.zip
[ELF] Fall back to search dirs for linker scripts specified with -T
Summary: This matches the behaviour of ld.bfd: https://sourceware.org/binutils/docs/ld/Options.html#Options If scriptfile does not exist in the current directory, ld looks for it in the directories specified by any preceding '-L' options. Multiple '-T' options accumulate. Reviewers: ruiu, grimar Reviewed By: ruiu, grimar Subscribers: emaste, llvm-commits Differential Revision: https://reviews.llvm.org/D40129 llvm-svn: 318655
-rw-r--r--lld/ELF/Driver.cpp8
-rw-r--r--lld/ELF/Driver.h1
-rw-r--r--lld/ELF/DriverUtils.cpp9
-rw-r--r--lld/ELF/ScriptParser.cpp12
-rw-r--r--lld/test/ELF/invalid-linkerscript.test2
-rw-r--r--lld/test/ELF/linkerscript/linker-script-in-search-path.s19
-rw-r--r--lld/test/ELF/linkerscript/linkerscript.s2
7 files changed, 39 insertions, 14 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a2e4559bab3..e8d3639483b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -862,8 +862,12 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
addFile(Arg->getValue(), /*WithLOption=*/false);
break;
case OPT_script:
- if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue()))
- readLinkerScript(*MB);
+ if (Optional<std::string> Path = searchLinkerScript(Arg->getValue())) {
+ if (Optional<MemoryBufferRef> MB = readFile(*Path))
+ readLinkerScript(*MB);
+ break;
+ }
+ error(Twine("cannot find linker script ") + Arg->getValue());
break;
case OPT_as_needed:
Config->AsNeeded = true;
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 617dcb2001b..351d7926de7 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -67,6 +67,7 @@ void printHelp(const char *Argv0);
std::string createResponseFile(const llvm::opt::InputArgList &Args);
llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
+llvm::Optional<std::string> searchLinkerScript(StringRef Path);
llvm::Optional<std::string> searchLibrary(StringRef Path);
} // namespace elf
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index ca13b309c4a..901760c439a 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -207,3 +207,12 @@ Optional<std::string> elf::searchLibrary(StringRef Name) {
}
return None;
}
+
+// If a linker script doesn't exist in the current directory, we also look for
+// the script in the '-L' search paths. This matches the behaviour of both '-T'
+// and linker script INPUT() directives in ld.bfd.
+Optional<std::string> elf::searchLinkerScript(StringRef Name) {
+ if (fs::exists(Name))
+ return Name.str();
+ return findFromSearchPaths(Name);
+}
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 8dd23668b7a..8130f27a53e 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -350,20 +350,12 @@ void ScriptParser::readInclude() {
return;
}
- // https://sourceware.org/binutils/docs/ld/File-Commands.html:
- // The file will be searched for in the current directory, and in any
- // directory specified with the -L option.
- if (sys::fs::exists(Tok)) {
- if (Optional<MemoryBufferRef> MB = readFile(Tok))
- tokenize(*MB);
- return;
- }
- if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
+ if (Optional<std::string> Path = searchLinkerScript(Tok)) {
if (Optional<MemoryBufferRef> MB = readFile(*Path))
tokenize(*MB);
return;
}
- setError("cannot open " + Tok);
+ setError("cannot find linker script " + Tok);
}
void ScriptParser::readOutput() {
diff --git a/lld/test/ELF/invalid-linkerscript.test b/lld/test/ELF/invalid-linkerscript.test
index 280686eff41..f9fb8478251 100644
--- a/lld/test/ELF/invalid-linkerscript.test
+++ b/lld/test/ELF/invalid-linkerscript.test
@@ -45,7 +45,7 @@
# RUN: echo "INCLUDE /no/such/file" > %t7
# RUN: not ld.lld %t7 no-such-file 2>&1 | FileCheck -check-prefix=ERR7 %s
-# ERR7: cannot open /no/such/file
+# ERR7: cannot find linker script /no/such/file
# ERR7: cannot open no-such-file:
# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
diff --git a/lld/test/ELF/linkerscript/linker-script-in-search-path.s b/lld/test/ELF/linkerscript/linker-script-in-search-path.s
new file mode 100644
index 00000000000..be83b55b899
--- /dev/null
+++ b/lld/test/ELF/linkerscript/linker-script-in-search-path.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+# Check that we fall back to search paths if a linker script was not found
+# This behaviour matches ld.bfd and various projects appear to rely on this
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: mkdir -p %T/searchpath
+# RUN: echo "OUTPUT(\"%t.out\")" > %T/searchpath/foo.script
+# RUN: ld.lld -T%T/searchpath/foo.script %t.o
+# RUN: llvm-readobj %t.out | FileCheck %s
+# CHECK: Format: ELF64-x86-64
+
+# If the linker script specified with -T is missing we should emit an error
+# RUN: not ld.lld -Tfoo.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR
+# ERROR: error: cannot find linker script foo.script
+
+# But if it exists in the search path we should fall back to that instead:
+# RUN: rm %t.out
+# RUN: ld.lld -L %T/searchpath -Tfoo.script %t.o
+# RUN: llvm-readobj %t.out | FileCheck %s
diff --git a/lld/test/ELF/linkerscript/linkerscript.s b/lld/test/ELF/linkerscript/linkerscript.s
index 7c8a5cbed2c..6a239ea57c8 100644
--- a/lld/test/ELF/linkerscript/linkerscript.s
+++ b/lld/test/ELF/linkerscript/linkerscript.s
@@ -37,7 +37,7 @@
# RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script
# RUN: not ld.lld %t.script > %t.log 2>&1
# RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log
-# INCLUDE_ERR: error: {{.+}}.script:1: cannot open foo.script
+# INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script
# INCLUDE_ERR-NEXT: INCLUDE "foo.script"
# RUN: ld.lld -L %T %t.script %t
OpenPOWER on IntegriCloud