Coverage Report

Created: 2019-02-21 13:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/CodeView/CVRecord.h
Line
Count
Source (jump to first uncovered line)
1
//===- CVRecord.h -----------------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
10
#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
11
12
#include "llvm/ADT/ArrayRef.h"
13
#include "llvm/ADT/Optional.h"
14
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
15
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
16
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
17
#include "llvm/Support/BinaryStreamReader.h"
18
#include "llvm/Support/BinaryStreamRef.h"
19
#include "llvm/Support/Endian.h"
20
#include "llvm/Support/Error.h"
21
#include <cstdint>
22
23
namespace llvm {
24
25
namespace codeview {
26
27
template <typename Kind> class CVRecord {
28
public:
29
98.6k
  CVRecord() : Type(static_cast<Kind>(0)) {}
30
31
31.0k
  CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>::CVRecord(llvm::codeview::TypeLeafKind, llvm::ArrayRef<unsigned char>)
Line
Count
Source
31
23.7k
  CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
llvm::codeview::CVRecord<llvm::codeview::SymbolKind>::CVRecord(llvm::codeview::SymbolKind, llvm::ArrayRef<unsigned char>)
Line
Count
Source
31
7.33k
  CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
32
33
  bool valid() const { return Type != static_cast<Kind>(0); }
34
35
19.4k
  uint32_t length() const { return RecordData.size(); }
36
47.1k
  Kind kind() const { return Type; }
llvm::codeview::CVRecord<llvm::codeview::SymbolKind>::kind() const
Line
Count
Source
36
16.6k
  Kind kind() const { return Type; }
llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>::kind() const
Line
Count
Source
36
30.4k
  Kind kind() const { return Type; }
37
  ArrayRef<uint8_t> data() const { return RecordData; }
38
1.84k
  StringRef str_data() const {
39
1.84k
    return StringRef(reinterpret_cast<const char *>(RecordData.data()),
40
1.84k
                     RecordData.size());
41
1.84k
  }
42
43
21.9k
  ArrayRef<uint8_t> content() const {
44
21.9k
    return RecordData.drop_front(sizeof(RecordPrefix));
45
21.9k
  }
llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>::content() const
Line
Count
Source
43
16.7k
  ArrayRef<uint8_t> content() const {
44
16.7k
    return RecordData.drop_front(sizeof(RecordPrefix));
45
16.7k
  }
llvm::codeview::CVRecord<llvm::codeview::SymbolKind>::content() const
Line
Count
Source
43
5.17k
  ArrayRef<uint8_t> content() const {
44
5.17k
    return RecordData.drop_front(sizeof(RecordPrefix));
45
5.17k
  }
46
47
  Kind Type;
48
  ArrayRef<uint8_t> RecordData;
49
};
50
51
template <typename Kind> struct RemappedRecord {
52
  explicit RemappedRecord(const CVRecord<Kind> &R) : OriginalRecord(R) {}
53
54
  CVRecord<Kind> OriginalRecord;
55
  SmallVector<std::pair<uint32_t, TypeIndex>, 8> Mappings;
56
};
57
58
template <typename Record, typename Func>
59
Error forEachCodeViewRecord(ArrayRef<uint8_t> StreamBuffer, Func F) {
60
  while (!StreamBuffer.empty()) {
61
    if (StreamBuffer.size() < sizeof(RecordPrefix))
62
      return make_error<CodeViewError>(cv_error_code::corrupt_record);
63
64
    const RecordPrefix *Prefix =
65
        reinterpret_cast<const RecordPrefix *>(StreamBuffer.data());
66
67
    size_t RealLen = Prefix->RecordLen + 2;
68
    if (StreamBuffer.size() < RealLen)
69
      return make_error<CodeViewError>(cv_error_code::corrupt_record);
70
71
    ArrayRef<uint8_t> Data = StreamBuffer.take_front(RealLen);
72
    StreamBuffer = StreamBuffer.drop_front(RealLen);
73
74
    Record R(static_cast<decltype(Record::Type)>((uint16_t)Prefix->RecordKind),
75
             Data);
76
    if (auto EC = F(R))
77
      return EC;
78
  }
79
  return Error::success();
80
}
81
82
/// Read a complete record from a stream at a random offset.
83
template <typename Kind>
84
inline Expected<CVRecord<Kind>> readCVRecordFromStream(BinaryStreamRef Stream,
85
17.4k
                                                       uint32_t Offset) {
86
17.4k
  const RecordPrefix *Prefix = nullptr;
87
17.4k
  BinaryStreamReader Reader(Stream);
88
17.4k
  Reader.setOffset(Offset);
89
17.4k
90
17.4k
  if (auto EC = Reader.readObject(Prefix))
91
1
    return std::move(EC);
92
17.4k
  if (Prefix->RecordLen < 2)
93
0
    return make_error<CodeViewError>(cv_error_code::corrupt_record);
94
17.4k
  Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
95
17.4k
96
17.4k
  Reader.setOffset(Offset);
97
17.4k
  ArrayRef<uint8_t> RawData;
98
17.4k
  if (auto EC = Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
99
0
    return std::move(EC);
100
17.4k
  return codeview::CVRecord<Kind>(K, RawData);
101
17.4k
}
llvm::Expected<llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind> > llvm::codeview::readCVRecordFromStream<llvm::codeview::TypeLeafKind>(llvm::BinaryStreamRef, unsigned int)
Line
Count
Source
85
14.6k
                                                       uint32_t Offset) {
86
14.6k
  const RecordPrefix *Prefix = nullptr;
87
14.6k
  BinaryStreamReader Reader(Stream);
88
14.6k
  Reader.setOffset(Offset);
89
14.6k
90
14.6k
  if (auto EC = Reader.readObject(Prefix))
91
0
    return std::move(EC);
92
14.6k
  if (Prefix->RecordLen < 2)
93
0
    return make_error<CodeViewError>(cv_error_code::corrupt_record);
94
14.6k
  Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
95
14.6k
96
14.6k
  Reader.setOffset(Offset);
97
14.6k
  ArrayRef<uint8_t> RawData;
98
14.6k
  if (auto EC = Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
99
0
    return std::move(EC);
100
14.6k
  return codeview::CVRecord<Kind>(K, RawData);
101
14.6k
}
llvm::Expected<llvm::codeview::CVRecord<llvm::codeview::SymbolKind> > llvm::codeview::readCVRecordFromStream<llvm::codeview::SymbolKind>(llvm::BinaryStreamRef, unsigned int)
Line
Count
Source
85
2.85k
                                                       uint32_t Offset) {
86
2.85k
  const RecordPrefix *Prefix = nullptr;
87
2.85k
  BinaryStreamReader Reader(Stream);
88
2.85k
  Reader.setOffset(Offset);
89
2.85k
90
2.85k
  if (auto EC = Reader.readObject(Prefix))
91
1
    return std::move(EC);
92
2.85k
  if (Prefix->RecordLen < 2)
93
0
    return make_error<CodeViewError>(cv_error_code::corrupt_record);
94
2.85k
  Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
95
2.85k
96
2.85k
  Reader.setOffset(Offset);
97
2.85k
  ArrayRef<uint8_t> RawData;
98
2.85k
  if (auto EC = Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
99
0
    return std::move(EC);
100
2.85k
  return codeview::CVRecord<Kind>(K, RawData);
101
2.85k
}
102
103
} // end namespace codeview
104
105
template <typename Kind>
106
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
107
  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
108
14.6k
                   codeview::CVRecord<Kind> &Item) {
109
14.6k
    auto ExpectedRec = codeview::readCVRecordFromStream<Kind>(Stream, 0);
110
14.6k
    if (!ExpectedRec)
111
0
      return ExpectedRec.takeError();
112
14.6k
    Item = *ExpectedRec;
113
14.6k
    Len = ExpectedRec->length();
114
14.6k
    return Error::success();
115
14.6k
  }
116
};
117
118
} // end namespace llvm
119
120
#endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H