From 2824225d27cc6706bf89408b1c8fda62ad3f0a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 17 Dec 2025 22:22:01 +0100 Subject: [PATCH] [LLD] [COFF] Fix implicit DLL entry point for MinGW (#171680) Previously, LLD would always set the implicit entry point for DLLs to the symbol that is prefixed with an underscore. However, mingw-w64 defines it without that underscore. This change fixes that by adding a special branch for MinGW. Also, it simplifies tests that use MinGW style DLL entry symbol by skipping the entry point argument. Note, tests that use MSVC style DLL entry symbol and LLD in MinGW mode, will now require using explicit entry point. I believe this is sensible. When an explicit entry point is passed, i.e. LLD is called by Clang or GCC, there will be no observable difference. Fixes https://github.com/llvm/llvm-project/issues/171441 --- lld/COFF/Driver.cpp | 11 +++++++++-- lld/test/COFF/autoimport-arm-code.s | 2 +- lld/test/COFF/autoimport-arm-data.s | 2 +- lld/test/COFF/autoimport-arm64-code.s | 2 +- lld/test/COFF/autoimport-arm64-data.s | 2 +- lld/test/COFF/autoimport-debug.s | 2 +- lld/test/COFF/autoimport-gc.s | 2 +- lld/test/COFF/autoimport-lto.ll | 2 +- lld/test/COFF/autoimport-refptr.s | 2 +- lld/test/COFF/autoimport-x86.s | 2 +- lld/test/COFF/exclude-all.s | 4 ++-- lld/test/COFF/export-all.s | 8 ++++---- 12 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 0e528de9c365..14cd61906fc0 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1489,6 +1489,14 @@ getVFS(COFFLinkerContext &ctx, const opt::InputArgList &args) { return nullptr; } +static StringRef DllDefaultEntryPoint(MachineTypes machine, bool mingw) { + if (mingw) { + return (machine == I386) ? "_DllMainCRTStartup@12" : "DllMainCRTStartup"; + } else { + return (machine == I386) ? "__DllMainCRTStartup@12" : "_DllMainCRTStartup"; + } +} + constexpr const char *lldsaveTempsValues[] = { "resolution", "preopt", "promote", "internalize", "import", "opt", "precodegen", "prelink", "combinedindex"}; @@ -2408,8 +2416,7 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { symtab.entry = symtab.addGCRoot(symtab.mangle(arg->getValue()), true); } else if (!symtab.entry && !config->noEntry) { if (args.hasArg(OPT_dll)) { - StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12" - : "_DllMainCRTStartup"; + StringRef s = DllDefaultEntryPoint(config->machine, config->mingw); symtab.entry = symtab.addGCRoot(s, true); } else if (config->driverWdm) { // /driver:wdm implies /entry:_NtProcessStartup diff --git a/lld/test/COFF/autoimport-arm-code.s b/lld/test/COFF/autoimport-arm-code.s index 562a1a959e38..8d7cc7f5cb01 100644 --- a/lld/test/COFF/autoimport-arm-code.s +++ b/lld/test/COFF/autoimport-arm-code.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj # RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s diff --git a/lld/test/COFF/autoimport-arm-data.s b/lld/test/COFF/autoimport-arm-data.s index 82c66f0989d4..efc19f7f1865 100644 --- a/lld/test/COFF/autoimport-arm-data.s +++ b/lld/test/COFF/autoimport-arm-data.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj # RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose diff --git a/lld/test/COFF/autoimport-arm64-code.s b/lld/test/COFF/autoimport-arm64-code.s index 9f5cc8f89425..b7cddf9bac04 100644 --- a/lld/test/COFF/autoimport-arm64-code.s +++ b/lld/test/COFF/autoimport-arm64-code.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj # RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s diff --git a/lld/test/COFF/autoimport-arm64-data.s b/lld/test/COFF/autoimport-arm64-data.s index 7934e2a96925..f3f16bc5210a 100644 --- a/lld/test/COFF/autoimport-arm64-data.s +++ b/lld/test/COFF/autoimport-arm64-data.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj # RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose diff --git a/lld/test/COFF/autoimport-debug.s b/lld/test/COFF/autoimport-debug.s index 1f31a2b9e554..5865dac8d0d1 100644 --- a/lld/test/COFF/autoimport-debug.s +++ b/lld/test/COFF/autoimport-debug.s @@ -10,7 +10,7 @@ ## debug info. # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/lib.s -filetype=obj -o %t.dir/lib.obj -# RUN: lld-link -out:%t.dir/lib.dll -dll -entry:DllMainCRTStartup %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib +# RUN: lld-link -out:%t.dir/lib.dll -dll %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj # RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib -opt:noref -debug:dwarf -runtime-pseudo-reloc:no diff --git a/lld/test/COFF/autoimport-gc.s b/lld/test/COFF/autoimport-gc.s index fef6c02eba82..f97fe4f534d2 100644 --- a/lld/test/COFF/autoimport-gc.s +++ b/lld/test/COFF/autoimport-gc.s @@ -2,7 +2,7 @@ # RUN: split-file %s %t.dir # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/lib.s -filetype=obj -o %t.dir/lib.obj -# RUN: lld-link -out:%t.dir/lib.dll -dll -entry:DllMainCRTStartup %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib +# RUN: lld-link -out:%t.dir/lib.dll -dll %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj # RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib -opt:ref -debug:dwarf diff --git a/lld/test/COFF/autoimport-lto.ll b/lld/test/COFF/autoimport-lto.ll index 94210e43cda6..9a63d2f232d4 100644 --- a/lld/test/COFF/autoimport-lto.ll +++ b/lld/test/COFF/autoimport-lto.ll @@ -2,7 +2,7 @@ ; RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s ; RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -; RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +; RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib ; RUN: llvm-as -o %t.obj %s ; RUN: lld-link -lldmingw -out:%t.exe -entry:entry %t.obj %t-lib.lib diff --git a/lld/test/COFF/autoimport-refptr.s b/lld/test/COFF/autoimport-refptr.s index 4071d6be0809..b087dd936355 100644 --- a/lld/test/COFF/autoimport-refptr.s +++ b/lld/test/COFF/autoimport-refptr.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=x86_64-windows-gnu %s -defsym listptrs=1 -filetype=obj -o %t.obj # RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose diff --git a/lld/test/COFF/autoimport-x86.s b/lld/test/COFF/autoimport-x86.s index 5d7c9c2c3fa5..39f2457a8259 100644 --- a/lld/test/COFF/autoimport-x86.s +++ b/lld/test/COFF/autoimport-x86.s @@ -2,7 +2,7 @@ # RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s # RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj -# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib +# RUN: lld-link -out:%t-lib.dll -dll %t-lib.obj -lldmingw -implib:%t-lib.lib # RUN: llvm-mc -triple=x86_64-windows-gnu -defsym listptrs=1 %s -filetype=obj -o %t.obj # RUN: lld-link -lldmingw -debug:symtab -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose diff --git a/lld/test/COFF/exclude-all.s b/lld/test/COFF/exclude-all.s index f1977836b18c..03dc0ddc6296 100644 --- a/lld/test/COFF/exclude-all.s +++ b/lld/test/COFF/exclude-all.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj -# RUN: lld-link -lldmingw -exclude-all-symbols -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj +# RUN: lld-link -lldmingw -exclude-all-symbols -dll -out:%t.dll %t.obj # RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s -check-prefix=NO-EXPORTS # NO-EXPORTS-NOT: Name: @@ -25,7 +25,7 @@ _dataSym: # RUN: yaml2obj %p/Inputs/export.yaml -o %t.obj # -# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -exclude-all-symbols -output-def:%t.def +# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -exclude-all-symbols -entry:_DllMainCRTStartup -output-def:%t.def # RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix=DLLEXPORT %s # DLLEXPORT: Name: exportfn3 diff --git a/lld/test/COFF/export-all.s b/lld/test/COFF/export-all.s index cd0a6f5f7b35..70266f37809c 100644 --- a/lld/test/COFF/export-all.s +++ b/lld/test/COFF/export-all.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj -# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj -implib:%t.lib +# RUN: lld-link -lldmingw -dll -out:%t.dll %t.obj -implib:%t.lib # RUN: llvm-readobj --coff-exports %t.dll | grep Name: | FileCheck %s # RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s --check-prefix=CHECK-RVA # RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s @@ -57,7 +57,7 @@ __imp__unexported: # RUN: yaml2obj %p/Inputs/export.yaml -o %t.obj # -# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -export-all-symbols -output-def:%t.def +# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -export-all-symbols -entry:_DllMainCRTStartup -output-def:%t.def # RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix=CHECK2 %s # RUN: cat %t.def | FileCheck -check-prefix=CHECK2-DEF %s @@ -88,7 +88,7 @@ __imp__unexported: # RUN: llvm-ar rcs %t.dir/libs/libmingwex.a %t.dir/libs/mingwfunc.o # RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %t.dir/libs/crtfunc.s # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/libs/crtfunc.s -filetype=obj -o %t.dir/libs/crt2.o -# RUN: lld-link -safeseh:no -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %t.dir/libs/crt2.o %t.dir/libs/libmingwex.a -output-def:%t.def +# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.main.obj -lldmingw %t.dir/libs/crt2.o %t.dir/libs/libmingwex.a -output-def:%t.def # RUN: echo "EOF" >> %t.def # RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s @@ -99,7 +99,7 @@ __imp__unexported: # Test that libraries included with -wholearchive: are autoexported, even if # they are in a library that otherwise normally would be excluded. -# RUN: lld-link -safeseh:no -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %t.dir/libs/crt2.o -wholearchive:%t.dir/libs/libmingwex.a -output-def:%t.def +# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.main.obj -lldmingw %t.dir/libs/crt2.o -wholearchive:%t.dir/libs/libmingwex.a -output-def:%t.def # RUN: echo "EOF" >> %t.def # RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s