Index: COFF/Config.h =================================================================== --- COFF/Config.h +++ COFF/Config.h @@ -27,7 +27,10 @@ llvm::COFF::MachineTypes MachineType = llvm::COFF::IMAGE_FILE_MACHINE_AMD64; bool Verbose = false; WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; - std::string EntryName; + StringRef EntryName; + + // Symbols in this set are considered as live by the garbage collector. + std::set GCRoots; std::set NoDefaultLibs; bool NoDefaultLibAll = false; Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -312,8 +312,11 @@ // Add undefined symbols given via the command line. // (/include is equivalent to Unix linker's -u option.) - for (auto *Arg : Args->filtered(OPT_incl)) - Symtab.addUndefined(Arg->getValue()); + for (auto *Arg : Args->filtered(OPT_incl)) { + StringRef Sym = Arg->getValue(); + Symtab.addUndefined(Sym); + Config->GCRoots.insert(Sym); + } // Parse all input files and put all symbols to the symbol table. // The symbol table will take care of name resolution. @@ -362,11 +365,14 @@ } Config->EntryName = EntryOrErr.get(); } + Config->GCRoots.insert(Config->EntryName); // Make sure we have resolved all symbols. if (Symtab.reportRemainingUndefines()) return false; + // Do LTO by compiling bitcode input files to a native COFF file + // then link that file. if (auto EC = Symtab.addCombinedLTOObject()) { llvm::errs() << EC.message() << "\n"; return false; Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -227,20 +227,17 @@ return std::error_code(); llvm::LTOCodeGenerator CG; - std::set PreservedBitcodeSymbols; // All symbols referenced by non-bitcode objects must be preserved. for (std::unique_ptr &File : ObjectFiles) for (SymbolBody *Body : File->getSymbols()) if (auto *S = dyn_cast(Body->getReplacement())) - PreservedBitcodeSymbols.insert(S); + CG.addMustPreserveSymbol(S->getName()); - // Likewise for the linker-generated reference to the entry point. - if (auto *S = dyn_cast(Symtab[Config->EntryName]->Body)) - PreservedBitcodeSymbols.insert(S); - - for (DefinedBitcode *S : PreservedBitcodeSymbols) - CG.addMustPreserveSymbol(S->getName()); + // Likewise for other symbols that must be preserved. + for (StringRef Name : Config->GCRoots) + if (isa(Symtab[Name]->Body)) + CG.addMustPreserveSymbol(Name); CG.setModule(BitcodeFiles[0]->releaseModule()); for (unsigned I = 1, E = BitcodeFiles.size(); I != E; ++I) Index: COFF/Writer.h =================================================================== --- COFF/Writer.h +++ COFF/Writer.h @@ -98,7 +98,6 @@ uint32_t ImportDirectoryTableSize = 0; uint32_t ImportAddressTableSize = 0; - Defined *Entry; uint64_t FileSize; uint64_t SizeOfImage; uint64_t SizeOfHeaders; Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -87,8 +87,8 @@ } void Writer::markLive() { - Entry = cast(Symtab->find(Config->EntryName)); - Entry->markLive(); + for (StringRef Name : Config->GCRoots) + cast(Symtab->find(Name))->markLive(); for (Chunk *C : Symtab->getChunks()) if (C->isRoot()) C->markLive(); @@ -291,6 +291,7 @@ PE->Subsystem = Config->Subsystem; PE->SizeOfImage = SizeOfImage; PE->SizeOfHeaders = SizeOfHeaders; + Defined *Entry = cast(Symtab->find(Config->EntryName)); PE->AddressOfEntryPoint = Entry->getRVA(); PE->SizeOfStackReserve = Config->StackReserve; PE->SizeOfStackCommit = Config->StackCommit;