diff options
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Options.td | 5 | ||||
| -rw-r--r-- | lld/ELF/Symbols.cpp | 4 | ||||
| -rw-r--r-- | lld/test/ELF/Inputs/warn-common.s | 2 | ||||
| -rw-r--r-- | lld/test/ELF/Inputs/warn-common2.s | 8 | ||||
| -rw-r--r-- | lld/test/ELF/warn-common.s | 25 |
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 |

