[LinkerScript] parse OUTPUT_ARCH.

llvm-svn: 202100
This commit is contained in:
Shankar Easwaran 2014-02-25 01:55:13 +00:00
parent 5090d9a732
commit 822ea4f9a3
3 changed files with 63 additions and 10 deletions

View File

@ -38,6 +38,7 @@ public:
kw_entry,
kw_group,
kw_output_format,
kw_output_arch,
kw_as_needed
};
@ -75,11 +76,7 @@ private:
class Command {
public:
enum class Kind {
Entry,
OutputFormat,
Group,
};
enum class Kind { Entry, OutputFormat, OutputArch, Group, };
Kind getKind() const { return _kind; }
@ -113,6 +110,25 @@ private:
StringRef _format;
};
class OutputArch : public Command {
public:
explicit OutputArch(StringRef arch)
: Command(Kind::OutputArch), _arch(arch) {}
static bool classof(const Command *c) {
return c->getKind() == Kind::OutputArch;
}
virtual void dump(raw_ostream &os) const {
os << "OUTPUT_arch(" << getArch() << ")\n";
}
StringRef getArch() const { return _arch; }
private:
StringRef _arch;
};
struct Path {
StringRef _path;
bool _asNeeded;
@ -212,6 +228,7 @@ private:
}
OutputFormat *parseOutputFormat();
OutputArch *parseOutputArch();
Group *parseGroup();
bool parseAsNeeded(std::vector<Path> &paths);
Entry *parseEntry();

View File

@ -28,6 +28,7 @@ void Token::dump(raw_ostream &os) const {
CASE(kw_entry)
CASE(kw_group)
CASE(kw_output_format)
CASE(kw_output_arch)
CASE(l_paren)
CASE(r_paren)
CASE(unknown)
@ -67,6 +68,7 @@ bool Lexer::canContinueName(char c) const {
case '7': case '8': case '9':
case '_': case '.': case '$': case '/': case '\\': case '~': case '=':
case '+': case ',': case '[': case ']': case '*': case '?': case '-':
case ':':
return true;
default:
return false;
@ -107,11 +109,12 @@ void Lexer::lex(Token &tok) {
break;
StringRef word = _buffer.substr(0, end);
Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
.Case("OUTPUT_FORMAT", Token::kw_output_format)
.Case("GROUP", Token::kw_group)
.Case("AS_NEEDED", Token::kw_as_needed)
.Case("ENTRY", Token::kw_entry)
.Default(Token::identifier);
.Case("OUTPUT_FORMAT", Token::kw_output_format)
.Case("OUTPUT_ARCH", Token::kw_output_arch)
.Case("GROUP", Token::kw_group)
.Case("AS_NEEDED", Token::kw_as_needed)
.Case("ENTRY", Token::kw_entry)
.Default(Token::identifier);
tok = Token(word, kind);
_buffer = _buffer.drop_front(end);
return;
@ -172,6 +175,13 @@ LinkerScript *Parser::parse() {
_script._commands.push_back(outputFormat);
break;
}
case Token::kw_output_arch: {
auto outputArch = parseOutputArch();
if (!outputArch)
return nullptr;
_script._commands.push_back(outputArch);
break;
}
case Token::kw_group: {
auto group = parseGroup();
if (!group)
@ -219,6 +229,27 @@ OutputFormat *Parser::parseOutputFormat() {
return ret;
}
// Parse OUTPUT_ARCH(ident)
OutputArch *Parser::parseOutputArch() {
assert(_tok._kind == Token::kw_output_arch && "Expected OUTPUT_ARCH!");
consumeToken();
if (!expectAndConsume(Token::l_paren, "expected ("))
return nullptr;
if (_tok._kind != Token::identifier) {
error(_tok, "Expected identifier in OUTPUT_ARCH.");
return nullptr;
}
auto ret = new (_alloc) OutputArch(_tok._range);
consumeToken();
if (!expectAndConsume(Token::r_paren, "expected )"))
return nullptr;
return ret;
}
// Parse GROUP(file ...)
Group *Parser::parseGroup() {
assert(_tok._kind == Token::kw_group && "Expected GROUP!");

View File

@ -1,11 +1,16 @@
/* RUN: linker-script-test %s | FileCheck %s
*/
OUTPUT_ARCH(i386:x86_64)
OUTPUT_FORMAT(elf64-x86-64)
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 ) )
ENTRY(init)
/*
CHECK: kw_output_arch: OUTPUT_ARCH
CHECK: l_paren: (
CHECK: identifier: i386:x86_64
CHECK: r_paren: )
CHECK: kw_output_format: OUTPUT_FORMAT
CHECK: l_paren: (
CHECK: identifier: elf64-x86-64