[PATCH] D52832: lld-link: Several tweaks to default entry point selection.

Nico Weber via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 3 08:52:03 PDT 2018


thakis created this revision.
thakis added a reviewer: ruiu.

Three related changes:

1. link.exe uses the presence of main and wmain to decide if it should call mainCRTStartup or wmainCRTStartup, even if /nodefaultlib is passed. For compatibility, remove `FindMain` logic.

2. Default to the non-wide entrypoint if main is not found. This has two effects:

  a. In normal links, lld-link now prints

  lld-link: error: undefined symbol: _main >>> referenced by f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:78 >>>               libcmt.lib(exe_main.obj):("int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)) >>> referenced by f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283 >>>               libcmt.lib(exe_main.obj):("int __cdecl __scrt_common_main_seh(void)" (?__scrt_common_main_seh@@YAHXZ))

  instead of

  lld-link: error: entry point must be defined

This is arguable a better error message, since it now mentions that _main is missing. (This matches link.exe's diagnostic in this case.)

  b. With /nodefautlib, we now default to mainCRTStartup if no main() is present, again matching link.exe. This makes r337407 obsolete.

This means if you have a cc file containing both mainCRTStartup and wmainCRTStartup and you pass `/nodefaultlib /subsystem:console`, lld-link will now call mainCRTStartup, matching link.exe

3. Print a warning if both main and wmain are present, similar to link.exe's LNK4067.


https://reviews.llvm.org/D52832

Files:
  COFF/Driver.cpp
  test/COFF/entry-inference.test


Index: test/COFF/entry-inference.test
===================================================================
--- test/COFF/entry-inference.test
+++ test/COFF/entry-inference.test
@@ -1,18 +1,26 @@
 # RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
 # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=MAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /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-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /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-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /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-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
 
 # MAIN:     error: <root>: undefined symbol: mainCRTStartup
 # WMAIN:    error: <root>: undefined symbol: wmainCRTStartup
Index: COFF/Driver.cpp
===================================================================
--- COFF/Driver.cpp
+++ COFF/Driver.cpp
@@ -430,26 +430,28 @@
   assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
          "must handle /subsystem before calling this");
 
-  // As a special case, if /nodefaultlib is given, we directly look for an
-  // entry point. This is because, if no default library is linked, users
-  // need to define an entry point instead of a "main".
-  bool FindMain = !Config->NoDefaultLibAll;
   if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
-    if (findUnderscoreMangle(FindMain ? "WinMain" : "WinMainCRTStartup"))
-      return mangle("WinMainCRTStartup");
-    if (findUnderscoreMangle(FindMain ? "wWinMain" : "wWinMainCRTStartup"))
-      return mangle("wWinMainCRTStartup");
-  }
-  if (findUnderscoreMangle(FindMain ? "main" : "mainCRTStartup"))
-    return mangle("mainCRTStartup");
-  if (findUnderscoreMangle(FindMain ? "wmain" : "wmainCRTStartup"))
-    return mangle("wmainCRTStartup");
-  return "";
+    if (findUnderscoreMangle("wWinMain")) {
+      if (!findUnderscoreMangle("WinMain"))
+        return mangle("wWinMainCRTStartup");
+      warn("found both wWinMain and WinMain, using latter");
+    }
+    return mangle("WinMainCRTStartup");
+  }
+  if (findUnderscoreMangle("wmain")) {
+    if (!findUnderscoreMangle("main"))
+      return mangle("wmainCRTStartup");
+    warn("found both wmain and main, using latter");
+  }
+  return mangle("mainCRTStartup");
 }
 
 WindowsSubsystem LinkerDriver::inferSubsystem() {
   if (Config->DLL)
     return IMAGE_SUBSYSTEM_WINDOWS_GUI;
+  // Note that link.exe infers the subsystem from the presence of these
+  // functions even if /entry: or /nodefaultlib are passed which causes them
+  // to not be called.
   bool HaveMain = findUnderscoreMangle("main");
   bool HaveWMain = findUnderscoreMangle("wmain");
   bool HaveWinMain = findUnderscoreMangle("WinMain");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52832.168119.patch
Type: text/x-patch
Size: 3411 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181003/3aad20aa/attachment.bin>


More information about the llvm-commits mailing list