diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 155e4ca6ee3f..5e5c7a974fa9 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1312,6 +1312,13 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) { if (Optional path = doFindFile(arg->getValue())) exporter.addWholeArchive(*path); + for (auto *arg : args.filtered(OPT_exclude_symbols)) { + SmallVector vec; + StringRef(arg->getValue()).split(vec, ','); + for (StringRef sym : vec) + exporter.addExcludedSymbol(mangle(sym)); + } + ctx.symtab.forEachSymbol([&](Symbol *s) { auto *def = dyn_cast(s); if (!exporter.shouldExport(ctx, def)) diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp index 7a3a3853572f..190f4388902e 100644 --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -122,6 +122,10 @@ void AutoExporter::addWholeArchive(StringRef path) { excludeLibs.erase(libName); } +void AutoExporter::addExcludedSymbol(StringRef symbol) { + excludeSymbols.insert(symbol); +} + bool AutoExporter::shouldExport(const COFFLinkerContext &ctx, Defined *sym) const { if (!sym || !sym->getChunk()) diff --git a/lld/COFF/MinGW.h b/lld/COFF/MinGW.h index 8f9343784fa0..4b65c20ec446 100644 --- a/lld/COFF/MinGW.h +++ b/lld/COFF/MinGW.h @@ -28,6 +28,7 @@ public: AutoExporter(); void addWholeArchive(StringRef path); + void addExcludedSymbol(StringRef symbol); llvm::StringSet<> excludeSymbols; llvm::StringSet<> excludeSymbolPrefixes; diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 5135f4ea34af..c728279ef5cc 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -45,6 +45,8 @@ def diasdkdir : P<"diasdkdir", "Set the location of the DIA SDK">; def entry : P<"entry", "Name of entry point symbol">; def errorlimit : P<"errorlimit", "Maximum number of errors to emit before stopping (0 = no limit)">; +def exclude_symbols : P<"exclude-symbols", "Exclude symbols from automatic export">, + MetaVarName<"">; def export : P<"export", "Export a function">; // No help text because /failifmismatch is not intended to be used by the user. def failifmismatch : P<"failifmismatch", "">; diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index 5920a5061d9c..37d2439c3925 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -398,6 +398,8 @@ bool mingw::link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, add("-delayload:" + StringRef(a->getValue())); for (auto *a : args.filtered(OPT_wrap)) add("-wrap:" + StringRef(a->getValue())); + for (auto *a : args.filtered(OPT_exclude_symbols)) + add("-exclude-symbols:" + StringRef(a->getValue())); std::vector searchPaths; for (auto *a : args.filtered(OPT_L)) { diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td index bfdd4af28800..cc94b93e388a 100644 --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -62,6 +62,8 @@ def enable_stdcall_fixup: F<"enable-stdcall-fixup">, defm entry: Eq<"entry", "Name of entry point symbol">, MetaVarName<"">; def exclude_all_symbols: F<"exclude-all-symbols">, HelpText<"Don't automatically export any symbols">; +defm exclude_symbols: Eq<"exclude-symbols", + "Exclude symbols from automatic export">, MetaVarName<"">; def export_all_symbols: F<"export-all-symbols">, HelpText<"Export all symbols even if a def file or dllexport attributes are used">; defm fatal_warnings: B<"fatal-warnings", diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 7759c149b142..21b3bade9d44 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -87,6 +87,8 @@ MinGW Improvements * The ``--disable-reloc-section`` option is now supported. (`D127478 `_) +* The ``--exclude-symbols`` option is now supported. + (`D130118 `_) MachO Improvements ------------------ diff --git a/lld/test/COFF/exclude-symbols.s b/lld/test/COFF/exclude-symbols.s new file mode 100644 index 000000000000..cd358712382d --- /dev/null +++ b/lld/test/COFF/exclude-symbols.s @@ -0,0 +1,20 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-win32-gnu %s -o %t.o + +// RUN: lld-link -lldmingw -dll -out:%t.dll %t.o -noentry -exclude-symbols:sym2,unknownsym -exclude-symbols:unknownsym,sym3 +// RUN: llvm-readobj --coff-exports %t.dll | FileCheck --implicit-check-not=Name: %s + +// CHECK: Name: +// CHECK: Name: sym1 + +.global _sym1 +_sym1: + ret + +.global _sym2 +_sym2: + ret + +.global _sym3 +_sym3: + ret diff --git a/lld/test/MinGW/driver.test b/lld/test/MinGW/driver.test index c67717d1a000..9c56bfa42f6b 100644 --- a/lld/test/MinGW/driver.test +++ b/lld/test/MinGW/driver.test @@ -321,6 +321,10 @@ RUN: ld.lld -### -m i386pep foo.o -wrap foo1 --wrap foo2 2>&1 | FileCheck -check RUN: ld.lld -### -m i386pep foo.o -wrap=foo1 --wrap=foo2 2>&1 | FileCheck -check-prefix WRAP %s WRAP: -wrap:foo1 -wrap:foo2 +RUN: ld.lld -### -m i386pep foo.o -exclude-symbols sym1,sym2 --exclude-symbols sym3 2>&1 | FileCheck -check-prefix EXCLUDE_SYMBOLS %s +RUN: ld.lld -### -m i386pep foo.o -exclude-symbols=sym1,sym2 --exclude-symbols=sym3 2>&1 | FileCheck -check-prefix EXCLUDE_SYMBOLS %s +EXCLUDE_SYMBOLS: -exclude-symbols:sym1,sym2 -exclude-symbols:sym3 + RUN: ld.lld -### -m i386pep foo.o 2>&1 | FileCheck -check-prefix DEMANGLE %s RUN: ld.lld -### -m i386pep foo.o -demangle 2>&1 | FileCheck -check-prefix DEMANGLE %s RUN: ld.lld -### -m i386pep foo.o --demangle 2>&1 | FileCheck -check-prefix DEMANGLE %s