LCOV - code coverage report
Current view: top level - lib/DebugInfo/CodeView - CodeViewRecordIO.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 77 98 78.6 %
Date: 2018-07-13 00:08:38 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       32092 : Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
      20             :   RecordLimit Limit;
      21             :   Limit.MaxLength = MaxLength;
      22       32092 :   Limit.BeginOffset = getCurrentOffset();
      23       32092 :   Limits.push_back(Limit);
      24       32092 :   return Error::success();
      25             : }
      26             : 
      27       32090 : Error CodeViewRecordIO::endRecord() {
      28             :   assert(!Limits.empty() && "Not in a record!");
      29             :   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       32090 :   return Error::success();
      39             : }
      40             : 
      41       18706 : 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             :   uint32_t Offset = getCurrentOffset();
      49       18706 :   Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
      50       31874 :   for (auto X : makeArrayRef(Limits).drop_front()) {
      51             :     Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
      52        6584 :     if (ThisMin.hasValue())
      53       13168 :       Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
      54             :   }
      55             :   assert(Min.hasValue() && "Every field must have a maximum length!");
      56             : 
      57       18706 :   return *Min;
      58             : }
      59             : 
      60        3291 : Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
      61        3291 :   if (isReading())
      62        2271 :     return Reader->padToAlignment(Align);
      63        1020 :   return Writer->padToAlignment(Align);
      64             : }
      65             : 
      66        8841 : Error CodeViewRecordIO::skipPadding() {
      67             :   assert(!isWriting() && "Cannot skip padding while writing!");
      68             : 
      69       17682 :   if (Reader->bytesRemaining() == 0)
      70             :     return Error::success();
      71             : 
      72        8578 :   uint8_t Leaf = Reader->peek();
      73        8578 :   if (Leaf < LF_PAD0)
      74             :     return Error::success();
      75             :   // Leaf is greater than 0xf0. We should advance by the number of bytes in
      76             :   // the low 4 bits.
      77        3284 :   unsigned BytesToAdvance = Leaf & 0x0F;
      78        3284 :   return Reader->skip(BytesToAdvance);
      79             : }
      80             : 
      81         994 : Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
      82         994 :   if (isWriting()) {
      83           4 :     if (auto EC = Writer->writeBytes(Bytes))
      84             :       return EC;
      85             :   } else {
      86        1984 :     if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
      87             :       return EC;
      88             :   }
      89             :   return Error::success();
      90             : }
      91             : 
      92          31 : Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
      93             :   ArrayRef<uint8_t> BytesRef(Bytes);
      94          62 :   if (auto EC = mapByteVectorTail(BytesRef))
      95             :     return EC;
      96          31 :   if (!isWriting())
      97             :     Bytes.assign(BytesRef.begin(), BytesRef.end());
      98             : 
      99             :   return Error::success();
     100             : }
     101             : 
     102       29188 : Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
     103       29188 :   if (isWriting()) {
     104       16689 :     if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
     105             :       return EC;
     106             :     return Error::success();
     107             :   }
     108             : 
     109             :   uint32_t I;
     110       47250 :   if (auto EC = Reader->readInteger(I))
     111             :     return EC;
     112       23625 :   TypeInd.setIndex(I);
     113             :   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             :         return EC;
     121             :     } else {
     122           0 :       if (auto EC = writeEncodedSignedInteger(Value))
     123             :         return EC;
     124             :     }
     125             :   } else {
     126             :     APSInt N;
     127           0 :     if (auto EC = consume(*Reader, N))
     128             :       return EC;
     129           0 :     Value = N.getExtValue();
     130             :   }
     131             : 
     132             :   return Error::success();
     133             : }
     134             : 
     135        4116 : Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
     136        4116 :   if (isWriting()) {
     137        1472 :     if (auto EC = writeEncodedUnsignedInteger(Value))
     138             :       return EC;
     139             :   } else {
     140             :     APSInt N;
     141        6760 :     if (auto EC = consume(*Reader, N))
     142             :       return EC;
     143        3380 :     Value = N.getZExtValue();
     144             :   }
     145             :   return Error::success();
     146             : }
     147             : 
     148       12786 : Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
     149       12786 :   if (isWriting()) {
     150        6087 :     if (Value.isSigned())
     151           0 :       return writeEncodedSignedInteger(Value.getSExtValue());
     152        6087 :     return writeEncodedUnsignedInteger(Value.getZExtValue());
     153             :   }
     154             : 
     155        6699 :   return consume(*Reader, Value);
     156             : }
     157             : 
     158       25721 : Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
     159       25721 :   if (isWriting()) {
     160             :     // Truncate if we attempt to write too much.
     161       18668 :     StringRef S = Value.take_front(maxFieldLength() - 1);
     162       18668 :     if (auto EC = Writer->writeCString(S))
     163             :       return EC;
     164             :   } else {
     165       32774 :     if (auto EC = Reader->readCString(Value))
     166             :       return EC;
     167             :   }
     168             :   return Error::success();
     169             : }
     170             : 
     171          12 : Error CodeViewRecordIO::mapGuid(GUID &Guid) {
     172             :   constexpr uint32_t GuidSize = 16;
     173          12 :   if (maxFieldLength() < GuidSize)
     174           0 :     return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
     175             : 
     176          12 :   if (isWriting()) {
     177          18 :     if (auto EC = Writer->writeBytes(Guid.Guid))
     178             :       return EC;
     179             :   } else {
     180           6 :     ArrayRef<uint8_t> GuidBytes;
     181          12 :     if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
     182             :       return EC;
     183           6 :     memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
     184             :   }
     185             :   return Error::success();
     186             : }
     187             : 
     188          90 : Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
     189          90 :   if (isWriting()) {
     190         628 :     for (auto V : Value) {
     191        1116 :       if (auto EC = mapStringZ(V))
     192             :         return EC;
     193             :     }
     194         140 :     if (auto EC = Writer->writeInteger<uint8_t>(0))
     195             :       return EC;
     196             :   } else {
     197          20 :     StringRef S;
     198          40 :     if (auto EC = mapStringZ(S))
     199             :       return EC;
     200         166 :     while (!S.empty()) {
     201         146 :       Value.push_back(S);
     202         292 :       if (auto EC = mapStringZ(S))
     203             :         return EC;
     204             :     };
     205             :   }
     206             :   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             :       return EC;
     214           0 :     if (auto EC = Writer->writeInteger<int8_t>(Value))
     215             :       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             :       return EC;
     219           0 :     if (auto EC = Writer->writeInteger<int16_t>(Value))
     220             :       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             :       return EC;
     224           0 :     if (auto EC = Writer->writeInteger<int32_t>(Value))
     225             :       return EC;
     226             :   } else {
     227           0 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
     228             :       return EC;
     229           0 :     if (auto EC = Writer->writeInteger(Value))
     230             :       return EC;
     231             :   }
     232             :   return Error::success();
     233             : }
     234             : 
     235        6823 : Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
     236        6823 :   if (Value < LF_NUMERIC) {
     237       13448 :     if (auto EC = Writer->writeInteger<uint16_t>(Value))
     238             :       return EC;
     239          99 :   } else if (Value <= std::numeric_limits<uint16_t>::max()) {
     240          14 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
     241             :       return EC;
     242          14 :     if (auto EC = Writer->writeInteger<uint16_t>(Value))
     243             :       return EC;
     244          92 :   } else if (Value <= std::numeric_limits<uint32_t>::max()) {
     245         182 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
     246             :       return EC;
     247         182 :     if (auto EC = Writer->writeInteger<uint32_t>(Value))
     248             :       return EC;
     249             :   } else {
     250           2 :     if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
     251             :       return EC;
     252           2 :     if (auto EC = Writer->writeInteger(Value))
     253             :       return EC;
     254             :   }
     255             : 
     256             :   return Error::success();
     257             : }

Generated by: LCOV version 1.13