diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 823385228c53..801478149697 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -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 GCRoots; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 634b63c425b8..d2dbd96a8fe2 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -265,6 +265,10 @@ bool LinkerDriver::link(llvm::ArrayRef 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(); diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 75157805d074..aae6b22b4a09 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -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 index 000000000000..69455a9b2dc9 --- /dev/null +++ b/lld/test/COFF/force.test @@ -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 +...