summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/Options.td5
-rw-r--r--lld/ELF/Symbols.cpp4
-rw-r--r--lld/test/ELF/Inputs/warn-common.s2
-rw-r--r--lld/test/ELF/Inputs/warn-common2.s8
-rw-r--r--lld/test/ELF/warn-common.s25
7 files changed, 45 insertions, 1 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index fa31b40ca9a..f1a90f2070e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -78,6 +78,7 @@ struct Configuration {
bool SysvHash = true;
bool Threads;
bool Verbose;
+ bool WarnCommon;
bool ZExecStack;
bool ZNodelete;
bool ZNow;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 22c61450e3f..f5eecb4148a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -244,6 +244,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->StripAll = Args.hasArg(OPT_strip_all);
Config->Threads = Args.hasArg(OPT_threads);
Config->Verbose = Args.hasArg(OPT_verbose);
+ Config->WarnCommon = Args.hasArg(OPT_warn_common);
Config->DynamicLinker = getString(Args, OPT_dynamic_linker);
Config->Entry = getString(Args, OPT_entry);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 6b47106c5b6..741013fef15 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -131,6 +131,9 @@ def verbose : Flag<["--"], "verbose">;
def version : Flag<["--", "-"], "version">,
HelpText<"Display the version number">;
+def warn_common : Flag<["--", "-"], "warn-common">,
+ HelpText<"Warn about duplicate common symbols">;
+
def whole_archive : Flag<["--", "-"], "whole-archive">,
HelpText<"Force load of all members in a static library">;
@@ -178,9 +181,9 @@ def start_group_paren: Flag<["-"], "(">;
def fatal_warnings : Flag<["--"], "fatal-warnings">;
def no_add_needed : Flag<["--"], "no-add-needed">;
def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">;
+def no_warn_common : Flag<["--", "-"], "no-warn-common">;
def no_warn_mismatch : Flag<["--"], "no-warn-mismatch">;
def version_script : Separate<["--"], "version-script">;
-def warn_common : Flag<["--"], "warn-common">;
def warn_shared_textrel : Flag<["--"], "warn-shared-textrel">;
def G : Separate<["-"], "G">;
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 53b9660411b..78662ee4798 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -159,6 +159,8 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
}
static int compareCommons(DefinedCommon *A, DefinedCommon *B) {
+ if (Config->WarnCommon)
+ warning("multiple common of " + A->getName());
A->Alignment = B->Alignment = std::max(A->Alignment, B->Alignment);
if (A->Size < B->Size)
return -1;
@@ -199,6 +201,8 @@ template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
if (isCommon() && Other->isCommon())
return compareCommons(cast<DefinedCommon>(this),
cast<DefinedCommon>(Other));
+ if (Config->WarnCommon)
+ warning("common " + this->getName() + " is overridden");
return isCommon() ? -1 : 1;
}
diff --git a/lld/test/ELF/Inputs/warn-common.s b/lld/test/ELF/Inputs/warn-common.s
new file mode 100644
index 00000000000..fc4509ba70c
--- /dev/null
+++ b/lld/test/ELF/Inputs/warn-common.s
@@ -0,0 +1,2 @@
+.type arr,@object
+.comm arr,8,4
diff --git a/lld/test/ELF/Inputs/warn-common2.s b/lld/test/ELF/Inputs/warn-common2.s
new file mode 100644
index 00000000000..976c5becb09
--- /dev/null
+++ b/lld/test/ELF/Inputs/warn-common2.s
@@ -0,0 +1,8 @@
+.type arr,@object
+.data
+.globl arr
+.p2align 2
+arr:
+ .long 1
+ .long 0
+ .size arr, 8
diff --git a/lld/test/ELF/warn-common.s b/lld/test/ELF/warn-common.s
new file mode 100644
index 00000000000..783a9ab77b5
--- /dev/null
+++ b/lld/test/ELF/warn-common.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common2.s -o %t3.o
+
+## Report multiple commons if warn-common is specified
+# RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN
+# WARN: multiple common of arr
+
+## no-warn-common is ignored
+# RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out
+# RUN: llvm-readobj %t.out > /dev/null
+
+## Report if common is overridden
+# RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
+# OVER: common arr is overridden
+
+## Report if common is overridden, but in different order
+# RUN: ld.lld --warn-common %t3.o %t1.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
+
+.globl _start
+_start:
+
+.type arr,@object
+.comm arr,4,4
OpenPOWER on IntegriCloud