[DebugInfo][PDB] Don't write empty debug streams
Before, empty debug streams were written as 8 bytes (4 bytes signature + 4 bytes for the GlobalRefs count). With this patch, unused empty streams aren't emitted anymore. Modules now encode 65535 as an 'unused stream' value, by convention. Also fix the * Linker * contrib section which wasn't correctly emitted previously. Differential Revision: https://reviews.llvm.org/D59502 llvm-svn: 356395
This commit is contained in:
parent
8723a56551
commit
4aeea4cc42
|
@ -1088,13 +1088,13 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
|
|||
}
|
||||
|
||||
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<SectionChunk>(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<SectionChunk>(C)) {
|
||||
SC.Characteristics = SecChunk->Header->Characteristics;
|
||||
SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
|
||||
ArrayRef<uint8_t> Contents = SecChunk->getContents();
|
||||
|
@ -1104,7 +1104,7 @@ static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
|
|||
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 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
|
|||
}
|
||||
}
|
||||
|
||||
// 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<object::coff_section> Sections = {
|
||||
(const object::coff_section *)SectionTable.data(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -134,7 +134,7 @@ 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 ``
|
||||
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
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
findChecksumsSubsection() const;
|
||||
|
||||
private:
|
||||
Error reloadSerialize(BinaryStreamReader &Reader);
|
||||
|
||||
DbiModuleDescriptor Mod;
|
||||
|
||||
uint32_t Signature;
|
||||
|
|
|
@ -103,7 +103,6 @@ uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
|
|||
}
|
||||
|
||||
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 @@ void DbiModuleDescriptorBuilder::finalize() {
|
|||
|
||||
// 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)
|
||||
|
|
|
@ -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 @@ ModuleDebugStreamRef::~ModuleDebugStreamRef() = default;
|
|||
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<RawError>(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 @@ Error ModuleDebugStreamRef::reload() {
|
|||
return EC;
|
||||
if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
|
||||
return EC;
|
||||
if (Reader.bytesRemaining() > 0)
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Unexpected bytes in module stream.");
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue