Index: COFF/MinGW.h =================================================================== --- COFF/MinGW.h +++ COFF/MinGW.h @@ -28,6 +28,8 @@ void addWholeArchive(StringRef Path); llvm::StringSet<> ExcludeSymbols; + llvm::StringSet<> ExcludeSymbolPrefixes; + llvm::StringSet<> ExcludeSymbolSuffixes; llvm::StringSet<> ExcludeLibs; llvm::StringSet<> ExcludeObjects; Index: COFF/MinGW.cpp =================================================================== --- COFF/MinGW.cpp +++ COFF/MinGW.cpp @@ -20,6 +20,22 @@ using namespace llvm::COFF; void AutoExporter::initSymbolExcludes() { + ExcludeSymbolPrefixes = { + // Import symbols + "__imp_", + "__IMPORT_DESCRIPTOR_", + // Extra import symbols from GNU import libraries + "__nm_", + // C++ symbols + "__rtti_", + "__builtin_", + // Artifical symbols such as .refptr + ".", + }; + ExcludeSymbolSuffixes = { + "_iname", + "_NULL_THUNK_DATA", + }; if (Config->Machine == I386) { ExcludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", @@ -36,6 +52,7 @@ "_DllEntryPoint@12", "_DllMainCRTStartup@12", }; + ExcludeSymbolPrefixes.insert("__head_"); } else { ExcludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", @@ -52,6 +69,7 @@ "DllEntryPoint", "DllMainCRTStartup", }; + ExcludeSymbolPrefixes.insert("_head_"); } } @@ -110,11 +128,12 @@ if (ExcludeSymbols.count(Sym->getName())) return false; - // Don't export anything that looks like an import symbol (which also can be - // a manually defined data symbol with such a name); don't export artificial - // symbols like .refptr pointer stubs. - if (Sym->getName().startswith("__imp_") || Sym->getName().startswith(".")) - return false; + for (StringRef Prefix : ExcludeSymbolPrefixes.keys()) + if (Sym->getName().startswith(Prefix)) + return false; + for (StringRef Suffix : ExcludeSymbolSuffixes.keys()) + if (Sym->getName().endswith(Suffix)) + return false; // If a corresponding __imp_ symbol exists and is defined, don't export it. if (Symtab->find(("__imp_" + Sym->getName()).str())) Index: test/COFF/imports-gnu-autoexport.s =================================================================== --- test/COFF/imports-gnu-autoexport.s +++ test/COFF/imports-gnu-autoexport.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# +# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o +# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o +# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o +# RUN: rm -f %t-implib.a +# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o +# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main -subsystem:console \ +# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib %t-implib.a -include:func +# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix=EXPORT %s + +# Check that only the single normal symbol was exported, none of the symbols +# from the import library. + +EXPORT: Export { +EXPORT-NEXT: Ordinal: 0 +EXPORT-NEXT: Name: +EXPORT-NEXT: RVA: 0x0 +EXPORT-NEXT: } +EXPORT-NEXT: Export { +EXPORT-NEXT: Ordinal: 1 +EXPORT-NEXT: Name: main +EXPORT-NEXT: RVA: 0x1010 +EXPORT-NEXT: } +EXPORT-NEXT-EMPTY: