[lld] r339060 - Add TARGET(foo) linker script directive.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 6 14:29:42 PDT 2018


Author: ruiu
Date: Mon Aug  6 14:29:41 2018
New Revision: 339060

URL: http://llvm.org/viewvc/llvm-project?rev=339060&view=rev
Log:
Add TARGET(foo) linker script directive.

GNU ld's manual says that TARGET(foo) is basically an alias for
`--format foo` where foo is a BFD target name such as elf64-x86-64.

Unlike GNU linkers, lld doesn't allow arbitrary BFD target name for
--format. We accept only "default", "elf" or "binary". This makes
situation a bit tricky because we can't simply make TARGET an alias for
--target.

A quick code search revealed that the usage number of TARGET is very
small, and the only meaningful usage is to switch to the binary mode.
Thus, in this patch, we handle only TARGET(elf.*) and TARGET(binary).

Differential Revision: https://reviews.llvm.org/D48153

Added:
    lld/trunk/test/ELF/linkerscript/target.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Driver.h
    lld/trunk/ELF/ScriptParser.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=339060&r1=339059&r2=339060&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon Aug  6 14:29:41 2018
@@ -139,6 +139,7 @@ struct Configuration {
   bool ExecuteOnly;
   bool ExportDynamic;
   bool FixCortexA53Errata843419;
+  bool FormatBinary = false;
   bool GcSections;
   bool GdbIndex;
   bool GnuHash = false;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=339060&r1=339059&r2=339060&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Aug  6 14:29:41 2018
@@ -183,7 +183,7 @@ void LinkerDriver::addFile(StringRef Pat
     return;
   MemoryBufferRef MBRef = *Buffer;
 
-  if (InBinary) {
+  if (Config->FormatBinary) {
     Files.push_back(make<BinaryFile>(MBRef));
     return;
   }
@@ -999,7 +999,7 @@ static void setConfigs(opt::InputArgList
 }
 
 // Returns a value of "-format" option.
-static bool getBinaryOption(StringRef S) {
+static bool isFormatBinary(StringRef S) {
   if (S == "binary")
     return true;
   if (S == "elf" || S == "default")
@@ -1041,7 +1041,7 @@ void LinkerDriver::createFiles(opt::Inpu
       Config->AsNeeded = true;
       break;
     case OPT_format:
-      InBinary = getBinaryOption(Arg->getValue());
+      Config->FormatBinary = isFormatBinary(Arg->getValue());
       break;
     case OPT_no_as_needed:
       Config->AsNeeded = false;

Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=339060&r1=339059&r2=339060&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Mon Aug  6 14:29:41 2018
@@ -42,9 +42,6 @@ private:
   // True if we are in --start-lib and --end-lib.
   bool InLib = false;
 
-  // True if we are in -format=binary and -format=elf.
-  bool InBinary = false;
-
   std::vector<InputFile *> Files;
 };
 

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=339060&r1=339059&r2=339060&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Mon Aug  6 14:29:41 2018
@@ -72,6 +72,7 @@ private:
   void readRegionAlias();
   void readSearchDir();
   void readSections();
+  void readTarget();
   void readVersion();
   void readVersionScriptCommand();
 
@@ -255,6 +256,8 @@ void ScriptParser::readLinkerScript() {
       readSearchDir();
     } else if (Tok == "SECTIONS") {
       readSections();
+    } else if (Tok == "TARGET") {
+      readTarget();
     } else if (Tok == "VERSION") {
       readVersion();
     } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
@@ -522,6 +525,23 @@ void ScriptParser::readSections() {
                                  V.end());
 }
 
+void ScriptParser::readTarget() {
+  // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
+  // we accept only a limited set of BFD names (i.e. "elf" or "binary")
+  // for --format. We recognize only /^elf/ and "binary" in the linker
+  // script as well.
+  expect("(");
+  StringRef Tok = next();
+  expect(")");
+
+  if (Tok.startswith("elf"))
+    Config->FormatBinary = false;
+  else if (Tok == "binary")
+    Config->FormatBinary = true;
+  else
+    setError("unknown target: " + Tok);
+}
+
 static int precedence(StringRef Op) {
   return StringSwitch<int>(Op)
       .Cases("*", "/", "%", 8)

Added: lld/trunk/test/ELF/linkerscript/target.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/target.s?rev=339060&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/target.s (added)
+++ lld/trunk/test/ELF/linkerscript/target.s Mon Aug  6 14:29:41 2018
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "TARGET(binary) INPUT(\"%t.o\") TARGET(elf64-x86-64) INPUT(\"%t.o\")" > %t.script
+# RUN: ld.lld --script %t.script -o %t.exe
+# RUN: llvm-readelf -symbols %t.exe | FileCheck %s
+
+# CHECK: _binary_
+# CHECK: foobar
+
+# RUN: echo "TARGET(foo)" > %t2.script
+# RUN: not ld.lld --script %t2.script -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s
+
+# ERR: unknown target: foo
+
+.global foobar
+foobar:
+  nop




More information about the llvm-commits mailing list