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,7 +129,7 @@ return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size(); } -uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const { +uint32_t DbiStreamBuilder::calculateNamesOffset() const { uint32_t Size = 0; Size += sizeof(ulittle16_t); // NumModules Size += sizeof(ulittle16_t); // NumSourceFiles @@ -139,6 +139,11 @@ for (const auto &M : ModiList) NumFileInfos += M->source_files().size(); Size += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets + return Size; +} + +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,27 @@ +--- +MSF: + SuperBlock: + BlockSize: 4096 + FreeBlockMap: 1 + NumBlocks: 11 + NumDirectoryBytes: 64 + Unknown1: 0 + BlockMapAddr: 3 + NumDirectoryBlocks: 1 + DirectoryBlocks: [ 10 ] + NumStreams: 0 + FileSize: 45056 +DbiStream: + VerHeader: V70 + Age: 1 + BuildNumber: 36352 + PdbDllVersion: 24210 + PdbDllRbld: 0 + Flags: 1 + MachineType: Amd64 + 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,27 @@ +--- +MSF: + SuperBlock: + BlockSize: 4096 + FreeBlockMap: 1 + NumBlocks: 11 + NumDirectoryBytes: 64 + Unknown1: 0 + BlockMapAddr: 3 + NumDirectoryBlocks: 1 + DirectoryBlocks: [ 10 ] + NumStreams: 0 + FileSize: 45056 +DbiStream: + VerHeader: V70 + Age: 1 + BuildNumber: 36352 + PdbDllVersion: 24210 + PdbDllRbld: 0 + Flags: 1 + MachineType: Amd64 + 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'