[lld] [LLD] [COFF] Fix crashes for conflicting exports with -export-all-symbols (PR #190492)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 4 14:14:14 PDT 2026


https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/190492

Commit adcdc9cc3740adba3577b328fa3ba492cbccd3a5 (since LLD 17) added a warning message if there are conflicting attempts to export a specific symbol.

That commit missed one source of exports, from the LLD specific -export-all-symbols flag (which only has an effect in mingw mode).

To trigger this case, one needs to have an export set by a def file, combined with the -export-all-symbols flag (which attempts to export all global symbols, despite explicit exports through embedded directives or a def file).

To trigger the warning (and the previous crash), one would have to have some difference between the export produced by -export-all-symbols and the one from the def file. That difference could be e.g. that the def file contained an explicit ordinal, or that the def file lacked a DATA marking for a symbol that the automatic export of all symbols decides to export as a data symbol.

This fixes https://github.com/llvm/llvm-project/issues/187318. (In the repro case in that bug, the def file lacked DATA markings for a data symbol.)

>From 2ab4bdf2917b44cacee61a06e9a966ba705af8f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Sat, 4 Apr 2026 23:31:44 +0300
Subject: [PATCH] [LLD] [COFF] Fix crashes for conflicting exports with
 -export-all-symbols

Commit adcdc9cc3740adba3577b328fa3ba492cbccd3a5 (since LLD 17)
added a warning message if there are conflicting attempts to
export a specific symbol.

That commit missed one source of exports, from the LLD specific
-export-all-symbols flag (which only has an effect in mingw mode).

To trigger this case, one needs to have an export set by a def file,
combined with the -export-all-symbols flag (which attempts to
export all global symbols, despite explicit exports through embedded
directives or a def file).

To trigger the warning (and the previous crash), one would have to
have some difference between the export produced by -export-all-symbols
and the one from the def file. That difference could be e.g. that
the def file contained an explicit ordinal, or that the def file
lacked a DATA marking for a symbol that the automatic export of all
symbols decides to export as a data symbol.

This fixes https://github.com/llvm/llvm-project/issues/187318.
(In the repro case in that bug, the def file lacked DATA markings
for a data symbol.)
---
 lld/COFF/Config.h                      |  1 +
 lld/COFF/Driver.cpp                    |  1 +
 lld/COFF/SymbolTable.cpp               |  2 ++
 lld/test/COFF/export-all-conflict.test | 18 ++++++++++++++++++
 4 files changed, 22 insertions(+)
 create mode 100644 lld/test/COFF/export-all-conflict.test

diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 6ac6355d976c2..f22d5800b62c4 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -48,6 +48,7 @@ enum class ExportSource {
   Directives,
   Export,
   ModuleDefinition,
+  ExportAll,
 };
 
 enum class EmitKind { Obj, LLVM, ASM };
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 23aa756cf6ae8..6d0973c1d0b78 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1487,6 +1487,7 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
       Export e;
       e.name = def->getName();
       e.sym = def;
+      e.source = ExportSource::ExportAll;
       if (Chunk *c = def->getChunk())
         if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
           e.data = true;
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 38a43390c15ab..4c6bf98c7eb17 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -1190,6 +1190,8 @@ static StringRef exportSourceName(ExportSource s) {
     return "/export";
   case ExportSource::ModuleDefinition:
     return "/def";
+  case ExportSource::ExportAll:
+    return "/export-all-symbols";
   default:
     llvm_unreachable("unknown ExportSource");
   }
diff --git a/lld/test/COFF/export-all-conflict.test b/lld/test/COFF/export-all-conflict.test
new file mode 100644
index 0000000000000..8ede145cfd14d
--- /dev/null
+++ b/lld/test/COFF/export-all-conflict.test
@@ -0,0 +1,18 @@
+REQUIRES: x86
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=x86_64-windows datasym.s -o datasym.obj
+
+RUN: lld-link -dll -noentry -out:test.dll datasym.obj -def:exports.def -lldmingw -export-all-symbols 2>&1 | FileCheck %s
+
+CHECK: warning: duplicate export: datasym first seen in /def, now in /export-all-symbols
+
+#--- datasym.s
+	.data
+	.globl	datasym
+datasym:
+	.long	42
+
+#--- exports.def
+EXPORTS
+datasym



More information about the llvm-commits mailing list