Index: include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h =================================================================== --- include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ 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: lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp =================================================================== --- lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ 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: test/DebugInfo/PDB/Inputs/source-names-1.yaml =================================================================== --- /dev/null +++ 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: test/DebugInfo/PDB/Inputs/source-names-2.yaml =================================================================== --- /dev/null +++ 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: test/DebugInfo/PDB/pdbdump-align-source-names.test =================================================================== --- /dev/null +++ test/DebugInfo/PDB/pdbdump-align-source-names.test @@ -0,0 +1,20 @@ +# Module source file names are contained in the file info substream. The +# substream is padded to a multiple of 4 bytes, and this padding must come +# after the file names. Putting it before the file names results in the +# possibility of source file names being read as empty or truncated. This test +# uses file names of two different lengths to make sure at least one hits the +# case where padding is needed and verifies that file names are correct in +# both cases. + +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'