Move MinGW-specific code out of LinkerDriver::link. NFC.

LinkerDriver::link is getting too long, it's time to simplify it.

Differential Revision: https://reviews.llvm.org/D58395

llvm-svn: 354391
This commit is contained in:
Rui Ueyama 2019-02-19 22:06:44 +00:00
parent 89d4a9d6e4
commit 659f2752a0
4 changed files with 76 additions and 71 deletions

View File

@ -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.

View File

@ -96,6 +96,8 @@ private:
// Library search path. The first element is always "" (current directory).
std::vector<StringRef> 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<llvm::sys::fs::UniqueID> VisitedFiles;

View File

@ -18,7 +18,34 @@ using namespace lld::coff;
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 @@ void AutoExporter::initSymbolExcludes() {
// Artifical symbols such as .refptr
".",
};
ExcludeSymbolSuffixes = {
"_iname",
"_NULL_THUNK_DATA",
};
if (Config->Machine == I386) {
ExcludeSymbols = {
"__NULL_IMPORT_DESCRIPTOR",
@ -72,44 +101,6 @@ 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",
};
}
void AutoExporter::addWholeArchive(StringRef Path) {
StringRef LibName = sys::path::filename(Path);
// Drop the file extension, to match the processing below.

View File

@ -22,8 +22,6 @@ class AutoExporter {
public:
AutoExporter();
void initSymbolExcludes();
void addWholeArchive(StringRef Path);
llvm::StringSet<> ExcludeSymbols;