[lld] [LLD][COFF] Add support for MinGW auto-export on ARM64X (PR #125862)

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 5 06:21:22 PST 2025


https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/125862

Export all symbols from both EC and native symbol tables. If an explicit export is present in only one symbol table, auto-export for the other symbol table remains unaffected.

>From a549289119900193da2898e3bd18e68687818c47 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 27 Jan 2025 23:36:13 +0100
Subject: [PATCH] [LLD][COFF] Add support for MinGW auto-export on ARM64X

Export all symbols from both EC and native symbol tables. If an explicit export is present
in only one symbol table, auto-export for the other symbol table remains unaffected.
---
 lld/COFF/Driver.cpp | 25 +++++++++++++------------
 lld/COFF/Driver.h   |  3 ++-
 lld/COFF/MinGW.cpp  |  9 ++++-----
 lld/COFF/MinGW.h    |  4 ++--
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 979c0ae4962732..599ee54c2b0703 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1377,18 +1377,19 @@ void LinkerDriver::pullArm64ECIcallHelper() {
 // explicitly specified. The automatic behavior can be disabled using the
 // -exclude-all-symbols option, so that lld-link behaves like link.exe rather
 // than MinGW in the case that nothing is explicitly exported.
-void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
+void LinkerDriver::maybeExportMinGWSymbols(SymbolTable &symtab,
+                                           const opt::InputArgList &args) {
   if (!args.hasArg(OPT_export_all_symbols)) {
     if (!ctx.config.dll)
       return;
 
-    if (!ctx.symtab.exports.empty())
+    if (!symtab.exports.empty())
       return;
     if (args.hasArg(OPT_exclude_all_symbols))
       return;
   }
 
-  AutoExporter exporter(ctx, excludedSymbols);
+  AutoExporter exporter(symtab, excludedSymbols);
 
   for (auto *arg : args.filtered(OPT_wholearchive_file))
     if (std::optional<StringRef> path = findFile(arg->getValue()))
@@ -1398,10 +1399,10 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
     SmallVector<StringRef, 2> vec;
     StringRef(arg->getValue()).split(vec, ',');
     for (StringRef sym : vec)
-      exporter.addExcludedSymbol(ctx.symtab.mangle(sym));
+      exporter.addExcludedSymbol(symtab.mangle(sym));
   }
 
-  ctx.symtab.forEachSymbol([&](Symbol *s) {
+  symtab.forEachSymbol([&](Symbol *s) {
     auto *def = dyn_cast<Defined>(s);
     if (!exporter.shouldExport(def))
       return;
@@ -1418,7 +1419,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
       if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
         e.data = true;
     s->isUsedInRegularObj = true;
-    ctx.symtab.exports.push_back(e);
+    symtab.exports.push_back(e);
   });
 }
 
@@ -2613,14 +2614,14 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
   if (errorCount())
     return;
 
-  ctx.forEachSymtab([](SymbolTable &symtab) {
+  ctx.forEachSymtab([&](SymbolTable &symtab) {
     symtab.hadExplicitExports = !symtab.exports.empty();
+    if (config->mingw) {
+      // In MinGW, all symbols are automatically exported if no symbols
+      // are chosen to be exported.
+      maybeExportMinGWSymbols(symtab, args);
+    }
   });
-  if (config->mingw) {
-    // In MinGW, all symbols are automatically exported if no symbols
-    // are chosen to be exported.
-    maybeExportMinGWSymbols(args);
-  }
 
   // Do LTO by compiling bitcode input files to a set of native COFF files then
   // link those files (unless -thinlto-index-only was given, in which case we
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 58dc5458e9a544..58ec1d7aabe5c4 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -161,7 +161,8 @@ class LinkerDriver {
   // trees into one resource tree.
   void convertResources();
 
-  void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);
+  void maybeExportMinGWSymbols(SymbolTable &symtab,
+                               const llvm::opt::InputArgList &args);
 
   // We don't want to add the same file more than once.
   // Files are uniquified by their filesystem and file number.
diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp
index 76f5a0a7500b9d..a6407bc279200e 100644
--- a/lld/COFF/MinGW.cpp
+++ b/lld/COFF/MinGW.cpp
@@ -25,9 +25,8 @@ using namespace lld;
 using namespace lld::coff;
 
 AutoExporter::AutoExporter(
-    COFFLinkerContext &ctx,
-    const llvm::DenseSet<StringRef> &manualExcludeSymbols)
-    : manualExcludeSymbols(manualExcludeSymbols), ctx(ctx) {
+    SymbolTable &symtab, const llvm::DenseSet<StringRef> &manualExcludeSymbols)
+    : manualExcludeSymbols(manualExcludeSymbols), symtab(symtab) {
   excludeLibs = {
       "libgcc",
       "libgcc_s",
@@ -84,7 +83,7 @@ AutoExporter::AutoExporter(
       "_NULL_THUNK_DATA",
   };
 
-  if (ctx.config.machine == I386) {
+  if (symtab.machine == I386) {
     excludeSymbols = {
         "__NULL_IMPORT_DESCRIPTOR",
         "__pei386_runtime_relocator",
@@ -151,7 +150,7 @@ bool AutoExporter::shouldExport(Defined *sym) const {
       return false;
 
   // If a corresponding __imp_ symbol exists and is defined, don't export it.
-  if (ctx.symtab.find(("__imp_" + sym->getName()).str()))
+  if (symtab.find(("__imp_" + sym->getName()).str()))
     return false;
 
   // Check that file is non-null before dereferencing it, symbols not
diff --git a/lld/COFF/MinGW.h b/lld/COFF/MinGW.h
index ffa500b234777b..265beb315c9a71 100644
--- a/lld/COFF/MinGW.h
+++ b/lld/COFF/MinGW.h
@@ -25,7 +25,7 @@ class COFFLinkerContext;
 // symbols for MinGW.
 class AutoExporter {
 public:
-  AutoExporter(COFFLinkerContext &ctx,
+  AutoExporter(SymbolTable &symtab,
                const llvm::DenseSet<StringRef> &manualExcludeSymbols);
 
   void addWholeArchive(StringRef path);
@@ -42,7 +42,7 @@ class AutoExporter {
   bool shouldExport(Defined *sym) const;
 
 private:
-  COFFLinkerContext &ctx;
+  SymbolTable &symtab;
 };
 
 void writeDefFile(COFFLinkerContext &, StringRef name,



More information about the llvm-commits mailing list