diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 5e5c7a974fa9e..680f89b79b958 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -372,6 +372,14 @@ void LinkerDriver::parseDirectives(InputFile *file) { for (StringRef inc : directives.includes) addUndefined(inc); + // Handle /exclude-symbols: in bulk. + for (StringRef e : directives.excludes) { + SmallVector vec; + e.split(vec, ','); + for (StringRef sym : vec) + excludedSymbols.insert(mangle(sym)); + } + // https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=msvc-160 for (auto *arg : directives.args) { switch (arg->getOption().getID()) { @@ -1306,7 +1314,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) { return; } - AutoExporter exporter; + AutoExporter exporter(excludedSymbols); for (auto *arg : args.filtered(OPT_wholearchive_file)) if (Optional path = doFindFile(arg->getValue())) diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index 955ec200da7dc..129a3d9c7317a 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -54,6 +54,7 @@ extern COFFOptTable optTable; struct ParsedDirectives { std::vector exports; std::vector includes; + std::vector excludes; llvm::opt::InputArgList args; }; @@ -160,6 +161,7 @@ class LinkerDriver { std::vector resources; llvm::DenseSet directivesExports; + llvm::DenseSet excludedSymbols; COFFLinkerContext &ctx; diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index 29a2d01658391..cdfe8587f3fa9 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -909,6 +909,9 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) { else if (tok.startswith_insensitive("/include:") || tok.startswith_insensitive("-include:")) result.includes.push_back(tok.substr(strlen("/include:"))); + else if (tok.startswith_insensitive("/exclude-symbols:") || + tok.startswith_insensitive("-exclude-symbols:")) + result.excludes.push_back(tok.substr(strlen("/exclude-symbols:"))); else { // Copy substrings that are not valid C strings. The tokenizer may have // already copied quoted arguments for us, so those do not need to be diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp index 190f4388902e5..0689e44cc3639 100644 --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -23,7 +23,9 @@ using namespace llvm::COFF; using namespace lld; using namespace lld::coff; -AutoExporter::AutoExporter() { +AutoExporter::AutoExporter( + const llvm::DenseSet &manualExcludeSymbols) + : manualExcludeSymbols(manualExcludeSymbols) { excludeLibs = { "libgcc", "libgcc_s", @@ -135,7 +137,7 @@ bool AutoExporter::shouldExport(const COFFLinkerContext &ctx, // disallow import symbols. if (!isa(sym) && !isa(sym)) return false; - if (excludeSymbols.count(sym->getName())) + if (excludeSymbols.count(sym->getName()) || manualExcludeSymbols.count(sym->getName())) return false; for (StringRef prefix : excludeSymbolPrefixes.keys()) diff --git a/lld/COFF/MinGW.h b/lld/COFF/MinGW.h index 4b65c20ec4466..5f2bbe4e99201 100644 --- a/lld/COFF/MinGW.h +++ b/lld/COFF/MinGW.h @@ -13,6 +13,7 @@ #include "Symbols.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringSet.h" #include "llvm/Option/ArgList.h" #include @@ -25,7 +26,7 @@ class COFFLinkerContext; // symbols for MinGW. class AutoExporter { public: - AutoExporter(); + AutoExporter(const llvm::DenseSet &manualExcludeSymbols); void addWholeArchive(StringRef path); void addExcludedSymbol(StringRef symbol); @@ -36,6 +37,8 @@ class AutoExporter { llvm::StringSet<> excludeLibs; llvm::StringSet<> excludeObjects; + const llvm::DenseSet &manualExcludeSymbols; + bool shouldExport(const COFFLinkerContext &ctx, Defined *sym) const; }; diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 21b3bade9d440..5819d67d32971 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -90,6 +90,9 @@ MinGW Improvements * The ``--exclude-symbols`` option is now supported. (`D130118 `_) +* Support for an entirely new object file directive, ``-exclude-symbols:``, + has been implemented. (`D130120 `_) + MachO Improvements ------------------ diff --git a/lld/test/COFF/exclude-symbols-embedded.s b/lld/test/COFF/exclude-symbols-embedded.s new file mode 100644 index 0000000000000..9ea8ed479d20e --- /dev/null +++ b/lld/test/COFF/exclude-symbols-embedded.s @@ -0,0 +1,24 @@ +// 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 +// 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 + +.section .drectve,"yn" +.ascii " -exclude-symbols:sym2,unknownsym" +.ascii " -exclude-symbols:unkonwnsym,sym3"