diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -96,6 +96,8 @@ // Library search path. The first element is always "" (current directory). std::vector SearchPaths; + void maybeExportMinGWSymbols(const llvm::opt::InputArgList &Args); + // We don't want to add the same file more than once. // Files are uniquified by their filesystem and file number. std::set VisitedFiles; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -907,6 +907,35 @@ Config->PDBAltPath = Buf; } +void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &Args) { + if (!Config->DLL) + return; + if (!Config->Exports.empty() && !Args.hasArg(OPT_export_all_symbols)) + return; + + AutoExporter Exporter; + + for (auto *Arg : Args.filtered(OPT_wholearchive_file)) + if (Optional Path = doFindFile(Arg->getValue())) + Exporter.addWholeArchive(*Path); + + Symtab->forEachSymbol([&](Symbol *S) { + auto *Def = dyn_cast(S); + if (!Exporter.shouldExport(Def)) + return; + + Export E; + E.Name = Def->getName(); + E.Sym = Def; + bool IsExec = + Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE; + + if (Def->getChunk() && !IsExec) + E.Data = true; + Config->Exports.push_back(E); + }); +} + void LinkerDriver::link(ArrayRef ArgsArr) { // If the first command line argument is "/lib", link.exe acts like lib.exe. // We call our own implementation of lib.exe that understands bitcode files. @@ -1335,14 +1364,10 @@ return; std::set WholeArchives; - AutoExporter Exporter; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) { - if (Optional Path = doFindFile(Arg->getValue())) { + 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. @@ -1606,23 +1631,8 @@ // In MinGW, all symbols are automatically exported if no symbols // are chosen to be exported. - if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) || - Args.hasArg(OPT_export_all_symbols))) { - Exporter.initSymbolExcludes(); - - Symtab->forEachSymbol([=](Symbol *S) { - auto *Def = dyn_cast(S); - if (!Exporter.shouldExport(Def)) - return; - Export E; - E.Name = Def->getName(); - E.Sym = Def; - if (Def->getChunk() && - !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) - E.Data = true; - Config->Exports.push_back(E); - }); - } + if (Config->MinGW) + maybeExportMinGWSymbols(Args); // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. diff --git a/lld/COFF/MinGW.h b/lld/COFF/MinGW.h --- a/lld/COFF/MinGW.h +++ b/lld/COFF/MinGW.h @@ -22,8 +22,6 @@ public: AutoExporter(); - void initSymbolExcludes(); - void addWholeArchive(StringRef Path); llvm::StringSet<> ExcludeSymbols; diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -18,7 +18,34 @@ using namespace llvm; using namespace llvm::COFF; -void AutoExporter::initSymbolExcludes() { +AutoExporter::AutoExporter() { + ExcludeLibs = { + "libgcc", + "libgcc_s", + "libstdc++", + "libmingw32", + "libmingwex", + "libg2c", + "libsupc++", + "libobjc", + "libgcj", + "libclang_rt.builtins", + "libclang_rt.builtins-aarch64", + "libclang_rt.builtins-arm", + "libclang_rt.builtins-i386", + "libclang_rt.builtins-x86_64", + "libc++", + "libc++abi", + "libunwind", + "libmsvcrt", + "libucrtbase", + }; + + ExcludeObjects = { + "crt0.o", "crt1.o", "crt1u.o", "crt2.o", "crt2u.o", "dllcrt1.o", + "dllcrt2.o", "gcrt0.o", "gcrt1.o", "gcrt2.o", "crtbegin.o", "crtend.o", + }; + ExcludeSymbolPrefixes = { // Import symbols "__imp_", @@ -31,10 +58,12 @@ // Artifical symbols such as .refptr ".", }; + ExcludeSymbolSuffixes = { "_iname", "_NULL_THUNK_DATA", }; + if (Config->Machine == I386) { ExcludeSymbols = { "__NULL_IMPORT_DESCRIPTOR", @@ -72,44 +101,6 @@ } } -AutoExporter::AutoExporter() { - ExcludeLibs = { - "libgcc", - "libgcc_s", - "libstdc++", - "libmingw32", - "libmingwex", - "libg2c", - "libsupc++", - "libobjc", - "libgcj", - "libclang_rt.builtins", - "libclang_rt.builtins-aarch64", - "libclang_rt.builtins-arm", - "libclang_rt.builtins-i386", - "libclang_rt.builtins-x86_64", - "libc++", - "libc++abi", - "libunwind", - "libmsvcrt", - "libucrtbase", - }; - ExcludeObjects = { - "crt0.o", - "crt1.o", - "crt1u.o", - "crt2.o", - "crt2u.o", - "dllcrt1.o", - "dllcrt2.o", - "gcrt0.o", - "gcrt1.o", - "gcrt2.o", - "crtbegin.o", - "crtend.o", - }; -} - void AutoExporter::addWholeArchive(StringRef Path) { StringRef LibName = sys::path::filename(Path); // Drop the file extension, to match the processing below.