diff options
author | Davide Italiano <davide@freebsd.org> | 2015-02-02 06:21:23 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2015-02-02 06:21:23 +0000 |
commit | 5cbde851edbe45945bd2899fa89cffa37b961b3f (patch) | |
tree | 2de101ed8adf433d291ec49dfa9ea1656d78b0c5 /lld | |
parent | e644b7578211b0811a340028e08b261ea3f79279 (diff) | |
download | bcm5719-llvm-5cbde851edbe45945bd2899fa89cffa37b961b3f.tar.gz bcm5719-llvm-5cbde851edbe45945bd2899fa89cffa37b961b3f.zip |
[ELF] Support for parsing OUTPUT command in LinkerScript
Differential Revision: D7326
Reviewed by: rafaelauler, shankarke, ruiu
llvm-svn: 227786
Diffstat (limited to 'lld')
-rw-r--r-- | lld/include/lld/ReaderWriter/LinkerScript.h | 26 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/LinkerScript.cpp | 30 | ||||
-rw-r--r-- | lld/test/LinkerScript/linker-script.test | 5 |
3 files changed, 61 insertions, 0 deletions
diff --git a/lld/include/lld/ReaderWriter/LinkerScript.h b/lld/include/lld/ReaderWriter/LinkerScript.h index be22bf3f5b0..26f1ea44253 100644 --- a/lld/include/lld/ReaderWriter/LinkerScript.h +++ b/lld/include/lld/ReaderWriter/LinkerScript.h @@ -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: /// diff --git a/lld/lib/ReaderWriter/LinkerScript.cpp b/lld/lib/ReaderWriter/LinkerScript.cpp index 3984408b605..c8dbfdd32fb 100644 --- a/lld/lib/ReaderWriter/LinkerScript.cpp +++ b/lld/lib/ReaderWriter/LinkerScript.cpp @@ -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::parseTernaryCondOp(const Expression *lhs) { 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!"); diff --git a/lld/test/LinkerScript/linker-script.test b/lld/test/LinkerScript/linker-script.test index a12f47791bd..421493666e8 100644 --- a/lld/test/LinkerScript/linker-script.test +++ b/lld/test/LinkerScript/linker-script.test @@ -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 |