kw_data,
kw_exports,
kw_heapsize,
+ kw_library,
kw_name,
kw_noname,
kw_stacksize,
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() {}
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)
} 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()));
.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)
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;
+LIBRARY foo.dll
EXPORTS
exportfn1 @5
exportfn2