COFF: Support /force flag.
authorRui Ueyama <ruiu@google.com>
Sun, 28 Jun 2015 19:35:15 +0000 (19:35 +0000)
committerRui Ueyama <ruiu@google.com>
Sun, 28 Jun 2015 19:35:15 +0000 (19:35 +0000)
This option is to ignore remaining undefined symbols and force
the linker to create an output file anyways.

The existing code assumes that there's no undefined symbol after
reportRemainingUndefines(). That assumption is legitimate.
I also don't want to mess up the existing code for this minor feature.
In order to keep it as is, remaining undefined symbols are replaced
with dummy defined symbols.

llvm-svn: 240913

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

index 8233852..8014781 100644 (file)
@@ -46,6 +46,7 @@ struct Configuration {
   std::string OutputFile;
   bool DoGC = true;
   bool Relocatable = true;
+  bool Force = false;
 
   // Symbols in this set are considered as live by the garbage collector.
   std::set<StringRef> GCRoots;
index 634b63c..d2dbd96 100644 (file)
@@ -265,6 +265,10 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
   if (Args.hasArg(OPT_verbose))
     Config->Verbose = true;
 
+  // Handle /force or /force:unresolved
+  if (Args.hasArg(OPT_force) || Args.hasArg(OPT_force_unresolved))
+    Config->Force = true;
+
   // Handle /entry
   if (auto *Arg = Args.getLastArg(OPT_entry)) {
     Config->EntryName = Arg->getValue();
index 7515780..aae6b22 100644 (file)
@@ -92,6 +92,12 @@ bool SymbolTable::reportRemainingUndefines() {
       }
     }
     llvm::errs() << "undefined symbol: " << Name << "\n";
+    // Remaining undefined symbols are not fatal if /force is specified.
+    // They are replaced with dummy defined symbols.
+    if (Config->Force) {
+      Sym->Body = new (Alloc) DefinedAbsolute(Name, 0);
+      continue;
+    }
     Ret = true;
   }
   return Ret;
diff --git a/lld/test/COFF/force.test b/lld/test/COFF/force.test
new file mode 100644 (file)
index 0000000..69455a9
--- /dev/null
@@ -0,0 +1,43 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj
+# RUN: FileCheck %s < %t.log
+# RUN: lld -flavor link2 /out:%t.exe %t.obj /force >& %t.log
+# RUN: FileCheck %s < %t.log
+
+# CHECK: undefined symbol: foo
+
+---
+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:            mainCRTStartup
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            foo
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...