[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