LCOV - code coverage report
Current view: top level - lib/DebugInfo/CodeView - RecordSerialization.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 29 81 35.8 %
Date: 2017-09-14 15:23:50 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        7943 : Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
      38             :   // Used to avoid overload ambiguity on APInt construtor.
      39        7943 :   bool FalseVal = false;
      40             :   uint16_t Short;
      41       23829 :   if (auto EC = Reader.readInteger(Short))
      42           0 :     return EC;
      43             : 
      44        7943 :   if (Short < LF_NUMERIC) {
      45       38665 :     Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
      46             :                  /*isUnsigned=*/true);
      47       23199 :     return Error::success();
      48             :   }
      49             : 
      50         210 :   switch (Short) {
      51           0 :   case LF_CHAR: {
      52             :     int8_t N;
      53           0 :     if (auto EC = Reader.readInteger(N))
      54           0 :       return EC;
      55           0 :     Num = APSInt(APInt(8, N, true), false);
      56           0 :     return Error::success();
      57             :   }
      58           0 :   case LF_SHORT: {
      59             :     int16_t N;
      60           0 :     if (auto EC = Reader.readInteger(N))
      61           0 :       return EC;
      62           0 :     Num = APSInt(APInt(16, N, true), false);
      63           0 :     return Error::success();
      64             :   }
      65          15 :   case LF_USHORT: {
      66             :     uint16_t N;
      67          45 :     if (auto EC = Reader.readInteger(N))
      68           0 :       return EC;
      69          75 :     Num = APSInt(APInt(16, N, false), true);
      70          45 :     return Error::success();
      71             :   }
      72           0 :   case LF_LONG: {
      73             :     int32_t N;
      74           0 :     if (auto EC = Reader.readInteger(N))
      75           0 :       return EC;
      76           0 :     Num = APSInt(APInt(32, N, true), false);
      77           0 :     return Error::success();
      78             :   }
      79         195 :   case LF_ULONG: {
      80             :     uint32_t N;
      81         585 :     if (auto EC = Reader.readInteger(N))
      82           0 :       return EC;
      83         975 :     Num = APSInt(APInt(32, N, FalseVal), true);
      84         585 :     return Error::success();
      85             :   }
      86           0 :   case LF_QUADWORD: {
      87             :     int64_t N;
      88           0 :     if (auto EC = Reader.readInteger(N))
      89           0 :       return EC;
      90           0 :     Num = APSInt(APInt(64, N, true), false);
      91           0 :     return Error::success();
      92             :   }
      93           0 :   case LF_UQUADWORD: {
      94             :     uint64_t N;
      95           0 :     if (auto EC = Reader.readInteger(N))
      96           0 :       return EC;
      97           0 :     Num = APSInt(APInt(64, N, false), true);
      98           0 :     return Error::success();
      99             :   }
     100             :   }
     101             :   return make_error<CodeViewError>(cv_error_code::corrupt_record,
     102           0 :                                    "Buffer contains invalid APSInt type");
     103             : }
     104             : 
     105           0 : Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
     106           0 :   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
     107           0 :   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           0 :   APSInt N;
     118           0 :   if (auto EC = consume(Reader, N))
     119           0 :     return EC;
     120           0 :   if (N.isSigned() || !N.isIntN(64))
     121             :     return make_error<CodeViewError>(cv_error_code::corrupt_record,
     122           0 :                                      "Data is not a numeric value!");
     123           0 :   Num = N.getLimitedValue();
     124           0 :   return Error::success();
     125             : }
     126             : 
     127        1353 : Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
     128        1353 :   return Reader.readInteger(Item);
     129             : }
     130             : 
     131        1353 : Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
     132        4059 :   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
     133        2706 :   BinaryByteStream S(Bytes, llvm::support::little);
     134        2706 :   BinaryStreamReader SR(S);
     135        1353 :   auto EC = consume(SR, Item);
     136        2706 :   Data = Data.take_back(SR.bytesRemaining());
     137        1353 :   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           0 :                                      "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          62 :   return readCVRecordFromStream<SymbolKind>(Stream, Offset);
     155             : }

Generated by: LCOV version 1.13