diff options
author | Zachary Turner <zturner@google.com> | 2017-05-02 16:56:09 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2017-05-02 16:56:09 +0000 |
commit | edef14510e36f307dff256faf030abbfb27be674 (patch) | |
tree | 5fd726720d7bd48b7b9059d2ac99826ffffb1580 /llvm/lib | |
parent | bb34f278a2e12f8af526b34725fd2b61c5c8c189 (diff) | |
download | bcm5719-llvm-edef14510e36f307dff256faf030abbfb27be674.tar.gz bcm5719-llvm-edef14510e36f307dff256faf030abbfb27be674.zip |
[PDB/CodeView] Read/write codeview inlinee line information.
Previously we wrote line information and file checksum
information, but we did not write information about inlinee
lines and functions. This patch adds support for that.
llvm-svn: 301936
Diffstat (limited to 'llvm/lib')
7 files changed, 147 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 4bfe3bf2b63..786b11618d7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -17,6 +17,7 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt index 7655f6c651e..421f22ca5d8 100644 --- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt @@ -11,6 +11,7 @@ add_llvm_library(LLVMDebugInfoCodeView ModuleDebugFragment.cpp ModuleDebugFragmentRecord.cpp ModuleDebugFragmentVisitor.cpp + ModuleDebugInlineeLinesFragment.cpp ModuleDebugLineFragment.cpp ModuleDebugUnknownFragment.cpp RecordSerialization.cpp diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp index 79e5b9d690d..c349e7ecce9 100644 --- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp @@ -68,7 +68,10 @@ void ModuleDebugFileChecksumFragment::addChecksum(uint32_t StringTableOffset, // This maps the offset of this string in the string table to the offset // of this checksum entry in the checksum buffer. OffsetMap[StringTableOffset] = SerializedSize; - SerializedSize += sizeof(FileChecksumEntryHeader) + Bytes.size(); + assert(SerializedSize % 4 == 0); + + uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4); + SerializedSize += Len; } uint32_t ModuleDebugFileChecksumFragment::calculateSerializedLength() { @@ -85,6 +88,8 @@ Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) { return EC; if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum))) return EC; + if (auto EC = Writer.padToAlignment(4)) + return EC; } return Error::success(); } diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp index 263b632da3f..b2543de7806 100644 --- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp @@ -34,6 +34,7 @@ Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream, switch (Kind) { case ModuleDebugFragmentKind::FileChecksums: case ModuleDebugFragmentKind::Lines: + case ModuleDebugFragmentKind::InlineeLines: break; default: llvm_unreachable("Unexpected debug fragment kind!"); diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp index b7a86ee6699..dc591f3990e 100644 --- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h" #include "llvm/Support/BinaryStreamReader.h" @@ -37,6 +38,12 @@ Error llvm::codeview::visitModuleDebugFragment( return V.visitFileChecksums(Fragment); } + case ModuleDebugFragmentKind::InlineeLines: { + ModuleDebugInlineeLineFragmentRef Fragment; + if (auto EC = Fragment.initialize(Reader)) + return EC; + return V.visitInlineeLines(Fragment); + } default: { ModuleDebugUnknownFragmentRef Fragment(R.kind(), R.getRecordData()); return V.visitUnknown(Fragment); diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp new file mode 100644 index 00000000000..483f7cb5c5a --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp @@ -0,0 +1,116 @@ +//===- ModuleDebugInlineeLineFragment.cpp ------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" + +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error VarStreamArrayExtractor<InlineeSourceLine>::extract( + BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item, + ContextType *Fragment) { + BinaryStreamReader Reader(Stream); + + if (auto EC = Reader.readObject(Item.Header)) + return EC; + + if (Fragment->hasExtraFiles()) { + uint32_t ExtraFileCount; + if (auto EC = Reader.readInteger(ExtraFileCount)) + return EC; + if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount)) + return EC; + } + + Len = Reader.getOffset(); + return Error::success(); +} + +ModuleDebugInlineeLineFragmentRef::ModuleDebugInlineeLineFragmentRef() + : ModuleDebugFragmentRef(ModuleDebugFragmentKind::InlineeLines) {} + +Error ModuleDebugInlineeLineFragmentRef::initialize(BinaryStreamReader Reader) { + if (auto EC = Reader.readEnum(Signature)) + return EC; + + if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining(), this)) + return EC; + + assert(Reader.bytesRemaining() == 0); + return Error::success(); +} + +bool ModuleDebugInlineeLineFragmentRef::hasExtraFiles() const { + return Signature == InlineeLinesSignature::ExtraFiles; +} + +ModuleDebugInlineeLineFragment::ModuleDebugInlineeLineFragment( + bool HasExtraFiles) + : ModuleDebugFragment(ModuleDebugFragmentKind::InlineeLines), + HasExtraFiles(HasExtraFiles) {} + +uint32_t ModuleDebugInlineeLineFragment::calculateSerializedLength() { + // 4 bytes for the signature + uint32_t Size = sizeof(InlineeLinesSignature); + + // one header for each entry. + Size += Entries.size() * sizeof(InlineeSourceLineHeader); + if (HasExtraFiles) { + // If extra files are enabled, one count for each entry. + Size += Entries.size() * sizeof(uint32_t); + + // And one file id for each file. + Size += ExtraFileCount * sizeof(uint32_t); + } + assert(Size % 4 == 0); + return Size; +} + +Error ModuleDebugInlineeLineFragment::commit(BinaryStreamWriter &Writer) { + InlineeLinesSignature Sig = InlineeLinesSignature::Normal; + if (HasExtraFiles) + Sig = InlineeLinesSignature::ExtraFiles; + + if (auto EC = Writer.writeEnum(Sig)) + return EC; + + for (const auto &E : Entries) { + if (auto EC = Writer.writeObject(E.Header)) + return EC; + + if (!HasExtraFiles) + continue; + + if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size())) + return EC; + if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles))) + return EC; + } + + return Error::success(); +} + +void ModuleDebugInlineeLineFragment::addExtraFile(uint32_t FileOffset) { + auto &Entry = Entries.back(); + Entry.ExtraFiles.push_back(ulittle32_t(FileOffset)); + ++ExtraFileCount; +} + +void ModuleDebugInlineeLineFragment::addInlineSite(TypeIndex FuncId, + uint32_t FileOffset, + uint32_t SourceLine) { + Entries.emplace_back(); + auto &Entry = Entries.back(); + Entry.Header.FileID = FileOffset; + Entry.Header.SourceLineNum = SourceLine; + Entry.Header.Inlinee = FuncId; +} diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp index 41cb23a188f..f994b4538ef 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -161,7 +161,7 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter, return Error::success(); } -void DbiModuleDescriptorBuilder::addC13LineFragment( +void DbiModuleDescriptorBuilder::addC13Fragment( std::unique_ptr<ModuleDebugLineFragment> Lines) { ModuleDebugLineFragment &Frag = *Lines; @@ -175,6 +175,20 @@ void DbiModuleDescriptorBuilder::addC13LineFragment( llvm::make_unique<ModuleDebugFragmentRecordBuilder>(Frag.kind(), Frag)); } +void DbiModuleDescriptorBuilder::addC13Fragment( + std::unique_ptr<codeview::ModuleDebugInlineeLineFragment> Inlinees) { + ModuleDebugInlineeLineFragment &Frag = *Inlinees; + + // File Checksums have to come first, so push an empty entry on if this + // is the first. + if (C13Builders.empty()) + C13Builders.push_back(nullptr); + + this->Inlinees.push_back(std::move(Inlinees)); + C13Builders.push_back( + llvm::make_unique<ModuleDebugFragmentRecordBuilder>(Frag.kind(), Frag)); +} + void DbiModuleDescriptorBuilder::setC13FileChecksums( std::unique_ptr<ModuleDebugFileChecksumFragment> Checksums) { assert(!ChecksumInfo && "Can't have more than one checksum info!"); |