LCOV - code coverage report
Current view: top level - lib/DebugInfo/CodeView - RecordSerialization.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 55 70.9 %
Date: 2018-09-23 13:06:45 Functions: 5 10 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- RecordSerialization.cpp -------------------------------------------===//
       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             : // Utilities for serializing and deserializing CodeView records.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
      15             : #include "llvm/ADT/APInt.h"
      16             : #include "llvm/ADT/APSInt.h"
      17             : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
      18             : #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
      19             : #include "llvm/DebugInfo/CodeView/TypeRecord.h"
      20             : #include "llvm/Support/BinaryByteStream.h"
      21             : 
      22             : using namespace llvm;
      23             : using namespace llvm::codeview;
      24             : using namespace llvm::support;
      25             : 
      26             : /// Reinterpret a byte array as an array of characters. Does not interpret as
      27             : /// a C string, as StringRef has several helpers (split) that make that easy.
      28          11 : StringRef llvm::codeview::getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
      29          11 :   return StringRef(reinterpret_cast<const char *>(LeafData.data()),
      30          11 :                    LeafData.size());
      31             : }
      32             : 
      33           0 : StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
      34           0 :   return getBytesAsCharacters(LeafData).split('\0').first;
      35             : }
      36             : 
      37       10806 : Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
      38             :   // Used to avoid overload ambiguity on APInt construtor.
      39             :   bool FalseVal = false;
      40             :   uint16_t Short;
      41       21612 :   if (auto EC = Reader.readInteger(Short))
      42             :     return EC;
      43             : 
      44       10806 :   if (Short < LF_NUMERIC) {
      45       20988 :     Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
      46       10494 :                  /*isUnsigned=*/true);
      47             :     return Error::success();
      48             :   }
      49             : 
      50         312 :   switch (Short) {
      51           4 :   case LF_CHAR: {
      52             :     int8_t N;
      53           8 :     if (auto EC = Reader.readInteger(N))
      54             :       return EC;
      55           8 :     Num = APSInt(APInt(8, N, true), false);
      56             :     return Error::success();
      57             :   }
      58           2 :   case LF_SHORT: {
      59             :     int16_t N;
      60           4 :     if (auto EC = Reader.readInteger(N))
      61             :       return EC;
      62           4 :     Num = APSInt(APInt(16, N, true), false);
      63             :     return Error::success();
      64             :   }
      65          23 :   case LF_USHORT: {
      66             :     uint16_t N;
      67          46 :     if (auto EC = Reader.readInteger(N))
      68             :       return EC;
      69          46 :     Num = APSInt(APInt(16, N, false), true);
      70             :     return Error::success();
      71             :   }
      72           2 :   case LF_LONG: {
      73             :     int32_t N;
      74           4 :     if (auto EC = Reader.readInteger(N))
      75             :       return EC;
      76           4 :     Num = APSInt(APInt(32, N, true), false);
      77             :     return Error::success();
      78             :   }
      79         277 :   case LF_ULONG: {
      80             :     uint32_t N;
      81         554 :     if (auto EC = Reader.readInteger(N))
      82             :       return EC;
      83         554 :     Num = APSInt(APInt(32, N, FalseVal), true);
      84             :     return Error::success();
      85             :   }
      86           2 :   case LF_QUADWORD: {
      87             :     int64_t N;
      88           4 :     if (auto EC = Reader.readInteger(N))
      89             :       return EC;
      90           4 :     Num = APSInt(APInt(64, N, true), false);
      91             :     return Error::success();
      92             :   }
      93           2 :   case LF_UQUADWORD: {
      94             :     uint64_t N;
      95           4 :     if (auto EC = Reader.readInteger(N))
      96             :       return EC;
      97           4 :     Num = APSInt(APInt(64, N, false), true);
      98             :     return Error::success();
      99             :   }
     100             :   }
     101             :   return make_error<CodeViewError>(cv_error_code::corrupt_record,
     102             :                                    "Buffer contains invalid APSInt type");
     103             : }
     104             : 
     105           0 : Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
     106             :   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
     107             :   BinaryByteStream S(Bytes, llvm::support::little);
     108           0 :   BinaryStreamReader SR(S);
     109           0 :   auto EC = consume(SR, Num);
     110           0 :   Data = Data.take_back(SR.bytesRemaining());
     111           0 :   return EC;
     112             : }
     113             : 
     114             : /// Decode a numeric leaf value that is known to be a uint64_t.
     115           0 : Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
     116             :                                       uint64_t &Num) {
     117             :   APSInt N;
     118           0 :   if (auto EC = consume(Reader, N))
     119             :     return EC;
     120           0 :   if (N.isSigned() || !N.isIntN(64))
     121             :     return make_error<CodeViewError>(cv_error_code::corrupt_record,
     122             :                                      "Data is not a numeric value!");
     123           0 :   Num = N.getLimitedValue();
     124             :   return Error::success();
     125             : }
     126             : 
     127        1840 : Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
     128        1840 :   return Reader.readInteger(Item);
     129             : }
     130             : 
     131        1840 : Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
     132             :   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
     133             :   BinaryByteStream S(Bytes, llvm::support::little);
     134        1840 :   BinaryStreamReader SR(S);
     135        1840 :   auto EC = consume(SR, Item);
     136        3680 :   Data = Data.take_back(SR.bytesRemaining());
     137        1840 :   return EC;
     138             : }
     139             : 
     140           0 : Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
     141           0 :   return Reader.readInteger(Item);
     142             : }
     143             : 
     144           0 : Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
     145           0 :   if (Reader.empty())
     146             :     return make_error<CodeViewError>(cv_error_code::corrupt_record,
     147             :                                      "Null terminated string buffer is empty!");
     148             : 
     149           0 :   return Reader.readCString(Item);
     150             : }
     151             : 
     152          31 : Expected<CVSymbol> llvm::codeview::readSymbolFromStream(BinaryStreamRef Stream,
     153             :                                                         uint32_t Offset) {
     154          31 :   return readCVRecordFromStream<SymbolKind>(Stream, Offset);
     155             : }

Generated by: LCOV version 1.13