[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
Wed Oct 4 01:02:19 PDT 2023


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

>From 695680b9b6c0af95c71cf1eb1360be2b409a6df0 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 562af7e0d23c19f..efb4100be6f7374 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -314,6 +314,7 @@ struct Configuration {
   bool stdcallFixup = false;
   bool writeCheckSum = false;
   EmitKind emit = EmitKind::Obj;
+  bool allowDuplicateWeak = false;
 };
 
 } // namespace lld::coff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 554db5969ea13dd..8dc77e6e101a686 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1993,6 +1993,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 a7a08fb2fa6ea50..11856875673c8d5 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 22add8ff72b95d3..38873dc1043461e 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 lldemit : P<"lldemit", "Specify output type">;
 def lldmingw : F<"lldmingw">;
 def noseh : F<"noseh">;
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