LCOV - code coverage report
Current view: top level - lib/DebugInfo/CodeView - CodeViewRecordIO.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 94 154 61.0 %
Date: 2017-09-14 15:23:50 Functions: 14 16 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- CodeViewRecordIO.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/CodeViewRecordIO.h"
      11             : #include "llvm/DebugInfo/CodeView/CodeView.h"
      12             : #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
      13             : #include "llvm/Support/BinaryStreamReader.h"
      14             : #include "llvm/Support/BinaryStreamWriter.h"
      15             : 
      16             : using namespace llvm;
      17             : using namespace llvm::codeview;
      18             : 
      19       22718 : Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
      20       45436 :   RecordLimit Limit;
      21       22718 :   Limit.MaxLength = MaxLength;
      22       22718 :   Limit.BeginOffset = getCurrentOffset();
      23       22718 :   Limits.push_back(Limit);
      24       90872 :   return Error::success();
      25             : }
      26             : 
      27       22718 : Error CodeViewRecordIO::endRecord() {
      28             :   assert(!Limits.empty() && "Not in a record!");
      29       45436 :   Limits.pop_back();
      30             :   // We would like to assert that we actually read / wrote all the bytes that we
      31             :   // expected to for this record, but unfortunately we can't do this.  Some
      32             :   // producers such as MASM over-allocate for certain types of records and
      33             :   // commit the extraneous data, so when reading we can't be sure every byte
      34             :   // will have been read.  And when writing we over-allocate temporarily since
      35             :   // we don't know how big the record is until we're finished writing it, so
      36             :   // even though we don't commit the extraneous data, we still can't guarantee
      37             :   // we're at the end of the allocated data.
      38       68154 :   return Error::success();
      39             : }
      40             : 
      41       12727 : uint32_t CodeViewRecordIO::maxFieldLength() const {
      42             :   assert(!Limits.empty() && "Not in a record!");
      43             : 
      44             :   // The max length of the next field is the minimum of all lengths that would
      45             :   // be allowed by any of the sub-records we're in.  In practice, we can only
      46             :   // ever be at most 1 sub-record deep (in a FieldList), but this works for
      47             :   // the general case.
      48       12727 :   uint32_t Offset = getCurrentOffset();
      49       50908 :   Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
      50       63198 :   for (auto X : makeArrayRef(Limits).drop_front()) {
      51       12290 :     Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
      52        6145 :     if (ThisMin.hasValue())
      53       12290 :       Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
      54             :   }
      55             :   assert(Min.hasValue() && "Every field must have a maximum length!");
      56             : 
      57       25454 :   return *Min;
      58             : }
      59             : 
      60        1998 : Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
      61        1998 :   if (isReading())
      62        1413 :     return Reader->padToAlignment(Align);
      63         585 :   return Writer->padToAlignment(Align);
      64             : }
      65             : 
      66        7444 : Error CodeViewRecordIO::skipPadding() {
      67             :   assert(!isWriting() && "Cannot skip padding while writing!");
      68             : 
      69       14888 :   if (Reader->bytesRemaining() == 0)
      70         327 :     return Error::success();
      71             : 
      72        7335 :   uint8_t Leaf = Reader->peek();
      73        7335 :   if (Leaf < LF_PAD0)
      74       15165 :     return Error::success();
      75             :   // Leaf is greater than 0xf0. We should advance by the number of bytes in
      76             :   // the low 4 bits.
      77        2280 :   unsigned BytesToAdvance = Leaf & 0x0F;
      78        2280 :   return Reader->skip(BytesToAdvance);
      79             : }
      80             : 
      81         484 : Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
      82         484 :   if (isWriting()) {
      83           0 :     if (auto EC = Writer->writeBytes(Bytes))
      84           0 :       return EC;
      85             :   } else {
      86        1936 :     if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
      87           0 :       return EC;
      88             :   }
      89        1452 :   return Error::success();
      90             : }
      91             : 
      92          26 : Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
      93          26 :   ArrayRef<uint8_t> BytesRef(Bytes);
      94          78 :   if (auto EC = mapByteVectorTail(BytesRef))
      95           0 :     return EC;
      96          26 :   if (!isWriting())
      97          26 :     Bytes.assign(BytesRef.begin(), BytesRef.end());
      98             : 
      99          78 :   return Error::success();
     100             : }
     101             : 
     102       14519 : Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
     103       14519 :   if (isWriting()) {
     104       13560 :     if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
     105           0 :       return EC;
     106       10170 :     return Error::success();
     107             :   }
     108             : 
     109             :   uint32_t I;
     110       33387 :   if (auto EC = Reader->readInteger(I))
     111           0 :     return EC;
     112       22258 :   TypeInd.setIndex(I);
     113       33387 :   return Error::success();
     114             : }
     115             : 
     116           0 : Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
     117           0 :   if (isWriting()) {
     118           0 :     if (Value >= 0) {
     119           0 :       if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
     120           0 :         return EC;
     121             :     } else {
     122           0 :       if (auto EC = writeEncodedSignedInteger(Value))
     123           0 :         return EC;
     124             :     }
     125             :   } else {
     126           0 :     APSInt N;
     127           0 :     if (auto EC = consume(*Reader, N))
     128           0 :       return EC;
     129           0 :     Value = N.getExtValue();
     130             :   }
     131             : 
     132           0 :   return Error::success();
     133             : }
     134             : 
     135        1908 : Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
     136        1908 :   if (isWriting()) {
     137        1461 :     if (auto EC = writeEncodedUnsignedInteger(Value))
     138           0 :       return EC;
     139             :   } else {
     140        2842 :     APSInt N;
     141        4263 :     if (auto EC = consume(*Reader, N))
     142           0 :       return EC;
     143        1421 :     Value = N.getZExtValue();
     144             :   }
     145        5724 :   return Error::success();
     146             : }
     147             : 
     148       12385 : Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
     149       12385 :   if (isWriting()) {
     150        5863 :     if (Value.isSigned())
     151           0 :       return writeEncodedSignedInteger(Value.getSExtValue());
     152       11726 :     return writeEncodedUnsignedInteger(Value.getZExtValue());
     153             :   }
     154             : 
     155        6522 :   return consume(*Reader, Value);
     156             : }
     157             : 
     158       19216 : Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
     159       19216 :   if (isWriting()) {
     160             :     // Truncate if we attempt to write too much.
     161       15702 :     StringRef S = Value.take_front(maxFieldLength() - 1);
     162       23553 :     if (auto EC = Writer->writeCString(S))
     163           0 :       return EC;
     164             :   } else {
     165       34095 :     if (auto EC = Reader->readCString(Value))
     166           0 :       return EC;
     167             :   }
     168       57648 :   return Error::success();
     169             : }
     170             : 
     171           7 : Error CodeViewRecordIO::mapGuid(GUID &Guid) {
     172           7 :   constexpr uint32_t GuidSize = 16;
     173           7 :   if (maxFieldLength() < GuidSize)
     174           0 :     return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
     175             : 
     176           7 :   if (isWriting()) {
     177          16 :     if (auto EC = Writer->writeBytes(Guid.Guid))
     178           0 :       return EC;
     179             :   } else {
     180           3 :     ArrayRef<uint8_t> GuidBytes;
     181           9 :     if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
     182           0 :       return EC;
     183           3 :     memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
     184             :   }
     185          21 :   return Error::success();
     186             : }
     187             : 
     188          58 : Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
     189          58 :   if (isWriting()) {
     190         490 :     for (auto V : Value) {
     191         978 :       if (auto EC = mapStringZ(V))
     192           0 :         return EC;
     193             :     }
     194         123 :     if (auto EC = Writer->writeInteger<uint8_t>(0))
     195           0 :       return EC;
     196             :   } else {
     197          17 :     StringRef S;
     198          51 :     if (auto EC = mapStringZ(S))
     199           0 :       return EC;
     200         139 :     while (!S.empty()) {
     201         122 :       Value.push_back(S);
     202         366 :       if (auto EC = mapStringZ(S))
     203           0 :         return EC;
     204             :     };
     205             :   }
     206         174 :   return Error::success();
     207             : }
     208             : 
     209           0 : Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
     210             :   assert(Value < 0 && "Encoded integer is not signed!");
     211           0 :   if (Value >= std::numeric_limits<int8_t>::min()) {
     212           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
     213           0 :       return EC;
     214           0 :     if (auto EC = Writer->writeInteger<int8_t>(Value))
     215           0 :       return EC;
     216           0 :   } else if (Value >= std::numeric_limits<int16_t>::min()) {
     217           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
     218           0 :       return EC;
     219           0 :     if (auto EC = Writer->writeInteger<int16_t>(Value))
     220           0 :       return EC;
     221           0 :   } else if (Value >= std::numeric_limits<int32_t>::min()) {
     222           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
     223           0 :       return EC;
     224           0 :     if (auto EC = Writer->writeInteger<int32_t>(Value))
     225           0 :       return EC;
     226             :   } else {
     227           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
     228           0 :       return EC;
     229           0 :     if (auto EC = Writer->writeInteger(Value))
     230           0 :       return EC;
     231             :   }
     232           0 :   return Error::success();
     233             : }
     234             : 
     235        6350 : Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
     236        6350 :   if (Value < LF_NUMERIC) {
     237       18924 :     if (auto EC = Writer->writeInteger<uint16_t>(Value))
     238           0 :       return EC;
     239          42 :   } else if (Value <= std::numeric_limits<uint16_t>::max()) {
     240           9 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
     241           0 :       return EC;
     242           9 :     if (auto EC = Writer->writeInteger<uint16_t>(Value))
     243           0 :       return EC;
     244          39 :   } else if (Value <= std::numeric_limits<uint32_t>::max()) {
     245         117 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
     246           0 :       return EC;
     247         117 :     if (auto EC = Writer->writeInteger<uint32_t>(Value))
     248           0 :       return EC;
     249             :   } else {
     250           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
     251           0 :       return EC;
     252           0 :     if (auto EC = Writer->writeInteger(Value))
     253           0 :       return EC;
     254             :   }
     255             : 
     256       19050 :   return Error::success();
     257             : }

Generated by: LCOV version 1.13