diff options
Diffstat (limited to 'lld/COFF/Driver.cpp')
-rw-r--r-- | lld/COFF/Driver.cpp | 74 |
1 files changed, 44 insertions, 30 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index e4a3df409d8..1de196c6570 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -907,6 +907,44 @@ static void parsePDBAltPath(StringRef AltPath) { Config->PDBAltPath = Buf; } +// In MinGW, if no symbols are chosen to be exported, then all symbols are +// automatically exported by default. This behavior can be forced by the +// -export-all-symbols option, so that it happens even when exports are +// explicitly specified. The automatic behavior can be disabled using the +// -exclude-all-symbols option, so that lld-link behaves like link.exe rather +// than MinGW in the case that nothing is explicitly exported. +void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &Args) { + if (!Config->DLL) + return; + + if (!Args.hasArg(OPT_export_all_symbols)) { + if (!Config->Exports.empty()) + return; + if (Args.hasArg(OPT_exclude_all_symbols)) + return; + } + + AutoExporter Exporter; + + for (auto *Arg : Args.filtered(OPT_wholearchive_file)) + if (Optional<StringRef> Path = doFindFile(Arg->getValue())) + Exporter.addWholeArchive(*Path); + + Symtab->forEachSymbol([&](Symbol *S) { + auto *Def = dyn_cast<Defined>(S); + if (!Exporter.shouldExport(Def)) + return; + + Export E; + E.Name = Def->getName(); + E.Sym = Def; + if (Chunk *C = Def->getChunk()) + if (!(C->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) + E.Data = true; + Config->Exports.push_back(E); + }); +} + void LinkerDriver::link(ArrayRef<const char *> 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 +1373,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { return; std::set<sys::fs::UniqueID> WholeArchives; - AutoExporter Exporter; - for (auto *Arg : Args.filtered(OPT_wholearchive_file)) { - if (Optional<StringRef> Path = doFindFile(Arg->getValue())) { + for (auto *Arg : Args.filtered(OPT_wholearchive_file)) + if (Optional<StringRef> Path = doFindFile(Arg->getValue())) if (Optional<sys::fs::UniqueID> 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. @@ -1604,30 +1638,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { return; } - // In MinGW, if no symbols are chosen to be exported, then all symbols are - // automatically exported by default. This behavior can be forced by the - // -export-all-symbols option, so that it happens even when exports are - // explicitly specified. The automatic behavior can be disabled using the - // -exclude-all-symbols option, so that lld-link behaves like link.exe rather - // than MinGW in the case that nothing is explicitly exported. - if (Config->MinGW && Config->DLL && - ((Config->Exports.empty() && !Args.hasArg(OPT_exclude_all_symbols)) || - Args.hasArg(OPT_export_all_symbols))) { - Exporter.initSymbolExcludes(); - - Symtab->forEachSymbol([=](Symbol *S) { - auto *Def = dyn_cast<Defined>(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); - }); - } + // In MinGW, all symbols are automatically exported if no symbols + // are chosen to be exported. + if (Config->MinGW) + maybeExportMinGWSymbols(Args); // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. |