[LLD][COFF] Follow up comments on pr146610 (#147152)
This is a follow-up PR for post-commit comments in https://github.com/llvm/llvm-project/pull/146610 - Changed "exporteddllmain" references to "importeddllmain". - Add support for x86 target and test coverage. - Changed a comment to better express why we're skipping importing `DllMain`.
This commit is contained in:
parent
423cea7607
commit
fcacd4e880
@ -319,7 +319,7 @@ struct Configuration {
|
|||||||
bool warnDebugInfoUnusable = true;
|
bool warnDebugInfoUnusable = true;
|
||||||
bool warnLongSectionNames = true;
|
bool warnLongSectionNames = true;
|
||||||
bool warnStdcallFixup = true;
|
bool warnStdcallFixup = true;
|
||||||
bool warnExportedDllMain = true;
|
bool warnImportedDllMain = true;
|
||||||
bool incremental = true;
|
bool incremental = true;
|
||||||
bool integrityCheck = false;
|
bool integrityCheck = false;
|
||||||
bool killAt = false;
|
bool killAt = false;
|
||||||
|
@ -1643,8 +1643,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
|
|||||||
config->warnLocallyDefinedImported = false;
|
config->warnLocallyDefinedImported = false;
|
||||||
else if (s == "longsections")
|
else if (s == "longsections")
|
||||||
config->warnLongSectionNames = false;
|
config->warnLongSectionNames = false;
|
||||||
else if (s == "exporteddllmain")
|
else if (s == "importeddllmain")
|
||||||
config->warnExportedDllMain = false;
|
config->warnImportedDllMain = false;
|
||||||
// Other warning numbers are ignored.
|
// Other warning numbers are ignored.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,6 @@ static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) {
|
|||||||
// Skip importing DllMain thunks from import libraries.
|
// Skip importing DllMain thunks from import libraries.
|
||||||
static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
|
static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
|
||||||
const Archive::Symbol &sym, bool &skipDllMain) {
|
const Archive::Symbol &sym, bool &skipDllMain) {
|
||||||
if (skipDllMain)
|
|
||||||
return true;
|
|
||||||
const Archive::Child &c =
|
const Archive::Child &c =
|
||||||
CHECK(sym.getMember(), file->getFileName() +
|
CHECK(sym.getMember(), file->getFileName() +
|
||||||
": could not get the member for symbol " +
|
": could not get the member for symbol " +
|
||||||
@ -128,13 +126,13 @@ static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
|
|||||||
file->getFileName() +
|
file->getFileName() +
|
||||||
": could not get the buffer for a child buffer of the archive");
|
": could not get the buffer for a child buffer of the archive");
|
||||||
if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) {
|
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
|
// 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
|
// coming from a import library. This message can be ignored with the flag
|
||||||
// '/ignore:exporteddllmain'
|
// '/ignore:importeddllmain'
|
||||||
Warn(ctx)
|
Warn(ctx)
|
||||||
<< file->getFileName()
|
<< 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.";
|
"might be a mistake when the DLL/library was produced.";
|
||||||
}
|
}
|
||||||
skipDllMain = true;
|
skipDllMain = true;
|
||||||
@ -204,14 +202,24 @@ void ArchiveFile::parse() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the symbol table to construct Lazy objects.
|
|
||||||
bool skipDllMain = false;
|
bool skipDllMain = false;
|
||||||
|
StringRef mangledDllMain, impMangledDllMain;
|
||||||
|
|
||||||
|
// The calls below will fail if we haven't set the machine type yet. Instead
|
||||||
|
// of failing, it is preferable to skip this "imported DllMain" check if we
|
||||||
|
// don't know the machine type at this point.
|
||||||
|
if (!file->isEmpty() && ctx.config.machine != IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||||
|
mangledDllMain = archiveSymtab->mangle("DllMain");
|
||||||
|
impMangledDllMain = uniqueSaver().save("__imp_" + mangledDllMain);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the symbol table to construct Lazy objects.
|
||||||
for (const Archive::Symbol &sym : file->symbols()) {
|
for (const Archive::Symbol &sym : file->symbols()) {
|
||||||
// If the DllMain symbol was exported by mistake, skip importing it
|
// If an import library provides the DllMain symbol, skip importing it, as
|
||||||
// otherwise we might end up with a import thunk in the final binary which
|
// we should be using our own DllMain, not another DLL's DllMain.
|
||||||
// is wrong.
|
if (!mangledDllMain.empty() && (sym.getName() == mangledDllMain ||
|
||||||
if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain") {
|
sym.getName() == impMangledDllMain)) {
|
||||||
if (fixupDllMain(ctx, file.get(), sym, skipDllMain))
|
if (skipDllMain || fixupDllMain(ctx, file.get(), sym, skipDllMain))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
archiveSymtab->addLazyArchive(this, sym);
|
archiveSymtab->addLazyArchive(this, sym);
|
||||||
|
58
lld/test/COFF/imported-dllmain-i386.test
Normal file
58
lld/test/COFF/imported-dllmain-i386.test
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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: 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
|
@ -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.
|
### 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 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
|
RUN: llvm-objdump --private-headers -d out.dll | FileCheck -check-prefix=DISASM %s
|
||||||
|
|
||||||
WARN: 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 exported DllMain symbol [exporteddllmain]
|
IGNORED-NOT: lld-link: warning: b.lib: skipping imported DllMain symbol [importeddllmain]
|
||||||
|
|
||||||
DISASM: The Import Tables:
|
DISASM: The Import Tables:
|
||||||
DISASM: DLL Name: b.dll
|
DISASM: DLL Name: b.dll
|
Loading…
x
Reference in New Issue
Block a user