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