// ulittle32_t Files[];
};
-struct FileChecksum {
- 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.
-};
-
} // namespace codeview
} // namespace llvm
--- /dev/null
+//===- ModuleDebugLineFragment.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+
+struct FileChecksumEntry {
+ uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
+ FileChecksumKind Kind; // The type of checksum.
+ ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
+};
+}
+}
+
+namespace llvm {
+template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
+public:
+ typedef void ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::FileChecksumEntry &Item, void *Ctx);
+};
+}
+
+namespace llvm {
+namespace codeview {
+class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment {
+ typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
+ typedef FileChecksumArray::Iterator Iterator;
+
+public:
+ ModuleDebugFileChecksumFragment()
+ : ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums) {}
+
+ static bool classof(const ModuleDebugFragment *S) {
+ return S->kind() == ModuleDebugFragmentKind::FileChecksums;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ Iterator begin() const { return Checksums.begin(); }
+ Iterator end() const { return Checksums.end(); }
+
+private:
+ FileChecksumArray Checksums;
+};
+}
+}
+
+#endif
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Casting.h"
namespace llvm {
namespace codeview {
-// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
-struct ModuleDebugFragmentHeader {
- support::ulittle32_t Kind; // codeview::ModuleDebugFragmentKind enum
- support::ulittle32_t Length; // number of bytes occupied by this record.
-};
-
-// Corresponds to the `CV_DebugSLinesHeader_t` structure.
-struct LineFragmentHeader {
- support::ulittle32_t RelocOffset; // Code offset of line contribution.
- support::ulittle16_t RelocSegment; // Code segment of line contribution.
- support::ulittle16_t Flags; // See LineFlags enumeration.
- support::ulittle32_t CodeSize; // Code size of this line contribution.
-};
-
-// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
-struct LineBlockFragmentHeader {
- support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
- support::ulittle32_t NumLines; // Number of lines
- support::ulittle32_t BlockSize; // Code size of block, in bytes.
- // The following two variable length arrays appear immediately after the
- // header. The structure definitions follow.
- // LineNumberEntry Lines[NumLines];
- // ColumnNumberEntry Columns[NumLines];
-};
-
-// Corresponds to `CV_Line_t` structure
-struct LineNumberEntry {
- support::ulittle32_t Offset; // Offset to start of code bytes for line number
- support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
-};
-
-// Corresponds to `CV_Column_t` structure
-struct ColumnNumberEntry {
- support::ulittle16_t StartColumn;
- support::ulittle16_t EndColumn;
-};
-
class ModuleDebugFragment {
public:
- ModuleDebugFragment();
- ModuleDebugFragment(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
- static Error initialize(BinaryStreamRef Stream, ModuleDebugFragment &Info);
- uint32_t getRecordLength() const;
- ModuleDebugFragmentKind kind() const;
- BinaryStreamRef getRecordData() const;
+ explicit ModuleDebugFragment(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
+
+ virtual ~ModuleDebugFragment();
+ ModuleDebugFragmentKind kind() const { return Kind; }
-private:
+protected:
ModuleDebugFragmentKind Kind;
- BinaryStreamRef Data;
};
-typedef VarStreamArray<ModuleDebugFragment> ModuleDebugFragmentArray;
} // namespace codeview
-
-template <> struct VarStreamArrayExtractor<codeview::ModuleDebugFragment> {
- typedef void ContextType;
-
- static Error extract(BinaryStreamRef Stream, uint32_t &Length,
- codeview::ModuleDebugFragment &Info, void *Ctx) {
- if (auto EC = codeview::ModuleDebugFragment::initialize(Stream, Info))
- return EC;
- Length = Info.getRecordLength();
- return Error::success();
- }
-};
} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
--- /dev/null
+//===- ModuleDebugFragment.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
+struct ModuleDebugFragmentHeader {
+ support::ulittle32_t Kind; // codeview::ModuleDebugFragmentKind enum
+ support::ulittle32_t Length; // number of bytes occupied by this record.
+};
+
+class ModuleDebugFragmentRecord {
+public:
+ ModuleDebugFragmentRecord();
+ ModuleDebugFragmentRecord(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
+
+ static Error initialize(BinaryStreamRef Stream,
+ ModuleDebugFragmentRecord &Info);
+ uint32_t getRecordLength() const;
+ ModuleDebugFragmentKind kind() const;
+ BinaryStreamRef getRecordData() const;
+
+private:
+ ModuleDebugFragmentKind Kind;
+ BinaryStreamRef Data;
+};
+
+typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
+
+} // namespace codeview
+
+template <>
+struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
+ typedef void ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Length,
+ codeview::ModuleDebugFragmentRecord &Info, void *Ctx) {
+ if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info))
+ return EC;
+ Length = Info.getRecordLength();
+ return Error::success();
+ }
+};
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/Line.h"
-#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
namespace codeview {
-struct LineColumnEntry {
- support::ulittle32_t NameIndex;
- FixedStreamArray<LineNumberEntry> LineNumbers;
- FixedStreamArray<ColumnNumberEntry> Columns;
-};
-
-struct FileChecksumEntry {
- uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
- FileChecksumKind Kind; // The type of checksum.
- ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
-};
-
-typedef VarStreamArray<LineColumnEntry> LineInfoArray;
-typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
-
class ModuleDebugFragmentVisitor {
public:
virtual ~ModuleDebugFragmentVisitor() = default;
- virtual Error visitUnknown(ModuleDebugFragmentKind Kind,
- BinaryStreamRef Data) = 0;
- virtual Error visitSymbols(BinaryStreamRef Data);
- virtual Error visitLines(BinaryStreamRef Data,
- const LineFragmentHeader *Header,
- const LineInfoArray &Lines);
- virtual Error visitStringTable(BinaryStreamRef Data);
- virtual Error visitFileChecksums(BinaryStreamRef Data,
- const FileChecksumArray &Checksums);
- virtual Error visitFrameData(BinaryStreamRef Data);
- virtual Error visitInlineeLines(BinaryStreamRef Data);
- virtual Error visitCrossScopeImports(BinaryStreamRef Data);
- virtual Error visitCrossScopeExports(BinaryStreamRef Data);
- virtual Error visitILLines(BinaryStreamRef Data);
- virtual Error visitFuncMDTokenMap(BinaryStreamRef Data);
- virtual Error visitTypeMDTokenMap(BinaryStreamRef Data);
- virtual Error visitMergedAssemblyInput(BinaryStreamRef Data);
- virtual Error visitCoffSymbolRVA(BinaryStreamRef Data);
-};
-
-Error visitModuleDebugFragment(const ModuleDebugFragment &R,
- ModuleDebugFragmentVisitor &V);
-} // end namespace codeview
-
-template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
-public:
- typedef const codeview::LineFragmentHeader ContextType;
-
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::LineColumnEntry &Item, ContextType *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;
- }
+ virtual Error visitUnknown(ModuleDebugUnknownFragment &Unknown) {
+ return Error::success();
+ }
+ virtual Error visitLines(ModuleDebugLineFragment &Lines) {
return Error::success();
}
-};
-
-template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
-public:
- typedef void ContextType;
- static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::FileChecksumEntry &Item, void *Ctx) {
- using namespace codeview;
- const FileChecksum *Header;
- BinaryStreamReader Reader(Stream);
- 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 = sizeof(FileChecksum) + Header->ChecksumSize;
+ virtual Error visitFileChecksums(ModuleDebugFileChecksumFragment &Checksums) {
return Error::success();
}
};
+Error visitModuleDebugFragment(const ModuleDebugFragmentRecord &R,
+ ModuleDebugFragmentVisitor &V);
+} // end namespace codeview
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
--- /dev/null
+//===- ModuleDebugLineFragment.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+// Corresponds to the `CV_DebugSLinesHeader_t` structure.
+struct LineFragmentHeader {
+ support::ulittle32_t RelocOffset; // Code offset of line contribution.
+ support::ulittle16_t RelocSegment; // Code segment of line contribution.
+ support::ulittle16_t Flags; // See LineFlags enumeration.
+ support::ulittle32_t CodeSize; // Code size of this line contribution.
+};
+
+// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
+struct LineBlockFragmentHeader {
+ support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
+ support::ulittle32_t NumLines; // Number of lines
+ support::ulittle32_t BlockSize; // Code size of block, in bytes.
+ // The following two variable length arrays appear immediately after the
+ // header. The structure definitions follow.
+ // LineNumberEntry Lines[NumLines];
+ // ColumnNumberEntry Columns[NumLines];
+};
+
+// Corresponds to `CV_Line_t` structure
+struct LineNumberEntry {
+ support::ulittle32_t Offset; // Offset to start of code bytes for line number
+ support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
+};
+
+// Corresponds to `CV_Column_t` structure
+struct ColumnNumberEntry {
+ support::ulittle16_t StartColumn;
+ support::ulittle16_t EndColumn;
+};
+
+struct LineColumnEntry {
+ support::ulittle32_t NameIndex;
+ FixedStreamArray<LineNumberEntry> LineNumbers;
+ FixedStreamArray<ColumnNumberEntry> Columns;
+};
+
+class LineColumnExtractor {
+public:
+ typedef const LineFragmentHeader ContextType;
+
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item, const LineFragmentHeader *Header);
+};
+
+class ModuleDebugLineFragment final : public ModuleDebugFragment {
+ friend class LineColumnExtractor;
+ typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray;
+ typedef LineInfoArray::Iterator Iterator;
+
+public:
+ ModuleDebugLineFragment();
+
+ static bool classof(const ModuleDebugFragment *S) {
+ return S->kind() == ModuleDebugFragmentKind::Lines;
+ }
+
+ Error initialize(BinaryStreamReader Reader);
+
+ Iterator begin() const { return LinesAndColumns.begin(); }
+ Iterator end() const { return LinesAndColumns.end(); }
+
+ const LineFragmentHeader *header() const { return Header; }
+
+private:
+ const LineFragmentHeader *Header = nullptr;
+ LineInfoArray LinesAndColumns;
+};
+}
+}
+
+#endif
--- /dev/null
+//===- ModuleDebugUnknownFragment.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamRef.h"
+
+namespace llvm {
+namespace codeview {
+
+class ModuleDebugUnknownFragment final : public ModuleDebugFragment {
+public:
+ ModuleDebugUnknownFragment(ModuleDebugFragmentKind Kind, BinaryStreamRef Data)
+ : ModuleDebugFragment(Kind), Data(Data) {}
+
+ BinaryStreamRef getData() const { return Data; }
+
+private:
+ BinaryStreamRef Data;
+};
+}
+}
+
+#endif
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/Support/BinaryStreamArray.h"
class DbiModuleDescriptor;
class ModuleDebugStream {
+ typedef codeview::ModuleDebugFragmentArray::Iterator
+ LinesAndChecksumsIterator;
+
public:
ModuleDebugStream(const DbiModuleDescriptor &Module,
std::unique_ptr<msf::MappedBlockStream> Stream);
iterator_range<codeview::CVSymbolArray::Iterator>
symbols(bool *HadError) const;
- iterator_range<codeview::ModuleDebugFragmentArray::Iterator>
- lines(bool *HadError) const;
+ llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const;
bool hasLineInfo() const;
BinaryStreamRef C13LinesSubstream;
BinaryStreamRef GlobalRefsSubstream;
- codeview::ModuleDebugFragmentArray LineInfo;
+ codeview::ModuleDebugFragmentArray LinesAndChecksums;
};
}
}
EnumTables.cpp
Formatters.cpp
Line.cpp
+ ModuleDebugFileChecksumFragment.cpp
ModuleDebugFragment.cpp
+ ModuleDebugFragmentRecord.cpp
ModuleDebugFragmentVisitor.cpp
+ ModuleDebugLineFragment.cpp
+ ModuleDebugUnknownFragment.cpp
RecordSerialization.cpp
SymbolRecordMapping.cpp
SymbolDumper.cpp
--- /dev/null
+//===- 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();
+}
-//===- ModuleDebugFragment.cpp --------------------------------------*- C++
-//-*-===//
+//===- ModuleDebugFragment.cpp -----------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
#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() {}
--- /dev/null
+//===- 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;
+}
//===----------------------------------------------------------------------===//
#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());
}
}
--- /dev/null
+//===- 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();
+}
--- /dev/null
+//===- 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
#include <cstdint>
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
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;
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(); }
#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
}
if (opts::raw::DumpLineInfo) {
ListScope SS(P, "LineInfo");
- bool HadError = false;
// Define a locally scoped visitor to print the different
// substream types types.
class RecordVisitor : public codeview::ModuleDebugFragmentVisitor {
public:
RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
- Error visitUnknown(ModuleDebugFragmentKind Kind,
- BinaryStreamRef Stream) override {
+ Error visitUnknown(ModuleDebugUnknownFragment &Fragment) override {
DictScope DD(P, "Unknown");
ArrayRef<uint8_t> Data;
- BinaryStreamReader R(Stream);
+ BinaryStreamReader R(Fragment.getData());
if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
return make_error<RawError>(
raw_error_code::corrupt_file,
P.printBinaryBlock("Data", Data);
return Error::success();
}
- Error
- visitFileChecksums(BinaryStreamRef Data,
- const FileChecksumArray &Checksums) override {
+ Error visitFileChecksums(
+ ModuleDebugFileChecksumFragment &Checksums) override {
DictScope DD(P, "FileChecksums");
for (const auto &C : Checksums) {
DictScope DDD(P, "Checksum");
return Error::success();
}
- Error visitLines(BinaryStreamRef Data,
- const LineFragmentHeader *Header,
- const LineInfoArray &Lines) override {
+ Error visitLines(ModuleDebugLineFragment &Lines) override {
DictScope DD(P, "Lines");
for (const auto &L : Lines) {
if (auto Result = getFileNameForOffset2(L.NameIndex))
};
RecordVisitor V(P, File);
- for (const auto &L : ModS.lines(&HadError)) {
+ for (const auto &L : ModS.linesAndChecksums()) {
if (auto EC = codeview::visitModuleDebugFragment(L, V))
return EC;
}
#include "llvm-pdbdump.h"
#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::pdb;
YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
}
namespace {
-class C13SubstreamVisitor : public codeview::ModuleDebugFragmentVisitor {
+class C13SubstreamVisitor : public ModuleDebugFragmentVisitor {
public:
C13SubstreamVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
: Info(Info), F(F) {}
- Error visitUnknown(codeview::ModuleDebugFragmentKind Kind,
- BinaryStreamRef Stream) override {
+ Error visitUnknown(ModuleDebugUnknownFragment &Fragment) override {
return Error::success();
}
Error
- visitFileChecksums(BinaryStreamRef Data,
- const codeview::FileChecksumArray &Checksums) override {
+ visitFileChecksums(ModuleDebugFileChecksumFragment &Checksums) override {
for (const auto &C : Checksums) {
llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
if (auto Result = getGlobalString(C.FileNameOffset))
return Error::success();
}
- Error visitLines(BinaryStreamRef Data,
- const codeview::LineFragmentHeader *Header,
- const codeview::LineInfoArray &Lines) override {
+ Error visitLines(ModuleDebugLineFragment &Lines) override {
- Info.Lines.CodeSize = Header->CodeSize;
+ Info.Lines.CodeSize = Lines.header()->CodeSize;
Info.Lines.Flags =
- static_cast<codeview::LineFlags>(uint16_t(Header->Flags));
- Info.Lines.RelocOffset = Header->RelocOffset;
- Info.Lines.RelocSegment = Header->RelocSegment;
+ static_cast<codeview::LineFlags>(uint16_t(Lines.header()->Flags));
+ Info.Lines.RelocOffset = Lines.header()->RelocOffset;
+ Info.Lines.RelocSegment = Lines.header()->RelocSegment;
for (const auto &L : Lines) {
llvm::pdb::yaml::PdbSourceLineBlock Block;
return None;
yaml::PdbSourceFileInfo Info;
- bool Error = false;
C13SubstreamVisitor Visitor(Info, File);
- for (auto &Frag : ModS.lines(&Error)) {
+ for (auto &Frag : ModS.linesAndChecksums()) {
if (auto E = codeview::visitModuleDebugFragment(Frag, Visitor))
return std::move(E);
}
#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
BinaryByteStream S(Subsection, llvm::support::little);
BinaryStreamReader SR(S);
- while (!SR.empty()) {
+ ModuleDebugFileChecksumFragment Checksums;
+ error(Checksums.initialize(SR));
+
+ for (auto &FC : Checksums) {
DictScope S(W, "FileChecksum");
- const FileChecksum *FC;
- error(SR.readObject(FC));
- if (FC->FileNameOffset >= CVStringTable.size())
+
+ if (FC.FileNameOffset >= CVStringTable.size())
error(object_error::parse_failed);
StringRef Filename =
- CVStringTable.drop_front(FC->FileNameOffset).split('\0').first;
- W.printHex("Filename", Filename, FC->FileNameOffset);
- W.printHex("ChecksumSize", FC->ChecksumSize);
- W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind),
+ CVStringTable.drop_front(FC.FileNameOffset).split('\0').first;
+ W.printHex("Filename", Filename, FC.FileNameOffset);
+ W.printHex("ChecksumSize", FC.Checksum.size());
+ W.printEnum("ChecksumKind", uint8_t(FC.Kind),
makeArrayRef(FileChecksumKindNames));
- if (FC->ChecksumSize >= SR.bytesRemaining())
- error(object_error::parse_failed);
- ArrayRef<uint8_t> ChecksumBytes;
- error(SR.readBytes(ChecksumBytes, FC->ChecksumSize));
- W.printBinary("ChecksumBytes", ChecksumBytes);
- unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) -
- sizeof(FileChecksum);
- PaddedSize -= ChecksumBytes.size();
- if (PaddedSize > SR.bytesRemaining())
- error(object_error::parse_failed);
- error(SR.skip(PaddedSize));
+
+ W.printBinary("ChecksumBytes", FC.Checksum);
}
}