From 08d5e1875ff2859cdaada55a8f4f6ed338949cca Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 18 Jun 2015 23:20:11 +0000 Subject: [PATCH] COFF: Handle /include in .drectve. We don't want to insert a new symbol to the symbol table while reading a .drectve section because it's going to be too complicated. That we are reading a directive section means that we are currently reading some object file. Adding a new undefined symbol to the symbol table can trigger a library file to read a new file, so it would make the call stack too deep. In this patch, I add new symbol names to a list to resolve them later. llvm-svn: 240076 --- lld/COFF/Config.h | 3 +++ lld/COFF/Driver.cpp | 21 +++++++++++++++------ lld/test/COFF/include.test | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 00d99dad..2614f07 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -53,6 +53,9 @@ struct Configuration { std::set NoDefaultLibs; bool NoDefaultLibAll = false; + // Used for /include. + std::set Includes; + // True if we are creating a DLL. bool DLL = false; StringRef Implib; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index ef1600f..80581bd 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -118,6 +118,9 @@ LinkerDriver::parseDirectives(StringRef S, if (auto EC = checkFailIfMismatch(Arg->getValue())) return EC; break; + case OPT_incl: + Config->Includes.insert(Arg->getValue()); + break; default: llvm::errs() << Arg->getSpelling() << " is not allowed in .drectve\n"; return make_error_code(LLDError::InvalidOption); @@ -343,6 +346,10 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { if (parseAlternateName(Arg->getValue())) return false; + // Handle /include + for (auto *Arg : Args->filtered(OPT_incl)) + Config->Includes.insert(Arg->getValue()); + // Handle /implib if (auto *Arg = Args->getLastArg(OPT_implib)) Config->Implib = Arg->getValue(); @@ -443,11 +450,8 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { // Add undefined symbols given via the command line. // (/include is equivalent to Unix linker's -u option.) - for (auto *Arg : Args->filtered(OPT_incl)) { - StringRef Sym = Arg->getValue(); + for (StringRef Sym : Config->Includes) Symtab.addUndefined(Sym); - Config->GCRoots.insert(Sym); - } // Windows specific -- Create a resource file containing a manifest file. if (Config->Manifest == Configuration::Embed) { @@ -495,7 +499,6 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { for (size_t I = 0; I < Config->Exports.size(); ++I) { StringRef Sym = Config->Exports[I].Name; Symtab.addUndefined(Sym); - Config->GCRoots.insert(Sym); } // Windows specific -- If entry point name is not given, we need to @@ -509,7 +512,6 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { } Config->EntryName = EntryOrErr.get(); } - Config->GCRoots.insert(Config->EntryName); // Add weak aliases. Weak aliases is a mechanism to give remaining // undefined symbols final chance to be resolved successfully. @@ -533,6 +535,13 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { if (Symtab.reportRemainingUndefines()) return false; + // Initialize a list of GC root. + for (StringRef Sym : Config->Includes) + Config->GCRoots.insert(Sym); + for (Export &E : Config->Exports) + Config->GCRoots.insert(E.Name); + Config->GCRoots.insert(Config->EntryName); + // Do LTO by compiling bitcode input files to a native COFF file // then link that file. if (auto EC = Symtab.addCombinedLTOObject()) { diff --git a/lld/test/COFF/include.test b/lld/test/COFF/include.test index 42711ce..8f233e7 100644 --- a/lld/test/COFF/include.test +++ b/lld/test/COFF/include.test @@ -10,7 +10,9 @@ # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log # CHECK1: Discarded unused +# CHECK1-NOT: Discarded used # CHECK2-NOT: Discarded unused +# CHECK2-NOT: Discarded used --- header: @@ -25,6 +27,14 @@ sections: Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 4 SectionData: B82A000000C3 + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: B82A000000C3 + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 2147483648 + SectionData: 2f696e636c7564653a7573656400 # /include:used symbols: - Name: '.text$mn' Value: 0 @@ -58,10 +68,16 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: unused + - Name: used Value: 0 SectionNumber: 2 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: unused + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... -- 2.7.4