summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-04-18 20:48:20 +0000
committerRui Ueyama <ruiu@google.com>2014-04-18 20:48:20 +0000
commit83743ccca445898babe867dab84531d90ece088e (patch)
tree6fcdda2eba1b6547152ac6812eb0f9802a00f059
parent2174f44f61ffe1736d64b3a9770ca20ae8e42842 (diff)
downloadbcm5719-llvm-83743ccca445898babe867dab84531d90ece088e.tar.gz
bcm5719-llvm-83743ccca445898babe867dab84531d90ece088e.zip
[PECOFF] Support LIBRARY directive.
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
-rw-r--r--lld/include/lld/Driver/WinLinkModuleDef.h20
-rw-r--r--lld/lib/Driver/WinLinkDriver.cpp5
-rw-r--r--lld/lib/Driver/WinLinkModuleDef.cpp9
-rw-r--r--lld/test/pecoff/Inputs/exports.def1
4 files changed, 34 insertions, 1 deletions
diff --git a/lld/include/lld/Driver/WinLinkModuleDef.h b/lld/include/lld/Driver/WinLinkModuleDef.h
index 6326b8fb7fd..0cf01bf7037 100644
--- a/lld/include/lld/Driver/WinLinkModuleDef.h
+++ b/lld/include/lld/Driver/WinLinkModuleDef.h
@@ -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)
diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp
index 6a7aa90d450..27a16d6444f 100644
--- a/lld/lib/Driver/WinLinkDriver.cpp
+++ b/lld/lib/Driver/WinLinkDriver.cpp
@@ -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()));
diff --git a/lld/lib/Driver/WinLinkModuleDef.cpp b/lld/lib/Driver/WinLinkModuleDef.cpp
index b87cf1b91be..71a838d7346 100644
--- a/lld/lib/Driver/WinLinkModuleDef.cpp
+++ b/lld/lib/Driver/WinLinkModuleDef.cpp
@@ -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;
diff --git a/lld/test/pecoff/Inputs/exports.def b/lld/test/pecoff/Inputs/exports.def
index 6cc7cb5f2ee..67aaea37b85 100644
--- a/lld/test/pecoff/Inputs/exports.def
+++ b/lld/test/pecoff/Inputs/exports.def
@@ -1,3 +1,4 @@
+LIBRARY foo.dll
EXPORTS
exportfn1 @5
exportfn2
OpenPOWER on IntegriCloud