diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -53,6 +53,7 @@ struct ParsedDirectives { std::vector exports; std::vector includes; + std::vector excludes; llvm::opt::InputArgList args; }; @@ -159,6 +160,7 @@ std::vector resources; llvm::DenseSet directivesExports; + llvm::DenseSet excludedSymbols; COFFLinkerContext &ctx; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -375,6 +375,14 @@ 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()) { @@ -1309,7 +1317,7 @@ 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/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -899,6 +899,9 @@ 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.h b/lld/COFF/MinGW.h --- 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 @@ -24,7 +25,7 @@ // symbols for MinGW. class AutoExporter { public: - AutoExporter(); + AutoExporter(const llvm::DenseSet &manualExcludeSymbols); void addWholeArchive(StringRef path); void addExcludedSymbol(StringRef symbol); @@ -35,6 +36,8 @@ llvm::StringSet<> excludeLibs; llvm::StringSet<> excludeObjects; + const llvm::DenseSet &manualExcludeSymbols; + bool shouldExport(const COFFLinkerContext &ctx, Defined *sym) const; }; diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -23,7 +23,9 @@ 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 @@ // 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/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -42,6 +42,9 @@ * 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 --- /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"