Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -25,6 +25,7 @@ bool DiscardNone = false; bool ExportDynamic = false; bool NoInhibitExec = false; + bool AllowMultipleDefinition = false; }; extern Configuration *Config; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -97,6 +97,9 @@ if (Args.hasArg(OPT_noinhibit_exec)) Config->NoInhibitExec = true; + if (Args.hasArg(OPT_allow_multiple_definition)) + Config->AllowMultipleDefinition = true; + // Create a list of input files. std::vector Inputs; Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -37,3 +37,6 @@ def export_dynamic : Flag<["--"], "export-dynamic">, HelpText<"Put symbols in the dynamic symbol table">; + +def allow_multiple_definition: Flag<["--"], "allow-multiple-definition">, + HelpText<"Allow multiple definitions">; Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -150,8 +150,13 @@ NewFile = F.get(); } - error(Twine("duplicate symbol: ") + Old.getName() + " in " + - OldFile->getName() + " and " + NewFile->getName()); + std::string Msg = (Twine("duplicate symbol: ") + Old.getName() + " in " + + OldFile->getName() + " and " + NewFile->getName()) + .str(); + if (Config->AllowMultipleDefinition) + warning(Msg); + else + error(Msg); } // This function resolves conflicts if there's an existing symbol with Index: test/elf2/Inputs/allow-multiple-definition.s =================================================================== --- test/elf2/Inputs/allow-multiple-definition.s +++ test/elf2/Inputs/allow-multiple-definition.s @@ -0,0 +1,4 @@ +.globl _bar +.type _bar, @function +_bar: + mov $2, %eax Index: test/elf2/allow-multiple-definition.s =================================================================== --- test/elf2/allow-multiple-definition.s +++ test/elf2/allow-multiple-definition.s @@ -0,0 +1,29 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/allow-multiple-definition.s -o %t2 +# RUN: not lld -flavor gnu2 %t1 %t2 -o %t3 +# RUN: lld -flavor gnu2 --allow-multiple-definition %t1 %t2 -o %t3 +# RUN: lld -flavor gnu2 --allow-multiple-definition %t2 %t1 -o %t4 +# RUN: llvm-objdump -d %t3 | FileCheck %s +# RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s + +# inputs contain different constants for instuction movl. +# Tests below checks that order of files in command line +# affects on what symbol will be used. +# If flag allow-multiple-definition is enabled the first +# meet symbol should be used. + +# CHECK: _bar: +# CHECK-NEXT: 11000: b8 01 00 00 00 movl $1, %eax + +# REVERT: _bar: +# REVERT-NEXT: 11000: b8 02 00 00 00 movl $2, %eax + +.globl _bar +.type _bar, @function +_bar: + mov $1, %eax + +.globl _start; +_start: