[LLD/PDB] Emit first section contribution for DBI Module Descriptor.

Part of the DBI stream is a list of variable length structures
describing each module that contributes to the final executable.

One member of this structure is a section contribution entry that
describes the first section contribution in the output file for
the given module.

We have been leaving this structure unpopulated until now, so with
this patch it is now filled out correctly.

Differential Revision: https://reviews.llvm.org/D45832

llvm-svn: 330457
This commit is contained in:
Zachary Turner 2018-04-20 18:00:46 +00:00
parent 358af38d37
commit 194be871b9
4 changed files with 55 additions and 34 deletions

View File

@ -125,9 +125,6 @@ public:
void addSections(ArrayRef<OutputSection *> OutputSections,
ArrayRef<uint8_t> SectionTable);
void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule,
OutputSection *OS, Chunk *C);
/// Write the PDB to disk.
void commit();
@ -780,6 +777,32 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
".debug$S");
}
static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
OutputSection *OS = C->getOutputSection();
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<SectionChunk>(C)) {
SC.Characteristics = SecChunk->Header->Characteristics;
SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
ArrayRef<uint8_t> Contents = SecChunk->getContents();
JamCRC CRC(0);
ArrayRef<char> CharContents = makeArrayRef(
reinterpret_cast<const char *>(Contents.data()), Contents.size());
CRC.update(CharContents);
SC.DataCrc = CRC.getCRC();
} else {
SC.Characteristics = OS->Header.Characteristics;
// FIXME: When we start creating DBI for import libraries, use those here.
SC.Imod = Modi;
}
SC.RelocCrc = 0; // FIXME
return SC;
}
void PDBLinker::addObjFile(ObjFile *File) {
// Add a module descriptor for every object file. We need to put an absolute
// path to the object into the PDB. If this is a plain object, we make its
@ -794,6 +817,18 @@ void PDBLinker::addObjFile(ObjFile *File) {
File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
File->ModuleDBI->setObjFileName(Path);
auto Chunks = File->getChunks();
assert(!Chunks.empty());
uint32_t Modi = File->ModuleDBI->getModuleIndex();
for (Chunk *C : Chunks) {
auto *SecChunk = dyn_cast<SectionChunk>(C);
if (!SecChunk || !SecChunk->isLive())
continue;
pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);
File->ModuleDBI->setFirstSectionContrib(SC);
break;
}
// Before we can process symbol substreams from .debug$S, we need to process
// type information, file checksums, and the string table. Add type info to
// the PDB first, so that we can get the map from object file type and item
@ -1110,31 +1145,6 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
DbiBuilder.setBuildNumber(14, 11);
}
void PDBLinker::addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule,
OutputSection *OS, Chunk *C) {
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<SectionChunk>(C)) {
SC.Characteristics = SecChunk->Header->Characteristics;
SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
ArrayRef<uint8_t> Contents = SecChunk->getContents();
JamCRC CRC(0);
ArrayRef<char> CharContents = makeArrayRef(
reinterpret_cast<const char *>(Contents.data()), Contents.size());
CRC.update(CharContents);
SC.DataCrc = CRC.getCRC();
} else {
SC.Characteristics = OS->Header.Characteristics;
// FIXME: When we start creating DBI for import libraries, use those here.
SC.Imod = LinkerModule.getModuleIndex();
}
SC.RelocCrc = 0; // FIXME
Builder.getDbiBuilder().addSectionContrib(SC);
}
void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
ArrayRef<uint8_t> SectionTable) {
// It's not entirely clear what this is, but the * Linker * module uses it.
@ -1150,8 +1160,11 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
// Add section contributions. They must be ordered by ascending RVA.
for (OutputSection *OS : OutputSections) {
addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
for (Chunk *C : OS->getChunks())
addSectionContrib(LinkerModule, OS, C);
for (Chunk *C : OS->getChunks()) {
pdb::SectionContrib SC =
createSectionContrib(C, LinkerModule.getModuleIndex());
Builder.getDbiBuilder().addSectionContrib(SC);
}
}
// Add Section Map stream.

View File

@ -120,14 +120,16 @@
RAW: Modules
RAW-NEXT: ============================================================
RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`:
RAW-NEXT: SC[???] | mod = 0, 0000:0000, size = 0, data crc = 0, reloc crc = 0
RAW-NEXT: none
RAW-NEXT: SC[.text] | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0
RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
RAW-NEXT: IMAGE_SCN_MEM_READ
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
RAW-NEXT: debug stream: 11, # files: 1, has ec info: false
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`:
RAW-NEXT: SC[???] | mod = 1, 0000:0000, size = 0, data crc = 0, reloc crc = 0
RAW-NEXT: none
RAW-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0
RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
RAW-NEXT: IMAGE_SCN_MEM_READ
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``

View File

@ -49,6 +49,7 @@ public:
void setPdbFilePathNI(uint32_t NI);
void setObjFileName(StringRef Name);
void setFirstSectionContrib(const SectionContrib &SC);
void addSymbol(codeview::CVSymbol Symbol);
void

View File

@ -60,6 +60,11 @@ void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
PdbFilePathNI = NI;
}
void DbiModuleDescriptorBuilder::setFirstSectionContrib(
const SectionContrib &SC) {
Layout.SC = SC;
}
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
Symbols.push_back(Symbol);
// Symbols written to a PDB file are required to be 4 byte aligned. The same