Files
archived-llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
Zachary Turner 7e17f48869 [codeview] Dump line number and column information.
To facilitate this, a couple of changes had to be made:

1. `ModuleSubstream` got moved from `DebugInfo/PDB` to
`DebugInfo/CodeView`, and various codeview related types are defined
there.  It turns out `DebugInfo/CodeView/Line.h` already defines many of
these structures, but this is really old code that is not endian aware,
doesn't interact well with `StreamInterface` and not very helpful for
getting stuff out of a PDB.  Eventually we should migrate the old readobj
`COFFDumper` code to these new structures, or at least merge their
functionality somehow.

2. A `ModuleSubstream` visitor is introduced.  Depending on where your
module substream array comes from, different subsets of record types can
be expected.  We are already hand parsing these substream arrays in many
places especially in `COFFDumper.cpp`.  In the future we can migrate these
paths to the visitor as well, which should reduce a lot of code in
`COFFDumper.cpp`.

Differential Revision: http://reviews.llvm.org/D20936
Reviewed By: ruiu, majnemer

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271621 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-03 03:25:59 +00:00

97 lines
3.6 KiB
C++

//===- ModuleSubstreamVisitor.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_MODULESUBSTREAMVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/StreamRef.h"
namespace llvm {
namespace codeview {
struct LineColumnEntry {
support::ulittle32_t Offset;
FixedStreamArray<LineNumberEntry> LineNumbers;
FixedStreamArray<ColumnNumberEntry> Columns;
};
class FileLineInfoExtractor {
public:
FileLineInfoExtractor(const LineSubstreamHeader *Header) : Header(Header) {}
Error operator()(StreamRef Stream, uint32_t &Len,
LineColumnEntry &Item) const {
const LineFileBlockHeader *BlockHeader;
StreamReader Reader(Stream);
if (auto EC = Reader.readObject(BlockHeader))
return EC;
bool HasColumn = Header->Flags & LineFlags::HaveColumns;
uint32_t LineInfoSize =
BlockHeader->NumLines *
(sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
return make_error<CodeViewError>(cv_error_code::corrupt_record,
"Invalid line block record size");
uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
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
// LineFileBlockHeader.
Len = BlockHeader->BlockSize;
Item.Offset = BlockHeader->FileOffset;
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();
}
private:
const LineSubstreamHeader *Header;
};
typedef VarStreamArray<LineColumnEntry, FileLineInfoExtractor> LineInfoArray;
class IModuleSubstreamVisitor {
public:
virtual ~IModuleSubstreamVisitor() {}
virtual Error visitUnknown(ModuleSubstreamKind Kind, StreamRef Data) = 0;
virtual Error visitSymbols(StreamRef Data);
virtual Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
LineInfoArray Lines);
virtual Error visitStringTable(StreamRef Data);
virtual Error visitFileChecksums(StreamRef Data);
virtual Error visitFrameData(StreamRef Data);
virtual Error visitInlineeLines(StreamRef Data);
virtual Error visitCrossScopeImports(StreamRef Data);
virtual Error visitCrossScopeExports(StreamRef Data);
virtual Error visitILLines(StreamRef Data);
virtual Error visitFuncMDTokenMap(StreamRef Data);
virtual Error visitTypeMDTokenMap(StreamRef Data);
virtual Error visitMergedAssemblyInput(StreamRef Data);
virtual Error visitCoffSymbolRVA(StreamRef Data);
};
Error visitModuleSubstream(const ModuleSubstream &R,
IModuleSubstreamVisitor &V);
} // namespace codeview
} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H