LCOV - code coverage report
Current view: top level - lib/DebugInfo/CodeView - ModuleDebugLineFragment.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 71 93 76.3 %
Date: 2017-05-20 02:07:48 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ModuleDebugLineFragment.cpp -------------------------------*- C++-*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
      11             : 
      12             : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
      13             : #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
      14             : #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
      15             : #include "llvm/DebugInfo/CodeView/StringTable.h"
      16             : 
      17             : using namespace llvm;
      18             : using namespace llvm::codeview;
      19             : 
      20         135 : Error LineColumnExtractor::extract(BinaryStreamRef Stream, uint32_t &Len,
      21             :                                    LineColumnEntry &Item,
      22             :                                    const LineFragmentHeader *Header) {
      23             :   using namespace codeview;
      24             :   const LineBlockFragmentHeader *BlockHeader;
      25         405 :   BinaryStreamReader Reader(Stream);
      26         405 :   if (auto EC = Reader.readObject(BlockHeader))
      27           0 :     return EC;
      28         270 :   bool HasColumn = Header->Flags & uint16_t(LF_HaveColumns);
      29             :   uint32_t LineInfoSize =
      30         135 :       BlockHeader->NumLines *
      31         270 :       (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
      32         270 :   if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader))
      33             :     return make_error<CodeViewError>(cv_error_code::corrupt_record,
      34           0 :                                      "Invalid line block record size");
      35         270 :   uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader);
      36         135 :   if (LineInfoSize > Size)
      37             :     return make_error<CodeViewError>(cv_error_code::corrupt_record,
      38           0 :                                      "Invalid line block record size");
      39             :   // The value recorded in BlockHeader->BlockSize includes the size of
      40             :   // LineBlockFragmentHeader.
      41         270 :   Len = BlockHeader->BlockSize;
      42         135 :   Item.NameIndex = BlockHeader->NameIndex;
      43         540 :   if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
      44           0 :     return EC;
      45         135 :   if (HasColumn) {
      46         276 :     if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
      47           0 :       return EC;
      48             :   }
      49         405 :   return Error::success();
      50             : }
      51             : 
      52         118 : ModuleDebugLineFragmentRef::ModuleDebugLineFragmentRef()
      53         354 :     : ModuleDebugFragmentRef(ModuleDebugFragmentKind::Lines) {}
      54             : 
      55         118 : Error ModuleDebugLineFragmentRef::initialize(BinaryStreamReader Reader) {
      56         354 :   if (auto EC = Reader.readObject(Header))
      57           0 :     return EC;
      58             : 
      59         118 :   if (auto EC =
      60         354 :           Reader.readArray(LinesAndColumns, Reader.bytesRemaining(), Header))
      61           0 :     return EC;
      62             : 
      63         354 :   return Error::success();
      64             : }
      65             : 
      66         372 : bool ModuleDebugLineFragmentRef::hasColumnInfo() const {
      67         744 :   return !!(Header->Flags & LF_HaveColumns);
      68             : }
      69             : 
      70           1 : ModuleDebugLineFragment::ModuleDebugLineFragment(
      71           1 :     ModuleDebugFileChecksumFragment &Checksums, StringTable &Strings)
      72             :     : ModuleDebugFragment(ModuleDebugFragmentKind::Lines),
      73           3 :       Checksums(Checksums) {}
      74             : 
      75           1 : void ModuleDebugLineFragment::createBlock(StringRef FileName) {
      76           1 :   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
      77             : 
      78           1 :   Blocks.emplace_back(Offset);
      79           1 : }
      80             : 
      81           3 : void ModuleDebugLineFragment::addLineInfo(uint32_t Offset,
      82             :                                           const LineInfo &Line) {
      83           6 :   Block &B = Blocks.back();
      84           3 :   LineNumberEntry LNE;
      85           6 :   LNE.Flags = Line.getRawData();
      86           3 :   LNE.Offset = Offset;
      87           3 :   B.Lines.push_back(LNE);
      88           3 : }
      89             : 
      90           0 : void ModuleDebugLineFragment::addLineAndColumnInfo(uint32_t Offset,
      91             :                                                    const LineInfo &Line,
      92             :                                                    uint32_t ColStart,
      93             :                                                    uint32_t ColEnd) {
      94           0 :   Block &B = Blocks.back();
      95             :   assert(B.Lines.size() == B.Columns.size());
      96             : 
      97           0 :   addLineInfo(Offset, Line);
      98           0 :   ColumnNumberEntry CNE;
      99           0 :   CNE.StartColumn = ColStart;
     100           0 :   CNE.EndColumn = ColEnd;
     101           0 :   B.Columns.push_back(CNE);
     102           0 : }
     103             : 
     104           1 : Error ModuleDebugLineFragment::commit(BinaryStreamWriter &Writer) {
     105           1 :   LineFragmentHeader Header;
     106           2 :   Header.CodeSize = CodeSize;
     107           2 :   Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0;
     108           2 :   Header.RelocOffset = RelocOffset;
     109           2 :   Header.RelocSegment = RelocSegment;
     110             : 
     111           3 :   if (auto EC = Writer.writeObject(Header))
     112           0 :     return EC;
     113             : 
     114           5 :   for (const auto &B : Blocks) {
     115           1 :     LineBlockFragmentHeader BlockHeader;
     116             :     assert(B.Lines.size() == B.Columns.size() || B.Columns.empty());
     117             : 
     118           3 :     BlockHeader.NumLines = B.Lines.size();
     119           1 :     BlockHeader.BlockSize = sizeof(LineBlockFragmentHeader);
     120           2 :     BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(LineNumberEntry);
     121           1 :     if (hasColumnInfo())
     122           0 :       BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(ColumnNumberEntry);
     123           2 :     BlockHeader.NameIndex = B.ChecksumBufferOffset;
     124           3 :     if (auto EC = Writer.writeObject(BlockHeader))
     125           0 :       return EC;
     126             : 
     127           4 :     if (auto EC = Writer.writeArray(makeArrayRef(B.Lines)))
     128           0 :       return EC;
     129             : 
     130           1 :     if (hasColumnInfo()) {
     131           0 :       if (auto EC = Writer.writeArray(makeArrayRef(B.Columns)))
     132           0 :         return EC;
     133             :     }
     134             :   }
     135           3 :   return Error::success();
     136             : }
     137             : 
     138           3 : uint32_t ModuleDebugLineFragment::calculateSerializedLength() {
     139           3 :   uint32_t Size = sizeof(LineFragmentHeader);
     140          15 :   for (const auto &B : Blocks) {
     141           3 :     Size += sizeof(LineBlockFragmentHeader);
     142           6 :     Size += B.Lines.size() * sizeof(LineNumberEntry);
     143           3 :     if (hasColumnInfo())
     144           0 :       Size += B.Columns.size() * sizeof(ColumnNumberEntry);
     145             :   }
     146           3 :   return Size;
     147             : }
     148             : 
     149           1 : void ModuleDebugLineFragment::setRelocationAddress(uint16_t Segment,
     150             :                                                    uint16_t Offset) {
     151           1 :   RelocOffset = Offset;
     152           1 :   RelocSegment = Segment;
     153           1 : }
     154             : 
     155           1 : void ModuleDebugLineFragment::setCodeSize(uint32_t Size) { CodeSize = Size; }
     156             : 
     157           1 : void ModuleDebugLineFragment::setFlags(LineFlags Flags) { this->Flags = Flags; }
     158             : 
     159           7 : bool ModuleDebugLineFragment::hasColumnInfo() const {
     160           7 :   return Flags & LF_HaveColumns;
     161             : }

Generated by: LCOV version 1.13