From 95925fd1abee62ab12293d3b7e255a5308e6d7af Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 28 Jun 2015 19:35:15 +0000 Subject: [PATCH] COFF: Support /force flag. 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 | 1 + lld/COFF/Driver.cpp | 4 ++++ lld/COFF/SymbolTable.cpp | 6 ++++++ lld/test/COFF/force.test | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 lld/test/COFF/force.test diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 8233852..8014781 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 634b63c..d2dbd96 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 7515780..aae6b22 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 0000000..69455a9 --- /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 +... -- 2.7.4