Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -548,42 +548,92 @@ } } -// Get a set of symbols not to automatically export -// when exporting all global symbols for MinGW. -static StringSet<> getExportExcludeSymbols() { - if (Config->Machine == I386) - return { - "__NULL_IMPORT_DESCRIPTOR", - "__pei386_runtime_relocator", - "_do_pseudo_reloc", - "_impure_ptr", - "__impure_ptr", - "__fmode", - "_environ", - "___dso_handle", - // These are the MinGW names that differ from the standard - // ones (lacking an extra underscore). - "_DllMain@12", - "_DllEntryPoint@12", - "_DllMainCRTStartup@12", - }; - - return { - "_NULL_IMPORT_DESCRIPTOR", - "_pei386_runtime_relocator", - "do_pseudo_reloc", - "impure_ptr", - "_impure_ptr", - "_fmode", - "environ", - "__dso_handle", - // These are the MinGW names that differ from the standard - // ones (lacking an extra underscore). - "DllMain", - "DllEntryPoint", - "DllMainCRTStartup", +// Logic for deciding what symbols to export, when exporting all +// symbols for MinGW. +class AutoExporter { +public: + AutoExporter() { + if (Config->Machine == I386) + ExcludeSymbols = { + "__NULL_IMPORT_DESCRIPTOR", + "__pei386_runtime_relocator", + "_do_pseudo_reloc", + "_impure_ptr", + "__impure_ptr", + "__fmode", + "_environ", + "___dso_handle", + // These are the MinGW names that differ from the standard + // ones (lacking an extra underscore). + "_DllMain@12", + "_DllEntryPoint@12", + "_DllMainCRTStartup@12", + }; + else + ExcludeSymbols = { + "_NULL_IMPORT_DESCRIPTOR", + "_pei386_runtime_relocator", + "do_pseudo_reloc", + "impure_ptr", + "_impure_ptr", + "_fmode", + "environ", + "__dso_handle", + // These are the MinGW names that differ from the standard + // ones (lacking an extra underscore). + "DllMain", + "DllEntryPoint", + "DllMainCRTStartup", + }; + } + + StringSet<> ExcludeSymbols; + StringSet<> ExcludeLibs = { + "libgcc", + "libgcc_s", + "libstdc++", + "libmingw32", + "libmingwex", + "libg2c", + "libsupc++", + "libobjc", + "libgcj", + "libclang_rt.builtins-aarch64", + "libclang_rt.builtins-arm", + "libclang_rt.builtins-i386", + "libclang_rt.builtins-x86_64", + }; + StringSet<> 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", }; -} + + bool shouldExport(Defined *Sym) const { + if (!Sym || !Sym->isLive() || !Sym->getChunk()) + return false; + if (ExcludeSymbols.count(Sym->getName())) + return false; + StringRef LibName = sys::path::filename(Sym->getFile()->ParentName); + // Drop the file extension. + LibName = LibName.substr(0, LibName.rfind('.')); + if (ExcludeLibs.count(LibName)) + return false; + StringRef FileName = sys::path::filename(Sym->getFile()->getName()); + if (LibName.empty() && ExcludeObjects.count(FileName)) + return false; + return true; + } +}; // This is MinGW specific. static void writeDefFile(StringRef Name) { @@ -1259,13 +1309,11 @@ // are chosen to be exported. if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) || Args.hasArg(OPT_export_all_symbols))) { - StringSet<> ExcludeSymbols = getExportExcludeSymbols(); + AutoExporter Exporter; Symtab->forEachSymbol([=](Symbol *S) { auto *Def = dyn_cast(S->body()); - if (!Def || !Def->isLive() || !Def->getChunk()) - return; - if (ExcludeSymbols.count(Def->getName())) + if (!Exporter.shouldExport(Def)) return; Export E; E.Name = Def->getName(); Index: lld/trunk/test/COFF/export-all.s =================================================================== --- lld/trunk/test/COFF/export-all.s +++ lld/trunk/test/COFF/export-all.s @@ -36,3 +36,21 @@ # CHECK2-DEF: exportfn1 @3 # CHECK2-DEF: exportfn2 @4 # CHECK2-DEF: exportfn3 @5 + +# Test ignoring certain object files and libs. + +# RUN: echo -e ".global foobar\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\nfoobar:\ncall mingwfunc\ncall crtfunc\nret\n" > %t.main.s +# RUN: llvm-mc -triple=x86_64-windows-gnu %t.main.s -filetype=obj -o %t.main.obj +# RUN: mkdir -p %T/libs +# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s +# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o +# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o +# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s +# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o +# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o %T/libs/libmingwex.a -output-def:%t.def +# RUN: echo "EOF" >> %t.def +# RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s + +# CHECK-EXCLUDE: EXPORTS +# CHECK-EXCLUDE-NEXT: foobar @1 +# CHECK-EXCLUDE-NEXT: EOF