From 9a4b6b77325777062f6f128d499578bc3feac6e5 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Sat, 5 Jul 2025 11:05:34 -0400 Subject: [PATCH] Follow up comments on pr146610 --- lld/COFF/Config.h | 2 +- lld/COFF/Driver.cpp | 4 +- lld/COFF/InputFiles.cpp | 14 ++--- lld/test/COFF/imported-dllmain-i386.test | 59 +++++++++++++++++++ ...ted-dllmain.test => imported-dllmain.test} | 6 +- 5 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 lld/test/COFF/imported-dllmain-i386.test rename lld/test/COFF/{exported-dllmain.test => imported-dllmain.test} (86%) diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 79b63e5b7236f..9220c847f356d 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -307,7 +307,7 @@ struct Configuration { bool warnDebugInfoUnusable = true; bool warnLongSectionNames = true; bool warnStdcallFixup = true; - bool warnExportedDllMain = true; + bool warnImportedDllMain = true; bool incremental = true; bool integrityCheck = false; bool killAt = false; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 283aeed1a19cd..0f649ff1cf4f8 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1643,8 +1643,8 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->warnLocallyDefinedImported = false; else if (s == "longsections") config->warnLongSectionNames = false; - else if (s == "exporteddllmain") - config->warnExportedDllMain = false; + else if (s == "importeddllmain") + config->warnImportedDllMain = false; // Other warning numbers are ignored. } } diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 0b7dbea8cdd99..1edd24cdf2dea 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -128,13 +128,13 @@ static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file, file->getFileName() + ": could not get the buffer for a child buffer of the archive"); if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) { - if (ctx.config.warnExportedDllMain) { + if (ctx.config.warnImportedDllMain) { // We won't place DllMain symbols in the symbol table if they are // coming from a import library. This message can be ignored with the flag - // '/ignore:exporteddllmain' + // '/ignore:importeddllmain' Warn(ctx) << file->getFileName() - << ": skipping exported DllMain symbol [exporteddllmain]\nNOTE: this " + << ": skipping imported DllMain symbol [importeddllmain]\nNOTE: this " "might be a mistake when the DLL/library was produced."; } skipDllMain = true; @@ -207,10 +207,10 @@ void ArchiveFile::parse() { // Read the symbol table to construct Lazy objects. bool skipDllMain = false; for (const Archive::Symbol &sym : file->symbols()) { - // If the DllMain symbol was exported by mistake, skip importing it - // otherwise we might end up with a import thunk in the final binary which - // is wrong. - if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain") { + // If an import library provides the DllMain symbol, skip importing it, as + // we should be using our own DllMain, not another DLL's DllMain. + if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain" || + sym.getName() == "_DllMain") { if (fixupDllMain(ctx, file.get(), sym, skipDllMain)) continue; } diff --git a/lld/test/COFF/imported-dllmain-i386.test b/lld/test/COFF/imported-dllmain-i386.test new file mode 100644 index 0000000000000..a9cd94d089e29 --- /dev/null +++ b/lld/test/COFF/imported-dllmain-i386.test @@ -0,0 +1,59 @@ +REQUIRES: x86 +RUN: split-file %s %t.dir && cd %t.dir + +RUN: llvm-mc -filetype=obj -triple=i386-windows a.s -o a.obj + +RUN: llvm-mc -filetype=obj -triple=i386-windows b1.s -o b1.obj +RUN: llvm-mc -filetype=obj -triple=i386-windows b2.s -o b2.obj + +### This is the line where our problem occurs. Here, we export the DllMain symbol which shouldn't happen normally. +RUN: lld-link b1.obj b2.obj -out:b.dll -dll -implib:b.lib -entry:DllMain -export:bar -export:DllMain -safeseh:no + +RUN: llvm-mc -filetype=obj -triple=i386-windows c.s -o c.obj +RUN: lld-link -lib c.obj -out:c.lib + +### Later, if b.lib is provided before other libs/objs that export DllMain statically, we previously were using the dllimported DllMain from b.lib, which is wrong. +RUN: lld-link a.obj b.lib c.lib -dll -out:out.dll -entry:DllMain -safeseh:no 2>&1 | FileCheck -check-prefix=WARN %s +RUN: lld-link a.obj b.lib c.lib -dll -out:out.dll -entry:DllMain -ignore:importeddllmain -safeseh:no 2>&1 | FileCheck -check-prefix=IGNORED --allow-empty %s +RUN: llvm-objdump --private-headers -d out.dll | FileCheck -check-prefix=DISASM %s + +WARN: lld-link: warning: b.lib: skipping imported DllMain symbol [importeddllmain] +IGNORED-NOT: lld-link: warning: b.lib: skipping imported DllMain symbol [importeddllmain] + +DISASM: The Import Tables: +DISASM: DLL Name: b.dll +DISASM-NOT: DllMain +DISASM: bar +DISASM: Disassembly of section .text: +DISASM-EMPTY: +DISASM-NEXT: b0 01 movb $0x1, %al +DISASM-NEXT: c3 retl + +#--- a.s + .text + .globl _foo +_foo: + call *__imp__bar + ret + +#--- b1.s + .text + .globl _bar +_bar: + ret + +#--- b2.s + .intel_syntax noprefix + .text + .globl _DllMain +_DllMain: + xor al, al + ret + +#--- c.s + .intel_syntax noprefix + .text + .globl _DllMain +_DllMain: + mov al, 1 + ret diff --git a/lld/test/COFF/exported-dllmain.test b/lld/test/COFF/imported-dllmain.test similarity index 86% rename from lld/test/COFF/exported-dllmain.test rename to lld/test/COFF/imported-dllmain.test index fcf6ed1005379..fa8579b1b41c5 100644 --- a/lld/test/COFF/exported-dllmain.test +++ b/lld/test/COFF/imported-dllmain.test @@ -14,11 +14,11 @@ RUN: lld-link -lib c.obj -out:c.lib ### Later, if b.lib is provided before other libs/objs that export DllMain statically, we previously were using the dllimported DllMain from b.lib, which is wrong. RUN: lld-link a.obj b.lib c.lib -dll -out:out.dll -entry:DllMain 2>&1 | FileCheck -check-prefix=WARN %s -RUN: lld-link a.obj b.lib c.lib -dll -out:out.dll -entry:DllMain -ignore:exporteddllmain 2>&1 | FileCheck -check-prefix=IGNORED --allow-empty %s +RUN: lld-link a.obj b.lib c.lib -dll -out:out.dll -entry:DllMain -ignore:importeddllmain 2>&1 | FileCheck -check-prefix=IGNORED --allow-empty %s RUN: llvm-objdump --private-headers -d out.dll | FileCheck -check-prefix=DISASM %s -WARN: lld-link: warning: b.lib: skipping exported DllMain symbol [exporteddllmain] -IGNORED-NOT: lld-link: warning: b.lib: skipping exported DllMain symbol [exporteddllmain] +WARN: lld-link: warning: b.lib: skipping imported DllMain symbol [importeddllmain] +IGNORED-NOT: lld-link: warning: b.lib: skipping imported DllMain symbol [importeddllmain] DISASM: The Import Tables: DISASM: DLL Name: b.dll