[lld] r227786 - [ELF] Support for parsing OUTPUT command in LinkerScript

Davide Italiano davide at freebsd.org
Sun Feb 1 22:21:23 PST 2015


Author: davide
Date: Mon Feb  2 00:21:23 2015
New Revision: 227786

URL: http://llvm.org/viewvc/llvm-project?rev=227786&view=rev
Log:
[ELF] Support for parsing OUTPUT command in LinkerScript

Differential Revision:	D7326
Reviewed by:	rafaelauler, shankarke, ruiu

Modified:
    lld/trunk/include/lld/ReaderWriter/LinkerScript.h
    lld/trunk/lib/ReaderWriter/LinkerScript.cpp
    lld/trunk/test/LinkerScript/linker-script.test

Modified: lld/trunk/include/lld/ReaderWriter/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/LinkerScript.h?rev=227786&r1=227785&r2=227786&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/LinkerScript.h (original)
+++ lld/trunk/include/lld/ReaderWriter/LinkerScript.h Mon Feb  2 00:21:23 2015
@@ -78,6 +78,7 @@ public:
     kw_provide_hidden,
     kw_only_if_ro,
     kw_only_if_rw,
+    kw_output,
     kw_output_arch,
     kw_output_format,
     kw_overlay,
@@ -149,6 +150,7 @@ public:
     Entry,
     Group,
     InputSectionsCmd,
+    Output,
     OutputArch,
     OutputFormat,
     OutputSectionDescription,
@@ -171,6 +173,23 @@ private:
   Kind _kind;
 };
 
+class Output : public Command {
+public:
+  explicit Output(StringRef outputFileName)
+      : Command(Kind::Output), _outputFileName(outputFileName) {}
+
+  static bool classof(const Command *c) { return c->getKind() == Kind::Output; }
+
+  void dump(raw_ostream &os) const override {
+    os << "OUTPUT(" << _outputFileName << ")\n";
+  }
+
+  StringRef getOutputFileName() const { return _outputFileName; }
+
+private:
+  StringRef _outputFileName;
+};
+
 class OutputFormat : public Command {
 public:
   explicit OutputFormat(StringRef format) : Command(Kind::OutputFormat) {
@@ -834,6 +853,13 @@ private:
 
   // ==== High-level commands parsing ====
 
+  /// Parse the OUTPUT linker script command.
+  /// Example:
+  /// OUTPUT(/path/to/file)
+  /// ^~~~> parseOutput()
+  ///
+  Output *parseOutput();
+
   /// Parse the OUTPUT_FORMAT linker script command.
   /// Example:
   ///

Modified: lld/trunk/lib/ReaderWriter/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/LinkerScript.cpp?rev=227786&r1=227785&r2=227786&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/LinkerScript.cpp (original)
+++ lld/trunk/lib/ReaderWriter/LinkerScript.cpp Mon Feb  2 00:21:23 2015
@@ -69,6 +69,7 @@ void Token::dump(raw_ostream &os) const
     CASE(kw_provide_hidden)
     CASE(kw_only_if_ro)
     CASE(kw_only_if_rw)
+    CASE(kw_output)
     CASE(kw_output_arch)
     CASE(kw_output_format)
     CASE(kw_overlay)
@@ -515,6 +516,7 @@ void Lexer::lex(Token &tok) {
             .Case("KEEP", Token::kw_keep)
             .Case("ONLY_IF_RO", Token::kw_only_if_ro)
             .Case("ONLY_IF_RW", Token::kw_only_if_rw)
+            .Case("OUTPUT", Token::kw_output)
             .Case("OUTPUT_ARCH", Token::kw_output_arch)
             .Case("OUTPUT_FORMAT", Token::kw_output_format)
             .Case("OVERLAY", Token::kw_overlay)
@@ -901,6 +903,13 @@ LinkerScript *Parser::parse() {
     case Token::semicolon:
       consumeToken();
       break;
+    case Token::kw_output: {
+      auto output = parseOutput();
+      if (!output)
+        return nullptr;
+      _script._commands.push_back(output);
+      break;
+    }
     case Token::kw_output_format: {
       auto outputFormat = parseOutputFormat();
       if (!outputFormat)
@@ -1211,6 +1220,27 @@ const Expression *Parser::parseTernaryCo
   return new (_alloc) TernaryConditional(lhs, trueExpr, falseExpr);
 }
 
+// Parse OUTPUT(ident)
+Output *Parser::parseOutput() {
+  assert(_tok._kind == Token::kw_output && "Expected OUTPUT");
+  consumeToken();
+  if (!expectAndConsume(Token::l_paren, "expected ("))
+    return nullptr;
+
+  if (_tok._kind != Token::identifier) {
+    error(_tok, "Expected identifier in OUTPUT.");
+    return nullptr;
+  }
+
+  auto ret = new (_alloc) Output(_tok._range);
+  consumeToken();
+
+  if (!expectAndConsume(Token::r_paren, "expected )"))
+    return nullptr;
+
+  return ret;
+}
+
 // Parse OUTPUT_FORMAT(ident)
 OutputFormat *Parser::parseOutputFormat() {
   assert(_tok._kind == Token::kw_output_format && "Expected OUTPUT_FORMAT!");

Modified: lld/trunk/test/LinkerScript/linker-script.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/LinkerScript/linker-script.test?rev=227786&r1=227785&r2=227786&view=diff
==============================================================================
--- lld/trunk/test/LinkerScript/linker-script.test (original)
+++ lld/trunk/test/LinkerScript/linker-script.test Mon Feb  2 00:21:23 2015
@@ -3,6 +3,7 @@
 
 OUTPUT_ARCH(i386:x86_64)
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT("/out/foo")
 GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a  AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ) -lm -l:libgcc.a )
 ENTRY(init)
 
@@ -19,6 +20,10 @@ CHECK: identifier: elf64-x86-64
 CHECK: comma: ,
 CHECK: identifier: elf64-x86-64
 CHECK: r_paren: )
+CHECK: kw_output: OUTPUT
+CHECK: l_paren: (
+CHECK: identifier: /out/foo
+CHECK: r_paren: )
 CHECK: kw_group: GROUP
 CHECK: l_paren: (
 CHECK: identifier: /lib/x86_64-linux-gnu/libc.so.6





More information about the llvm-commits mailing list