diff options
Diffstat (limited to 'COFF/Writer.cpp')
-rw-r--r-- | COFF/Writer.cpp | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp index cf3ad7ef045c9..fb1f3cae5bb2f 100644 --- a/COFF/Writer.cpp +++ b/COFF/Writer.cpp @@ -365,6 +365,9 @@ void Writer::createImportTables() { // the same order as in the command line. (That affects DLL // initialization order, and this ordering is MSVC-compatible.) for (ImportFile *File : Symtab->ImportFiles) { + if (!File->Live) + continue; + std::string DLL = StringRef(File->DLLName).lower(); if (Config->DLLOrder.count(DLL) == 0) Config->DLLOrder[DLL] = Config->DLLOrder.size(); @@ -372,19 +375,28 @@ void Writer::createImportTables() { OutputSection *Text = createSection(".text"); for (ImportFile *File : Symtab->ImportFiles) { + if (!File->Live) + continue; + if (DefinedImportThunk *Thunk = File->ThunkSym) Text->addChunk(Thunk->getChunk()); + if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) { + if (!File->ThunkSym) + fatal("cannot delay-load " + toString(File) + + " due to import of data: " + toString(*File->ImpSym)); DelayIdata.add(File->ImpSym); } else { Idata.add(File->ImpSym); } } + if (!Idata.empty()) { OutputSection *Sec = createSection(".idata"); for (Chunk *C : Idata.getChunks()) Sec->addChunk(C); } + if (!DelayIdata.empty()) { Defined *Helper = cast<Defined>(Config->DelayLoadHelper); DelayIdata.create(Helper); @@ -437,6 +449,14 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { if (!D->getChunk()->isLive()) return None; + if (auto *Sym = dyn_cast<DefinedImportData>(Def)) + if (!Sym->File->Live) + return None; + + if (auto *Sym = dyn_cast<DefinedImportThunk>(Def)) + if (!Sym->WrappedSym->File->Live) + return None; + coff_symbol16 Sym; StringRef Name = Def->getName(); if (Name.size() > COFF::NameSize) { @@ -491,14 +511,17 @@ void Writer::createSymbolAndStringTable() { Sec->setStringTableOff(addEntryToStringTable(Name)); } - for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) - for (SymbolBody *B : File->getSymbols()) - if (auto *D = dyn_cast<Defined>(B)) - if (!D->WrittenToSymtab) { - D->WrittenToSymtab = true; - if (Optional<coff_symbol16> Sym = createSymbol(D)) - OutputSymtab.push_back(*Sym); - } + for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) { + for (SymbolBody *B : File->getSymbols()) { + auto *D = dyn_cast<Defined>(B); + if (!D || D->WrittenToSymtab) + continue; + D->WrittenToSymtab = true; + + if (Optional<coff_symbol16> Sym = createSymbol(D)) + OutputSymtab.push_back(*Sym); + } + } OutputSection *LastSection = OutputSections.back(); // We position the symbol table to be adjacent to the end of the last section. @@ -782,19 +805,15 @@ void Writer::writeBuildId() { if (BuildId == nullptr) return; - MD5 Hash; - MD5::MD5Result Res; - - Hash.update(ArrayRef<uint8_t>{Buffer->getBufferStart(), - Buffer->getBufferEnd()}); - Hash.final(Res); - assert(BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 && "only PDB 7.0 is supported"); - assert(sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) && + assert(sizeof(BuildId->DI->PDB70.Signature) == 16 && "signature size mismatch"); - memcpy(BuildId->DI->PDB70.Signature, Res.Bytes.data(), - sizeof(codeview::PDB70DebugInfo::Signature)); + + // Compute an MD5 hash. + ArrayRef<uint8_t> Buf(Buffer->getBufferStart(), Buffer->getBufferEnd()); + memcpy(BuildId->DI->PDB70.Signature, MD5::hash(Buf).data(), 16); + // TODO(compnerd) track the Age BuildId->DI->PDB70.Age = 1; } |