Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -1198,10 +1198,14 @@ return; std::set WholeArchives; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) - if (Optional Path = doFindFile(Arg->getValue())) + AutoExporter Exporter; + for (auto *Arg : Args.filtered(OPT_wholearchive_file)) { + if (Optional Path = doFindFile(Arg->getValue())) { if (Optional ID = getUniqueID(*Path)) WholeArchives.insert(*ID); + Exporter.addWholeArchive(*Path); + } + } // A predicate returning true if a given path is an argument for // /wholearchive:, or /wholearchive is enabled globally. @@ -1458,7 +1462,7 @@ // are chosen to be exported. if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) || Args.hasArg(OPT_export_all_symbols))) { - AutoExporter Exporter; + Exporter.initSymbolExcludes(); Symtab->forEachSymbol([=](Symbol *S) { auto *Def = dyn_cast(S); Index: lld/trunk/COFF/MinGW.h =================================================================== --- lld/trunk/COFF/MinGW.h +++ lld/trunk/COFF/MinGW.h @@ -23,6 +23,10 @@ public: AutoExporter(); + void initSymbolExcludes(); + + void addWholeArchive(StringRef Path); + llvm::StringSet<> ExcludeSymbols; llvm::StringSet<> ExcludeLibs; llvm::StringSet<> ExcludeObjects; Index: lld/trunk/COFF/MinGW.cpp =================================================================== --- lld/trunk/COFF/MinGW.cpp +++ lld/trunk/COFF/MinGW.cpp @@ -19,7 +19,7 @@ using namespace llvm; using namespace llvm::COFF; -AutoExporter::AutoExporter() { +void AutoExporter::initSymbolExcludes() { if (Config->Machine == I386) { ExcludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", @@ -53,7 +53,9 @@ "DllMainCRTStartup", }; } +} +AutoExporter::AutoExporter() { ExcludeLibs = { "libgcc", "libgcc_s", @@ -90,6 +92,13 @@ }; } +void AutoExporter::addWholeArchive(StringRef Path) { + StringRef LibName = sys::path::filename(Path); + // Drop the file extension, to match the processing below. + LibName = LibName.substr(0, LibName.rfind('.')); + ExcludeLibs.erase(LibName); +} + bool AutoExporter::shouldExport(Defined *Sym) const { if (!Sym || !Sym->isLive() || !Sym->getChunk()) return false; Index: lld/trunk/test/COFF/export-all.s =================================================================== --- lld/trunk/test/COFF/export-all.s +++ lld/trunk/test/COFF/export-all.s @@ -77,6 +77,18 @@ # CHECK-EXCLUDE-NEXT: foobar @1 # CHECK-EXCLUDE-NEXT: EOF +# Test that libraries included with -wholearchive: are autoexported, even if +# they are in a library that otherwise normally would be excluded. + +# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o -wholearchive:%T/libs/libmingwex.a -output-def:%t.def +# RUN: echo "EOF" >> %t.def +# RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s + +# CHECK-WHOLEARCHIVE: EXPORTS +# CHECK-WHOLEARCHIVE-NEXT: foobar @1 +# CHECK-WHOLEARCHIVE-NEXT: mingwfunc @2 +# CHECK-WHOLEARCHIVE-NEXT: EOF + # Test that we handle import libraries together with -opt:noref. # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj