summaryrefslogtreecommitdiff
path: root/COFF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'COFF/Driver.cpp')
-rw-r--r--COFF/Driver.cpp93
1 files changed, 84 insertions, 9 deletions
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 4c0ea44b875ec..d871f942737db 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -19,6 +19,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Object/ArchiveWriter.h"
+#include "llvm/Object/COFFImportFile.h"
+#include "llvm/Object/COFFModuleDefinition.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
@@ -35,6 +37,7 @@
#include <future>
using namespace llvm;
+using namespace llvm::object;
using namespace llvm::COFF;
using llvm::sys::Process;
using llvm::sys::fs::file_magic;
@@ -97,12 +100,11 @@ static std::future<MBErrPair> createFutureForFile(std::string Path) {
MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
MemoryBufferRef MBRef = *MB;
- OwningMBs.push_back(std::move(MB));
+ make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership
if (Driver->Tar)
Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()),
MBRef.getBuffer());
-
return MBRef;
}
@@ -420,6 +422,84 @@ static std::string getMapFile(const opt::InputArgList &Args) {
return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
}
+static std::string getImplibPath() {
+ if (!Config->Implib.empty())
+ return Config->Implib;
+ SmallString<128> Out = StringRef(Config->OutputFile);
+ sys::path::replace_extension(Out, ".lib");
+ return Out.str();
+}
+
+std::vector<COFFShortExport> createCOFFShortExportFromConfig() {
+ std::vector<COFFShortExport> Exports;
+ for (Export &E1 : Config->Exports) {
+ COFFShortExport E2;
+ E2.Name = E1.Name;
+ E2.ExtName = E1.ExtName;
+ E2.Ordinal = E1.Ordinal;
+ E2.Noname = E1.Noname;
+ E2.Data = E1.Data;
+ E2.Private = E1.Private;
+ E2.Constant = E1.Constant;
+ Exports.push_back(E2);
+ }
+ return Exports;
+}
+
+static void createImportLibrary() {
+ std::vector<COFFShortExport> Exports = createCOFFShortExportFromConfig();
+ std::string DLLName = sys::path::filename(Config->OutputFile);
+ std::string Path = getImplibPath();
+ writeImportLibrary(DLLName, Path, Exports, Config->Machine);
+}
+
+static void parseModuleDefs(StringRef Path) {
+ std::unique_ptr<MemoryBuffer> MB = check(
+ MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
+ MemoryBufferRef MBRef = MB->getMemBufferRef();
+
+ Expected<COFFModuleDefinition> Def =
+ parseCOFFModuleDefinition(MBRef, Config->Machine);
+ if (!Def)
+ fatal(errorToErrorCode(Def.takeError()).message());
+
+ COFFModuleDefinition &M = *Def;
+ if (Config->OutputFile.empty())
+ Config->OutputFile = Saver.save(M.OutputFile);
+
+ if (M.ImageBase)
+ Config->ImageBase = M.ImageBase;
+ if (M.StackReserve)
+ Config->StackReserve = M.StackReserve;
+ if (M.StackCommit)
+ Config->StackCommit = M.StackCommit;
+ if (M.HeapReserve)
+ Config->HeapReserve = M.HeapReserve;
+ if (M.HeapCommit)
+ Config->HeapCommit = M.HeapCommit;
+ if (M.MajorImageVersion)
+ Config->MajorImageVersion = M.MajorImageVersion;
+ if (M.MinorImageVersion)
+ Config->MinorImageVersion = M.MinorImageVersion;
+ if (M.MajorOSVersion)
+ Config->MajorOSVersion = M.MajorOSVersion;
+ if (M.MinorOSVersion)
+ Config->MinorOSVersion = M.MinorOSVersion;
+
+ for (COFFShortExport E1 : M.Exports) {
+ Export E2;
+ E2.Name = Saver.save(E1.Name);
+ if (E1.isWeak())
+ E2.ExtName = Saver.save(E1.ExtName);
+ E2.Ordinal = E1.Ordinal;
+ E2.Noname = E1.Noname;
+ E2.Data = E1.Data;
+ E2.Private = E1.Private;
+ E2.Constant = E1.Constant;
+ Config->Exports.push_back(E2);
+ }
+}
+
std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
std::vector<MemoryBufferRef> V;
Error Err = Error::success();
@@ -821,8 +901,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->ManifestInput.push_back(Arg->getValue());
// Handle miscellaneous boolean flags.
- if (Args.hasArg(OPT_allowbind_no))
- Config->AllowBind = false;
if (Args.hasArg(OPT_allowisolation_no))
Config->AllowIsolation = false;
if (Args.hasArg(OPT_dynamicbase_no))
@@ -834,7 +912,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (Args.hasArg(OPT_nosymtab))
Config->WriteSymtab = false;
Config->DumpPdb = Args.hasArg(OPT_dumppdb);
- Config->DebugPdb = Args.hasArg(OPT_debugpdb);
Config->MapFile = getMapFile(Args);
@@ -916,9 +993,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// Handle /def
if (auto *Arg = Args.getLastArg(OPT_deffile)) {
// parseModuleDefs mutates Config object.
- parseModuleDefs(
- takeBuffer(check(MemoryBuffer::getFile(Arg->getValue()),
- Twine("could not open ") + Arg->getValue())));
+ parseModuleDefs(Arg->getValue());
}
// Handle /delayload
@@ -1038,7 +1113,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// need to create a .lib file.
if (!Config->Exports.empty() || Config->DLL) {
fixupExports();
- writeImportLibrary();
+ createImportLibrary();
assignExportOrdinals();
}