[lld] r318655 - [ELF] Fall back to search dirs for linker scripts specified with -T

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 07:43:20 PST 2017


Author: arichardson
Date: Mon Nov 20 07:43:20 2017
New Revision: 318655

URL: http://llvm.org/viewvc/llvm-project?rev=318655&view=rev
Log:
[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

Added:
    lld/trunk/test/ELF/linkerscript/linker-script-in-search-path.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Driver.h
    lld/trunk/ELF/DriverUtils.cpp
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/test/ELF/invalid-linkerscript.test
    lld/trunk/test/ELF/linkerscript/linkerscript.s

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Nov 20 07:43:20 2017
@@ -862,8 +862,12 @@ void LinkerDriver::createFiles(opt::Inpu
       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;

Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Mon Nov 20 07:43:20 2017
@@ -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

Modified: lld/trunk/ELF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DriverUtils.cpp?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/ELF/DriverUtils.cpp (original)
+++ lld/trunk/ELF/DriverUtils.cpp Mon Nov 20 07:43:20 2017
@@ -207,3 +207,12 @@ Optional<std::string> elf::searchLibrary
   }
   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);
+}

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Mon Nov 20 07:43:20 2017
@@ -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() {

Modified: lld/trunk/test/ELF/invalid-linkerscript.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/invalid-linkerscript.test?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/test/ELF/invalid-linkerscript.test (original)
+++ lld/trunk/test/ELF/invalid-linkerscript.test Mon Nov 20 07:43:20 2017
@@ -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

Added: lld/trunk/test/ELF/linkerscript/linker-script-in-search-path.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linker-script-in-search-path.s?rev=318655&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linker-script-in-search-path.s (added)
+++ lld/trunk/test/ELF/linkerscript/linker-script-in-search-path.s Mon Nov 20 07:43:20 2017
@@ -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

Modified: lld/trunk/test/ELF/linkerscript/linkerscript.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript.s?rev=318655&r1=318654&r2=318655&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript.s (original)
+++ lld/trunk/test/ELF/linkerscript/linkerscript.s Mon Nov 20 07:43:20 2017
@@ -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
 




More information about the llvm-commits mailing list