[PDB] Teach libpdb to write DBI Stream ECNames.
Based strictly on the name, this seems to have something to do
width edit & continue. The goal of this patch has nothing to do
with supporting edit and continue though. msvc link.exe writes
very basic information into this area even when *not* compiling
with support for E&C, and so the goal here is to bring lld-link
to parity. Since we cannot know what assumptions standard tools
make about the content of PDB files, we need to be as close as
possible.
This ECNames data structure is a standard PDB string hash table.
link.exe puts a single string into this hash table, which is the
full path to the PDB file on disk. It then references this string
from the module descriptor for the compiler generated `* Linker *`
module.
With this patch, lld-link will generate the exact same sequence of
bytes as MSVC link for this subsection for a given object file
input (as reported by `llvm-pdbutil bytes -ec`).
llvm-svn: 307356
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 745dd74..897f78c 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -65,6 +65,10 @@
ObjFileName = Name;
}
+void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
+ PdbFilePathNI = NI;
+}
+
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
Symbols.push_back(Symbol);
// Symbols written to a PDB file are required to be 4 byte aligned. The same
@@ -111,7 +115,7 @@
(void)Layout.Mod; // Set in constructor
(void)Layout.ModDiStream; // Set in finalizeMsfLayout
Layout.NumFiles = SourceFiles.size();
- Layout.PdbFilePathNI = 0;
+ Layout.PdbFilePathNI = PdbFilePathNI;
Layout.SrcFileNameNI = 0;
// This value includes both the signature field as well as the record bytes
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
index a1f0671..78cf2c5 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -225,6 +225,10 @@
}
}
+Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
+ return ECNames.getStringForID(NI);
+}
+
Error DbiStream::initializeSectionContributionData() {
if (SecContrSubstream.empty())
return Error::success();
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index aad247e..2993f78 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -63,11 +63,16 @@
return Error::success();
}
+uint32_t DbiStreamBuilder::addECName(StringRef Name) {
+ return ECNamesBuilder.insert(Name);
+}
+
uint32_t DbiStreamBuilder::calculateSerializedLength() const {
// For now we only support serializing the header.
return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +
- calculateSectionMapStreamSize() + calculateDbgStreamsSize();
+ calculateSectionMapStreamSize() + calculateDbgStreamsSize() +
+ ECNamesBuilder.calculateSerializedSize();
}
Expected<DbiModuleDescriptorBuilder &>
@@ -247,7 +252,7 @@
H->PdbDllVersion = PdbDllVersion;
H->MachineType = static_cast<uint16_t>(MachineType);
- H->ECSubstreamSize = 0;
+ H->ECSubstreamSize = ECNamesBuilder.calculateSerializedSize();
H->FileInfoSize = FileInfoBuffer.getLength();
H->ModiSubstreamSize = calculateModiSubstreamSize();
H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
@@ -383,6 +388,9 @@
if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
return EC;
+ if (auto EC = ECNamesBuilder.commit(Writer))
+ return EC;
+
for (auto &Stream : DbgStreams)
if (auto EC = Writer.writeInteger(Stream.StreamNumber))
return EC;