llvm/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
Zachary Turner 2834a6874e [CodeView] Isolate Debug Info Fragments into standalone classes.
Previously parsing of these were all grouped together into a
single master class that could parse any type of debug info
fragment.

With writing forthcoming, the complexity of each individual
fragment is enough to warrant them having their own classes so
that reading and writing of each fragment type can be grouped
together, but isolated from the code for reading and writing
other fragment types.

In doing so, I found a place where parsing code was duplicated
for the FileChecksums fragment, across llvm-readobj and the
CodeView library, and one of the implementations had a bug.
Now that the codepaths are merged, the bug is resolved.

Differential Revision: https://reviews.llvm.org/D32547

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301557 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-27 16:12:16 +00:00

64 lines
2.3 KiB
C++

//===- 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();
}