LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - RecordSerialization.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1 1 100.0 %
Date: 2017-08-25 02:00:44 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- RecordSerialization.h ------------------------------------*- 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             : #ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
      11             : #define LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
      12             : 
      13             : #include "llvm/ADT/APSInt.h"
      14             : #include "llvm/ADT/ArrayRef.h"
      15             : #include "llvm/ADT/StringRef.h"
      16             : #include "llvm/DebugInfo/CodeView/CodeView.h"
      17             : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
      18             : #include "llvm/Support/BinaryStreamReader.h"
      19             : #include "llvm/Support/Endian.h"
      20             : #include "llvm/Support/Error.h"
      21             : #include <cinttypes>
      22             : #include <tuple>
      23             : 
      24             : namespace llvm {
      25             : namespace codeview {
      26             : using llvm::support::little32_t;
      27             : using llvm::support::ulittle16_t;
      28             : using llvm::support::ulittle32_t;
      29             : 
      30             : /// Limit on the size of all codeview symbol and type records, including the
      31             : /// RecordPrefix. MSVC does not emit any records larger than this.
      32             : enum : unsigned { MaxRecordLength = 0xFF00 };
      33             : 
      34        2238 : struct RecordPrefix {
      35             :   ulittle16_t RecordLen;  // Record length, starting from &RecordKind.
      36             :   ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
      37             : };
      38             : 
      39             : /// Reinterpret a byte array as an array of characters. Does not interpret as
      40             : /// a C string, as StringRef has several helpers (split) that make that easy.
      41             : StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
      42             : StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
      43             : 
      44             : inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
      45             : 
      46             : /// Decodes a numeric "leaf" value. These are integer literals encountered in
      47             : /// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
      48             : /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
      49             : /// that indicates the bitwidth and sign of the numeric data.
      50             : Error consume(BinaryStreamReader &Reader, APSInt &Num);
      51             : 
      52             : /// Decodes a numeric leaf value that is known to be a particular type.
      53             : Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
      54             : 
      55             : /// Decodes signed and unsigned fixed-length integers.
      56             : Error consume(BinaryStreamReader &Reader, uint32_t &Item);
      57             : Error consume(BinaryStreamReader &Reader, int32_t &Item);
      58             : 
      59             : /// Decodes a null terminated string.
      60             : Error consume(BinaryStreamReader &Reader, StringRef &Item);
      61             : 
      62             : Error consume(StringRef &Data, APSInt &Num);
      63             : Error consume(StringRef &Data, uint32_t &Item);
      64             : 
      65             : /// Decodes an arbitrary object whose layout matches that of the underlying
      66             : /// byte sequence, and returns a pointer to the object.
      67             : template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
      68             :   return Reader.readObject(Item);
      69             : }
      70             : 
      71             : template <typename T, typename U> struct serialize_conditional_impl {
      72             :   serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
      73             : 
      74             :   Error deserialize(BinaryStreamReader &Reader) const {
      75             :     if (!Func())
      76             :       return Error::success();
      77             :     return consume(Reader, Item);
      78             :   }
      79             : 
      80             :   T &Item;
      81             :   U Func;
      82             : };
      83             : 
      84             : template <typename T, typename U>
      85             : serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
      86             :   return serialize_conditional_impl<T, U>(Item, Func);
      87             : }
      88             : 
      89             : template <typename T, typename U> struct serialize_array_impl {
      90             :   serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
      91             : 
      92             :   Error deserialize(BinaryStreamReader &Reader) const {
      93             :     return Reader.readArray(Item, Func());
      94             :   }
      95             : 
      96             :   ArrayRef<T> &Item;
      97             :   U Func;
      98             : };
      99             : 
     100             : template <typename T> struct serialize_vector_tail_impl {
     101             :   serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
     102             : 
     103             :   Error deserialize(BinaryStreamReader &Reader) const {
     104             :     T Field;
     105             :     // Stop when we run out of bytes or we hit record padding bytes.
     106             :     while (!Reader.empty() && Reader.peek() < LF_PAD0) {
     107             :       if (auto EC = consume(Reader, Field))
     108             :         return EC;
     109             :       Item.push_back(Field);
     110             :     }
     111             :     return Error::success();
     112             :   }
     113             : 
     114             :   std::vector<T> &Item;
     115             : };
     116             : 
     117             : struct serialize_null_term_string_array_impl {
     118             :   serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
     119             :       : Item(Item) {}
     120             : 
     121             :   Error deserialize(BinaryStreamReader &Reader) const {
     122             :     if (Reader.empty())
     123             :       return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
     124             :                                        "Null terminated string is empty!");
     125             : 
     126             :     while (Reader.peek() != 0) {
     127             :       StringRef Field;
     128             :       if (auto EC = Reader.readCString(Field))
     129             :         return EC;
     130             :       Item.push_back(Field);
     131             :     }
     132             :     return Reader.skip(1);
     133             :   }
     134             : 
     135             :   std::vector<StringRef> &Item;
     136             : };
     137             : 
     138             : template <typename T> struct serialize_arrayref_tail_impl {
     139             :   serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
     140             : 
     141             :   Error deserialize(BinaryStreamReader &Reader) const {
     142             :     uint32_t Count = Reader.bytesRemaining() / sizeof(T);
     143             :     return Reader.readArray(Item, Count);
     144             :   }
     145             : 
     146             :   ArrayRef<T> &Item;
     147             : };
     148             : 
     149             : template <typename T> struct serialize_numeric_impl {
     150             :   serialize_numeric_impl(T &Item) : Item(Item) {}
     151             : 
     152             :   Error deserialize(BinaryStreamReader &Reader) const {
     153             :     return consume_numeric(Reader, Item);
     154             :   }
     155             : 
     156             :   T &Item;
     157             : };
     158             : 
     159             : template <typename T, typename U>
     160             : serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
     161             :   return serialize_array_impl<T, U>(Item, Func);
     162             : }
     163             : 
     164             : inline serialize_null_term_string_array_impl
     165             : serialize_null_term_string_array(std::vector<StringRef> &Item) {
     166             :   return serialize_null_term_string_array_impl(Item);
     167             : }
     168             : 
     169             : template <typename T>
     170             : serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
     171             :   return serialize_vector_tail_impl<T>(Item);
     172             : }
     173             : 
     174             : template <typename T>
     175             : serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
     176             :   return serialize_arrayref_tail_impl<T>(Item);
     177             : }
     178             : 
     179             : template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
     180             :   return serialize_numeric_impl<T>(Item);
     181             : }
     182             : 
     183             : // This field is only present in the byte record if the condition is true.  The
     184             : // condition is evaluated lazily, so it can depend on items that were
     185             : // deserialized
     186             : // earlier.
     187             : #define CV_CONDITIONAL_FIELD(I, C)                                             \
     188             :   serialize_conditional(I, [&]() { return !!(C); })
     189             : 
     190             : // This is an array of N items, where N is evaluated lazily, so it can refer
     191             : // to a field deserialized earlier.
     192             : #define CV_ARRAY_FIELD_N(I, N) serialize_array(I, [&]() { return N; })
     193             : 
     194             : // This is an array that exhausts the remainder of the input buffer.
     195             : #define CV_ARRAY_FIELD_TAIL(I) serialize_array_tail(I)
     196             : 
     197             : // This is an array that consumes null terminated strings until a double null
     198             : // is encountered.
     199             : #define CV_STRING_ARRAY_NULL_TERM(I) serialize_null_term_string_array(I)
     200             : 
     201             : #define CV_NUMERIC_FIELD(I) serialize_numeric(I)
     202             : 
     203             : template <typename T, typename U>
     204             : Error consume(BinaryStreamReader &Reader,
     205             :               const serialize_conditional_impl<T, U> &Item) {
     206             :   return Item.deserialize(Reader);
     207             : }
     208             : 
     209             : template <typename T, typename U>
     210             : Error consume(BinaryStreamReader &Reader,
     211             :               const serialize_array_impl<T, U> &Item) {
     212             :   return Item.deserialize(Reader);
     213             : }
     214             : 
     215             : inline Error consume(BinaryStreamReader &Reader,
     216             :                      const serialize_null_term_string_array_impl &Item) {
     217             :   return Item.deserialize(Reader);
     218             : }
     219             : 
     220             : template <typename T>
     221             : Error consume(BinaryStreamReader &Reader,
     222             :               const serialize_vector_tail_impl<T> &Item) {
     223             :   return Item.deserialize(Reader);
     224             : }
     225             : 
     226             : template <typename T>
     227             : Error consume(BinaryStreamReader &Reader,
     228             :               const serialize_arrayref_tail_impl<T> &Item) {
     229             :   return Item.deserialize(Reader);
     230             : }
     231             : 
     232             : template <typename T>
     233             : Error consume(BinaryStreamReader &Reader,
     234             :               const serialize_numeric_impl<T> &Item) {
     235             :   return Item.deserialize(Reader);
     236             : }
     237             : 
     238             : template <typename T, typename U, typename... Args>
     239             : Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
     240             :   if (auto EC = consume(Reader, X))
     241             :     return EC;
     242             :   return consume(Reader, Y, std::forward<Args>(Rest)...);
     243             : }
     244             : 
     245             : #define CV_DESERIALIZE(...)                                                    \
     246             :   if (auto EC = consume(__VA_ARGS__))                                          \
     247             :     return std::move(EC);
     248             : }
     249             : }
     250             : 
     251             : #endif

Generated by: LCOV version 1.13