summaryrefslogtreecommitdiffstats
path: root/lld/lib/Driver/WinLinkModuleDef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/Driver/WinLinkModuleDef.cpp')
-rw-r--r--lld/lib/Driver/WinLinkModuleDef.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lld/lib/Driver/WinLinkModuleDef.cpp b/lld/lib/Driver/WinLinkModuleDef.cpp
index 7ca70efb4b4..dd71b8508a1 100644
--- a/lld/lib/Driver/WinLinkModuleDef.cpp
+++ b/lld/lib/Driver/WinLinkModuleDef.cpp
@@ -48,9 +48,11 @@ Token Lexer::lex() {
"0123456789_.*~+!@#$%^&*()/");
StringRef word = _buffer.substr(0, end);
Kind kind = llvm::StringSwitch<Kind>(word)
+ .Case("BASE", Kind::kw_base)
.Case("DATA", Kind::kw_data)
.Case("EXPORTS", Kind::kw_exports)
.Case("HEAPSIZE", Kind::kw_heapsize)
+ .Case("NAME", Kind::kw_name)
.Case("NONAME", Kind::kw_noname)
.Default(Kind::identifier);
_buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end);
@@ -82,6 +84,15 @@ bool Parser::consumeTokenAsInt(uint64_t &result) {
return true;
}
+bool Parser::expectAndConsume(Kind kind, Twine msg) {
+ consumeToken();
+ if (_tok._kind != kind) {
+ error(_tok, msg);
+ return false;
+ }
+ return true;
+}
+
void Parser::ungetToken() { _tokBuf.push_back(_tok); }
void Parser::error(const Token &tok, Twine msg) {
@@ -92,6 +103,7 @@ void Parser::error(const Token &tok, Twine msg) {
llvm::Optional<Directive *> Parser::parse() {
consumeToken();
+ // EXPORTS
if (_tok._kind == Kind::kw_exports) {
std::vector<PECOFFLinkingContext::ExportDesc> exports;
for (;;) {
@@ -102,12 +114,21 @@ llvm::Optional<Directive *> Parser::parse() {
}
return new (_alloc) Exports(exports);
}
+ // HEAPSIZE
if (_tok._kind == Kind::kw_heapsize) {
uint64_t reserve, commit;
if (!parseHeapsize(reserve, commit))
return llvm::None;
return new (_alloc) Heapsize(reserve, commit);
}
+ // NAME
+ if (_tok._kind == Kind::kw_name) {
+ std::string outputPath;
+ uint64_t baseaddr;
+ if (!parseName(outputPath, baseaddr))
+ return llvm::None;
+ return new (_alloc) Name(outputPath, baseaddr);
+ }
error(_tok, Twine("Unknown directive: ") + _tok._range);
return llvm::None;
}
@@ -141,6 +162,7 @@ bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) {
}
}
+// HEAPSIZE reserve [, commit]
bool Parser::parseHeapsize(uint64_t &reserve, uint64_t &commit) {
if (!consumeTokenAsInt(reserve))
return false;
@@ -157,5 +179,25 @@ bool Parser::parseHeapsize(uint64_t &reserve, uint64_t &commit) {
return true;
}
+// NAME [outputPath] [BASE=address]
+bool Parser::parseName(std::string &outputPath, uint64_t &baseaddr) {
+ consumeToken();
+ if (_tok._kind == Kind::identifier) {
+ outputPath = _tok._range;
+ consumeToken();
+ } else {
+ outputPath = "";
+ }
+ if (_tok._kind == Kind::kw_base) {
+ if (!expectAndConsume(Kind::equal, "'=' expected"))
+ return false;
+ if (!consumeTokenAsInt(baseaddr))
+ return false;
+ } else {
+ baseaddr = 0;
+ }
+ return true;
+}
+
} // moddef
} // namespace lld
OpenPOWER on IntegriCloud