summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/CodeView.h1
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/EnumTables.h1
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamRef.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h1
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/ModStream.h8
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/ModuleSubstreamRecord.h51
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/RawTypes.h39
-rw-r--r--llvm/lib/DebugInfo/CodeView/EnumTables.cpp20
-rw-r--r--llvm/lib/DebugInfo/CodeView/StreamReader.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp12
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModuleSubstreamRecord.cpp49
-rw-r--r--llvm/test/DebugInfo/PDB/pdbdump-headers.test23
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp58
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
OpenPOWER on IntegriCloud