Coverage Report

Created: 2018-07-19 03:59

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/FaultMaps.h
Line
Count
Source
1
//===- FaultMaps.h - The "FaultMaps" section --------------------*- 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_CODEGEN_FAULTMAPS_H
11
#define LLVM_CODEGEN_FAULTMAPS_H
12
13
#include "llvm/MC/MCSymbol.h"
14
#include "llvm/Support/Endian.h"
15
#include <cassert>
16
#include <cstddef>
17
#include <cstdint>
18
#include <map>
19
#include <vector>
20
21
namespace llvm {
22
23
class AsmPrinter;
24
class MCExpr;
25
class raw_ostream;
26
27
class FaultMaps {
28
public:
29
  enum FaultKind {
30
    FaultingLoad = 1,
31
    FaultingLoadStore,
32
    FaultingStore,
33
    FaultKindMax
34
  };
35
36
  explicit FaultMaps(AsmPrinter &AP);
37
38
  static const char *faultTypeToString(FaultKind);
39
40
  void recordFaultingOp(FaultKind FaultTy, const MCSymbol *HandlerLabel);
41
  void serializeToFaultMapSection();
42
11.1k
  void reset() {
43
11.1k
    FunctionInfos.clear();
44
11.1k
  }
45
46
private:
47
  static const char *WFMP;
48
49
  struct FaultInfo {
50
    FaultKind Kind = FaultKindMax;
51
    const MCExpr *FaultingOffsetExpr = nullptr;
52
    const MCExpr *HandlerOffsetExpr = nullptr;
53
54
    FaultInfo() = default;
55
56
    explicit FaultInfo(FaultMaps::FaultKind Kind, const MCExpr *FaultingOffset,
57
                       const MCExpr *HandlerOffset)
58
        : Kind(Kind), FaultingOffsetExpr(FaultingOffset),
59
26
          HandlerOffsetExpr(HandlerOffset) {}
60
  };
61
62
  using FunctionFaultInfos = std::vector<FaultInfo>;
63
64
  // We'd like to keep a stable iteration order for FunctionInfos to help
65
  // FileCheck based testing.
66
  struct MCSymbolComparator {
67
77
    bool operator()(const MCSymbol *LHS, const MCSymbol *RHS) const {
68
77
      return LHS->getName() < RHS->getName();
69
77
    }
70
  };
71
72
  std::map<const MCSymbol *, FunctionFaultInfos, MCSymbolComparator>
73
      FunctionInfos;
74
  AsmPrinter &AP;
75
76
  void emitFunctionInfo(const MCSymbol *FnLabel, const FunctionFaultInfos &FFI);
77
};
78
79
/// A parser for the __llvm_faultmaps section generated by the FaultMaps class
80
/// above.  This parser is version locked with with the __llvm_faultmaps section
81
/// generated by the version of LLVM that includes it.  No guarantees are made
82
/// with respect to forward or backward compatibility.
83
class FaultMapParser {
84
  using FaultMapVersionType = uint8_t;
85
  using Reserved0Type = uint8_t;
86
  using Reserved1Type = uint16_t;
87
  using NumFunctionsType = uint32_t;
88
89
  static const size_t FaultMapVersionOffset = 0;
90
  static const size_t Reserved0Offset =
91
      FaultMapVersionOffset + sizeof(FaultMapVersionType);
92
  static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type);
93
  static const size_t NumFunctionsOffset =
94
      Reserved1Offset + sizeof(Reserved1Type);
95
  static const size_t FunctionInfosOffset =
96
      NumFunctionsOffset + sizeof(NumFunctionsType);
97
98
  const uint8_t *P;
99
  const uint8_t *E;
100
101
135
  template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
102
135
    assert(P + sizeof(T) <= E && "out of bounds read!");
103
135
    return support::endian::read<T, support::little, 1>(P);
104
135
  }
unsigned int llvm::FaultMapParser::read<unsigned int>(unsigned char const*, unsigned char const*)
Line
Count
Source
101
114
  template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
102
114
    assert(P + sizeof(T) <= E && "out of bounds read!");
103
114
    return support::endian::read<T, support::little, 1>(P);
104
114
  }
unsigned long long llvm::FaultMapParser::read<unsigned long long>(unsigned char const*, unsigned char const*)
Line
Count
Source
101
18
  template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
102
18
    assert(P + sizeof(T) <= E && "out of bounds read!");
103
18
    return support::endian::read<T, support::little, 1>(P);
104
18
  }
unsigned char llvm::FaultMapParser::read<unsigned char>(unsigned char const*, unsigned char const*)
Line
Count
Source
101
3
  template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
102
3
    assert(P + sizeof(T) <= E && "out of bounds read!");
103
3
    return support::endian::read<T, support::little, 1>(P);
104
3
  }
