[lld] [LLD] [COFF] Add a separate option for allowing duplicate weak symbols (PR #68077)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 01:26:11 PDT 2023


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

The MinGW mode (enabled with the flag -lldmingw) does allow duplicate weak symbols. A test in
compiler-rt/test/profile/Windows/coverage-weak-lld.cpp does currently enable the -lldmingw flag in an MSVC context, in order to deal with duplicate weak symbols.

Add a new, separate, lld specific flag for enabling this. In MinGW mode, this is enabled by default, otherwise it is disabled.

This allows making the MinGW mode more restrictive in adding libpaths from the surrounding environment; in MinGW mode, all libpaths are passed explicitly by the compiler driver to the linker, which is attempted in https://reviews.llvm.org/D144084.

>From 149ff9a470a8b9d1fd52a7e50c0488b7cc163d83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Sun, 1 Oct 2023 00:01:31 +0300
Subject: [PATCH] [LLD] [COFF] Add a separate option for allowing duplicate
 weak symbols

The MinGW mode (enabled with the flag -lldmingw) does allow duplicate
weak symbols. A test in
compiler-rt/test/profile/Windows/coverage-weak-lld.cpp does currently
enable the -lldmingw flag in an MSVC context, in order to deal with
duplicate weak symbols.

Add a new, separate, lld specific flag for enabling this. In MinGW
mode, this is enabled by default, otherwise it is disabled.

This allows making the MinGW mode more restrictive in adding
libpaths from the surrounding environment; in MinGW mode, all
libpaths are passed explicitly by the compiler driver to the
linker, which is attempted in https://reviews.llvm.org/D144084.
---
 lld/COFF/Config.h           | 1 +
 lld/COFF/Driver.cpp         | 3 +++
 lld/COFF/InputFiles.cpp     | 2 +-
 lld/COFF/Options.td         | 1 +
 lld/test/COFF/gnu-weak.test | 5 +++++
 5 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 4ade2c953c73e40..1695e935ee39241 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -311,6 +311,7 @@ struct Configuration {
   bool pseudoRelocs = false;
   bool stdcallFixup = false;
   bool writeCheckSum = false;
+  bool allowDuplicateWeak = false;
 };
 
 } // namespace lld::coff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e2f414f78ecb7bc..f7538514355fc0b 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1980,6 +1980,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
   config->stdcallFixup =
       args.hasFlag(OPT_stdcall_fixup, OPT_stdcall_fixup_no, config->mingw);
   config->warnStdcallFixup = !args.hasArg(OPT_stdcall_fixup);
+  config->allowDuplicateWeak =
+      args.hasFlag(OPT_lld_allow_duplicate_weak,
+                   OPT_lld_allow_duplicate_weak_no, config->mingw);
 
   if (args.hasFlag(OPT_inferasanlibs, OPT_inferasanlibs_no, false))
     warn("ignoring '/inferasanlibs', this flag is not supported");
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 541837a7fceca72..1316167c745c4b7 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -81,7 +81,7 @@ static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f,
       // of another symbol emitted near the weak symbol.
       // Just use the definition from the first object file that defined
       // this weak symbol.
-      if (ctx.config.mingw)
+      if (ctx.config.allowDuplicateWeak)
         return;
       ctx.symtab.reportDuplicate(source, f);
     }
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index ea4ddb2d849534e..bd48c4ba03e9f2d 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -232,6 +232,7 @@ defm demangle : B<"demangle",
 def include_optional : Joined<["/", "-", "/?", "-?"], "includeoptional:">,
     HelpText<"Add symbol as undefined, but allow it to remain undefined">;
 def kill_at : F<"kill-at">;
+defm lld_allow_duplicate_weak : B_priv<"lld-allow-duplicate-weak">;
 def lldmingw : F<"lldmingw">;
 def noseh : F<"noseh">;
 def osversion : P_priv<"osversion">;
diff --git a/lld/test/COFF/gnu-weak.test b/lld/test/COFF/gnu-weak.test
index 20284d7f02436e3..08e59734e042472 100644
--- a/lld/test/COFF/gnu-weak.test
+++ b/lld/test/COFF/gnu-weak.test
@@ -1,4 +1,9 @@
 RUN: lld-link -lldmingw %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
+RUN: lld-link -lld-allow-duplicate-weak %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
+RUN: not lld-link %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe 2>&1 | FileCheck %s --check-prefix=DEFAULT-ERROR
+
+DEFAULT-ERROR: error: duplicate symbol: weakfunc
+
 
 GNU ld can handle several definitions of the same weak symbol, and
 unless there is a strong definition of it, it just picks the first



More information about the llvm-commits mailing list