Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -1088,13 +1088,13 @@ } static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) { - OutputSection *OS = C->getOutputSection(); + OutputSection *OS = C ? C->getOutputSection() : nullptr; pdb::SectionContrib SC; memset(&SC, 0, sizeof(SC)); - SC.ISect = OS->SectionIndex; - SC.Off = C->getRVA() - OS->getRVA(); - SC.Size = C->getSize(); - if (auto *SecChunk = dyn_cast(C)) { + SC.ISect = OS ? OS->SectionIndex : llvm::pdb::kInvalidStreamIndex; + SC.Off = C && OS ? C->getRVA() - OS->getRVA() : 0; + SC.Size = C ? C->getSize() : -1; + if (auto *SecChunk = dyn_cast_or_null(C)) { SC.Characteristics = SecChunk->Header->Characteristics; SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); ArrayRef Contents = SecChunk->getContents(); @@ -1104,7 +1104,7 @@ CRC.update(CharContents); SC.DataCrc = CRC.getCRC(); } else { - SC.Characteristics = OS->Header.Characteristics; + SC.Characteristics = OS ? OS->Header.Characteristics : 0; // FIXME: When we start creating DBI for import libraries, use those here. SC.Imod = Modi; } @@ -1589,6 +1589,13 @@ } } + // The * Linker * first section contrib is only used along with /INCREMENTAL, + // to provide trampolines thunks for incremental function patching. Set this + // as "unused" because LLD doesn't support /INCREMENTAL link. + pdb::SectionContrib SC = + createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex); + LinkerModule.setFirstSectionContrib(SC); + // Add Section Map stream. ArrayRef Sections = { (const object::coff_section *)SectionTable.data(), Index: lld/trunk/test/COFF/pdb-global-gc.yaml =================================================================== --- lld/trunk/test/COFF/pdb-global-gc.yaml +++ lld/trunk/test/COFF/pdb-global-gc.yaml @@ -23,6 +23,7 @@ # CHECK: ============================================================ # CHECK-NEXT: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: # CHECK-NEXT: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: +# CHECK-NEXT: Error loading module stream 1. The specified stream could not be loaded. Module stream not present # CHECK-NEXT: Mod 0002 | `* Linker *`: --- !COFF Index: lld/trunk/test/COFF/pdb-lib.s =================================================================== --- lld/trunk/test/COFF/pdb-lib.s +++ lld/trunk/test/COFF/pdb-lib.s @@ -13,15 +13,15 @@ # CHECK-NEXT: ============================================================ # CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: -# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false +# CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` # CHECK-NEXT: Mod 0001 | `bar.obj`: # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: -# CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false +# CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` # CHECK-NEXT: Mod 0002 | `* Linker *`: # CHECK-NEXT: Obj: ``: -# CHECK-NEXT: debug stream: 12, # files: 0, has ec info: false +# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 `` .def _main; Index: lld/trunk/test/COFF/pdb.test =================================================================== --- lld/trunk/test/COFF/pdb.test +++ lld/trunk/test/COFF/pdb.test @@ -134,7 +134,7 @@ RAW-NEXT: debug stream: 12, # files: 1, has ec info: false RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` RAW-NEXT: Mod 0002 | `* Linker *`: -RAW-NEXT: SC[???] | mod = 2, 0000:0000, size = 0, data crc = 0, reloc crc = 0 +RAW-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0 RAW-NEXT: none RAW-NEXT: Obj: ``: RAW-NEXT: debug stream: 13, # files: 0, has ec info: false Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -68,6 +68,8 @@ findChecksumsSubsection() const; private: + Error reloadSerialize(BinaryStreamReader &Reader); + DbiModuleDescriptor Mod; uint32_t Signature; Index: llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -103,7 +103,6 @@ } void DbiModuleDescriptorBuilder::finalize() { - Layout.SC.Imod = Layout.Mod; Layout.FileNameOffs = 0; // TODO: Fix this Layout.Flags = 0; // TODO: Fix this Layout.C11Bytes = 0; @@ -116,12 +115,15 @@ // This value includes both the signature field as well as the record bytes // from the symbol stream. - Layout.SymBytes = SymbolByteSize + sizeof(uint32_t); + Layout.SymBytes = + Layout.ModDiStream == kInvalidStreamIndex ? 0 : getNextSymbolOffset(); } Error DbiModuleDescriptorBuilder::finalizeMsfLayout() { this->Layout.ModDiStream = kInvalidStreamIndex; uint32_t C13Size = calculateC13DebugInfoSize(); + if (!C13Size && !SymbolByteSize) + return Error::success(); auto ExpectedSN = MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size)); if (!ExpectedSN) Index: llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamRef.h" @@ -36,6 +37,17 @@ Error ModuleDebugStreamRef::reload() { BinaryStreamReader Reader(*Stream); + if (Mod.getModuleStreamIndex() != llvm::pdb::kInvalidStreamIndex) { + if (Error E = reloadSerialize(Reader)) + return E; + } + if (Reader.bytesRemaining() > 0) + return make_error(raw_error_code::corrupt_file, + "Unexpected bytes in module stream."); + return Error::success(); +} + +Error ModuleDebugStreamRef::reloadSerialize(BinaryStreamReader &Reader) { uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize(); uint32_t C11Size = Mod.getC11LineInfoByteSize(); uint32_t C13Size = Mod.getC13LineInfoByteSize(); @@ -71,10 +83,6 @@ return EC; if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize)) return EC; - if (Reader.bytesRemaining() > 0) - return make_error(raw_error_code::corrupt_file, - "Unexpected bytes in module stream."); - return Error::success(); }