diff options
Diffstat (limited to 'lld/COFF/InputFiles.cpp')
-rw-r--r-- | lld/COFF/InputFiles.cpp | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index c24b59deb39..7bdeee9b361 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -73,6 +73,10 @@ static void checkAndSetWeakAlias(SymbolTable *symtab, InputFile *f, } } +static bool ignoredSymbolName(StringRef name) { + return name == "@feat.00" || name == "@comp.id"; +} + ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {} void ArchiveFile::parse() { @@ -81,7 +85,7 @@ void ArchiveFile::parse() { // Read the symbol table to construct Lazy objects. for (const Archive::Symbol &sym : file->symbols()) - symtab->addLazy(this, sym); + symtab->addLazyArchive(this, sym); } // Returns a buffer pointing to a member file containing a given symbol. @@ -116,6 +120,49 @@ std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) { return v; } +void LazyObjFile::fetch() { + if (mb.getBuffer().empty()) + return; + + InputFile *file; + if (isBitcode(mb)) + file = make<BitcodeFile>(mb, "", 0, std::move(symbols)); + else + file = make<ObjFile>(mb, std::move(symbols)); + mb = {}; + symtab->addFile(file); +} + +void LazyObjFile::parse() { + if (isBitcode(this->mb)) { + // Bitcode file. + std::unique_ptr<lto::InputFile> obj = + CHECK(lto::InputFile::create(this->mb), this); + for (const lto::InputFile::Symbol &sym : obj->symbols()) { + if (!sym.isUndefined()) + symtab->addLazyObject(this, sym.getName()); + } + return; + } + + // Native object file. + COFFObjectFile *coffObj = + dyn_cast<COFFObjectFile>(CHECK(createBinary(mb), this).get()); + uint32_t numSymbols = coffObj->getNumberOfSymbols(); + for (uint32_t i = 0; i < numSymbols; ++i) { + COFFSymbolRef coffSym = check(coffObj->getSymbol(i)); + if (coffSym.isUndefined() || !coffSym.isExternal() || + coffSym.isWeakExternal()) + continue; + StringRef name; + coffObj->getSymbolName(coffSym, name); + if (coffSym.isAbsolute() && ignoredSymbolName(name)) + continue; + symtab->addLazyObject(this, name); + i += coffSym.getNumberOfAuxSymbols(); + } +} + void ObjFile::parse() { // Parse a memory buffer as a COFF file. std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this); @@ -526,13 +573,11 @@ Optional<Symbol *> ObjFile::createDefined( if (sym.isAbsolute()) { StringRef name = getName(); - // Skip special symbols. - if (name == "@comp.id") - return nullptr; - if (name == "@feat.00") { + if (name == "@feat.00") feat00Flags = sym.getValue(); + // Skip special symbols. + if (ignoredSymbolName(name)) return nullptr; - } if (sym.isExternal()) return symtab->addAbsolute(name, sym); @@ -782,8 +827,9 @@ void ImportFile::parse() { } BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, - uint64_t offsetInArchive) - : InputFile(BitcodeKind, mb) { + uint64_t offsetInArchive, + std::vector<Symbol *> &&symbols) + : InputFile(BitcodeKind, mb), symbols(std::move(symbols)) { std::string path = mb.getBufferIdentifier().str(); if (config->thinLTOIndexOnly) path = replaceThinLTOSuffix(mb.getBufferIdentifier()); |