Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -82,6 +82,7 @@ Error finalize(); uint32_t calculateModiSubstreamSize() const; + uint32_t calculateNamesOffset() const; uint32_t calculateSectionContribsStreamSize() const; uint32_t calculateSectionMapStreamSize() const; uint32_t calculateFileInfoSubstreamSize() const; Index: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -129,16 +129,21 @@ return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size(); } -uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const { - uint32_t Size = 0; - Size += sizeof(ulittle16_t); // NumModules - Size += sizeof(ulittle16_t); // NumSourceFiles - Size += ModiList.size() * sizeof(ulittle16_t); // ModIndices - Size += ModiList.size() * sizeof(ulittle16_t); // ModFileCounts +uint32_t DbiStreamBuilder::calculateNamesOffset() const { + uint32_t Offset = 0; + Offset += sizeof(ulittle16_t); // NumModules + Offset += sizeof(ulittle16_t); // NumSourceFiles + Offset += ModiList.size() * sizeof(ulittle16_t); // ModIndices + Offset += ModiList.size() * sizeof(ulittle16_t); // ModFileCounts uint32_t NumFileInfos = 0; for (const auto &M : ModiList) NumFileInfos += M->source_files().size(); - Size += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets + Offset += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets + return Offset; +} + +uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const { + uint32_t Size = calculateNamesOffset(); Size += calculateNamesBufferSize(); return alignTo(Size, sizeof(uint32_t)); } @@ -157,9 +162,8 @@ Error DbiStreamBuilder::generateFileInfoSubstream() { uint32_t Size = calculateFileInfoSubstreamSize(); - uint32_t NameSize = calculateNamesBufferSize(); auto Data = Allocator.Allocate(Size); - uint32_t NamesOffset = Size - NameSize; + uint32_t NamesOffset = calculateNamesOffset(); FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef(Data, Size), llvm::support::little); @@ -207,6 +211,9 @@ } } + if (auto EC = NameBufferWriter.padToAlignment(sizeof(uint32_t))) + return EC; + if (NameBufferWriter.bytesRemaining() > 0) return make_error(raw_error_code::invalid_format, "The names buffer contained unexpected data."); Index: llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-1.yaml =================================================================== --- llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-1.yaml +++ llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-1.yaml @@ -0,0 +1,8 @@ +--- +DbiStream: + Modules: + - Module: 'C:\src\test.obj' + ObjFile: 'C:\src\test.obj' + SourceFiles: + - 'C:\src\test.c' +... Index: llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-2.yaml =================================================================== --- llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-2.yaml +++ llvm/trunk/test/DebugInfo/PDB/Inputs/source-names-2.yaml @@ -0,0 +1,8 @@ +--- +DbiStream: + Modules: + - Module: 'C:\src\test.obj' + ObjFile: 'C:\src\test.obj' + SourceFiles: + - 'C:\src\test.cc' +... Index: llvm/trunk/test/DebugInfo/PDB/pdbdump-source-names.test =================================================================== --- llvm/trunk/test/DebugInfo/PDB/pdbdump-source-names.test +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-source-names.test @@ -0,0 +1,20 @@ +# Test that we can write source file names to PDBs and read them back. +# Because the subsection the file names are stored in is 4-byte +# aligned, there is a possibility of misaligning the file names. This +# will cause them to be read back empty or truncated. To guard +# against this, we test with two different lengths of file name data +# that differ by one byte, so that at least one of those will only +# pass if alignment is implemented correctly. + +RUN: llvm-pdbdump yaml2pdb -pdb=%T/source-names-1.pdb %p/Inputs/source-names-1.yaml +RUN: llvm-pdbdump pdb2yaml -dbi-module-source-info %T/source-names-1.pdb \ +RUN: | FileCheck -check-prefix=CHECK1 %s +RUN: llvm-pdbdump yaml2pdb -pdb=%T/source-names-2.pdb %p/Inputs/source-names-2.yaml +RUN: llvm-pdbdump pdb2yaml -dbi-module-source-info %T/source-names-2.pdb \ +RUN: | FileCheck -check-prefix=CHECK2 %s + +CHECK1: SourceFiles: +CHECK1: 'C:\src\test.c' + +CHECK2: SourceFiles: +CHECK2: 'C:\src\test.cc'