mirror of
https://github.com/intel/llvm.git
synced 2026-01-18 07:57:36 +08:00
[ELF] Support for parsing OUTPUT command in LinkerScript
Differential Revision: D7326 Reviewed by: rafaelauler, shankarke, ruiu llvm-svn: 227786
This commit is contained in:
@@ -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:
|
||||
///
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user