diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1315,6 +1315,13 @@ 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.h b/lld/COFF/MinGW.h --- a/lld/COFF/MinGW.h +++ b/lld/COFF/MinGW.h @@ -27,6 +27,7 @@ AutoExporter(); void addWholeArchive(StringRef path); + void addExcludedSymbol(StringRef symbol); llvm::StringSet<> excludeSymbols; llvm::StringSet<> excludeSymbolPrefixes; diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -122,6 +122,10 @@ 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/Options.td b/lld/COFF/Options.td --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -45,6 +45,8 @@ 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 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -398,6 +398,8 @@ 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 --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -62,6 +62,8 @@ 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 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -39,7 +39,8 @@ MinGW Improvements ------------------ -* ... +* 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 --- /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 --- 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-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