From: Bob Haarman Date: Thu, 25 May 2017 21:12:15 +0000 (+0000) Subject: [pdb] pad source file name buffer at the end instead of the beginning X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae12b7b36034f0ce05b80326d78205f52b1dd35c;p=llvm [pdb] pad source file name buffer at the end instead of the beginning Summary: DbiStreamBuilder calculated the offset of the source file names inside the file info substream as the size of the file info substream minus the size of the file names. Since the file info substream is padded to a multiple of 4 bytes, this caused the first file name to be aligned on a 4-byte boundary. By contrast, DbiModuleList would read the file names immediately after the file name offset table, without skipping to the next 4-byte boundary. This change makes it so that the file names are written to the location where DbiModuleList expects them, and puts any necessary padding for the file info substream after the file names instead of before it. Reviewers: amccarth, rnk, zturner Reviewed By: amccarth, zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33475 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303917 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index bcac182e214..e116f314ac0 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -82,6 +82,7 @@ private: Error finalize(); uint32_t calculateModiSubstreamSize() const; + uint32_t calculateNamesOffset() const; uint32_t calculateSectionContribsStreamSize() const; uint32_t calculateSectionMapStreamSize() const; uint32_t calculateFileInfoSubstreamSize() const; diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp index c19a2f0d311..23c7456d777 100644 --- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -129,16 +129,21 @@ uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const { 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 @@ uint32_t DbiStreamBuilder::calculateDbgStreamsSize() const { 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 @@ Error DbiStreamBuilder::generateFileInfoSubstream() { } } + 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."); diff --git a/test/DebugInfo/PDB/Inputs/source-names-1.yaml b/test/DebugInfo/PDB/Inputs/source-names-1.yaml new file mode 100644 index 00000000000..96f7dedd2fc --- /dev/null +++ b/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' +... diff --git a/test/DebugInfo/PDB/Inputs/source-names-2.yaml b/test/DebugInfo/PDB/Inputs/source-names-2.yaml new file mode 100644 index 00000000000..5f782ddbca2 --- /dev/null +++ b/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' +... diff --git a/test/DebugInfo/PDB/pdbdump-source-names.test b/test/DebugInfo/PDB/pdbdump-source-names.test new file mode 100644 index 00000000000..181f4d5e0ee --- /dev/null +++ b/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'