Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -204,7 +204,9 @@ StringRef ParentName) { file_magic Magic = identify_magic(MB.getBuffer()); if (Magic == file_magic::coff_import_library) { - Symtab->addFile(make(MB)); + InputFile *Imp = make(MB); + Imp->ParentName = ParentName; + Symtab->addFile(Imp); return; } Index: lld/trunk/COFF/InputFiles.cpp =================================================================== --- lld/trunk/COFF/InputFiles.cpp +++ lld/trunk/COFF/InputFiles.cpp @@ -778,7 +778,7 @@ std::string lld::toString(const coff::InputFile *File) { if (!File) return ""; - if (File->ParentName.empty()) + if (File->ParentName.empty() || File->kind() == coff::InputFile::ImportKind) return File->getName(); return (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -109,6 +109,9 @@ /// Link CodeView from each object file in the symbol table into the PDB. void addObjectsToPDB(); + /// Link info for each import file in the symbol table into the PDB. + void addImportFilesToPDB(ArrayRef OutputSections); + /// Link CodeView from a single object file into the target (output) PDB. /// When a precompiled headers object is linked, its TPI map might be provided /// externally. @@ -878,7 +881,7 @@ } static void scopeStackClose(SmallVectorImpl &Stack, - uint32_t CurOffset, ObjFile *File) { + uint32_t CurOffset, InputFile *File) { if (Stack.empty()) { warn("symbol scopes are not balanced in " + File->getName()); return; @@ -1104,7 +1107,6 @@ SC.DataCrc = CRC.getCRC(); } else { SC.Characteristics = OS ? OS->Header.Characteristics : 0; - // FIXME: When we start creating DBI for import libraries, use those here. SC.Imod = Modi; } SC.RelocCrc = 0; // FIXME @@ -1454,16 +1456,7 @@ return R; } -static void addCommonLinkerModuleSymbols(StringRef Path, - pdb::DbiModuleDescriptorBuilder &Mod, - BumpPtrAllocator &Allocator) { - ObjNameSym ONS(SymbolRecordKind::ObjNameSym); - Compile3Sym CS(SymbolRecordKind::Compile3Sym); - EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); - - ONS.Name = "* Linker *"; - ONS.Signature = 0; - +static void fillLinkerVerRecord(Compile3Sym &CS) { CS.Machine = toCodeViewMachine(Config->Machine); // Interestingly, if we set the string to 0.0.0.0, then when trying to view // local variables WinDbg emits an error that private symbols are not present. @@ -1487,6 +1480,18 @@ CS.VersionFrontendQFE = 0; CS.Version = "LLVM Linker"; CS.setLanguage(SourceLanguage::Link); +} + +static void addCommonLinkerModuleSymbols(StringRef Path, + pdb::DbiModuleDescriptorBuilder &Mod, + BumpPtrAllocator &Allocator) { + ObjNameSym ONS(SymbolRecordKind::ObjNameSym); + EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); + Compile3Sym CS(SymbolRecordKind::Compile3Sym); + fillLinkerVerRecord(CS); + + ONS.Name = "* Linker *"; + ONS.Signature = 0; ArrayRef Args = makeArrayRef(Config->Argv).drop_front(); std::string ArgStr = quote(Args); @@ -1513,6 +1518,33 @@ EBS, Allocator, CodeViewContainer::Pdb)); } +static void addLinkerModuleCoffGroup(PartialSection *Sec, + pdb::DbiModuleDescriptorBuilder &Mod, + OutputSection &OS, + BumpPtrAllocator &Allocator) { + // If there's a section, there's at least one chunk + assert(!Sec->Chunks.empty()); + const Chunk *firstChunk = *Sec->Chunks.begin(); + const Chunk *lastChunk = *Sec->Chunks.rbegin(); + + // Emit COFF group + CoffGroupSym CGS(SymbolRecordKind::CoffGroupSym); + CGS.Name = Sec->Name; + CGS.Segment = OS.SectionIndex; + CGS.Offset = firstChunk->getRVA() - OS.getRVA(); + CGS.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA(); + CGS.Characteristics = Sec->Characteristics; + + // Somehow .idata sections & sections groups in the debug symbol stream have + // the "write" flag set. However the section header for the corresponding + // .idata section doesn't have it. + if (CGS.Name.startswith(".idata")) + CGS.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE; + + Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + CGS, Allocator, CodeViewContainer::Pdb)); +} + static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, OutputSection &OS, BumpPtrAllocator &Allocator) { @@ -1525,6 +1557,97 @@ Sym.SectionNumber = OS.SectionIndex; Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( Sym, Allocator, CodeViewContainer::Pdb)); + + // Skip COFF groups in MinGW because it adds a significant footprint to the + // PDB, due to each function being in its own section + if (Config->MinGW) + return; + + // Output COFF groups for individual chunks of this section. + for (PartialSection *Sec : OS.ContribSections) { + addLinkerModuleCoffGroup(Sec, Mod, OS, Allocator); + } +} + +// Add all import files as modules to the PDB. +void PDBLinker::addImportFilesToPDB(ArrayRef OutputSections) { + if (ImportFile::Instances.empty()) + return; + + std::map DllToModuleDbi; + + for (ImportFile *File : ImportFile::Instances) { + if (!File->Live) + continue; + + if (!File->ThunkSym) + continue; + + std::string DLL = StringRef(File->DLLName).lower(); + llvm::pdb::DbiModuleDescriptorBuilder *&Mod = DllToModuleDbi[DLL]; + if (!Mod) { + pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); + SmallString<128> LibPath = File->ParentName; + pdbMakeAbsolute(LibPath); + sys::path::native(LibPath); + + // Name modules similar to MSVC's link.exe. + // The first module is the simple dll filename + llvm::pdb::DbiModuleDescriptorBuilder &FirstMod = + ExitOnErr(DbiBuilder.addModuleInfo(File->DLLName)); + FirstMod.setObjFileName(LibPath); + pdb::SectionContrib SC = + createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex); + FirstMod.setFirstSectionContrib(SC); + + // The second module is where the import stream goes. + Mod = &ExitOnErr(DbiBuilder.addModuleInfo("Import:" + File->DLLName)); + Mod->setObjFileName(LibPath); + } + + DefinedImportThunk *Thunk = cast(File->ThunkSym); + + ObjNameSym ONS(SymbolRecordKind::ObjNameSym); + Compile3Sym CS(SymbolRecordKind::Compile3Sym); + Thunk32Sym TS(SymbolRecordKind::Thunk32Sym); + ScopeEndSym ES(SymbolRecordKind::ScopeEndSym); + + ONS.Name = File->DLLName; + ONS.Signature = 0; + + fillLinkerVerRecord(CS); + + TS.Name = Thunk->getName(); + TS.Parent = 0; + TS.End = 0; + TS.Next = 0; + TS.Thunk = ThunkOrdinal::Standard; + TS.Length = Thunk->getChunk()->getSize(); + TS.Segment = Thunk->getChunk()->getOutputSection()->SectionIndex; + TS.Offset = Thunk->getChunk()->OutputSectionOff; + + Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( + ONS, Alloc, CodeViewContainer::Pdb)); + Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol( + CS, Alloc, CodeViewContainer::Pdb)); + + SmallVector Scopes; + CVSymbol NewSym = codeview::SymbolSerializer::writeOneSymbol( + TS, Alloc, CodeViewContainer::Pdb); + scopeStackOpen(Scopes, Mod->getNextSymbolOffset(), NewSym); + + Mod->addSymbol(NewSym); + + NewSym = codeview::SymbolSerializer::writeOneSymbol(ES, Alloc, + CodeViewContainer::Pdb); + scopeStackClose(Scopes, Mod->getNextSymbolOffset(), File); + + Mod->addSymbol(NewSym); + + pdb::SectionContrib SC = + createSectionContrib(Thunk->getChunk(), Mod->getModuleIndex()); + Mod->setFirstSectionContrib(SC); + } } // Creates a PDB file. @@ -1537,6 +1660,7 @@ PDB.initialize(BuildId); PDB.addObjectsToPDB(); + PDB.addImportFilesToPDB(OutputSections); PDB.addSections(OutputSections, SectionTable); PDB.addNatvisFiles(); Index: lld/trunk/COFF/Writer.h =================================================================== --- lld/trunk/COFF/Writer.h +++ lld/trunk/COFF/Writer.h @@ -22,6 +22,15 @@ void writeResult(); +class PartialSection { +public: + PartialSection(StringRef N, uint32_t Chars) + : Name(N), Characteristics(Chars) {} + StringRef Name; + unsigned Characteristics; + std::vector Chunks; +}; + // OutputSection represents a section in an output file. It's a // container of chunks. OutputSection and Chunk are 1:N relationship. // Chunks cannot belong to more than one OutputSections. The writer @@ -39,6 +48,7 @@ uint64_t getRVA() { return Header.VirtualAddress; } uint64_t getFileOff() { return Header.PointerToRawData; } void writeHeaderTo(uint8_t *Buf); + void addContributingPartialSection(PartialSection *Sec); // Returns the size of this section in an executable memory image. // This may be smaller than the raw size (the raw size is multiple @@ -63,11 +73,13 @@ std::vector Chunks; std::vector OrigChunks; + std::vector ContribSections; + private: uint32_t StringTableOff = 0; }; -} -} +} // namespace coff +} // namespace lld #endif Index: lld/trunk/COFF/Writer.cpp =================================================================== --- lld/trunk/COFF/Writer.cpp +++ lld/trunk/COFF/Writer.cpp @@ -175,15 +175,6 @@ } }; -class PartialSection { -public: - PartialSection(StringRef N, uint32_t Chars) - : Name(N), Characteristics(Chars) {} - StringRef Name; - unsigned Characteristics; - std::vector Chunks; -}; - // The writer writes a SymbolTable result to a file. class Writer { public: @@ -312,6 +303,9 @@ C->setOutputSection(this); Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end()); Other->Chunks.clear(); + ContribSections.insert(ContribSections.end(), Other->ContribSections.begin(), + Other->ContribSections.end()); + Other->ContribSections.clear(); } // Write the section header to a given buffer. @@ -329,6 +323,10 @@ } } +void OutputSection::addContributingPartialSection(PartialSection *Sec) { + ContribSections.push_back(Sec); +} + } // namespace coff } // namespace lld @@ -842,6 +840,8 @@ OutputSection *Sec = CreateSection(Name, OutChars); for (Chunk *C : PSec->Chunks) Sec->addChunk(C); + + Sec->addContributingPartialSection(PSec); } // Finally, move some output sections to the end. Index: lld/trunk/test/COFF/pdb-publics-import.test =================================================================== --- lld/trunk/test/COFF/pdb-publics-import.test +++ lld/trunk/test/COFF/pdb-publics-import.test @@ -8,7 +8,48 @@ RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /pdbaltpath:test.pdb \ RUN: /debug /entry:main %t2.obj %t1.lib -RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s +RUN: llvm-pdbutil dump %t2.pdb -all | FileCheck %s + +CHECK: Streams +CHECK-NEXT: ============================================================ +CHECK-LABEL: Stream 10 ( 256 bytes): [Module "Import:pdb-publics-import.test.tmp1.dll"] + +CHECK: Module Stats +CHECK-NEXT: ============================================================ +CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`: +CHECK-NEXT: Mod 0 (debug info not present): [{{.*}}pdb-publics-import.test.tmp2.obj] +CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: Mod 1 (debug info not present): [pdb-publics-import.test.tmp1.dll] +CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: Stream 10, 256 bytes + +CHECK: Modules +CHECK-NEXT: ============================================================ +CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`: +CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE | +CHECK-NEXT: IMAGE_SCN_MEM_READ +CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp2.obj`: +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 | `pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0 +CHECK-NEXT: none +CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`: +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 | `Import:pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: SC[.text] | mod = 2, 0001:0032, size = 6, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ +CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`: +CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false +CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` +CHECK-NEXT: Mod 0003 | `* Linker *`: +CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0 +CHECK-NEXT: none +CHECK-NEXT: Obj: ``: +CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false +CHECK-NEXT: pdb file ni: 1 `{{.*}}pdb-publics-import.test.tmp2.pdb`, src file ni: 0 `` CHECK: Public Symbols CHECK-NEXT: ============================================================ @@ -24,6 +65,86 @@ CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1` CHECK-NEXT: flags = none, addr = 0002:0128 +CHECK: Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`: +CHECK-NEXT: Error loading module stream 0. The specified stream could not be loaded. Module stream not present +CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: Error loading module stream 1. The specified stream could not be loaded. Module stream not present +CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`: +CHECK-NEXT: 4 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll` +CHECK-NEXT: 48 | S_COMPILE3 [size = 40] +CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link +CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0 +CHECK-NEXT: flags = none +CHECK-NEXT: 88 | S_THUNK32 [size = 36] `exportfn1` +CHECK-NEXT: parent = 0, end = 124, next = 0 +CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0016 +CHECK-NEXT: 124 | S_END [size = 4] +CHECK-NEXT: 128 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll` +CHECK-NEXT: 172 | S_COMPILE3 [size = 40] +CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link +CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0 +CHECK-NEXT: flags = none +CHECK-NEXT: 212 | S_THUNK32 [size = 36] `exportfn2` +CHECK-NEXT: parent = 0, end = 248, next = 0 +CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0032 +CHECK-NEXT: 248 | S_END [size = 4] +CHECK-NEXT: Mod 0003 | `* Linker *`: +CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *` +CHECK-NEXT: 24 | S_COMPILE3 [size = 40] +CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link +CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0 +CHECK-NEXT: flags = none +CHECK-NEXT: 64 | S_ENVBLOCK [size = {{[0-9]+}}] +CHECK: {{[0-9]+}} | S_SECTION [size = 28] `.text` +CHECK-NEXT: length = 38, alignment = 12, rva = 4096, section # = 1 +CHECK-NEXT: characteristics = +CHECK-NEXT: code +CHECK-NEXT: execute permissions +CHECK-NEXT: read permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 24] `.text` +CHECK-NEXT: length = 8, addr = 0001:0000 +CHECK-NEXT: characteristics = +CHECK-NEXT: code +CHECK-NEXT: execute permissions +CHECK-NEXT: read permissions +CHECK-NEXT: {{[0-9]+}} | S_SECTION [size = 28] `.rdata` +CHECK-NEXT: length = 209, alignment = 12, rva = 8192, section # = 2 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$2` +CHECK-NEXT: length = 40, addr = 0002:0061 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: write permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$4` +CHECK-NEXT: length = 24, addr = 0002:0104 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: write permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$5` +CHECK-NEXT: length = 24, addr = 0002:0128 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: write permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$6` +CHECK-NEXT: length = 24, addr = 0002:0152 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: write permissions +CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$7` +CHECK-NEXT: length = 33, addr = 0002:0176 +CHECK-NEXT: characteristics = +CHECK-NEXT: initialized data +CHECK-NEXT: read permissions +CHECK-NEXT: write permissions + CHECK: Section Contributions CHECK-NEXT: ============================================================ main @@ -31,13 +152,35 @@ CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE | CHECK-NEXT: IMAGE_SCN_MEM_READ exportfn1 thunk -CHECK-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 0, reloc crc = 0 +CHECK-NEXT: SC[.text] | mod = 3, 0001:0016, size = 6, data crc = 0, reloc crc = 0 CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ exportfn2 thunk -CHECK-NEXT: SC[.text] | mod = 1, 0001:0032, size = 6, data crc = 0, reloc crc = 0 +CHECK-NEXT: SC[.text] | mod = 3, 0001:0032, size = 6, data crc = 0, reloc crc = 0 CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ .rdata debug directory data chunks -CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0 -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ -CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0028, size = 33, data crc = 0, reloc crc = 0 +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0000, size = 28, data crc = 0, reloc crc = 0 CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0028, size = 33, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0061, size = 20, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0081, size = 20, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0104, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0112, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0120, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0128, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0136, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0144, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0152, size = 12, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0164, size = 12, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0176, size = 33, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