1 //===- FaultMaps.h - The "FaultMaps" section --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CODEGEN_FAULTMAPS_H
11 #define LLVM_CODEGEN_FAULTMAPS_H
13 #include "llvm/MC/MCSymbol.h"
14 #include "llvm/Support/Endian.h"
36 explicit FaultMaps(AsmPrinter &AP);
38 static const char *faultTypeToString(FaultKind);
40 void recordFaultingOp(FaultKind FaultTy, const MCSymbol *HandlerLabel);
41 void serializeToFaultMapSection();
44 static const char *WFMP;
47 FaultKind Kind = FaultKindMax;
48 const MCExpr *FaultingOffsetExpr = nullptr;
49 const MCExpr *HandlerOffsetExpr = nullptr;
51 FaultInfo() = default;
53 explicit FaultInfo(FaultMaps::FaultKind Kind, const MCExpr *FaultingOffset,
54 const MCExpr *HandlerOffset)
55 : Kind(Kind), FaultingOffsetExpr(FaultingOffset),
56 HandlerOffsetExpr(HandlerOffset) {}
59 typedef std::vector<FaultInfo> FunctionFaultInfos;
61 // We'd like to keep a stable iteration order for FunctionInfos to help
62 // FileCheck based testing.
63 struct MCSymbolComparator {
64 bool operator()(const MCSymbol *LHS, const MCSymbol *RHS) const {
65 return LHS->getName() < RHS->getName();
69 std::map<const MCSymbol *, FunctionFaultInfos, MCSymbolComparator>
73 void emitFunctionInfo(const MCSymbol *FnLabel, const FunctionFaultInfos &FFI);
76 /// A parser for the __llvm_faultmaps section generated by the FaultMaps class
77 /// above. This parser is version locked with with the __llvm_faultmaps section
78 /// generated by the version of LLVM that includes it. No guarantees are made
79 /// with respect to forward or backward compatibility.
80 class FaultMapParser {
81 typedef uint8_t FaultMapVersionType;
82 static const size_t FaultMapVersionOffset = 0;
84 typedef uint8_t Reserved0Type;
85 static const size_t Reserved0Offset =
86 FaultMapVersionOffset + sizeof(FaultMapVersionType);
88 typedef uint16_t Reserved1Type;
89 static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type);
91 typedef uint32_t NumFunctionsType;
92 static const size_t NumFunctionsOffset =
93 Reserved1Offset + sizeof(Reserved1Type);
95 static const size_t FunctionInfosOffset =
96 NumFunctionsOffset + sizeof(NumFunctionsType);
101 template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
102 assert(P + sizeof(T) <= E && "out of bounds read!");
103 return support::endian::read<T, support::little, 1>(P);
107 class FunctionFaultInfoAccessor {
108 typedef uint32_t FaultKindType;
109 static const size_t FaultKindOffset = 0;
111 typedef uint32_t FaultingPCOffsetType;
112 static const size_t FaultingPCOffsetOffset =
113 FaultKindOffset + sizeof(FaultKindType);
115 typedef uint32_t HandlerPCOffsetType;
116 static const size_t HandlerPCOffsetOffset =
117 FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType);
123 static const size_t Size =
124 HandlerPCOffsetOffset + sizeof(HandlerPCOffsetType);
126 explicit FunctionFaultInfoAccessor(const uint8_t *P, const uint8_t *E)
129 FaultKindType getFaultKind() const {
130 return read<FaultKindType>(P + FaultKindOffset, E);
133 FaultingPCOffsetType getFaultingPCOffset() const {
134 return read<FaultingPCOffsetType>(P + FaultingPCOffsetOffset, E);
137 HandlerPCOffsetType getHandlerPCOffset() const {
138 return read<HandlerPCOffsetType>(P + HandlerPCOffsetOffset, E);
142 class FunctionInfoAccessor {
143 typedef uint64_t FunctionAddrType;
144 static const size_t FunctionAddrOffset = 0;
146 typedef uint32_t NumFaultingPCsType;
147 static const size_t NumFaultingPCsOffset =
148 FunctionAddrOffset + sizeof(FunctionAddrType);
150 typedef uint32_t ReservedType;
151 static const size_t ReservedOffset =
152 NumFaultingPCsOffset + sizeof(NumFaultingPCsType);
154 static const size_t FunctionFaultInfosOffset =
155 ReservedOffset + sizeof(ReservedType);
157 static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset;
159 const uint8_t *P = nullptr;
160 const uint8_t *E = nullptr;
163 FunctionInfoAccessor() = default;
165 explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E)
168 FunctionAddrType getFunctionAddr() const {
169 return read<FunctionAddrType>(P + FunctionAddrOffset, E);
172 NumFaultingPCsType getNumFaultingPCs() const {
173 return read<NumFaultingPCsType>(P + NumFaultingPCsOffset, E);
176 FunctionFaultInfoAccessor getFunctionFaultInfoAt(uint32_t Index) const {
177 assert(Index < getNumFaultingPCs() && "index out of bounds!");
178 const uint8_t *Begin = P + FunctionFaultInfosOffset +
179 FunctionFaultInfoAccessor::Size * Index;
180 return FunctionFaultInfoAccessor(Begin, E);
183 FunctionInfoAccessor getNextFunctionInfo() const {
184 size_t MySize = FunctionInfoHeaderSize +
185 getNumFaultingPCs() * FunctionFaultInfoAccessor::Size;
187 const uint8_t *Begin = P + MySize;
188 assert(Begin < E && "out of bounds!");
189 return FunctionInfoAccessor(Begin, E);
193 explicit FaultMapParser(const uint8_t *Begin, const uint8_t *End)
194 : P(Begin), E(End) {}
196 FaultMapVersionType getFaultMapVersion() const {
197 auto Version = read<FaultMapVersionType>(P + FaultMapVersionOffset, E);
198 assert(Version == 1 && "only version 1 supported!");
202 NumFunctionsType getNumFunctions() const {
203 return read<NumFunctionsType>(P + NumFunctionsOffset, E);
206 FunctionInfoAccessor getFirstFunctionInfo() const {
207 const uint8_t *Begin = P + FunctionInfosOffset;
208 return FunctionInfoAccessor(Begin, E);
213 operator<<(raw_ostream &OS, const FaultMapParser::FunctionFaultInfoAccessor &);
215 raw_ostream &operator<<(raw_ostream &OS,
216 const FaultMapParser::FunctionInfoAccessor &);
218 raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &);
220 } // end namespace llvm
222 #endif // LLVM_CODEGEN_FAULTMAPS_H