diff options
| -rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/CodeView.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/EnumTables.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/StreamRef.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h | 8 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h | 51 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h | 39 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/CodeView/EnumTables.cpp | 20 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/CodeView/StreamReader.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModuleSubstreamRecord.cpp | 49 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/PDB/pdbdump-headers.test | 23 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 58 |
14 files changed, 246 insertions, 22 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h index 67c974a6f56..a597d5426c0 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h @@ -287,6 +287,7 @@ enum class ModifierOptions : uint16_t { CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions) enum class ModuleSubstreamKind : uint32_t { + None = 0, Symbols = 0xf1, Lines = 0xf2, StringTable = 0xf3, diff --git a/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h b/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h index 7d148637a07..d1b103dae3b 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h +++ b/llvm/include/llvm/DebugInfo/CodeView/EnumTables.h @@ -30,6 +30,7 @@ ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames(); ArrayRef<EnumEntry<unsigned>> getCPUTypeNames(); ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames(); ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames(); +ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames(); ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames(); ArrayRef<EnumEntry<uint16_t>> getTrampolineNames(); ArrayRef<EnumEntry<COFF::SectionCharacteristics>> diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h b/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h index b1643817472..107ab759ecb 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h +++ b/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h @@ -23,6 +23,8 @@ public: : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {} StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length) : Stream(&Stream), ViewOffset(Offset), Length(Length) {} + + StreamRef(const StreamRef &Stream, uint32_t Offset, uint32_t Length) = delete; StreamRef(const StreamRef &Other) : Stream(Other.Stream), ViewOffset(Other.ViewOffset), Length(Other.Length) {} diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h index 53198849bc6..35a6564008b 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h @@ -15,6 +15,7 @@ #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" +#include "llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h" #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawTypes.h" diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h index 1460e829740..d7fb0cb8e9b 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h @@ -12,9 +12,11 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamRef.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h" #include "llvm/Support/Error.h" namespace llvm { @@ -24,6 +26,8 @@ class ModInfo; class ModStream { public: + typedef codeview::VarStreamArray<ModuleSubstreamRecord> LineInfoArray; + ModStream(PDBFile &File, const ModInfo &Module); ~ModStream(); @@ -32,6 +36,8 @@ public: iterator_range<codeview::CVSymbolArray::Iterator> symbols(bool *HadError) const; + iterator_range<LineInfoArray::Iterator> lines(bool *HadError) const; + private: const ModInfo &Mod; @@ -41,6 +47,8 @@ private: codeview::StreamRef LinesSubstream; codeview::StreamRef C13LinesSubstream; codeview::StreamRef GlobalRefsSubstream; + + LineInfoArray LineInfo; }; } } diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h b/llvm/include/llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h new file mode 100644 index 00000000000..d2f837a237b --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h @@ -0,0 +1,51 @@ +//===- ModuleSubstreamRecord.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_PDB_RAW_MODULESUBSTREAMRECORD_H +#define LLVM_DEBUGINFO_PDB_RAW_MODULESUBSTREAMRECORD_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" +#include "llvm/DebugInfo/CodeView/StreamRef.h" +#include "llvm/Support/Error.h" + +namespace llvm { + +namespace pdb { +class ModuleSubstreamRecord { +public: + ModuleSubstreamRecord(); + ModuleSubstreamRecord(codeview::ModuleSubstreamKind Kind, + codeview::StreamRef Data); + static Error initialize(codeview::StreamRef Stream, + ModuleSubstreamRecord &Info); + uint32_t getRecordLength() const; + codeview::ModuleSubstreamKind getSubstreamKind() const; + codeview::StreamRef getRecordData() const; + +private: + codeview::ModuleSubstreamKind Kind; + codeview::StreamRef Data; +}; +} + +namespace codeview { +template <> struct VarStreamArrayExtractor<pdb::ModuleSubstreamRecord> { + Error operator()(StreamRef Stream, uint32_t &Length, + pdb::ModuleSubstreamRecord &Info) const { + if (auto EC = pdb::ModuleSubstreamRecord::initialize(Stream, Info)) + return EC; + Length = Info.getRecordLength(); + return Error::success(); + } +}; +} +} + +#endif // LLVM_DEBUGINFO_PDB_RAW_MODULESUBSTREAMRECORD_H diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h b/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h index f804830f123..dad07b583b8 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h @@ -72,6 +72,45 @@ struct SecMapEntry { support::ulittle32_t SecByteLength; // Byte count of the segment or group. }; +// Corresponds to the `CV_DebugSSubsectionHeader_t` structure. +struct ModuleSubsectionHeader { + support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum + support::ulittle32_t Length; // number of bytes occupied by this record. +}; + +// Corresponds to the `CV_DebugSLinesHeader_t` structure. +struct LineTableSubsectionHeader { + support::ulittle32_t OffCon; + support::ulittle16_t SegCon; + support::ulittle16_t Flags; + support::ulittle32_t CbCon; +}; + +// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. +struct SourceFileBlockHeader { + support::ulittle32_t offFile; + support::ulittle32_t nLines; + support::ulittle32_t cbBlock; + // LineInfo lines[nLines]; + // ColumnInfo columns[nColumns]; +}; + +// Corresponds to `CV_Line_t` structure +struct LineInfo { + unsigned long Offset; // Offset to start of code bytes for line number + unsigned long LinenumStart : 24; // line where statement/expression starts + unsigned long + DeltaLineEnd : 7; // delta to line where statement ends (optional) + unsigned long FStatement : 1; // true if a statement linenumber, else an + // expression line num +}; + +// Corresponds to `CV_Column_t` structure +struct ColumnInfo { + support::ulittle16_t OffColumnStart; + support::ulittle16_t OffColumnEnd; +}; + } // namespace pdb } // namespace llvm diff --git a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp index b209aa9f98e..edb489767d4 100644 --- a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp @@ -231,6 +231,23 @@ static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = { CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw), }; +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), +}; + static const EnumEntry<uint16_t> ExportSymFlagNames[] = { CV_ENUM_CLASS_ENT(ExportFlags, IsConstant), CV_ENUM_CLASS_ENT(ExportFlags, IsData), @@ -331,6 +348,9 @@ ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames() { ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames() { return makeArrayRef(ExportSymFlagNames); } +ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames() { + return makeArrayRef(ModuleSubstreamKindNames); +} ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames() { return makeArrayRef(ThunkOrdinalNames); } diff --git a/llvm/lib/DebugInfo/CodeView/StreamReader.cpp b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp index 2adf9487e5d..cc5cebc9c43 100644 --- a/llvm/lib/DebugInfo/CodeView/StreamReader.cpp +++ b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp @@ -15,7 +15,7 @@ using namespace llvm; using namespace llvm::codeview; -StreamReader::StreamReader(StreamRef Stream) : Stream(Stream), Offset(0) {} +StreamReader::StreamReader(StreamRef S) : Stream(S), Offset(0) {} Error StreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { if (auto EC = Stream.readBytes(Offset, Size, Buffer)) diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 46074f769cd..4dc0b4f8c31 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -33,6 +33,7 @@ add_pdb_impl_folder(Raw Raw/InfoStream.cpp Raw/MappedBlockStream.cpp Raw/ModInfo.cpp + Raw/ModuleSubstreamRecord.cpp Raw/ModStream.cpp Raw/NameHashTable.cpp Raw/NameMap.cpp diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp index b7204cb5afa..a6d1977165f 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -13,6 +13,7 @@ #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" using namespace llvm; using namespace llvm::pdb; @@ -45,9 +46,9 @@ Error ModStream::reload() { return EC; if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) return EC; - ArrayRef<uint8_t> LineBytes; - codeview::StreamReader LinesReader(C13LinesSubstream); - if (auto EC = LinesReader.readBytes(LineBytes, C13LinesSubstream.getLength())) + + codeview::StreamReader LineReader(C13LinesSubstream); + if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining())) return EC; uint32_t GlobalRefsSize; @@ -67,3 +68,8 @@ ModStream::symbols(bool *HadError) const { return llvm::make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); } + +iterator_range<ModStream::LineInfoArray::Iterator> +ModStream::lines(bool *HadError) const { + return llvm::make_range(LineInfo.begin(HadError), LineInfo.end()); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModuleSubstreamRecord.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModuleSubstreamRecord.cpp new file mode 100644 index 00000000000..3e0573bf5ef --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/ModuleSubstreamRecord.cpp @@ -0,0 +1,49 @@ +//===- ModuleSubstreamRecord.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/PDB/Raw/ModuleSubstreamRecord.h" + +#include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +ModuleSubstreamRecord::ModuleSubstreamRecord() + : Kind(ModuleSubstreamKind::None) {} + +ModuleSubstreamRecord::ModuleSubstreamRecord(ModuleSubstreamKind Kind, + StreamRef Data) + : Kind(Kind), Data(Data) {} + +Error ModuleSubstreamRecord::initialize(StreamRef Stream, + ModuleSubstreamRecord &Info) { + const ModuleSubsectionHeader *Header; + StreamReader 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 ModuleSubstreamRecord::getRecordLength() const { + return sizeof(ModuleSubsectionHeader) + Data.getLength(); +} + +ModuleSubstreamKind ModuleSubstreamRecord::getSubstreamKind() const { + return Kind; +} + +StreamRef ModuleSubstreamRecord::getRecordData() const { return Data; } diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test index b8f2b56767b..85885fbe984 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test @@ -1,8 +1,8 @@ ; RUN: llvm-pdbdump -raw-headers -raw-tpi-records -raw-tpi-record-bytes -raw-module-syms \ ; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \ ; RUN: -raw-stream-summary -raw-stream-blocks -raw-ipi-records -raw-ipi-record-bytes \ -; RUN: -raw-section-contribs -raw-section-map -raw-section-headers %p/Inputs/empty.pdb \ -; RUN: | FileCheck -check-prefix=EMPTY %s +; RUN: -raw-section-contribs -raw-section-map -raw-section-headers -raw-line-info \ +; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s ; RUN: llvm-pdbdump -raw-all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s ; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \ ; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s @@ -330,6 +330,23 @@ ; EMPTY-NEXT: ) ; EMPTY-NEXT: } ; EMPTY-NEXT: ] +; EMPTY-NEXT: LineInfo [ +; EMPTY-NEXT: { +; EMPTY-NEXT: Kind: Lines (0xF2) +; EMPTY-NEXT: Data ( +; EMPTY-NEXT: 0000: 10000000 01000000 0A000000 00000000 |................| +; EMPTY-NEXT: 0010: 03000000 24000000 00000000 05000080 |....$...........| +; EMPTY-NEXT: 0020: 03000000 06000080 08000000 07000080 |................| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: Kind: FileChecksums (0xF4) +; EMPTY-NEXT: Data ( +; EMPTY-NEXT: 0000: 56000000 1001A0A5 BD0D3ECD 93FC29D1 |V.........>...).| +; EMPTY-NEXT: 0010: 9DE826FB F4BC0000 |..&.....| +; EMPTY-NEXT: ) +; EMPTY-NEXT: } +; EMPTY-NEXT: ] ; EMPTY-NEXT: } ; EMPTY-NEXT: { ; EMPTY-NEXT: Name: * Linker * @@ -568,6 +585,8 @@ ; EMPTY-NEXT: ) ; EMPTY-NEXT: } ; EMPTY-NEXT: ] +; EMPTY-NEXT: LineInfo [ +; EMPTY-NEXT: ] ; EMPTY-NEXT: } ; EMPTY-NEXT: ] ; EMPTY-NEXT: } diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index b295876da39..0e7003d0f53 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -144,6 +144,9 @@ cl::opt<bool> DumpPublics("raw-publics", cl::desc("dump Publics stream data"), cl::opt<bool> DumpSectionContribs("raw-section-contribs", cl::desc("dump section contributions"), cl::cat(NativeOptions)); +cl::opt<bool> DumpLineInfo("raw-line-info", + cl::desc("dump file and line information"), + cl::cat(NativeOptions)); cl::opt<bool> DumpSectionMap("raw-section-map", cl::desc("dump section map"), cl::cat(NativeOptions)); cl::opt<bool> @@ -429,8 +432,8 @@ static Error dumpNamedStream(ScopedPrinter &P, PDBFile &File) { static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, codeview::CVTypeDumper &TD) { - bool DumpModules = - opts::DumpModules || opts::DumpModuleSyms || opts::DumpModuleFiles; + bool DumpModules = opts::DumpModules || opts::DumpModuleSyms || + opts::DumpModuleFiles || opts::DumpLineInfo; if (!opts::DumpHeaders && !DumpModules) return Error::success(); @@ -487,25 +490,45 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, (Modi.Info.getModuleStreamIndex() < File.getNumStreams()); bool ShouldDumpSymbols = (opts::DumpModuleSyms || opts::DumpSymRecordBytes); - if (HasModuleDI && ShouldDumpSymbols) { - ListScope SS(P, "Symbols"); + if (HasModuleDI && (ShouldDumpSymbols || opts::DumpLineInfo)) { ModStream ModS(File, Modi.Info); if (auto EC = ModS.reload()) return EC; - codeview::CVSymbolDumper SD(P, TD, nullptr, false); - bool HadError = false; - for (auto &S : ModS.symbols(&HadError)) { - DictScope DD(P, ""); - - if (opts::DumpModuleSyms) - SD.dump(S); - if (opts::DumpSymRecordBytes) - P.printBinaryBlock("Bytes", S.Data); + if (ShouldDumpSymbols) { + ListScope SS(P, "Symbols"); + codeview::CVSymbolDumper SD(P, TD, nullptr, false); + bool HadError = false; + for (auto &S : ModS.symbols(&HadError)) { + DictScope DD(P, ""); + + if (opts::DumpModuleSyms) + SD.dump(S); + if (opts::DumpSymRecordBytes) + P.printBinaryBlock("Bytes", S.Data); + } + if (HadError) + return make_error<RawError>( + raw_error_code::corrupt_file, + "DBI stream contained corrupt symbol record"); + } + if (opts::DumpLineInfo) { + ListScope SS(P, "LineInfo"); + bool HadError = false; + for (auto &L : ModS.lines(&HadError)) { + DictScope DD(P, ""); + P.printEnum("Kind", uint32_t(L.getSubstreamKind()), + codeview::getModuleSubstreamKindNames()); + ArrayRef<uint8_t> Data; + codeview::StreamReader R(L.getRecordData()); + if (auto EC = R.readBytes(Data, R.bytesRemaining())) { + return make_error<RawError>( + raw_error_code::corrupt_file, + "DBI stream contained corrupt line info record"); + } + P.printBinaryBlock("Data", Data); + } } - if (HadError) - return make_error<RawError>(raw_error_code::corrupt_file, - "DBI stream contained corrupt record"); } } } @@ -805,6 +828,8 @@ bool isRawDumpEnabled() { return true; if (opts::DumpSectionMap) return true; + if (opts::DumpLineInfo) + return true; return false; } @@ -972,6 +997,7 @@ int main(int argc_, const char *argv_[]) { opts::DumpIpiRecords = true; opts::DumpSectionMap = true; opts::DumpSectionContribs = true; + opts::DumpLineInfo = true; } // When adding filters for excluded compilands and types, we need to remember |

