COFF: Add support for /force:multiple option
authorRui Ueyama <ruiu@google.com>
Thu, 13 Sep 2018 22:05:10 +0000 (22:05 +0000)
committerRui Ueyama <ruiu@google.com>
Thu, 13 Sep 2018 22:05:10 +0000 (22:05 +0000)
Patch by Thomas Roughton.

This patch adds support for linking with multiple definitions to LLD's
COFF driver, in line with link.exe's /force:multiple option.

Differential Revision: https://reviews.llvm.org/D50598

llvm-svn: 342191

lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Options.td
lld/COFF/SymbolTable.cpp
lld/test/COFF/force-multiple.test [new file with mode: 0644]

index 3ae50b8..e639b77 100644 (file)
@@ -94,7 +94,8 @@ struct Configuration {
   bool DoICF = true;
   bool TailMerge;
   bool Relocatable = true;
-  bool Force = false;
+  bool ForceMultiple = false;
+  bool ForceUnresolved = false;
   bool Debug = false;
   bool DebugDwarf = false;
   bool DebugGHashes = false;
index 4c3ad67..ff15553 100644 (file)
@@ -888,7 +888,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
 
   // Handle /force or /force:unresolved
   if (Args.hasArg(OPT_force, OPT_force_unresolved))
-    Config->Force = true;
+    Config->ForceUnresolved = true;
+
+  // Handle /force or /force:multiple
+  if (Args.hasArg(OPT_force, OPT_force_multiple))
+    Config->ForceMultiple = true;
 
   // Handle /debug
   if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) {
index 8536763..1394747 100644 (file)
@@ -99,8 +99,11 @@ def verbose : F<"verbose">;
 def wholearchive_flag : F<"wholearchive">;
 
 def force : F<"force">,
+    HelpText<"Allow undefined and multiply defined symbols when creating executables">;
+def force_unresolved : F<"force:unresolved">,
     HelpText<"Allow undefined symbols when creating executables">;
-def force_unresolved : F<"force:unresolved">;
+def force_multiple : F<"force:multiple">,
+    HelpText<"Allow multiply defined symbols when creating executables">;
 defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
 
 defm allowbind : B<"allowbind", "Enable DLL binding (default)",
index 0d45018..1e3ebfc 100644 (file)
@@ -60,7 +60,7 @@ void SymbolTable::addFile(InputFile *File) {
 }
 
 static void errorOrWarn(const Twine &S) {
-  if (Config->Force)
+  if (Config->ForceUnresolved)
     warn(S);
   else
     error(S);
@@ -237,7 +237,7 @@ void SymbolTable::reportRemainingUndefines() {
 
     // Remaining undefined symbols are not fatal if /force is specified.
     // They are replaced with dummy defined symbols.
-    if (Config->Force)
+    if (Config->ForceUnresolved)
       replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
     Undefs.insert(Sym);
   }
@@ -326,8 +326,14 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
 }
 
 void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
-  error("duplicate symbol: " + toString(*Existing) + " in " +
-        toString(Existing->getFile()) + " and in " + toString(NewFile));
+  std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
+                    toString(Existing->getFile()) + " and in " +
+                    toString(NewFile);
+
+  if (Config->ForceMultiple)
+    warn(Msg);
+  else
+    error(Msg);
 }
 
 Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
diff --git a/lld/test/COFF/force-multiple.test b/lld/test/COFF/force-multiple.test
new file mode 100644 (file)
index 0000000..9f60e13
--- /dev/null
@@ -0,0 +1,45 @@
+# RUN: yaml2obj < %s > %t1.obj
+# RUN: yaml2obj < %s > %t2.obj
+
+# RUN: not lld-link /out:%t.exe /entry:main %t1.obj %t2.obj >& %t.log
+# RUN: FileCheck -check-prefix=ERROR %s < %t.log
+
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force >& %t.log
+# RUN: FileCheck -check-prefix=WARN %s < %t.log
+
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force:multiple >& %t.log
+# RUN: FileCheck -check-prefix=WARN %s < %t.log
+
+# ERROR: error: duplicate symbol: main
+
+# WARN: warning: duplicate symbol: main
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     000000000000
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...