[LLD] [COFF] Add support for a new, mingw specific embedded directive -exclude-symbols:
authorMartin Storsjö <martin@martin.st>
Sun, 17 Jul 2022 21:11:37 +0000 (00:11 +0300)
committerMartin Storsjö <martin@martin.st>
Thu, 11 Aug 2022 08:59:48 +0000 (11:59 +0300)
This is an entirely new embedded directive - extending the GNU ld
command line option --exclude-symbols to be usable in embedded
directives too.

(GNU ld.bfd also got support for the same new directive, currently in
the latest git version, after the 2.39 branch.)

This works as an inverse to the regular embedded dllexport directives,
for cases when autoexport of all eligible symbols is performed.

Differential Revision: https://reviews.llvm.org/D130120

lld/COFF/Driver.cpp
lld/COFF/Driver.h
lld/COFF/DriverUtils.cpp
lld/COFF/MinGW.cpp
lld/COFF/MinGW.h
lld/docs/ReleaseNotes.rst
lld/test/COFF/exclude-symbols-embedded.s [new file with mode: 0644]

index 4440634..11248d2 100644 (file)
@@ -375,6 +375,14 @@ void LinkerDriver::parseDirectives(InputFile *file) {
   for (StringRef inc : directives.includes)
     addUndefined(inc);
 
+  // Handle /exclude-symbols: in bulk.
+  for (StringRef e : directives.excludes) {
+    SmallVector<StringRef, 2> 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 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
       return;
   }
 
-  AutoExporter exporter;
+  AutoExporter exporter(excludedSymbols);
 
   for (auto *arg : args.filtered(OPT_wholearchive_file))
     if (Optional<StringRef> path = doFindFile(arg->getValue()))
index 902f122..3f6f98d 100644 (file)
@@ -53,6 +53,7 @@ extern COFFOptTable optTable;
 struct ParsedDirectives {
   std::vector<StringRef> exports;
   std::vector<StringRef> includes;
+  std::vector<StringRef> excludes;
   llvm::opt::InputArgList args;
 };
 
@@ -159,6 +160,7 @@ private:
   std::vector<MemoryBufferRef> resources;
 
   llvm::DenseSet<StringRef> directivesExports;
+  llvm::DenseSet<StringRef> excludedSymbols;
 
   COFFLinkerContext &ctx;
 
index 505967f..ab69551 100644 (file)
@@ -899,6 +899,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
index 190f438..0689e44 100644 (file)
@@ -23,7 +23,9 @@ using namespace llvm::COFF;
 using namespace lld;
 using namespace lld::coff;
 
-AutoExporter::AutoExporter() {
+AutoExporter::AutoExporter(
+    const llvm::DenseSet<StringRef> &manualExcludeSymbols)
+    : manualExcludeSymbols(manualExcludeSymbols) {
   excludeLibs = {
       "libgcc",
       "libgcc_s",
@@ -135,7 +137,7 @@ bool AutoExporter::shouldExport(const COFFLinkerContext &ctx,
   // disallow import symbols.
   if (!isa<DefinedRegular>(sym) && !isa<DefinedCommon>(sym))
     return false;
-  if (excludeSymbols.count(sym->getName()))
+  if (excludeSymbols.count(sym->getName()) || manualExcludeSymbols.count(sym->getName()))
     return false;
 
   for (StringRef prefix : excludeSymbolPrefixes.keys())
index af40d1b..113cd83 100644 (file)
@@ -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 <vector>
@@ -24,7 +25,7 @@ class COFFLinkerContext;
 // symbols for MinGW.
 class AutoExporter {
 public:
-  AutoExporter();
+  AutoExporter(const llvm::DenseSet<StringRef> &manualExcludeSymbols);
 
   void addWholeArchive(StringRef path);
   void addExcludedSymbol(StringRef symbol);
@@ -35,6 +36,8 @@ public:
   llvm::StringSet<> excludeLibs;
   llvm::StringSet<> excludeObjects;
 
+  const llvm::DenseSet<StringRef> &manualExcludeSymbols;
+
   bool shouldExport(const COFFLinkerContext &ctx, Defined *sym) const;
 };
 
index fcf9e99..d6b149d 100644 (file)
@@ -42,6 +42,9 @@ MinGW Improvements
 * The ``--exclude-symbols`` option is now supported.
   (`D130118 <https://reviews.llvm.org/D130118>`_)
 
+* Support for an entirely new object file directive, ``-exclude-symbols:``,
+  has been implemented. (`D130120 <https://reviews.llvm.org/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 (file)
index 0000000..9ea8ed4
--- /dev/null
@@ -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"