diff options
-rw-r--r-- | lld/COFF/Config.h | 1 | ||||
-rw-r--r-- | lld/COFF/Driver.cpp | 15 | ||||
-rw-r--r-- | lld/COFF/Writer.cpp | 6 | ||||
-rw-r--r-- | lld/test/COFF/noentry.test | 10 |
4 files changed, 27 insertions, 5 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 801478149697..67f6034b0fa4 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -43,6 +43,7 @@ struct Configuration { bool Verbose = false; WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; StringRef EntryName; + bool NoEntry = false; std::string OutputFile; bool DoGC = true; bool Relocatable = true; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index d2dbd96a8fe2..c643f517024e 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -275,11 +275,20 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { addUndefined(Config->EntryName); } + // Handle /noentry + if (Args.hasArg(OPT_noentry)) { + if (!Args.hasArg(OPT_dll)) { + llvm::errs() << "/noentry must be specified with /dll\n"; + return false; + } + Config->NoEntry = true; + } + // Handle /dll if (Args.hasArg(OPT_dll)) { Config->DLL = true; Config->ManifestID = 2; - if (Config->EntryName.empty()) { + if (Config->EntryName.empty() && !Config->NoEntry) { Config->EntryName = "_DllMainCRTStartup"; addUndefined("_DllMainCRTStartup"); } @@ -539,15 +548,15 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // Windows specific -- If entry point name is not given, we need to // infer that from user-defined entry name. The symbol table takes // care of details. - if (Config->EntryName.empty()) { + if (Config->EntryName.empty() && !Config->NoEntry) { auto EntryOrErr = Symtab.findDefaultEntry(); if (auto EC = EntryOrErr.getError()) { llvm::errs() << EC.message() << "\n"; return false; } Config->EntryName = EntryOrErr.get(); + addUndefined(Config->EntryName); } - addUndefined(Config->EntryName); if (auto EC = Symtab.run()) { llvm::errs() << EC.message() << "\n"; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 81a9b2425527..c0a7f4565e2a 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -316,8 +316,10 @@ void Writer::writeHeader() { PE->Subsystem = Config->Subsystem; PE->SizeOfImage = SizeOfImage; PE->SizeOfHeaders = SizeOfHeaders; - Defined *Entry = cast<Defined>(Symtab->find(Config->EntryName)); - PE->AddressOfEntryPoint = Entry->getRVA(); + if (!Config->NoEntry) { + Defined *Entry = cast<Defined>(Symtab->find(Config->EntryName)); + PE->AddressOfEntryPoint = Entry->getRVA(); + } PE->SizeOfStackReserve = Config->StackReserve; PE->SizeOfStackCommit = Config->StackCommit; PE->SizeOfHeapReserve = Config->HeapReserve; diff --git a/lld/test/COFF/noentry.test b/lld/test/COFF/noentry.test new file mode 100644 index 000000000000..e31435c91fb3 --- /dev/null +++ b/lld/test/COFF/noentry.test @@ -0,0 +1,10 @@ +# REQUIRES: winres + +# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj +# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj +# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s +# RUN: lld -flavor link2 /out:%t.dll /dll /noentry %t.obj +# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOENTRY %s + +ENTRY: AddressOfEntryPoint: 0x1000 +NOENTRY: AddressOfEntryPoint: 0x0 |