[lld] r338877 - lld-link: Fix subsystem inference for non-console apps on 32-bit, and fix entry point inference on 32-bit with /nodefaultlib
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 3 05:00:13 PDT 2018
Author: nico
Date: Fri Aug 3 05:00:12 2018
New Revision: 338877
URL: http://llvm.org/viewvc/llvm-project?rev=338877&view=rev
Log:
lld-link: Fix subsystem inference for non-console apps on 32-bit, and fix entry point inference on 32-bit with /nodefaultlib
LinkerDriver::inferSubsystem() used to do Symtab->findUnderscore("WinMain"),
but WinMain is stdcall in 32-bit and is hence is called _WinMain at 16. Instead,
Symtab->findMangle(mangle("WinMain")) needs to be called.
But since LinkerDriver::inferSubsystem() and LinkerDriver::findDefaultEntry()
both need to call this, introduce a common helper function for this and call it
from both places. (Also call it for "main" for consistency, even though
findUnderscore() is enough for main since that's __cdecl on 32-bit).
This also exposed a bug for /nodefaultlib entrypoint inference: The code here
called findMangle(Sym) instead of findMangle(mangle(Sym)), again doing the
wrong thing on 32-bit. Fix that too.
While here, make Driver::mangle() a static free function.
https://reviews.llvm.org/D50184
Added:
lld/trunk/test/COFF/entry-inference332.test
lld/trunk/test/COFF/subsystem-inference32.test
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/test/COFF/entry-inference3.test
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=338877&r1=338876&r2=338877&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri Aug 3 05:00:12 2018
@@ -116,6 +116,19 @@ static std::future<MBErrPair> createFutu
});
}
+// Symbol names are mangled by prepending "_" on x86.
+static StringRef mangle(StringRef Sym) {
+ assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN);
+ if (Config->Machine == I386)
+ return Saver.save("_" + Sym);
+ return Sym;
+}
+
+static bool findUnderscoreMangle(StringRef Sym) {
+ StringRef Entry = Symtab->findMangle(mangle(Sym));
+ return !Entry.empty() && !isa<Undefined>(Symtab->find(Entry));
+}
+
MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
MemoryBufferRef MBRef = *MB;
make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership
@@ -407,14 +420,6 @@ Symbol *LinkerDriver::addUndefined(Strin
return B;
}
-// Symbol names are mangled by appending "_" prefix on x86.
-StringRef LinkerDriver::mangle(StringRef Sym) {
- assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN);
- if (Config->Machine == I386)
- return Saver.save("_" + Sym);
- return Sym;
-}
-
// Windows specific -- find default entry point name.
//
// There are four different entry point functions for Windows executables,
@@ -427,8 +432,7 @@ StringRef LinkerDriver::findDefaultEntry
if (Config->NoDefaultLibAll) {
for (StringRef S : {"mainCRTStartup", "wmainCRTStartup",
"WinMainCRTStartup", "wWinMainCRTStartup"}) {
- StringRef Entry = Symtab->findMangle(S);
- if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry)))
+ if (findUnderscoreMangle(S))
return mangle(S);
}
return "";
@@ -442,8 +446,7 @@ StringRef LinkerDriver::findDefaultEntry
{"wWinMain", "wWinMainCRTStartup"},
};
for (auto E : Entries) {
- StringRef Entry = Symtab->findMangle(mangle(E[0]));
- if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry)))
+ if (findUnderscoreMangle(E[0]))
return mangle(E[1]);
}
return "";
@@ -452,9 +455,9 @@ StringRef LinkerDriver::findDefaultEntry
WindowsSubsystem LinkerDriver::inferSubsystem() {
if (Config->DLL)
return IMAGE_SUBSYSTEM_WINDOWS_GUI;
- if (Symtab->findUnderscore("main") || Symtab->findUnderscore("wmain"))
+ if (findUnderscoreMangle("main") || findUnderscoreMangle("wmain"))
return IMAGE_SUBSYSTEM_WINDOWS_CUI;
- if (Symtab->findUnderscore("WinMain") || Symtab->findUnderscore("wWinMain"))
+ if (findUnderscoreMangle("WinMain") || findUnderscoreMangle("wWinMain"))
return IMAGE_SUBSYSTEM_WINDOWS_GUI;
return IMAGE_SUBSYSTEM_UNKNOWN;
}
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=338877&r1=338876&r2=338877&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Fri Aug 3 05:00:12 2018
@@ -103,7 +103,6 @@ private:
std::set<std::string> VisitedLibs;
Symbol *addUndefined(StringRef Sym);
- StringRef mangle(StringRef Sym);
// Windows specific -- "main" is not the only main function in Windows.
// You can choose one from these four -- {w,}{WinMain,main}.
Modified: lld/trunk/test/COFF/entry-inference3.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/entry-inference3.test?rev=338877&r1=338876&r2=338877&view=diff
==============================================================================
--- lld/trunk/test/COFF/entry-inference3.test (original)
+++ lld/trunk/test/COFF/entry-inference3.test Fri Aug 3 05:00:12 2018
@@ -1,4 +1,8 @@
-# RUN: yaml2obj < %s > %t.obj
+# RUN: sed -e s/ENTRYNAME/mainCRTStartup/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# RUN: sed -e s/ENTRYNAME/?mainCRTStartup@@YAHXZ/ %s | yaml2obj > %t.obj
# RUN: not lld-link /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
# RUN: FileCheck %s < %t.log
@@ -26,7 +30,7 @@ symbols:
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- - Name: mainCRTStartup
+ - Name: "ENTRYNAME"
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
Added: lld/trunk/test/COFF/entry-inference332.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/entry-inference332.test?rev=338877&view=auto
==============================================================================
--- lld/trunk/test/COFF/entry-inference332.test (added)
+++ lld/trunk/test/COFF/entry-inference332.test Fri Aug 3 05:00:12 2018
@@ -0,0 +1,39 @@
+# RUN: sed -e s/ENTRYNAME/_mainCRTStartup/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# RUN: sed -e s/ENTRYNAME/?mainCRTStartup@@YAHXZ/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# CHECK: Entry name inferred: _mainCRTStartup
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_I386
+ 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
+...
Added: lld/trunk/test/COFF/subsystem-inference32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/subsystem-inference32.test?rev=338877&view=auto
==============================================================================
--- lld/trunk/test/COFF/subsystem-inference32.test (added)
+++ lld/trunk/test/COFF/subsystem-inference32.test Fri Aug 3 05:00:12 2018
@@ -0,0 +1,74 @@
+# RUN: sed -e s/ENTRYNAME/_main/ %s | yaml2obj > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAIN %s
+
+# RUN: sed s/ENTRYNAME/_wmain/ %s | yaml2obj > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
+
+# RUN: sed s/ENTRYNAME/_WinMain at 16/ %s | yaml2obj > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
+
+# RUN: sed s/ENTRYNAME/_wWinMain at 16/ %s | yaml2obj > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
+
+# MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
+# WMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
+# WINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
+# WWINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_I386
+ 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
+ - Name: _mainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _wmainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _WinMainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _wWinMainCRTStartup
+ 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