[lld] r249967 - ELF2: LinkerScript: Interpret -l and = file name prefixes.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 10 20:28:42 PDT 2015


Author: ruiu
Date: Sat Oct 10 22:28:42 2015
New Revision: 249967

URL: http://llvm.org/viewvc/llvm-project?rev=249967&view=rev
Log:
ELF2: LinkerScript: Interpret -l and = file name prefixes.

In the linker script, -l and = have the same meaning as in the command line.
In addition to that, if a path is not absolute, the path needs to be searched
from the search paths. This patch implements them.

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Driver.h
    lld/trunk/ELF/DriverUtils.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/elf2/linkerscript.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Sat Oct 10 22:28:42 2015
@@ -38,7 +38,7 @@ struct Configuration {
   llvm::StringRef SoName;
   llvm::StringRef Sysroot;
   std::string RPath;
-  std::vector<llvm::StringRef> InputSearchPaths;
+  std::vector<llvm::StringRef> SearchPaths;
   bool AllowMultipleDefinition;
   bool DiscardAll;
   bool DiscardLocals;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Sat Oct 10 22:28:42 2015
@@ -134,7 +134,7 @@ void LinkerDriver::main(ArrayRef<const c
 
 void LinkerDriver::createFiles(opt::InputArgList &Args) {
   for (auto *Arg : Args.filtered(OPT_L))
-    Config->InputSearchPaths.push_back(Arg->getValue());
+    Config->SearchPaths.push_back(Arg->getValue());
 
   std::vector<StringRef> RPaths;
   for (auto *Arg : Args.filtered(OPT_rpath))

Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Sat Oct 10 22:28:42 2015
@@ -65,6 +65,7 @@ enum {
 // Parses a linker script. Calling this function updates the Symtab and Config.
 void readLinkerScript(llvm::BumpPtrAllocator *A, MemoryBufferRef MB);
 
+std::string findFromSearchPaths(StringRef Path);
 std::string searchLibrary(StringRef Path);
 std::string buildSysrootedPath(llvm::StringRef Dir, llvm::StringRef File);
 

Modified: lld/trunk/ELF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DriverUtils.cpp?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/ELF/DriverUtils.cpp (original)
+++ lld/trunk/ELF/DriverUtils.cpp Sat Oct 10 22:28:42 2015
@@ -78,6 +78,15 @@ opt::InputArgList ArgParser::parse(Array
   return Args;
 }
 
+std::string lld::elf2::findFromSearchPaths(StringRef Path) {
+  for (StringRef Dir : Config->SearchPaths) {
+    std::string FullPath = buildSysrootedPath(Dir, Path);
+    if (sys::fs::exists(FullPath))
+      return FullPath;
+  }
+  return "";
+}
+
 // Searches a given library from input search paths, which are filled
 // from -L command line switches. Returns a path to an existent library file.
 std::string lld::elf2::searchLibrary(StringRef Path) {
@@ -89,12 +98,10 @@ std::string lld::elf2::searchLibrary(Str
       Names.push_back(("lib" + Path + ".so").str());
     Names.push_back(("lib" + Path + ".a").str());
   }
-  for (StringRef Dir : Config->InputSearchPaths) {
-    for (const std::string &Name : Names) {
-      std::string FullPath = buildSysrootedPath(Dir, Name);
-      if (sys::fs::exists(FullPath))
-        return FullPath;
-    }
+  for (const std::string &Name : Names) {
+    std::string S = findFromSearchPaths(Name);
+    if (!S.empty())
+      return S;
   }
   error("Unable to find library -l" + Path);
 }

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Sat Oct 10 22:28:42 2015
@@ -38,6 +38,8 @@ private:
   bool atEOF() { return Tokens.size() == Pos; }
   void expect(StringRef Expect);
 
+  void addFile(StringRef Path);
+
   void readAsNeeded();
   void readEntry();
   void readGroup();
@@ -133,13 +135,31 @@ void LinkerScript::expect(StringRef Expe
     error(Expect + " expected, but got " + Tok);
 }
 
+void LinkerScript::addFile(StringRef S) {
+  if (S.startswith("/")) {
+    Driver->addFile(S);
+  } else if (S.startswith("=")) {
+    if (Config->Sysroot.empty())
+      Driver->addFile(S.substr(1));
+    else
+      Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
+  } else if (S.startswith("-l")) {
+    Driver->addFile(searchLibrary(S.substr(2)));
+  } else {
+    std::string Path = findFromSearchPaths(S);
+    if (Path.empty())
+      error("Unable to find " + S);
+    Driver->addFile(Saver.save(Path));
+  }
+}
+
 void LinkerScript::readAsNeeded() {
   expect("(");
   for (;;) {
     StringRef Tok = next();
     if (Tok == ")")
       return;
-    Driver->addFile(Tok);
+    addFile(Tok);
   }
 }
 
@@ -162,7 +182,7 @@ void LinkerScript::readGroup() {
       readAsNeeded();
       continue;
     }
-    Driver->addFile(Tok);
+    addFile(Tok);
   }
 }
 
@@ -194,7 +214,7 @@ void LinkerScript::readOutputFormat() {
 
 void LinkerScript::readSearchDir() {
   expect("(");
-  Config->InputSearchPaths.push_back(next());
+  Config->SearchPaths.push_back(next());
   expect(")");
 }
 

Modified: lld/trunk/test/elf2/linkerscript.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/linkerscript.s?rev=249967&r1=249966&r2=249967&view=diff
==============================================================================
--- lld/trunk/test/elf2/linkerscript.s (original)
+++ lld/trunk/test/elf2/linkerscript.s Sat Oct 10 22:28:42 2015
@@ -1,5 +1,10 @@
 # REQUIRES: x86
+# RUN: mkdir -p %t.dir
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN:   %p/Inputs/libsearch-st.s -o %t2.o
+# RUN: rm -f %t.dir/libxyz.a
+# RUN: llvm-ar rcs %t.dir/libxyz.a %t2.o
 
 # RUN: echo "GROUP(" %t ")" > %t.script
 # RUN: ld.lld2 -o %t2 %t.script
@@ -9,6 +14,26 @@
 # RUN: ld.lld2 -o %t2 %t.script
 # RUN: llvm-readobj %t2 > /dev/null
 
+# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script
+# RUN: not ld.lld2 -o %t2 %t.script
+# RUN: ld.lld2 -o %t2 %t.script -L%t.dir
+# RUN: llvm-readobj %t2 > /dev/null
+
+# RUN: echo "GROUP(" %t =libxyz.a ")" > %t.script
+# RUN: not ld.lld2 -o %t2 %t.script
+# RUN: ld.lld2 -o %t2 %t.script --sysroot=%t.dir
+# RUN: llvm-readobj %t2 > /dev/null
+
+# RUN: echo "GROUP(" %t -lxyz ")" > %t.script
+# RUN: not ld.lld2 -o %t2 %t.script
+# RUN: ld.lld2 -o %t2 %t.script -L%t.dir
+# RUN: llvm-readobj %t2 > /dev/null
+
+# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script
+# RUN: not ld.lld2 -o %t2 %t.script
+# RUN: ld.lld2 -o %t2 %t.script -L%t.dir
+# RUN: llvm-readobj %t2 > /dev/null
+
 # RUN: echo "GROUP(" %t.script2 ")" > %t.script1
 # RUN: echo "GROUP(" %t ")" > %t.script2
 # RUN: ld.lld2 -o %t2 %t.script1




More information about the llvm-commits mailing list