[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
This commit is contained in:
parent
2419452505
commit
1de78471f5
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue