diff options
Diffstat (limited to 'lld/COFF/InputFiles.cpp')
-rw-r--r-- | lld/COFF/InputFiles.cpp | 806 |
1 files changed, 403 insertions, 403 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index aac3b40c1ef..6737db884ed 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -49,80 +49,80 @@ using llvm::support::ulittle32_t; namespace lld { namespace coff { -std::vector<ObjFile *> ObjFile::Instances; -std::vector<ImportFile *> ImportFile::Instances; -std::vector<BitcodeFile *> BitcodeFile::Instances; +std::vector<ObjFile *> ObjFile::instances; +std::vector<ImportFile *> ImportFile::instances; +std::vector<BitcodeFile *> BitcodeFile::instances; /// Checks that Source is compatible with being a weak alias to Target. /// If Source is Undefined and has no weak alias set, makes it a weak /// alias to Target. -static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F, - Symbol *Source, Symbol *Target) { - if (auto *U = dyn_cast<Undefined>(Source)) { - if (U->WeakAlias && U->WeakAlias != Target) { +static void checkAndSetWeakAlias(SymbolTable *symtab, InputFile *f, + Symbol *source, Symbol *target) { + if (auto *u = dyn_cast<Undefined>(source)) { + if (u->weakAlias && u->weakAlias != target) { // Weak aliases as produced by GCC are named in the form // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name // of another symbol emitted near the weak symbol. // Just use the definition from the first object file that defined // this weak symbol. - if (Config->MinGW) + if (config->mingw) return; - Symtab->reportDuplicate(Source, F); + symtab->reportDuplicate(source, f); } - U->WeakAlias = Target; + u->weakAlias = target; } } -ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} +ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {} void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. - File = CHECK(Archive::create(MB), this); + file = CHECK(Archive::create(mb), this); // Read the symbol table to construct Lazy objects. - for (const Archive::Symbol &Sym : File->symbols()) - Symtab->addLazy(this, Sym); + for (const Archive::Symbol &sym : file->symbols()) + symtab->addLazy(this, sym); } // Returns a buffer pointing to a member file containing a given symbol. -void ArchiveFile::addMember(const Archive::Symbol *Sym) { - const Archive::Child &C = - CHECK(Sym->getMember(), - "could not get the member for symbol " + Sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol *sym) { + const Archive::Child &c = + CHECK(sym->getMember(), + "could not get the member for symbol " + sym->getName()); // Return an empty buffer if we have already returned the same buffer. - if (!Seen.insert(C.getChildOffset()).second) + if (!seen.insert(c.getChildOffset()).second) return; - Driver->enqueueArchiveMember(C, Sym->getName(), getName()); + driver->enqueueArchiveMember(c, sym->getName(), getName()); } -std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) { - std::vector<MemoryBufferRef> V; - Error Err = Error::success(); - for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) { - Archive::Child C = - CHECK(COrErr, - File->getFileName() + ": could not get the child of the archive"); - MemoryBufferRef MBRef = - CHECK(C.getMemoryBufferRef(), - File->getFileName() + +std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) { + std::vector<MemoryBufferRef> v; + Error err = Error::success(); + for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) { + Archive::Child c = + CHECK(cOrErr, + file->getFileName() + ": could not get the child of the archive"); + MemoryBufferRef mbref = + CHECK(c.getMemoryBufferRef(), + file->getFileName() + ": could not get the buffer for a child of the archive"); - V.push_back(MBRef); + v.push_back(mbref); } - if (Err) - fatal(File->getFileName() + - ": Archive::children failed: " + toString(std::move(Err))); - return V; + if (err) + fatal(file->getFileName() + + ": Archive::children failed: " + toString(std::move(err))); + return v; } void ObjFile::parse() { // Parse a memory buffer as a COFF file. - std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), this); + std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this); - if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) { - Bin.release(); - COFFObj.reset(Obj); + if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) { + bin.release(); + coffObj.reset(obj); } else { fatal(toString(this) + " is not a COFF file"); } @@ -134,11 +134,11 @@ void ObjFile::parse() { initializeDependencies(); } -const coff_section* ObjFile::getSection(uint32_t I) { - const coff_section *Sec; - if (auto EC = COFFObj->getSection(I, Sec)) - fatal("getSection failed: #" + Twine(I) + ": " + EC.message()); - return Sec; +const coff_section* ObjFile::getSection(uint32_t i) { + const coff_section *sec; + if (auto ec = coffObj->getSection(i, sec)) + fatal("getSection failed: #" + Twine(i) + ": " + ec.message()); + return sec; } // We set SectionChunk pointers in the SparseChunks vector to this value @@ -147,42 +147,42 @@ const coff_section* ObjFile::getSection(uint32_t I) { // an associative section definition together with the parent comdat's leader, // we set the pointer to either nullptr (to mark the section as discarded) or a // valid SectionChunk for that section. -static SectionChunk *const PendingComdat = reinterpret_cast<SectionChunk *>(1); +static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1); void ObjFile::initializeChunks() { - uint32_t NumSections = COFFObj->getNumberOfSections(); - Chunks.reserve(NumSections); - SparseChunks.resize(NumSections + 1); - for (uint32_t I = 1; I < NumSections + 1; ++I) { - const coff_section *Sec = getSection(I); - if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT) - SparseChunks[I] = PendingComdat; + uint32_t numSections = coffObj->getNumberOfSections(); + chunks.reserve(numSections); + sparseChunks.resize(numSections + 1); + for (uint32_t i = 1; i < numSections + 1; ++i) { + const coff_section *sec = getSection(i); + if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT) + sparseChunks[i] = pendingComdat; else - SparseChunks[I] = readSection(I, nullptr, ""); + sparseChunks[i] = readSection(i, nullptr, ""); } } -SectionChunk *ObjFile::readSection(uint32_t SectionNumber, - const coff_aux_section_definition *Def, - StringRef LeaderName) { - const coff_section *Sec = getSection(SectionNumber); +SectionChunk *ObjFile::readSection(uint32_t sectionNumber, + const coff_aux_section_definition *def, + StringRef leaderName) { + const coff_section *sec = getSection(sectionNumber); - StringRef Name; - if (Expected<StringRef> E = COFFObj->getSectionName(Sec)) - Name = *E; + StringRef name; + if (Expected<StringRef> e = coffObj->getSectionName(sec)) + name = *e; else - fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " + - toString(E.takeError())); + fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " + + toString(e.takeError())); - if (Name == ".drectve") { - ArrayRef<uint8_t> Data; - cantFail(COFFObj->getSectionContents(Sec, Data)); - Directives = StringRef((const char *)Data.data(), Data.size()); + if (name == ".drectve") { + ArrayRef<uint8_t> data; + cantFail(coffObj->getSectionContents(sec, data)); + directives = StringRef((const char *)data.data(), data.size()); return nullptr; } - if (Name == ".llvm_addrsig") { - AddrsigSec = Sec; + if (name == ".llvm_addrsig") { + addrsigSec = sec; return nullptr; } @@ -197,166 +197,166 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, // and then write it to a separate .pdb file. // Ignore DWARF debug info unless /debug is given. - if (!Config->Debug && Name.startswith(".debug_")) + if (!config->debug && name.startswith(".debug_")) return nullptr; - if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) + if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) return nullptr; - auto *C = make<SectionChunk>(this, Sec); - if (Def) - C->Checksum = Def->CheckSum; + auto *c = make<SectionChunk>(this, sec); + if (def) + c->checksum = def->CheckSum; // link.exe uses the presence of .rsrc$01 for LNK4078, so match that. - if (Name == ".rsrc$01") - IsResourceObjFile = true; + if (name == ".rsrc$01") + isResourceObjFile = true; // CodeView sections are stored to a different vector because they are not // linked in the regular manner. - if (C->isCodeView()) - DebugChunks.push_back(C); - else if (Name == ".gfids$y") - GuardFidChunks.push_back(C); - else if (Name == ".gljmp$y") - GuardLJmpChunks.push_back(C); - else if (Name == ".sxdata") - SXDataChunks.push_back(C); - else if (Config->TailMerge && Sec->NumberOfRelocations == 0 && - Name == ".rdata" && LeaderName.startswith("??_C@")) + if (c->isCodeView()) + debugChunks.push_back(c); + else if (name == ".gfids$y") + guardFidChunks.push_back(c); + else if (name == ".gljmp$y") + guardLJmpChunks.push_back(c); + else if (name == ".sxdata") + sXDataChunks.push_back(c); + else if (config->tailMerge && sec->NumberOfRelocations == 0 && + name == ".rdata" && leaderName.startswith("??_C@")) // COFF sections that look like string literal sections (i.e. no // relocations, in .rdata, leader symbol name matches the MSVC name mangling // for string literals) are subject to string tail merging. - MergeChunk::addSection(C); + MergeChunk::addSection(c); else - Chunks.push_back(C); + chunks.push_back(c); - return C; + return c; } void ObjFile::readAssociativeDefinition( - COFFSymbolRef Sym, const coff_aux_section_definition *Def) { - readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj())); + COFFSymbolRef sym, const coff_aux_section_definition *def) { + readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj())); } -void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym, - const coff_aux_section_definition *Def, - uint32_t ParentIndex) { - SectionChunk *Parent = SparseChunks[ParentIndex]; - int32_t SectionNumber = Sym.getSectionNumber(); - - auto Diag = [&]() { - StringRef Name, ParentName; - COFFObj->getSymbolName(Sym, Name); - - const coff_section *ParentSec = getSection(ParentIndex); - if (Expected<StringRef> E = COFFObj->getSectionName(ParentSec)) - ParentName = *E; - error(toString(this) + ": associative comdat " + Name + " (sec " + - Twine(SectionNumber) + ") has invalid reference to section " + - ParentName + " (sec " + Twine(ParentIndex) + ")"); +void ObjFile::readAssociativeDefinition(COFFSymbolRef sym, + const coff_aux_section_definition *def, + uint32_t parentIndex) { + SectionChunk *parent = sparseChunks[parentIndex]; + int32_t sectionNumber = sym.getSectionNumber(); + + auto diag = [&]() { + StringRef name, parentName; + coffObj->getSymbolName(sym, name); + + const coff_section *parentSec = getSection(parentIndex); + if (Expected<StringRef> e = coffObj->getSectionName(parentSec)) + parentName = *e; + error(toString(this) + ": associative comdat " + name + " (sec " + + Twine(sectionNumber) + ") has invalid reference to section " + + parentName + " (sec " + Twine(parentIndex) + ")"); }; - if (Parent == PendingComdat) { + if (parent == pendingComdat) { // This can happen if an associative comdat refers to another associative // comdat that appears after it (invalid per COFF spec) or to a section // without any symbols. - Diag(); + diag(); return; } // Check whether the parent is prevailing. If it is, so are we, and we read // the section; otherwise mark it as discarded. - if (Parent) { - SectionChunk *C = readSection(SectionNumber, Def, ""); - SparseChunks[SectionNumber] = C; - if (C) { - C->Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE; - Parent->addAssociative(C); + if (parent) { + SectionChunk *c = readSection(sectionNumber, def, ""); + sparseChunks[sectionNumber] = c; + if (c) { + c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE; + parent->addAssociative(c); } } else { - SparseChunks[SectionNumber] = nullptr; + sparseChunks[sectionNumber] = nullptr; } } void ObjFile::recordPrevailingSymbolForMingw( - COFFSymbolRef Sym, DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { + COFFSymbolRef sym, DenseMap<StringRef, uint32_t> &prevailingSectionMap) { // For comdat symbols in executable sections, where this is the copy // of the section chunk we actually include instead of discarding it, // add the symbol to a map to allow using it for implicitly // associating .[px]data$<func> sections to it. - int32_t SectionNumber = Sym.getSectionNumber(); - SectionChunk *SC = SparseChunks[SectionNumber]; - if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); + int32_t sectionNumber = sym.getSectionNumber(); + SectionChunk *sc = sparseChunks[sectionNumber]; + if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { + StringRef name; + coffObj->getSymbolName(sym, name); if (getMachineType() == I386) - Name.consume_front("_"); - PrevailingSectionMap[Name] = SectionNumber; + name.consume_front("_"); + prevailingSectionMap[name] = sectionNumber; } } void ObjFile::maybeAssociateSEHForMingw( - COFFSymbolRef Sym, const coff_aux_section_definition *Def, - const DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$") || - Name.consume_front(".eh_frame$")) { + COFFSymbolRef sym, const coff_aux_section_definition *def, + const DenseMap<StringRef, uint32_t> &prevailingSectionMap) { + StringRef name; + coffObj->getSymbolName(sym, name); + if (name.consume_front(".pdata$") || name.consume_front(".xdata$") || + name.consume_front(".eh_frame$")) { // For MinGW, treat .[px]data$<func> and .eh_frame$<func> as implicitly // associative to the symbol <func>. - auto ParentSym = PrevailingSectionMap.find(Name); - if (ParentSym != PrevailingSectionMap.end()) - readAssociativeDefinition(Sym, Def, ParentSym->second); + auto parentSym = prevailingSectionMap.find(name); + if (parentSym != prevailingSectionMap.end()) + readAssociativeDefinition(sym, def, parentSym->second); } } -Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { - SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; - if (Sym.isExternal()) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - if (SC) - return Symtab->addRegular(this, Name, Sym.getGeneric(), SC); +Symbol *ObjFile::createRegular(COFFSymbolRef sym) { + SectionChunk *sc = sparseChunks[sym.getSectionNumber()]; + if (sym.isExternal()) { + StringRef name; + coffObj->getSymbolName(sym, name); + if (sc) + return symtab->addRegular(this, name, sym.getGeneric(), sc); // For MinGW symbols named .weak.* that point to a discarded section, // don't create an Undefined symbol. If nothing ever refers to the symbol, // everything should be fine. If something actually refers to the symbol // (e.g. the undefined weak alias), linking will fail due to undefined // references at the end. - if (Config->MinGW && Name.startswith(".weak.")) + if (config->mingw && name.startswith(".weak.")) return nullptr; - return Symtab->addUndefined(Name, this, false); + return symtab->addUndefined(name, this, false); } - if (SC) + if (sc) return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false, - /*IsExternal*/ false, Sym.getGeneric(), SC); + /*IsExternal*/ false, sym.getGeneric(), sc); return nullptr; } void ObjFile::initializeSymbols() { - uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); - Symbols.resize(NumSymbols); - - SmallVector<std::pair<Symbol *, uint32_t>, 8> WeakAliases; - std::vector<uint32_t> PendingIndexes; - PendingIndexes.reserve(NumSymbols); - - DenseMap<StringRef, uint32_t> PrevailingSectionMap; - std::vector<const coff_aux_section_definition *> ComdatDefs( - COFFObj->getNumberOfSections() + 1); - - for (uint32_t I = 0; I < NumSymbols; ++I) { - COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); - bool PrevailingComdat; - if (COFFSym.isUndefined()) { - Symbols[I] = createUndefined(COFFSym); - } else if (COFFSym.isWeakExternal()) { - Symbols[I] = createUndefined(COFFSym); - uint32_t TagIndex = COFFSym.getAux<coff_aux_weak_external>()->TagIndex; - WeakAliases.emplace_back(Symbols[I], TagIndex); - } else if (Optional<Symbol *> OptSym = - createDefined(COFFSym, ComdatDefs, PrevailingComdat)) { - Symbols[I] = *OptSym; - if (Config->MinGW && PrevailingComdat) - recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap); + uint32_t numSymbols = coffObj->getNumberOfSymbols(); + symbols.resize(numSymbols); + + SmallVector<std::pair<Symbol *, uint32_t>, 8> weakAliases; + std::vector<uint32_t> pendingIndexes; + pendingIndexes.reserve(numSymbols); + + DenseMap<StringRef, uint32_t> prevailingSectionMap; + std::vector<const coff_aux_section_definition *> comdatDefs( + coffObj->getNumberOfSections() + 1); + + for (uint32_t i = 0; i < numSymbols; ++i) { + COFFSymbolRef coffSym = check(coffObj->getSymbol(i)); + bool prevailingComdat; + if (coffSym.isUndefined()) { + symbols[i] = createUndefined(coffSym); + } else if (coffSym.isWeakExternal()) { + symbols[i] = createUndefined(coffSym); + uint32_t tagIndex = coffSym.getAux<coff_aux_weak_external>()->TagIndex; + weakAliases.emplace_back(symbols[i], tagIndex); + } else if (Optional<Symbol *> optSym = + createDefined(coffSym, comdatDefs, prevailingComdat)) { + symbols[i] = *optSym; + if (config->mingw && prevailingComdat) + recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap); } else { // createDefined() returns None if a symbol belongs to a section that // was pending at the point when the symbol was read. This can happen in @@ -366,71 +366,71 @@ void ObjFile::initializeSymbols() { // In both of these cases, we can expect the section to be resolved by // the time we finish visiting the remaining symbols in the symbol // table. So we postpone the handling of this symbol until that time. - PendingIndexes.push_back(I); + pendingIndexes.push_back(i); } - I += COFFSym.getNumberOfAuxSymbols(); + i += coffSym.getNumberOfAuxSymbols(); } - for (uint32_t I : PendingIndexes) { - COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); - if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) { - if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) - readAssociativeDefinition(Sym, Def); - else if (Config->MinGW) - maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap); + for (uint32_t i : pendingIndexes) { + COFFSymbolRef sym = check(coffObj->getSymbol(i)); + if (const coff_aux_section_definition *def = sym.getSectionDefinition()) { + if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) + readAssociativeDefinition(sym, def); + else if (config->mingw) + maybeAssociateSEHForMingw(sym, def, prevailingSectionMap); } - if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - log("comdat section " + Name + + if (sparseChunks[sym.getSectionNumber()] == pendingComdat) { + StringRef name; + coffObj->getSymbolName(sym, name); + log("comdat section " + name + " without leader and unassociated, discarding"); continue; } - Symbols[I] = createRegular(Sym); + symbols[i] = createRegular(sym); } - for (auto &KV : WeakAliases) { - Symbol *Sym = KV.first; - uint32_t Idx = KV.second; - checkAndSetWeakAlias(Symtab, this, Sym, Symbols[Idx]); + for (auto &kv : weakAliases) { + Symbol *sym = kv.first; + uint32_t idx = kv.second; + checkAndSetWeakAlias(symtab, this, sym, symbols[idx]); } } -Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - return Symtab->addUndefined(Name, this, Sym.isWeakExternal()); +Symbol *ObjFile::createUndefined(COFFSymbolRef sym) { + StringRef name; + coffObj->getSymbolName(sym, name); + return symtab->addUndefined(name, this, sym.isWeakExternal()); } -void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, - bool &Prevailing, DefinedRegular *Leader) { - if (Prevailing) +void ObjFile::handleComdatSelection(COFFSymbolRef sym, COMDATType &selection, + bool &prevailing, DefinedRegular *leader) { + if (prevailing) return; // There's already an existing comdat for this symbol: `Leader`. // Use the comdats's selection field to determine if the new // symbol in `Sym` should be discarded, produce a duplicate symbol // error, etc. - SectionChunk *LeaderChunk = nullptr; - COMDATType LeaderSelection = IMAGE_COMDAT_SELECT_ANY; + SectionChunk *leaderChunk = nullptr; + COMDATType leaderSelection = IMAGE_COMDAT_SELECT_ANY; - if (Leader->Data) { - LeaderChunk = Leader->getChunk(); - LeaderSelection = LeaderChunk->Selection; + if (leader->data) { + leaderChunk = leader->getChunk(); + leaderSelection = leaderChunk->selection; } else { // FIXME: comdats from LTO files don't know their selection; treat them // as "any". - Selection = LeaderSelection; + selection = leaderSelection; } - if ((Selection == IMAGE_COMDAT_SELECT_ANY && - LeaderSelection == IMAGE_COMDAT_SELECT_LARGEST) || - (Selection == IMAGE_COMDAT_SELECT_LARGEST && - LeaderSelection == IMAGE_COMDAT_SELECT_ANY)) { + if ((selection == IMAGE_COMDAT_SELECT_ANY && + leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) || + (selection == IMAGE_COMDAT_SELECT_LARGEST && + leaderSelection == IMAGE_COMDAT_SELECT_ANY)) { // cl.exe picks "any" for vftables when building with /GR- and // "largest" when building with /GR. To be able to link object files // compiled with each flag, "any" and "largest" are merged as "largest". - LeaderSelection = Selection = IMAGE_COMDAT_SELECT_LARGEST; + leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST; } // Other than that, comdat selections must match. This is a bit more @@ -440,18 +440,18 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, // Making this symmetric independent of which selection is seen first // seems better though. // (This behavior matches ModuleLinker::getComdatResult().) - if (Selection != LeaderSelection) { - log(("conflicting comdat type for " + toString(*Leader) + ": " + - Twine((int)LeaderSelection) + " in " + toString(Leader->getFile()) + - " and " + Twine((int)Selection) + " in " + toString(this)) + if (selection != leaderSelection) { + log(("conflicting comdat type for " + toString(*leader) + ": " + + Twine((int)leaderSelection) + " in " + toString(leader->getFile()) + + " and " + Twine((int)selection) + " in " + toString(this)) .str()); - Symtab->reportDuplicate(Leader, this); + symtab->reportDuplicate(leader, this); return; } - switch (Selection) { + switch (selection) { case IMAGE_COMDAT_SELECT_NODUPLICATES: - Symtab->reportDuplicate(Leader, this); + symtab->reportDuplicate(leader, this); break; case IMAGE_COMDAT_SELECT_ANY: @@ -459,17 +459,17 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, break; case IMAGE_COMDAT_SELECT_SAME_SIZE: - if (LeaderChunk->getSize() != getSection(Sym)->SizeOfRawData) - Symtab->reportDuplicate(Leader, this); + if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) + symtab->reportDuplicate(leader, this); break; case IMAGE_COMDAT_SELECT_EXACT_MATCH: { - SectionChunk NewChunk(this, getSection(Sym)); + SectionChunk newChunk(this, getSection(sym)); // link.exe only compares section contents here and doesn't complain // if the two comdat sections have e.g. different alignment. // Match that. - if (LeaderChunk->getContents() != NewChunk.getContents()) - Symtab->reportDuplicate(Leader, this); + if (leaderChunk->getContents() != newChunk.getContents()) + symtab->reportDuplicate(leader, this); break; } @@ -481,20 +481,20 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, llvm_unreachable("createDefined not called for associative comdats"); case IMAGE_COMDAT_SELECT_LARGEST: - if (LeaderChunk->getSize() < getSection(Sym)->SizeOfRawData) { + if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) { // Replace the existing comdat symbol with the new one. - StringRef Name; - COFFObj->getSymbolName(Sym, Name); + StringRef name; + coffObj->getSymbolName(sym, name); // FIXME: This is incorrect: With /opt:noref, the previous sections // make it into the final executable as well. Correct handling would // be to undo reading of the whole old section that's being replaced, // or doing one pass that determines what the final largest comdat // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading // only the largest one. - replaceSymbol<DefinedRegular>(Leader, this, Name, /*IsCOMDAT*/ true, - /*IsExternal*/ true, Sym.getGeneric(), + replaceSymbol<DefinedRegular>(leader, this, name, /*IsCOMDAT*/ true, + /*IsExternal*/ true, sym.getGeneric(), nullptr); - Prevailing = true; + prevailing = true; } break; @@ -504,50 +504,50 @@ void ObjFile::handleComdatSelection(COFFSymbolRef Sym, COMDATType &Selection, } Optional<Symbol *> ObjFile::createDefined( - COFFSymbolRef Sym, - std::vector<const coff_aux_section_definition *> &ComdatDefs, - bool &Prevailing) { - Prevailing = false; - auto GetName = [&]() { - StringRef S; - COFFObj->getSymbolName(Sym, S); - return S; + COFFSymbolRef sym, + std::vector<const coff_aux_section_definition *> &comdatDefs, + bool &prevailing) { + prevailing = false; + auto getName = [&]() { + StringRef s; + coffObj->getSymbolName(sym, s); + return s; }; - if (Sym.isCommon()) { - auto *C = make<CommonChunk>(Sym); - Chunks.push_back(C); - return Symtab->addCommon(this, GetName(), Sym.getValue(), Sym.getGeneric(), - C); + if (sym.isCommon()) { + auto *c = make<CommonChunk>(sym); + chunks.push_back(c); + return symtab->addCommon(this, getName(), sym.getValue(), sym.getGeneric(), + c); } - if (Sym.isAbsolute()) { - StringRef Name = GetName(); + if (sym.isAbsolute()) { + StringRef name = getName(); // Skip special symbols. - if (Name == "@comp.id") + if (name == "@comp.id") return nullptr; - if (Name == "@feat.00") { - Feat00Flags = Sym.getValue(); + if (name == "@feat.00") { + feat00Flags = sym.getValue(); return nullptr; } - if (Sym.isExternal()) - return Symtab->addAbsolute(Name, Sym); - return make<DefinedAbsolute>(Name, Sym); + if (sym.isExternal()) + return symtab->addAbsolute(name, sym); + return make<DefinedAbsolute>(name, sym); } - int32_t SectionNumber = Sym.getSectionNumber(); - if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) + int32_t sectionNumber = sym.getSectionNumber(); + if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) return nullptr; - if (llvm::COFF::isReservedSectionNumber(SectionNumber)) - fatal(toString(this) + ": " + GetName() + - " should not refer to special section " + Twine(SectionNumber)); + if (llvm::COFF::isReservedSectionNumber(sectionNumber)) + fatal(toString(this) + ": " + getName() + + " should not refer to special section " + Twine(sectionNumber)); - if ((uint32_t)SectionNumber >= SparseChunks.size()) - fatal(toString(this) + ": " + GetName() + - " should not refer to non-existent section " + Twine(SectionNumber)); + if ((uint32_t)sectionNumber >= sparseChunks.size()) + fatal(toString(this) + ": " + getName() + + " should not refer to non-existent section " + Twine(sectionNumber)); // Comdat handling. // A comdat symbol consists of two symbol table entries. @@ -560,65 +560,65 @@ Optional<Symbol *> ObjFile::createDefined( // symbol entry it reads ComdatDefs and then sets it back to nullptr. // Handle comdat leader. - if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { - ComdatDefs[SectionNumber] = nullptr; - DefinedRegular *Leader; + if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) { + comdatDefs[sectionNumber] = nullptr; + DefinedRegular *leader; - if (Sym.isExternal()) { - std::tie(Leader, Prevailing) = - Symtab->addComdat(this, GetName(), Sym.getGeneric()); + if (sym.isExternal()) { + std::tie(leader, prevailing) = + symtab->addComdat(this, getName(), sym.getGeneric()); } else { - Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false, - /*IsExternal*/ false, Sym.getGeneric()); - Prevailing = true; + leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false, + /*IsExternal*/ false, sym.getGeneric()); + prevailing = true; } - if (Def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES || + if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES || // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either. - Def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) { - fatal("unknown comdat type " + std::to_string((int)Def->Selection) + - " for " + GetName() + " in " + toString(this)); + def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) { + fatal("unknown comdat type " + std::to_string((int)def->Selection) + + " for " + getName() + " in " + toString(this)); } - COMDATType Selection = (COMDATType)Def->Selection; + COMDATType selection = (COMDATType)def->Selection; - if (Leader->IsCOMDAT) - handleComdatSelection(Sym, Selection, Prevailing, Leader); + if (leader->isCOMDAT) + handleComdatSelection(sym, selection, prevailing, leader); - if (Prevailing) { - SectionChunk *C = readSection(SectionNumber, Def, GetName()); - SparseChunks[SectionNumber] = C; - C->Sym = cast<DefinedRegular>(Leader); - C->Selection = Selection; - cast<DefinedRegular>(Leader)->Data = &C->Repl; + if (prevailing) { + SectionChunk *c = readSection(sectionNumber, def, getName()); + sparseChunks[sectionNumber] = c; + c->sym = cast<DefinedRegular>(leader); + c->selection = selection; + cast<DefinedRegular>(leader)->data = &c->repl; } else { - SparseChunks[SectionNumber] = nullptr; + sparseChunks[sectionNumber] = nullptr; } - return Leader; + return leader; } // Prepare to handle the comdat leader symbol by setting the section's // ComdatDefs pointer if we encounter a non-associative comdat. - if (SparseChunks[SectionNumber] == PendingComdat) { - if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) { - if (Def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE) - ComdatDefs[SectionNumber] = Def; + if (sparseChunks[sectionNumber] == pendingComdat) { + if (const coff_aux_section_definition *def = sym.getSectionDefinition()) { + if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE) + comdatDefs[sectionNumber] = def; } return None; } - return createRegular(Sym); + return createRegular(sym); } MachineTypes ObjFile::getMachineType() { - if (COFFObj) - return static_cast<MachineTypes>(COFFObj->getMachine()); + if (coffObj) + return static_cast<MachineTypes>(coffObj->getMachine()); return IMAGE_FILE_MACHINE_UNKNOWN; } -ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef SecName) { - if (SectionChunk *Sec = SectionChunk::findByName(DebugChunks, SecName)) - return Sec->consumeDebugMagic(); +ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) { + if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName)) + return sec->consumeDebugMagic(); return {}; } @@ -628,43 +628,43 @@ ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef SecName) { // PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is // currently used to initialize the HotPatchable member. void ObjFile::initializeFlags() { - ArrayRef<uint8_t> Data = getDebugSection(".debug$S"); - if (Data.empty()) + ArrayRef<uint8_t> data = getDebugSection(".debug$S"); + if (data.empty()) return; - DebugSubsectionArray Subsections; + DebugSubsectionArray subsections; - BinaryStreamReader Reader(Data, support::little); - ExitOnError ExitOnErr; - ExitOnErr(Reader.readArray(Subsections, Data.size())); + BinaryStreamReader reader(data, support::little); + ExitOnError exitOnErr; + exitOnErr(reader.readArray(subsections, data.size())); - for (const DebugSubsectionRecord &SS : Subsections) { - if (SS.kind() != DebugSubsectionKind::Symbols) + for (const DebugSubsectionRecord &ss : subsections) { + if (ss.kind() != DebugSubsectionKind::Symbols) continue; - unsigned Offset = 0; + unsigned offset = 0; // Only parse the first two records. We are only looking for S_OBJNAME // and S_COMPILE3, and they usually appear at the beginning of the // stream. - for (unsigned I = 0; I < 2; ++I) { - Expected<CVSymbol> Sym = readSymbolFromStream(SS.getRecordData(), Offset); - if (!Sym) { - consumeError(Sym.takeError()); + for (unsigned i = 0; i < 2; ++i) { + Expected<CVSymbol> sym = readSymbolFromStream(ss.getRecordData(), offset); + if (!sym) { + consumeError(sym.takeError()); return; } - if (Sym->kind() == SymbolKind::S_COMPILE3) { - auto CS = - cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(Sym.get())); - HotPatchable = - (CS.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None; + if (sym->kind() == SymbolKind::S_COMPILE3) { + auto cs = + cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(sym.get())); + hotPatchable = + (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None; } - if (Sym->kind() == SymbolKind::S_OBJNAME) { - auto ObjName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>( - Sym.get())); - PCHSignature = ObjName.Signature; + if (sym->kind() == SymbolKind::S_OBJNAME) { + auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>( + sym.get())); + pchSignature = objName.Signature; } - Offset += Sym->length(); + offset += sym->length(); } } } @@ -677,112 +677,112 @@ void ObjFile::initializeFlags() { // DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular // output even with /Yc and /Yu and with /Zi. void ObjFile::initializeDependencies() { - if (!Config->Debug) + if (!config->debug) return; - bool IsPCH = false; + bool isPCH = false; - ArrayRef<uint8_t> Data = getDebugSection(".debug$P"); - if (!Data.empty()) - IsPCH = true; + ArrayRef<uint8_t> data = getDebugSection(".debug$P"); + if (!data.empty()) + isPCH = true; else - Data = getDebugSection(".debug$T"); + data = getDebugSection(".debug$T"); - if (Data.empty()) + if (data.empty()) return; - CVTypeArray Types; - BinaryStreamReader Reader(Data, support::little); - cantFail(Reader.readArray(Types, Reader.getLength())); + CVTypeArray types; + BinaryStreamReader reader(data, support::little); + cantFail(reader.readArray(types, reader.getLength())); - CVTypeArray::Iterator FirstType = Types.begin(); - if (FirstType == Types.end()) + CVTypeArray::Iterator firstType = types.begin(); + if (firstType == types.end()) return; - DebugTypes.emplace(Types); + debugTypes.emplace(types); - if (IsPCH) { - DebugTypesObj = makePrecompSource(this); + if (isPCH) { + debugTypesObj = makePrecompSource(this); return; } - if (FirstType->kind() == LF_TYPESERVER2) { - TypeServer2Record TS = cantFail( - TypeDeserializer::deserializeAs<TypeServer2Record>(FirstType->data())); - DebugTypesObj = makeUseTypeServerSource(this, &TS); + if (firstType->kind() == LF_TYPESERVER2) { + TypeServer2Record ts = cantFail( + TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data())); + debugTypesObj = makeUseTypeServerSource(this, &ts); return; } - if (FirstType->kind() == LF_PRECOMP) { - PrecompRecord Precomp = cantFail( - TypeDeserializer::deserializeAs<PrecompRecord>(FirstType->data())); - DebugTypesObj = makeUsePrecompSource(this, &Precomp); + if (firstType->kind() == LF_PRECOMP) { + PrecompRecord precomp = cantFail( + TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data())); + debugTypesObj = makeUsePrecompSource(this, &precomp); return; } - DebugTypesObj = makeTpiSource(this); + debugTypesObj = makeTpiSource(this); } -StringRef ltrim1(StringRef S, const char *Chars) { - if (!S.empty() && strchr(Chars, S[0])) - return S.substr(1); - return S; +StringRef ltrim1(StringRef s, const char *chars) { + if (!s.empty() && strchr(chars, s[0])) + return s.substr(1); + return s; } void ImportFile::parse() { - const char *Buf = MB.getBufferStart(); - const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf); + const char *buf = mb.getBufferStart(); + const auto *hdr = reinterpret_cast<const coff_import_header *>(buf); // Check if the total size is valid. - if (MB.getBufferSize() != sizeof(*Hdr) + Hdr->SizeOfData) + if (mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData) fatal("broken import library"); // Read names and create an __imp_ symbol. - StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr))); - StringRef ImpName = Saver.save("__imp_" + Name); - const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1; - DLLName = StringRef(NameStart); - StringRef ExtName; - switch (Hdr->getNameType()) { + StringRef name = saver.save(StringRef(buf + sizeof(*hdr))); + StringRef impName = saver.save("__imp_" + name); + const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1; + dllName = StringRef(nameStart); + StringRef extName; + switch (hdr->getNameType()) { case IMPORT_ORDINAL: - ExtName = ""; + extName = ""; break; case IMPORT_NAME: - ExtName = Name; + extName = name; break; case IMPORT_NAME_NOPREFIX: - ExtName = ltrim1(Name, "?@_"); + extName = ltrim1(name, "?@_"); break; case IMPORT_NAME_UNDECORATE: - ExtName = ltrim1(Name, "?@_"); - ExtName = ExtName.substr(0, ExtName.find('@')); + extName = ltrim1(name, "?@_"); + extName = extName.substr(0, extName.find('@')); break; } - this->Hdr = Hdr; - ExternalName = ExtName; + this->hdr = hdr; + externalName = extName; - ImpSym = Symtab->addImportData(ImpName, this); + impSym = symtab->addImportData(impName, this); // If this was a duplicate, we logged an error but may continue; // in this case, ImpSym is nullptr. - if (!ImpSym) + if (!impSym) return; - if (Hdr->getType() == llvm::COFF::IMPORT_CONST) - static_cast<void>(Symtab->addImportData(Name, this)); + if (hdr->getType() == llvm::COFF::IMPORT_CONST) + static_cast<void>(symtab->addImportData(name, this)); // If type is function, we need to create a thunk which jump to an // address pointed by the __imp_ symbol. (This allows you to call // DLL functions just like regular non-DLL functions.) - if (Hdr->getType() == llvm::COFF::IMPORT_CODE) - ThunkSym = Symtab->addImportThunk( - Name, cast_or_null<DefinedImportData>(ImpSym), Hdr->Machine); + if (hdr->getType() == llvm::COFF::IMPORT_CODE) + thunkSym = symtab->addImportThunk( + name, cast_or_null<DefinedImportData>(impSym), hdr->Machine); } -BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, - uint64_t OffsetInArchive) - : InputFile(BitcodeKind, MB) { - std::string Path = MB.getBufferIdentifier().str(); +BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, + uint64_t offsetInArchive) + : InputFile(BitcodeKind, mb) { + std::string path = mb.getBufferIdentifier().str(); // ThinLTO assumes that all MemoryBufferRefs given to it have a unique // name. If two archives define two members with the same name, this @@ -790,53 +790,53 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, // into consideration at LTO time (which very likely causes undefined // symbols later in the link stage). So we append file offset to make // filename unique. - MemoryBufferRef MBRef( - MB.getBuffer(), - Saver.save(ArchiveName + Path + - (ArchiveName.empty() ? "" : utostr(OffsetInArchive)))); + MemoryBufferRef mbref( + mb.getBuffer(), + saver.save(archiveName + path + + (archiveName.empty() ? "" : utostr(offsetInArchive)))); - Obj = check(lto::InputFile::create(MBRef)); + obj = check(lto::InputFile::create(mbref)); } void BitcodeFile::parse() { - std::vector<std::pair<Symbol *, bool>> Comdat(Obj->getComdatTable().size()); - for (size_t I = 0; I != Obj->getComdatTable().size(); ++I) + std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size()); + for (size_t i = 0; i != obj->getComdatTable().size(); ++i) // FIXME: lto::InputFile doesn't keep enough data to do correct comdat // selection handling. - Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I])); - for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) { - StringRef SymName = Saver.save(ObjSym.getName()); - int ComdatIndex = ObjSym.getComdatIndex(); - Symbol *Sym; - if (ObjSym.isUndefined()) { - Sym = Symtab->addUndefined(SymName, this, false); - } else if (ObjSym.isCommon()) { - Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize()); - } else if (ObjSym.isWeak() && ObjSym.isIndirect()) { + comdat[i] = symtab->addComdat(this, saver.save(obj->getComdatTable()[i])); + for (const lto::InputFile::Symbol &objSym : obj->symbols()) { + StringRef symName = saver.save(objSym.getName()); + int comdatIndex = objSym.getComdatIndex(); + Symbol *sym; + if (objSym.isUndefined()) { + sym = symtab->addUndefined(symName, this, false); + } else if (objSym.isCommon()) { + sym = symtab->addCommon(this, symName, objSym.getCommonSize()); + } else if (objSym.isWeak() && objSym.isIndirect()) { // Weak external. - Sym = Symtab->addUndefined(SymName, this, true); - std::string Fallback = ObjSym.getCOFFWeakExternalFallback(); - Symbol *Alias = Symtab->addUndefined(Saver.save(Fallback)); - checkAndSetWeakAlias(Symtab, this, Sym, Alias); - } else if (ComdatIndex != -1) { - if (SymName == Obj->getComdatTable()[ComdatIndex]) - Sym = Comdat[ComdatIndex].first; - else if (Comdat[ComdatIndex].second) - Sym = Symtab->addRegular(this, SymName); + sym = symtab->addUndefined(symName, this, true); + std::string fallback = objSym.getCOFFWeakExternalFallback(); + Symbol *alias = symtab->addUndefined(saver.save(fallback)); + checkAndSetWeakAlias(symtab, this, sym, alias); + } else if (comdatIndex != -1) { + if (symName == obj->getComdatTable()[comdatIndex]) + sym = comdat[comdatIndex].first; + else if (comdat[comdatIndex].second) + sym = symtab->addRegular(this, symName); else - Sym = Symtab->addUndefined(SymName, this, false); + sym = symtab->addUndefined(symName, this, false); } else { - Sym = Symtab->addRegular(this, SymName); + sym = symtab->addRegular(this, symName); } - Symbols.push_back(Sym); - if (ObjSym.isUsed()) - Config->GCRoot.push_back(Sym); + symbols.push_back(sym); + if (objSym.isUsed()) + config->gCRoot.push_back(sym); } - Directives = Obj->getCOFFLinkerOpts(); + directives = obj->getCOFFLinkerOpts(); } MachineTypes BitcodeFile::getMachineType() { - switch (Triple(Obj->getTargetTriple()).getArch()) { + switch (Triple(obj->getTargetTriple()).getArch()) { case Triple::x86_64: return AMD64; case Triple::x86: @@ -853,18 +853,18 @@ MachineTypes BitcodeFile::getMachineType() { } // namespace lld // Returns the last element of a path, which is supposed to be a filename. -static StringRef getBasename(StringRef Path) { - return sys::path::filename(Path, sys::path::Style::windows); +static StringRef getBasename(StringRef path) { + return sys::path::filename(path, sys::path::Style::windows); } // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". -std::string lld::toString(const coff::InputFile *File) { - if (!File) +std::string lld::toString(const coff::InputFile *file) { + if (!file) return "<internal>"; - if (File->ParentName.empty() || File->kind() == coff::InputFile::ImportKind) - return File->getName(); + if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind) + return file->getName(); - return (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + + return (getBasename(file->parentName) + "(" + getBasename(file->getName()) + ")") .str(); } |