summaryrefslogtreecommitdiff
path: root/tools/llvm-pdbdump/YAMLOutputStyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-pdbdump/YAMLOutputStyle.cpp')
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.cpp136
1 files changed, 129 insertions, 7 deletions
diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp
index 5b53d2137166a..b329de265e720 100644
--- a/tools/llvm-pdbdump/YAMLOutputStyle.cpp
+++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp
@@ -12,6 +12,9 @@
#include "PdbYaml.h"
#include "llvm-pdbdump.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -33,8 +36,13 @@ Error YAMLOutputStyle::dump() {
opts::pdb2yaml::StreamMetadata = true;
if (opts::pdb2yaml::DbiModuleSyms)
opts::pdb2yaml::DbiModuleInfo = true;
+
+ if (opts::pdb2yaml::DbiModuleSourceLineInfo)
+ opts::pdb2yaml::DbiModuleSourceFileInfo = true;
+
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
opts::pdb2yaml::DbiModuleInfo = true;
+
if (opts::pdb2yaml::DbiModuleInfo)
opts::pdb2yaml::DbiStream = true;
@@ -66,6 +74,112 @@ Error YAMLOutputStyle::dump() {
return Error::success();
}
+namespace {
+class C13SubstreamVisitor : public codeview::IModuleSubstreamVisitor {
+public:
+ C13SubstreamVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
+ : Info(Info), F(F) {}
+
+ Error visitUnknown(codeview::ModuleSubstreamKind Kind,
+ BinaryStreamRef Stream) override {
+ return Error::success();
+ }
+
+ Error
+ visitFileChecksums(BinaryStreamRef Data,
+ const codeview::FileChecksumArray &Checksums) override {
+ for (const auto &C : Checksums) {
+ llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
+ if (auto Result = getGlobalString(C.FileNameOffset))
+ Entry.FileName = *Result;
+ else
+ return Result.takeError();
+
+ Entry.Kind = C.Kind;
+ Entry.ChecksumBytes.Bytes = C.Checksum;
+ Info.FileChecksums.push_back(Entry);
+ }
+ return Error::success();
+ }
+
+ Error visitLines(BinaryStreamRef Data,
+ const codeview::LineSubstreamHeader *Header,
+ const codeview::LineInfoArray &Lines) override {
+
+ Info.Lines.CodeSize = Header->CodeSize;
+ Info.Lines.Flags =
+ static_cast<codeview::LineFlags>(uint16_t(Header->Flags));
+ Info.Lines.RelocOffset = Header->RelocOffset;
+ Info.Lines.RelocSegment = Header->RelocSegment;
+
+ for (const auto &L : Lines) {
+ llvm::pdb::yaml::PdbSourceLineBlock Block;
+
+ if (auto Result = getDbiFileName(L.NameIndex))
+ Block.FileName = *Result;
+ else
+ return Result.takeError();
+
+ for (const auto &N : L.LineNumbers) {
+ llvm::pdb::yaml::PdbSourceLineEntry Line;
+ Line.Offset = N.Offset;
+ codeview::LineInfo LI(N.Flags);
+ Line.LineStart = LI.getStartLine();
+ Line.EndDelta = LI.getEndLine();
+ Line.IsStatement = LI.isStatement();
+ Block.Lines.push_back(Line);
+ }
+
+ if (Info.Lines.Flags & codeview::LineFlags::HaveColumns) {
+ for (const auto &C : L.Columns) {
+ llvm::pdb::yaml::PdbSourceColumnEntry Column;
+ Column.StartColumn = C.StartColumn;
+ Column.EndColumn = C.EndColumn;
+ Block.Columns.push_back(Column);
+ }
+ }
+
+ Info.Lines.LineInfo.push_back(Block);
+ }
+ return Error::success();
+ }
+
+private:
+ Expected<StringRef> getGlobalString(uint32_t Offset) {
+ auto ST = F.getStringTable();
+ if (!ST)
+ return ST.takeError();
+
+ return ST->getStringForID(Offset);
+ }
+ Expected<StringRef> getDbiFileName(uint32_t Offset) {
+ auto DS = F.getPDBDbiStream();
+ if (!DS)
+ return DS.takeError();
+ return DS->getFileNameForIndex(Offset);
+ }
+
+ llvm::pdb::yaml::PdbSourceFileInfo &Info;
+ PDBFile &F;
+};
+}
+
+Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
+YAMLOutputStyle::getFileLineInfo(const pdb::ModStream &ModS) {
+ if (!ModS.hasLineInfo())
+ return None;
+
+ yaml::PdbSourceFileInfo Info;
+ bool Error = false;
+ C13SubstreamVisitor Visitor(Info, File);
+ for (auto &Substream : ModS.lines(&Error)) {
+ if (auto E = codeview::visitModuleSubstream(Substream, Visitor))
+ return std::move(E);
+ }
+
+ return Info;
+}
+
Error YAMLOutputStyle::dumpFileHeaders() {
if (opts::pdb2yaml::NoFileHeaders)
return Error::success();
@@ -175,16 +289,24 @@ Error YAMLOutputStyle::dumpDbiStream() {
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
DMI.SourceFiles = MI.SourceFiles;
+ auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
+ File.getMsfLayout(), File.getMsfBuffer(),
+ MI.Info.getModuleStreamIndex());
+
+ pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
+ if (auto EC = ModS.reload())
+ return EC;
+
+ if (opts::pdb2yaml::DbiModuleSourceLineInfo) {
+ auto ExpectedInfo = getFileLineInfo(ModS);
+ if (!ExpectedInfo)
+ return ExpectedInfo.takeError();
+ DMI.FileLineInfo = *ExpectedInfo;
+ }
+
if (opts::pdb2yaml::DbiModuleSyms &&
MI.Info.getModuleStreamIndex() != kInvalidStreamIndex) {
DMI.Modi.emplace();
- auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
- File.getMsfLayout(), File.getMsfBuffer(),
- MI.Info.getModuleStreamIndex());
-
- pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
- if (auto EC = ModS.reload())
- return EC;
DMI.Modi->Signature = ModS.signature();
bool HadError = false;