105
106
public:
107
  class FunctionFaultInfoAccessor {
108
    using FaultKindType = uint32_t;
109
    using FaultingPCOffsetType = uint32_t;
110
    using HandlerPCOffsetType = uint32_t;
111
112
    static const size_t FaultKindOffset = 0;
113
    static const size_t FaultingPCOffsetOffset =
114
        FaultKindOffset + sizeof(FaultKindType);
115
    static const size_t HandlerPCOffsetOffset =
116
        FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType);
117
118
    const uint8_t *P;
119
    const uint8_t *E;
120
121
  public:
122
    static const size_t Size =
123
        HandlerPCOffsetOffset + sizeof(HandlerPCOffsetType);
124
125
    explicit FunctionFaultInfoAccessor(const uint8_t *P, const uint8_t *E)
126
18
        : P(P), E(E) {}
127
128
18
    FaultKindType getFaultKind() const {
129
18
      return read<FaultKindType>(P + FaultKindOffset, E);
130
18
    }
131
132
18
    FaultingPCOffsetType getFaultingPCOffset() const {
133
18
      return read<FaultingPCOffsetType>(P + FaultingPCOffsetOffset, E);
134
18
    }
135
136
18
    HandlerPCOffsetType getHandlerPCOffset() const {
137
18
      return read<HandlerPCOffsetType>(P + HandlerPCOffsetOffset, E);
138
18
    }
139
  };
140
141
  class FunctionInfoAccessor {
142
    using FunctionAddrType = uint64_t;
143
    using NumFaultingPCsType = uint32_t;
144
    using ReservedType = uint32_t;
145
146
    static const size_t FunctionAddrOffset = 0;
147
    static const size_t NumFaultingPCsOffset =
148
        FunctionAddrOffset + sizeof(FunctionAddrType);
149
    static const size_t ReservedOffset =
150
        NumFaultingPCsOffset + sizeof(NumFaultingPCsType);
151
    static const size_t FunctionFaultInfosOffset =
152
        ReservedOffset + sizeof(ReservedType);
153
    static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset;
154
155
    const uint8_t *P = nullptr;
156
    const uint8_t *E = nullptr;
157
158
  public:
159
3
    FunctionInfoAccessor() = default;
160
161
    explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E)
162
18
        : P(P), E(E) {}
163
164
18
    FunctionAddrType getFunctionAddr() const {
165
18
      return read<FunctionAddrType>(P + FunctionAddrOffset, E);
166
18
    }
167
168
51
    NumFaultingPCsType getNumFaultingPCs() const {
169
51
      return read<NumFaultingPCsType>(P + NumFaultingPCsOffset, E);
170
51
    }
171
172
18
    FunctionFaultInfoAccessor getFunctionFaultInfoAt(uint32_t Index) const {
173
18
      assert(Index < getNumFaultingPCs() && "index out of bounds!");
174
18
      const uint8_t *Begin = P + FunctionFaultInfosOffset +
175
18
                             FunctionFaultInfoAccessor::Size * Index;
176
18
      return FunctionFaultInfoAccessor(Begin, E);
177
18
    }
178
179
15
    FunctionInfoAccessor getNextFunctionInfo() const {
180
15
      size_t MySize = FunctionInfoHeaderSize +
181
15
                      getNumFaultingPCs() * FunctionFaultInfoAccessor::Size;
182
15
183
15
      const uint8_t *Begin = P + MySize;
184
15
      assert(Begin < E && "out of bounds!");
185
15
      return FunctionInfoAccessor(Begin, E);
186
15
    }
187
  };
188
189
  explicit FaultMapParser(const uint8_t *Begin, const uint8_t *End)
190
      : P(Begin), E(End) {}
191
192
3
  FaultMapVersionType getFaultMapVersion() const {
193
3
    auto Version = read<FaultMapVersionType>(P + FaultMapVersionOffset, E);
194
3
    assert(Version == 1 && "only version 1 supported!");
195
3
    return Version;
196
3
  }
197
198
9
  NumFunctionsType getNumFunctions() const {
199
9
    return read<NumFunctionsType>(P + NumFunctionsOffset, E);
200
9
  }
201
202
3
  FunctionInfoAccessor getFirstFunctionInfo() const {
203
3
    const uint8_t *Begin = P + FunctionInfosOffset;
204
3
    return FunctionInfoAccessor(Begin, E);
205
3
  }
206
};
207
208
raw_ostream &
209
operator<<(raw_ostream &OS, const FaultMapParser::FunctionFaultInfoAccessor &);
210
211
raw_ostream &operator<<(raw_ostream &OS,
212
                        const FaultMapParser::FunctionInfoAccessor &);
213
214
raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &);
215
216
} // end namespace llvm
217
218
#endif // LLVM_CODEGEN_FAULTMAPS_H