diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
| commit | a303c417bbdb53703c2c17398b08486bde78f1f6 (patch) | |
| tree | 98366d6b93d863cefdc53f16c66c0c5ae7fb2261 /lib/DebugInfo/CodeView | |
| parent | 12f3ca4cdb95b193af905a00e722a4dcb40b3de3 (diff) | |
Notes
Diffstat (limited to 'lib/DebugInfo/CodeView')
| -rw-r--r-- | lib/DebugInfo/CodeView/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/EnumTables.cpp | 28 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp | 102 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugFragment.cpp | 16 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp | 84 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp | 52 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp | 116 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp | 155 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp | 10 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleSubstream.cpp | 43 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp | 106 | ||||
| -rw-r--r-- | lib/DebugInfo/CodeView/TypeDatabase.cpp | 4 |
12 files changed, 560 insertions, 165 deletions
diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt index 6e9214d72adc..421f22ca5d8d 100644 --- a/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/lib/DebugInfo/CodeView/CMakeLists.txt @@ -7,8 +7,13 @@ add_llvm_library(LLVMDebugInfoCodeView EnumTables.cpp Formatters.cpp Line.cpp - ModuleSubstream.cpp - ModuleSubstreamVisitor.cpp + ModuleDebugFileChecksumFragment.cpp + ModuleDebugFragment.cpp + ModuleDebugFragmentRecord.cpp + ModuleDebugFragmentVisitor.cpp + ModuleDebugInlineeLinesFragment.cpp + ModuleDebugLineFragment.cpp + ModuleDebugUnknownFragment.cpp RecordSerialization.cpp SymbolRecordMapping.cpp SymbolDumper.cpp diff --git a/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp index 0e20bcb27ec9..fc6008ba66de 100644 --- a/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/lib/DebugInfo/CodeView/EnumTables.cpp @@ -245,20 +245,20 @@ static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = { }; static const EnumEntry<uint32_t> ModuleSubstreamKindNames[] = { - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, None), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput), - CV_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, None), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Symbols), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Lines), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, StringTable), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FileChecksums), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FrameData), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, InlineeLines), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeImports), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeExports), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, ILLines), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FuncMDTokenMap), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, TypeMDTokenMap), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, MergedAssemblyInput), + CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CoffSymbolRVA), }; static const EnumEntry<uint16_t> ExportSymFlagNames[] = { diff --git a/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp new file mode 100644 index 000000000000..c349e7ecce96 --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp @@ -0,0 +1,102 @@ +//===- ModuleDebugFileChecksumFragment.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/ModuleDebugFileChecksumFragment.h" + +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/Support/BinaryStreamReader.h" + +using namespace llvm; +using namespace llvm::codeview; + +struct FileChecksumEntryHeader { + using ulittle32_t = support::ulittle32_t; + + ulittle32_t FileNameOffset; // Byte offset of filename in global string table. + uint8_t ChecksumSize; // Number of bytes of checksum. + uint8_t ChecksumKind; // FileChecksumKind + // Checksum bytes follow. +}; + +Error llvm::VarStreamArrayExtractor<FileChecksumEntry>::extract( + BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item, void *Ctx) { + BinaryStreamReader Reader(Stream); + + const FileChecksumEntryHeader *Header; + if (auto EC = Reader.readObject(Header)) + return EC; + + Item.FileNameOffset = Header->FileNameOffset; + Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind); + if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize)) + return EC; + + Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4); + return Error::success(); +} + +Error ModuleDebugFileChecksumFragmentRef::initialize( + BinaryStreamReader Reader) { + if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining())) + return EC; + + return Error::success(); +} + +ModuleDebugFileChecksumFragment::ModuleDebugFileChecksumFragment() + : ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums) {} + +void ModuleDebugFileChecksumFragment::addChecksum(uint32_t StringTableOffset, + FileChecksumKind Kind, + ArrayRef<uint8_t> Bytes) { + FileChecksumEntry Entry; + if (!Bytes.empty()) { + uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size()); + ::memcpy(Copy, Bytes.data(), Bytes.size()); + Entry.Checksum = makeArrayRef(Copy, Bytes.size()); + } + Entry.FileNameOffset = StringTableOffset; + Entry.Kind = Kind; + Checksums.push_back(Entry); + + // 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; + assert(SerializedSize % 4 == 0); + + uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4); + SerializedSize += Len; +} + +uint32_t ModuleDebugFileChecksumFragment::calculateSerializedLength() { + return SerializedSize; +} + +Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) { + for (const auto &FC : Checksums) { + FileChecksumEntryHeader Header; + Header.ChecksumKind = uint8_t(FC.Kind); + Header.ChecksumSize = FC.Checksum.size(); + Header.FileNameOffset = FC.FileNameOffset; + if (auto EC = Writer.writeObject(Header)) + return EC; + if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum))) + return EC; + if (auto EC = Writer.padToAlignment(4)) + return EC; + } + return Error::success(); +} + +uint32_t ModuleDebugFileChecksumFragment::mapChecksumOffset( + uint32_t StringTableOffset) const { + auto Iter = OffsetMap.find(StringTableOffset); + assert(Iter != OffsetMap.end()); + return Iter->second; +} diff --git a/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp new file mode 100644 index 000000000000..2af1917413da --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp @@ -0,0 +1,16 @@ +//===- ModuleDebugFragment.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/ModuleDebugFragment.h" + +using namespace llvm::codeview; + +ModuleDebugFragmentRef::~ModuleDebugFragmentRef() {} + +ModuleDebugFragment::~ModuleDebugFragment() {} diff --git a/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp b/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp new file mode 100644 index 000000000000..b2543de78069 --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp @@ -0,0 +1,84 @@ +//===- ModuleDebugFragmentRecord.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/ModuleDebugFragmentRecord.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" + +#include "llvm/Support/BinaryStreamReader.h" + +using namespace llvm; +using namespace llvm::codeview; + +ModuleDebugFragmentRecord::ModuleDebugFragmentRecord() + : Kind(ModuleDebugFragmentKind::None) {} + +ModuleDebugFragmentRecord::ModuleDebugFragmentRecord( + ModuleDebugFragmentKind Kind, BinaryStreamRef Data) + : Kind(Kind), Data(Data) {} + +Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream, + ModuleDebugFragmentRecord &Info) { + const ModuleDebugFragmentHeader *Header; + BinaryStreamReader Reader(Stream); + if (auto EC = Reader.readObject(Header)) + return EC; + + ModuleDebugFragmentKind Kind = + static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind)); + switch (Kind) { + case ModuleDebugFragmentKind::FileChecksums: + case ModuleDebugFragmentKind::Lines: + case ModuleDebugFragmentKind::InlineeLines: + break; + default: + llvm_unreachable("Unexpected debug fragment kind!"); + } + if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) + return EC; + Info.Kind = Kind; + return Error::success(); +} + +uint32_t ModuleDebugFragmentRecord::getRecordLength() const { + uint32_t Result = sizeof(ModuleDebugFragmentHeader) + Data.getLength(); + assert(Result % 4 == 0); + return Result; +} + +ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; } + +BinaryStreamRef ModuleDebugFragmentRecord::getRecordData() const { + return Data; +} + +ModuleDebugFragmentRecordBuilder::ModuleDebugFragmentRecordBuilder( + ModuleDebugFragmentKind Kind, ModuleDebugFragment &Frag) + : Kind(Kind), Frag(Frag) {} + +uint32_t ModuleDebugFragmentRecordBuilder::calculateSerializedLength() { + uint32_t Size = sizeof(ModuleDebugFragmentHeader) + + alignTo(Frag.calculateSerializedLength(), 4); + return Size; +} + +Error ModuleDebugFragmentRecordBuilder::commit(BinaryStreamWriter &Writer) { + ModuleDebugFragmentHeader Header; + Header.Kind = uint32_t(Kind); + Header.Length = + calculateSerializedLength() - sizeof(ModuleDebugFragmentHeader); + + if (auto EC = Writer.writeObject(Header)) + return EC; + if (auto EC = Frag.commit(Writer)) + return EC; + if (auto EC = Writer.padToAlignment(4)) + return EC; + + return Error::success(); +} diff --git a/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp b/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp new file mode 100644 index 000000000000..dc591f3990e2 --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp @@ -0,0 +1,52 @@ +//===- ModuleDebugFragmentVisitor.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/ModuleDebugFragmentVisitor.h" + +#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" +#include "llvm/Support/BinaryStreamRef.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error llvm::codeview::visitModuleDebugFragment( + const ModuleDebugFragmentRecord &R, ModuleDebugFragmentVisitor &V) { + BinaryStreamReader Reader(R.getRecordData()); + switch (R.kind()) { + case ModuleDebugFragmentKind::Lines: { + ModuleDebugLineFragmentRef Fragment; + if (auto EC = Fragment.initialize(Reader)) + return EC; + + return V.visitLines(Fragment); + } + case ModuleDebugFragmentKind::FileChecksums: { + ModuleDebugFileChecksumFragmentRef Fragment; + if (auto EC = Fragment.initialize(Reader)) + return EC; + + 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/lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.cpp new file mode 100644 index 000000000000..483f7cb5c5ad --- /dev/null +++ b/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/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp new file mode 100644 index 000000000000..103010ca2833 --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp @@ -0,0 +1,155 @@ +//===- ModuleDebugLineFragment.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/ModuleDebugLineFragment.h" + +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error LineColumnExtractor::extract(BinaryStreamRef Stream, uint32_t &Len, + LineColumnEntry &Item, + const LineFragmentHeader *Header) { + using namespace codeview; + const LineBlockFragmentHeader *BlockHeader; + BinaryStreamReader Reader(Stream); + if (auto EC = Reader.readObject(BlockHeader)) + return EC; + bool HasColumn = Header->Flags & uint16_t(LF_HaveColumns); + uint32_t LineInfoSize = + BlockHeader->NumLines * + (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0)); + if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader)) + return make_error<CodeViewError>(cv_error_code::corrupt_record, + "Invalid line block record size"); + uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader); + if (LineInfoSize > Size) + return make_error<CodeViewError>(cv_error_code::corrupt_record, + "Invalid line block record size"); + // The value recorded in BlockHeader->BlockSize includes the size of + // LineBlockFragmentHeader. + Len = BlockHeader->BlockSize; + Item.NameIndex = BlockHeader->NameIndex; + if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines)) + return EC; + if (HasColumn) { + if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines)) + return EC; + } + return Error::success(); +} + +ModuleDebugLineFragmentRef::ModuleDebugLineFragmentRef() + : ModuleDebugFragmentRef(ModuleDebugFragmentKind::Lines) {} + +Error ModuleDebugLineFragmentRef::initialize(BinaryStreamReader Reader) { + if (auto EC = Reader.readObject(Header)) + return EC; + + if (auto EC = + Reader.readArray(LinesAndColumns, Reader.bytesRemaining(), Header)) + return EC; + + return Error::success(); +} + +bool ModuleDebugLineFragmentRef::hasColumnInfo() const { + return !!(Header->Flags & LF_HaveColumns); +} + +ModuleDebugLineFragment::ModuleDebugLineFragment() + : ModuleDebugFragment(ModuleDebugFragmentKind::Lines) {} + +void ModuleDebugLineFragment::createBlock(uint32_t ChecksumBufferOffset) { + Blocks.emplace_back(ChecksumBufferOffset); +} + +void ModuleDebugLineFragment::addLineInfo(uint32_t Offset, + const LineInfo &Line) { + Block &B = Blocks.back(); + LineNumberEntry LNE; + LNE.Flags = Line.getRawData(); + LNE.Offset = Offset; + B.Lines.push_back(LNE); +} + +void ModuleDebugLineFragment::addLineAndColumnInfo(uint32_t Offset, + const LineInfo &Line, + uint32_t ColStart, + uint32_t ColEnd) { + Block &B = Blocks.back(); + assert(B.Lines.size() == B.Columns.size()); + + addLineInfo(Offset, Line); + ColumnNumberEntry CNE; + CNE.StartColumn = ColStart; + CNE.EndColumn = ColEnd; + B.Columns.push_back(CNE); +} + +Error ModuleDebugLineFragment::commit(BinaryStreamWriter &Writer) { + LineFragmentHeader Header; + Header.CodeSize = CodeSize; + Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0; + Header.RelocOffset = RelocOffset; + Header.RelocSegment = RelocSegment; + + if (auto EC = Writer.writeObject(Header)) + return EC; + + for (const auto &B : Blocks) { + LineBlockFragmentHeader BlockHeader; + assert(B.Lines.size() == B.Columns.size() || B.Columns.empty()); + + BlockHeader.NumLines = B.Lines.size(); + BlockHeader.BlockSize = sizeof(LineBlockFragmentHeader); + BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(LineNumberEntry); + if (hasColumnInfo()) + BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(ColumnNumberEntry); + BlockHeader.NameIndex = B.ChecksumBufferOffset; + if (auto EC = Writer.writeObject(BlockHeader)) + return EC; + + if (auto EC = Writer.writeArray(makeArrayRef(B.Lines))) + return EC; + + if (hasColumnInfo()) { + if (auto EC = Writer.writeArray(makeArrayRef(B.Columns))) + return EC; + } + } + return Error::success(); +} + +uint32_t ModuleDebugLineFragment::calculateSerializedLength() { + uint32_t Size = sizeof(LineFragmentHeader); + for (const auto &B : Blocks) { + Size += sizeof(LineBlockFragmentHeader); + Size += B.Lines.size() * sizeof(LineNumberEntry); + if (hasColumnInfo()) + Size += B.Columns.size() * sizeof(ColumnNumberEntry); + } + return Size; +} + +void ModuleDebugLineFragment::setRelocationAddress(uint16_t Segment, + uint16_t Offset) { + RelocOffset = Offset; + RelocSegment = Segment; +} + +void ModuleDebugLineFragment::setCodeSize(uint32_t Size) { CodeSize = Size; } + +void ModuleDebugLineFragment::setFlags(LineFlags Flags) { this->Flags = Flags; } + +bool ModuleDebugLineFragment::hasColumnInfo() const { + return Flags & LF_HaveColumns; +} diff --git a/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp new file mode 100644 index 000000000000..9fd2cb8ed3e8 --- /dev/null +++ b/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp @@ -0,0 +1,10 @@ +//===- ModuleDebugUnknownFragment.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/ModuleDebugUnknownFragment.h"
\ No newline at end of file diff --git a/lib/DebugInfo/CodeView/ModuleSubstream.cpp b/lib/DebugInfo/CodeView/ModuleSubstream.cpp deleted file mode 100644 index 69a7c59116cf..000000000000 --- a/lib/DebugInfo/CodeView/ModuleSubstream.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===- ModuleSubstream.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/ModuleSubstream.h" - -#include "llvm/Support/BinaryStreamReader.h" - -using namespace llvm; -using namespace llvm::codeview; - -ModuleSubstream::ModuleSubstream() : Kind(ModuleSubstreamKind::None) {} - -ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data) - : Kind(Kind), Data(Data) {} - -Error ModuleSubstream::initialize(BinaryStreamRef Stream, - ModuleSubstream &Info) { - const ModuleSubsectionHeader *Header; - BinaryStreamReader Reader(Stream); - if (auto EC = Reader.readObject(Header)) - return EC; - - ModuleSubstreamKind Kind = - static_cast<ModuleSubstreamKind>(uint32_t(Header->Kind)); - if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) - return EC; - Info.Kind = Kind; - return Error::success(); -} - -uint32_t ModuleSubstream::getRecordLength() const { - return sizeof(ModuleSubsectionHeader) + Data.getLength(); -} - -ModuleSubstreamKind ModuleSubstream::getSubstreamKind() const { return Kind; } - -BinaryStreamRef ModuleSubstream::getRecordData() const { return Data; } diff --git a/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp b/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp deleted file mode 100644 index e490a78cadbc..000000000000 --- a/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//===- ModuleSubstreamVisitor.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/ModuleSubstreamVisitor.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/BinaryStreamRef.h" - -using namespace llvm; -using namespace llvm::codeview; - -Error IModuleSubstreamVisitor::visitSymbols(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::Symbols, Data); -} -Error IModuleSubstreamVisitor::visitLines(BinaryStreamRef Data, - const LineSubstreamHeader *Header, - const LineInfoArray &Lines) { - return visitUnknown(ModuleSubstreamKind::Lines, Data); -} -Error IModuleSubstreamVisitor::visitStringTable(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::StringTable, Data); -} -Error IModuleSubstreamVisitor::visitFileChecksums( - BinaryStreamRef Data, const FileChecksumArray &Checksums) { - return visitUnknown(ModuleSubstreamKind::FileChecksums, Data); -} -Error IModuleSubstreamVisitor::visitFrameData(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::FrameData, Data); -} -Error IModuleSubstreamVisitor::visitInlineeLines(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::InlineeLines, Data); -} -Error IModuleSubstreamVisitor::visitCrossScopeImports(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::CrossScopeExports, Data); -} -Error IModuleSubstreamVisitor::visitCrossScopeExports(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::CrossScopeImports, Data); -} -Error IModuleSubstreamVisitor::visitILLines(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::ILLines, Data); -} -Error IModuleSubstreamVisitor::visitFuncMDTokenMap(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::FuncMDTokenMap, Data); -} -Error IModuleSubstreamVisitor::visitTypeMDTokenMap(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::TypeMDTokenMap, Data); -} -Error IModuleSubstreamVisitor::visitMergedAssemblyInput(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::MergedAssemblyInput, Data); -} -Error IModuleSubstreamVisitor::visitCoffSymbolRVA(BinaryStreamRef Data) { - return visitUnknown(ModuleSubstreamKind::CoffSymbolRVA, Data); -} - -Error llvm::codeview::visitModuleSubstream(const ModuleSubstream &R, - IModuleSubstreamVisitor &V) { - switch (R.getSubstreamKind()) { - case ModuleSubstreamKind::Symbols: - return V.visitSymbols(R.getRecordData()); - case ModuleSubstreamKind::Lines: { - BinaryStreamReader Reader(R.getRecordData()); - const LineSubstreamHeader *Header; - if (auto EC = Reader.readObject(Header)) - return EC; - VarStreamArrayExtractor<LineColumnEntry> E(Header); - LineInfoArray LineInfos(E); - if (auto EC = Reader.readArray(LineInfos, Reader.bytesRemaining())) - return EC; - return V.visitLines(R.getRecordData(), Header, LineInfos); - } - case ModuleSubstreamKind::StringTable: - return V.visitStringTable(R.getRecordData()); - case ModuleSubstreamKind::FileChecksums: { - BinaryStreamReader Reader(R.getRecordData()); - FileChecksumArray Checksums; - if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining())) - return EC; - return V.visitFileChecksums(R.getRecordData(), Checksums); - } - case ModuleSubstreamKind::FrameData: - return V.visitFrameData(R.getRecordData()); - case ModuleSubstreamKind::InlineeLines: - return V.visitInlineeLines(R.getRecordData()); - case ModuleSubstreamKind::CrossScopeImports: - return V.visitCrossScopeImports(R.getRecordData()); - case ModuleSubstreamKind::CrossScopeExports: - return V.visitCrossScopeExports(R.getRecordData()); - case ModuleSubstreamKind::ILLines: - return V.visitILLines(R.getRecordData()); - case ModuleSubstreamKind::FuncMDTokenMap: - return V.visitFuncMDTokenMap(R.getRecordData()); - case ModuleSubstreamKind::TypeMDTokenMap: - return V.visitTypeMDTokenMap(R.getRecordData()); - case ModuleSubstreamKind::MergedAssemblyInput: - return V.visitMergedAssemblyInput(R.getRecordData()); - case ModuleSubstreamKind::CoffSymbolRVA: - return V.visitCoffSymbolRVA(R.getRecordData()); - default: - return V.visitUnknown(R.getSubstreamKind(), R.getRecordData()); - } -} diff --git a/lib/DebugInfo/CodeView/TypeDatabase.cpp b/lib/DebugInfo/CodeView/TypeDatabase.cpp index f9ded6ce2a86..efaba4646ffe 100644 --- a/lib/DebugInfo/CodeView/TypeDatabase.cpp +++ b/lib/DebugInfo/CodeView/TypeDatabase.cpp @@ -110,6 +110,10 @@ const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const { return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex]; } +CVType &TypeDatabase::getTypeRecord(TypeIndex Index) { + return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex]; +} + bool TypeDatabase::containsTypeIndex(TypeIndex Index) const { uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex; return I < CVUDTNames.size(); |
