[PECOFF] Support LIBRARY directive.
authorRui Ueyama <ruiu@google.com>
Fri, 18 Apr 2014 20:48:20 +0000 (20:48 +0000)
committerRui Ueyama <ruiu@google.com>
Fri, 18 Apr 2014 20:48:20 +0000 (20:48 +0000)
LIBRARY directive in a module definition file specifies the output
DLL file name. It also takes an optional value for the base address.

llvm-svn: 206647

lld/include/lld/Driver/WinLinkModuleDef.h
lld/lib/Driver/WinLinkDriver.cpp
lld/lib/Driver/WinLinkModuleDef.cpp
lld/test/pecoff/Inputs/exports.def

index 6326b8f..0cf01bf 100644 (file)
@@ -33,6 +33,7 @@ enum class Kind {
   kw_data,
   kw_exports,
   kw_heapsize,
+  kw_library,
   kw_name,
   kw_noname,
   kw_stacksize,
@@ -64,7 +65,7 @@ private:
 
 class Directive {
 public:
-  enum class Kind { exports, heapsize, name, stacksize, version };
+  enum class Kind { exports, heapsize, library, name, stacksize, version };
 
   Kind getKind() const { return _kind; }
   virtual ~Directive() {}
@@ -131,6 +132,23 @@ private:
   const uint64_t _baseaddr;
 };
 
+class Library : public Directive {
+public:
+  Library(StringRef name, uint64_t baseaddr)
+      : Directive(Kind::library), _name(name), _baseaddr(baseaddr) {}
+
+  static bool classof(const Directive *dir) {
+    return dir->getKind() == Kind::library;
+  }
+
+  StringRef getName() const { return _name; }
+  uint64_t getBaseAddress() const { return _baseaddr; }
+
+private:
+  const std::string _name;
+  const uint64_t _baseaddr;
+};
+
 class Version : public Directive {
 public:
   Version(int major, int minor)
index 6a7aa90..27a16d6 100644 (file)
@@ -1062,6 +1062,11 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
       } else if (auto *hs = dyn_cast<moduledef::Heapsize>(dir.getValue())) {
         ctx.setHeapReserve(hs->getReserve());
         ctx.setHeapCommit(hs->getCommit());
+      } else if (auto *lib = dyn_cast<moduledef::Library>(dir.getValue())) {
+        ctx.setIsDll(true);
+        ctx.setOutputPath(ctx.allocate(lib->getName()));
+        if (lib->getBaseAddress() && !ctx.getBaseAddress())
+          ctx.setBaseAddress(lib->getBaseAddress());
       } else if (auto *name = dyn_cast<moduledef::Name>(dir.getValue())) {
         if (!name->getOutputPath().empty() && ctx.outputPath().empty())
           ctx.setOutputPath(ctx.allocate(name->getOutputPath()));
index b87cf1b..71a838d 100644 (file)
@@ -52,6 +52,7 @@ Token Lexer::lex() {
                     .Case("DATA", Kind::kw_data)
                     .Case("EXPORTS", Kind::kw_exports)
                     .Case("HEAPSIZE", Kind::kw_heapsize)
+                    .Case("LIBRARY", Kind::kw_library)
                     .Case("NAME", Kind::kw_name)
                     .Case("NONAME", Kind::kw_noname)
                     .Case("STACKSIZE", Kind::kw_stacksize)
@@ -124,6 +125,14 @@ llvm::Optional<Directive *> Parser::parse() {
       return llvm::None;
     return new (_alloc) Heapsize(reserve, commit);
   }
+  case Kind::kw_library: {
+    // LIBRARY
+    std::string name;
+    uint64_t baseaddr;
+    if (!parseName(name, baseaddr))
+      return llvm::None;
+    return new (_alloc) Library(name, baseaddr);
+  }
   case Kind::kw_stacksize: {
     // STACKSIZE
     uint64_t reserve, commit;
index 6cc7cb5..67aaea3 100644 (file)
@@ -1,3 +1,4 @@
+LIBRARY foo.dll
 EXPORTS
   exportfn1 @5
   exportfn2