diff options
author | Alexander Richardson <arichardson.kde@gmail.com> | 2017-11-20 15:43:20 +0000 |
---|---|---|
committer | Alexander Richardson <arichardson.kde@gmail.com> | 2017-11-20 15:43:20 +0000 |
commit | 1de78471f524e79dc77ecacbe09fada47bfd7418 (patch) | |
tree | b9fdcb325bdaf2133ff38f4a93cacd40666101af | |
parent | 24194525057b73ecc1d78b7853ce1bbd6ceaf9c2 (diff) | |
download | bcm5719-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.cpp | 8 | ||||
-rw-r--r-- | lld/ELF/Driver.h | 1 | ||||
-rw-r--r-- | lld/ELF/DriverUtils.cpp | 9 | ||||
-rw-r--r-- | lld/ELF/ScriptParser.cpp | 12 | ||||
-rw-r--r-- | lld/test/ELF/invalid-linkerscript.test | 2 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/linker-script-in-search-path.s | 19 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/linkerscript.s | 2 |
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 |