diff options
Diffstat (limited to 'llvm/lib')
8 files changed, 200 insertions, 120 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt index 5dae51eedd1..7655f6c651e 100644 --- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt @@ -7,8 +7,12 @@ add_llvm_library(LLVMDebugInfoCodeView EnumTables.cpp Formatters.cpp Line.cpp + ModuleDebugFileChecksumFragment.cpp ModuleDebugFragment.cpp + ModuleDebugFragmentRecord.cpp ModuleDebugFragmentVisitor.cpp + ModuleDebugLineFragment.cpp + ModuleDebugUnknownFragment.cpp RecordSerialization.cpp SymbolRecordMapping.cpp SymbolDumper.cpp diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp new file mode 100644 index 00000000000..3f234adc1c2 --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp @@ -0,0 +1,49 @@ +//===- 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 ModuleDebugFileChecksumFragment::initialize(BinaryStreamReader Reader) { + if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining())) + return EC; + + return Error::success(); +} diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp index 1329f8cc8f6..a3327b06b98 100644 --- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp @@ -1,5 +1,4 @@ -//===- ModuleDebugFragment.cpp --------------------------------------*- C++ -//-*-===// +//===- ModuleDebugFragment.cpp -----------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -10,37 +9,6 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" -#include "llvm/Support/BinaryStreamReader.h" - -using namespace llvm; using namespace llvm::codeview; -ModuleDebugFragment::ModuleDebugFragment() - : Kind(ModuleDebugFragmentKind::None) {} - -ModuleDebugFragment::ModuleDebugFragment(ModuleDebugFragmentKind Kind, - BinaryStreamRef Data) - : Kind(Kind), Data(Data) {} - -Error ModuleDebugFragment::initialize(BinaryStreamRef Stream, - ModuleDebugFragment &Info) { - const ModuleDebugFragmentHeader *Header; - BinaryStreamReader Reader(Stream); - if (auto EC = Reader.readObject(Header)) - return EC; - - ModuleDebugFragmentKind Kind = - static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind)); - if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) - return EC; - Info.Kind = Kind; - return Error::success(); -} - -uint32_t ModuleDebugFragment::getRecordLength() const { - return sizeof(ModuleDebugFragmentHeader) + Data.getLength(); -} - -ModuleDebugFragmentKind ModuleDebugFragment::kind() const { return Kind; } - -BinaryStreamRef ModuleDebugFragment::getRecordData() const { return Data; } +ModuleDebugFragment::~ModuleDebugFragment() {} diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp new file mode 100644 index 00000000000..20c06e9bebe --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp @@ -0,0 +1,47 @@ +//===- 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/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)); + if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) + return EC; + Info.Kind = Kind; + return Error::success(); +} + +uint32_t ModuleDebugFragmentRecord::getRecordLength() const { + return sizeof(ModuleDebugFragmentHeader) + Data.getLength(); +} + +ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; } + +BinaryStreamRef ModuleDebugFragmentRecord::getRecordData() const { + return Data; +} diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp index 37cd887d783..53dc922a649 100644 --- a/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp @@ -8,99 +8,36 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h" + +#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamRef.h" using namespace llvm; using namespace llvm::codeview; -Error ModuleDebugFragmentVisitor::visitSymbols(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::Symbols, Data); -} -Error ModuleDebugFragmentVisitor::visitLines(BinaryStreamRef Data, - const LineFragmentHeader *Header, - const LineInfoArray &Lines) { - return visitUnknown(ModuleDebugFragmentKind::Lines, Data); -} -Error ModuleDebugFragmentVisitor::visitStringTable(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::StringTable, Data); -} -Error ModuleDebugFragmentVisitor::visitFileChecksums( - BinaryStreamRef Data, const FileChecksumArray &Checksums) { - return visitUnknown(ModuleDebugFragmentKind::FileChecksums, Data); -} -Error ModuleDebugFragmentVisitor::visitFrameData(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::FrameData, Data); -} -Error ModuleDebugFragmentVisitor::visitInlineeLines(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::InlineeLines, Data); -} -Error ModuleDebugFragmentVisitor::visitCrossScopeImports(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::CrossScopeExports, Data); -} -Error ModuleDebugFragmentVisitor::visitCrossScopeExports(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::CrossScopeImports, Data); -} -Error ModuleDebugFragmentVisitor::visitILLines(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::ILLines, Data); -} -Error ModuleDebugFragmentVisitor::visitFuncMDTokenMap(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::FuncMDTokenMap, Data); -} -Error ModuleDebugFragmentVisitor::visitTypeMDTokenMap(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::TypeMDTokenMap, Data); -} -Error ModuleDebugFragmentVisitor::visitMergedAssemblyInput( - BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::MergedAssemblyInput, Data); -} -Error ModuleDebugFragmentVisitor::visitCoffSymbolRVA(BinaryStreamRef Data) { - return visitUnknown(ModuleDebugFragmentKind::CoffSymbolRVA, Data); -} - -Error llvm::codeview::visitModuleDebugFragment(const ModuleDebugFragment &R, - ModuleDebugFragmentVisitor &V) { +Error llvm::codeview::visitModuleDebugFragment( + const ModuleDebugFragmentRecord &R, ModuleDebugFragmentVisitor &V) { + BinaryStreamReader Reader(R.getRecordData()); switch (R.kind()) { - case ModuleDebugFragmentKind::Symbols: - return V.visitSymbols(R.getRecordData()); case ModuleDebugFragmentKind::Lines: { - BinaryStreamReader Reader(R.getRecordData()); - const LineFragmentHeader *Header; - if (auto EC = Reader.readObject(Header)) + ModuleDebugLineFragment Fragment; + if (auto EC = Fragment.initialize(Reader)) return EC; - LineInfoArray LineInfos; - if (auto EC = Reader.readArray(LineInfos, Reader.bytesRemaining(), Header)) - return EC; - return V.visitLines(R.getRecordData(), Header, LineInfos); + + return V.visitLines(Fragment); } - case ModuleDebugFragmentKind::StringTable: - return V.visitStringTable(R.getRecordData()); case ModuleDebugFragmentKind::FileChecksums: { - BinaryStreamReader Reader(R.getRecordData()); - FileChecksumArray Checksums; - if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining())) + ModuleDebugFileChecksumFragment Fragment; + if (auto EC = Fragment.initialize(Reader)) return EC; - return V.visitFileChecksums(R.getRecordData(), Checksums); + + return V.visitFileChecksums(Fragment); + } + default: { + ModuleDebugUnknownFragment Fragment(R.kind(), R.getRecordData()); + return V.visitUnknown(Fragment); } - case ModuleDebugFragmentKind::FrameData: - return V.visitFrameData(R.getRecordData()); - case ModuleDebugFragmentKind::InlineeLines: - return V.visitInlineeLines(R.getRecordData()); - case ModuleDebugFragmentKind::CrossScopeImports: - return V.visitCrossScopeImports(R.getRecordData()); - case ModuleDebugFragmentKind::CrossScopeExports: - return V.visitCrossScopeExports(R.getRecordData()); - case ModuleDebugFragmentKind::ILLines: - return V.visitILLines(R.getRecordData()); - case ModuleDebugFragmentKind::FuncMDTokenMap: - return V.visitFuncMDTokenMap(R.getRecordData()); - case ModuleDebugFragmentKind::TypeMDTokenMap: - return V.visitTypeMDTokenMap(R.getRecordData()); - case ModuleDebugFragmentKind::MergedAssemblyInput: - return V.visitMergedAssemblyInput(R.getRecordData()); - case ModuleDebugFragmentKind::CoffSymbolRVA: - return V.visitCoffSymbolRVA(R.getRecordData()); - default: - return V.visitUnknown(R.kind(), R.getRecordData()); } } diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp new file mode 100644 index 00000000000..1b840890560 --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp @@ -0,0 +1,63 @@ +//===- 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 & uint32_t(LineFlags::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(); +} + +ModuleDebugLineFragment::ModuleDebugLineFragment() + : ModuleDebugFragment(ModuleDebugFragmentKind::Lines) {} + +Error ModuleDebugLineFragment::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(); +} diff --git a/llvm/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp b/llvm/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp new file mode 100644 index 00000000000..9fd2cb8ed3e --- /dev/null +++ b/llvm/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/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp index 8caa4b85772..56e415a3d54 100644 --- a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -21,6 +21,7 @@ #include <cstdint> using namespace llvm; +using namespace llvm::codeview; using namespace llvm::msf; using namespace llvm::pdb; @@ -54,7 +55,8 @@ Error ModuleDebugStream::reload() { return EC; BinaryStreamReader LineReader(C13LinesSubstream); - if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining())) + if (auto EC = + LineReader.readArray(LinesAndChecksums, LineReader.bytesRemaining())) return EC; uint32_t GlobalRefsSize; @@ -77,13 +79,13 @@ ModuleDebugStream::symbols(bool *HadError) const { return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); } -iterator_range<codeview::ModuleDebugFragmentArray::Iterator> -ModuleDebugStream::lines(bool *HadError) const { - return make_range(LineInfo.begin(HadError), LineInfo.end()); +llvm::iterator_range<ModuleDebugStream::LinesAndChecksumsIterator> +ModuleDebugStream::linesAndChecksums() const { + return make_range(LinesAndChecksums.begin(), LinesAndChecksums.end()); } bool ModuleDebugStream::hasLineInfo() const { - return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0; + return C13LinesSubstream.getLength() > 0; } Error ModuleDebugStream::commit() { return Error::success(); } |