forked from OSchip/llvm-project
[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:
parent
358af38d37
commit
194be871b9
|
@ -125,9 +125,6 @@ public:
|
||||||
void addSections(ArrayRef<OutputSection *> OutputSections,
|
void addSections(ArrayRef<OutputSection *> OutputSections,
|
||||||
ArrayRef<uint8_t> SectionTable);
|
ArrayRef<uint8_t> SectionTable);
|
||||||
|
|
||||||
void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule,
|
|
||||||
OutputSection *OS, Chunk *C);
|
|
||||||
|
|
||||||
/// Write the PDB to disk.
|
/// Write the PDB to disk.
|
||||||
void commit();
|
void commit();
|
||||||
|
|
||||||
|
@ -780,6 +777,32 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
|
||||||
".debug$S");
|
".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) {
|
void PDBLinker::addObjFile(ObjFile *File) {
|
||||||
// Add a module descriptor for every object file. We need to put an absolute
|
// 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
|
// 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 = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
|
||||||
File->ModuleDBI->setObjFileName(Path);
|
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
|
// 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
|
// 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
|
// 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);
|
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,
|
void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
|
||||||
ArrayRef<uint8_t> SectionTable) {
|
ArrayRef<uint8_t> SectionTable) {
|
||||||
// It's not entirely clear what this is, but the * Linker * module uses it.
|
// 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.
|
// Add section contributions. They must be ordered by ascending RVA.
|
||||||
for (OutputSection *OS : OutputSections) {
|
for (OutputSection *OS : OutputSections) {
|
||||||
addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
|
addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
|
||||||
for (Chunk *C : OS->getChunks())
|
for (Chunk *C : OS->getChunks()) {
|
||||||
addSectionContrib(LinkerModule, OS, C);
|
pdb::SectionContrib SC =
|
||||||
|
createSectionContrib(C, LinkerModule.getModuleIndex());
|
||||||
|
Builder.getDbiBuilder().addSectionContrib(SC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Section Map stream.
|
// Add Section Map stream.
|
||||||
|
|
|
@ -120,14 +120,16 @@
|
||||||
RAW: Modules
|
RAW: Modules
|
||||||
RAW-NEXT: ============================================================
|
RAW-NEXT: ============================================================
|
||||||
RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`:
|
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: SC[.text] | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0
|
||||||
RAW-NEXT: none
|
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: Obj: `{{.*}}pdb.test.tmp1.obj`:
|
||||||
RAW-NEXT: debug stream: 11, # files: 1, has ec info: false
|
RAW-NEXT: debug stream: 11, # files: 1, has ec info: false
|
||||||
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
||||||
RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`:
|
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: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0
|
||||||
RAW-NEXT: none
|
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: Obj: `{{.*}}pdb.test.tmp2.obj`:
|
||||||
RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
|
RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
|
||||||
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
|
|
||||||
void setPdbFilePathNI(uint32_t NI);
|
void setPdbFilePathNI(uint32_t NI);
|
||||||
void setObjFileName(StringRef Name);
|
void setObjFileName(StringRef Name);
|
||||||
|
void setFirstSectionContrib(const SectionContrib &SC);
|
||||||
void addSymbol(codeview::CVSymbol Symbol);
|
void addSymbol(codeview::CVSymbol Symbol);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -60,6 +60,11 @@ void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
|
||||||
PdbFilePathNI = NI;
|
PdbFilePathNI = NI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DbiModuleDescriptorBuilder::setFirstSectionContrib(
|
||||||
|
const SectionContrib &SC) {
|
||||||
|
Layout.SC = SC;
|
||||||
|
}
|
||||||
|
|
||||||
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
|
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
|
||||||
Symbols.push_back(Symbol);
|
Symbols.push_back(Symbol);
|
||||||
// Symbols written to a PDB file are required to be 4 byte aligned. The same
|
// Symbols written to a PDB file are required to be 4 byte aligned. The same
|
||||||
|
|
Loading…
Reference in New Issue