summaryrefslogtreecommitdiff
path: root/COFF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'COFF/Writer.cpp')
-rw-r--r--COFF/Writer.cpp55
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;
}