forked from OSchip/llvm-project
parent
5090d9a732
commit
822ea4f9a3
|
@ -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();
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue