[lld] r199020 - [PECOFF] Support NAME directive.
Rui Ueyama
ruiu at google.com
Sat Jan 11 13:53:46 PST 2014
Author: ruiu
Date: Sat Jan 11 15:53:46 2014
New Revision: 199020
URL: http://llvm.org/viewvc/llvm-project?rev=199020&view=rev
Log:
[PECOFF] Support NAME directive.
Modified:
lld/trunk/include/lld/Driver/WinLinkModuleDef.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/lib/Driver/WinLinkModuleDef.cpp
lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp
Modified: lld/trunk/include/lld/Driver/WinLinkModuleDef.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkModuleDef.h?rev=199020&r1=199019&r2=199020&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkModuleDef.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkModuleDef.h Sat Jan 11 15:53:46 2014
@@ -29,9 +29,11 @@ enum class Kind {
identifier,
comma,
equal,
+ kw_base,
kw_data,
kw_exports,
kw_heapsize,
+ kw_name,
kw_noname,
};
@@ -60,7 +62,7 @@ private:
class Directive {
public:
- enum class Kind { exports, heapsize };
+ enum class Kind { exports, heapsize, name };
Kind getKind() const { return _kind; }
virtual ~Directive() {}
@@ -106,6 +108,23 @@ private:
const uint64_t _commit;
};
+class Name : public Directive {
+public:
+ explicit Name(StringRef outputPath, uint64_t baseaddr)
+ : Directive(Kind::name), _outputPath(outputPath), _baseaddr(baseaddr) {}
+
+ static bool classof(const Directive *dir) {
+ return dir->getKind() == Kind::name;
+ }
+
+ StringRef getOutputPath() const { return _outputPath; }
+ uint64_t getBaseAddress() const { return _baseaddr; }
+
+private:
+ const std::string _outputPath;
+ const uint64_t _baseaddr;
+};
+
class Parser {
public:
explicit Parser(Lexer &lex, llvm::BumpPtrAllocator &alloc)
@@ -116,11 +135,14 @@ public:
private:
void consumeToken();
bool consumeTokenAsInt(uint64_t &result);
+ bool expectAndConsume(Kind kind, Twine msg);
+
void ungetToken();
void error(const Token &tok, Twine msg);
bool parseExport(PECOFFLinkingContext::ExportDesc &result);
bool parseHeapsize(uint64_t &reserve, uint64_t &commit);
+ bool parseName(std::string &outfile, uint64_t &baseaddr);
Lexer &_lex;
llvm::BumpPtrAllocator &_alloc;
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=199020&r1=199019&r2=199020&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Sat Jan 11 15:53:46 2014
@@ -935,6 +935,11 @@ WinLinkDriver::parse(int argc, const cha
} else if (auto *hs = dyn_cast<moduledef::Heapsize>(dir.getValue())) {
ctx.setHeapReserve(hs->getReserve());
ctx.setHeapCommit(hs->getCommit());
+ } else if (auto *name = dyn_cast<moduledef::Name>(dir.getValue())) {
+ if (!name->getOutputPath().empty() && ctx.outputPath().empty())
+ ctx.setOutputPath(ctx.allocate(name->getOutputPath()));
+ if (name->getBaseAddress() && ctx.getBaseAddress())
+ ctx.setBaseAddress(name->getBaseAddress());
} else {
llvm::dbgs() << static_cast<int>(dir.getValue()->getKind()) << "\n";
llvm_unreachable("Unknown module-definition directive.\n");
Modified: lld/trunk/lib/Driver/WinLinkModuleDef.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkModuleDef.cpp?rev=199020&r1=199019&r2=199020&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkModuleDef.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkModuleDef.cpp Sat Jan 11 15:53:46 2014
@@ -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
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, Twi
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::pars
}
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(PECOFFLinkingCo
}
}
+// 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 &res
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
Modified: lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp?rev=199020&r1=199019&r2=199020&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp Sat Jan 11 15:53:46 2014
@@ -87,3 +87,23 @@ TEST_F(ParserTest, Heapsize2) {
EXPECT_EQ(65536U, heapsize->getReserve());
EXPECT_EQ(8192U, heapsize->getCommit());
}
+
+TEST_F(ParserTest, Name1) {
+ llvm::BumpPtrAllocator alloc;
+ llvm::Optional<moduledef::Directive *> dir = parse("NAME foo.exe", alloc);
+ EXPECT_TRUE(dir.hasValue());
+ auto *name = dyn_cast<moduledef::Name>(dir.getValue());
+ EXPECT_TRUE(name != nullptr);
+ EXPECT_EQ("foo.exe", name->getOutputPath());
+ EXPECT_EQ(0U, name->getBaseAddress());
+}
+
+TEST_F(ParserTest, Name2) {
+ llvm::BumpPtrAllocator alloc;
+ llvm::Optional<moduledef::Directive *> dir = parse("NAME foo.exe BASE=4096", alloc);
+ EXPECT_TRUE(dir.hasValue());
+ auto *name = dyn_cast<moduledef::Name>(dir.getValue());
+ EXPECT_TRUE(name != nullptr);
+ EXPECT_EQ("foo.exe", name->getOutputPath());
+ EXPECT_EQ(4096U, name->getBaseAddress());
+}
More information about the llvm-commits
mailing list