[lld] r238667 - COFF: Infer entry symbol name if /entry is not given.
Rui Ueyama
ruiu at google.com
Sat May 30 20:34:08 PDT 2015
Author: ruiu
Date: Sat May 30 22:34:08 2015
New Revision: 238667
URL: http://llvm.org/viewvc/llvm-project?rev=238667&view=rev
Log:
COFF: Infer entry symbol name if /entry is not given.
`main` is not the only main function in Windows. You can choose one
from these four -- {w,}{WinMain,main}. There are four different entry
point functions for them, {w,}{WinMain,main}CRTStartup, respectively.
The linker needs to choose the right one depending on which `main`
function is defined.
Added:
lld/trunk/test/COFF/entry-inference.test
Modified:
lld/trunk/COFF/Config.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/SymbolTable.h
Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=238667&r1=238666&r2=238667&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Sat May 30 22:34:08 2015
@@ -26,7 +26,7 @@ public:
llvm::COFF::MachineTypes MachineType = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI;
- std::string EntryName = "mainCRTStartup";
+ std::string EntryName;
uint64_t ImageBase = 0x140000000;
uint64_t StackReserve = 1024 * 1024;
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238667&r1=238666&r2=238667&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sat May 30 22:34:08 2015
@@ -183,6 +183,20 @@ bool link(int Argc, const char *Argv[])
return false;
}
}
+
+ // 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()) {
+ auto EntryOrErr = Symtab.findDefaultEntry();
+ if (auto EC = EntryOrErr.getError()) {
+ llvm::errs() << EC.message() << "\n";
+ return false;
+ }
+ Config->EntryName = EntryOrErr.get();
+ }
+
+ // Make sure we have resolved all symbols.
if (Symtab.reportRemainingUndefines())
return false;
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=238667&r1=238666&r2=238667&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Sat May 30 22:34:08 2015
@@ -19,13 +19,9 @@ namespace lld {
namespace coff {
SymbolTable::SymbolTable() {
- addInitialSymbol(new DefinedAbsolute("__ImageBase", Config->ImageBase));
- addInitialSymbol(new Undefined(Config->EntryName));
-}
-
-void SymbolTable::addInitialSymbol(SymbolBody *Body) {
- OwnedSymbols.push_back(std::unique_ptr<SymbolBody>(Body));
- Symtab[Body->getName()] = new (Alloc) Symbol(Body);
+ addSymbol(new DefinedAbsolute("__ImageBase", Config->ImageBase));
+ if (!Config->EntryName.empty())
+ addSymbol(new Undefined(Config->EntryName));
}
std::error_code SymbolTable::addFile(std::unique_ptr<InputFile> File) {
@@ -155,11 +151,40 @@ std::vector<Chunk *> SymbolTable::getChu
return Res;
}
-SymbolBody *SymbolTable::find(StringRef Name) {
+Defined *SymbolTable::find(StringRef Name) {
auto It = Symtab.find(Name);
if (It == Symtab.end())
return nullptr;
- return It->second->Body;
+ if (auto *Def = dyn_cast<Defined>(It->second->Body))
+ return Def;
+ return nullptr;
+}
+
+// Link default entry point name.
+ErrorOr<StringRef> SymbolTable::findDefaultEntry() {
+ static const char *Entries[][2] = {
+ {"mainCRTStartup", "mainCRTStartup"},
+ {"wmainCRTStartup", "wmainCRTStartup"},
+ {"WinMainCRTStartup", "WinMainCRTStartup"},
+ {"wWinMainCRTStartup", "wWinMainCRTStartup"},
+ {"main", "mainCRTStartup"},
+ {"wmain", "wmainCRTStartup"},
+ {"WinMain", "WinMainCRTStartup"},
+ {"wWinMain", "wWinMainCRTStartup"},
+ };
+ for (size_t I = 0; I < sizeof(Entries); ++I) {
+ if (!find(Entries[I][0]))
+ continue;
+ if (auto EC = addSymbol(new Undefined(Entries[I][1])))
+ return EC;
+ return StringRef(Entries[I][1]);
+ }
+ return make_dynamic_error_code("entry point must be defined");
+}
+
+std::error_code SymbolTable::addSymbol(SymbolBody *Body) {
+ OwningSymbols.push_back(std::unique_ptr<SymbolBody>(Body));
+ return resolve(Body);
}
void SymbolTable::dump() {
Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=238667&r1=238666&r2=238667&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Sat May 30 22:34:08 2015
@@ -44,7 +44,16 @@ public:
// returned symbol actually has the same name (because of various
// mechanisms to allow aliases, a name can be resolved to a
// different symbol). Returns a nullptr if not found.
- SymbolBody *find(StringRef Name);
+ Defined *find(StringRef Name);
+
+ // Windows specific -- `main` is not the only main function in Windows.
+ // You can choose one from these four -- {w,}{WinMain,main}.
+ // There are four different entry point functions for them,
+ // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to
+ // choose the right one depending on which `main` function is defined.
+ // This function looks up the symbol table and resolve corresponding
+ // entry point name.
+ ErrorOr<StringRef> findDefaultEntry();
// Dump contents of the symbol table to stderr.
void dump();
@@ -63,11 +72,11 @@ private:
std::error_code resolve(SymbolBody *Body);
std::error_code addMemberFile(Lazy *Body);
- void addInitialSymbol(SymbolBody *Body);
+ std::error_code addSymbol(SymbolBody *Body);
std::unordered_map<StringRef, Symbol *> Symtab;
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
- std::vector<std::unique_ptr<SymbolBody>> OwnedSymbols;
+ std::vector<std::unique_ptr<SymbolBody>> OwningSymbols;
llvm::BumpPtrAllocator Alloc;
StringAllocator StringAlloc;
};
Added: lld/trunk/test/COFF/entry-inference.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/entry-inference.test?rev=238667&view=auto
==============================================================================
--- lld/trunk/test/COFF/entry-inference.test (added)
+++ lld/trunk/test/COFF/entry-inference.test Sat May 30 22:34:08 2015
@@ -0,0 +1,50 @@
+# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=MAIN %s < %t.log
+
+# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
+
+# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
+
+# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
+
+# MAIN: undefined symbol: mainCRTStartup
+# WMAIN: undefined symbol: wmainCRTStartup
+# WINMAIN: undefined symbol: WinMainCRTStartup
+# WWINMAIN: undefined symbol: wWinMainCRTStartup
+
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B82A000000C3
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: ENTRYNAME
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list