Coverage Report

Created: 2019-07-24 05:18

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