File indexing completed on 2026-05-10 08:44:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_OBJECT_FAULTMAPPARSER_H
0010 #define LLVM_OBJECT_FAULTMAPPARSER_H
0011
0012 #include "llvm/Support/Endian.h"
0013 #include <cassert>
0014 #include <cstdint>
0015
0016 namespace llvm {
0017
0018 class raw_ostream;
0019
0020
0021
0022
0023
0024
0025 class FaultMapParser {
0026 using FaultMapVersionType = uint8_t;
0027 using Reserved0Type = uint8_t;
0028 using Reserved1Type = uint16_t;
0029 using NumFunctionsType = uint32_t;
0030
0031 static const size_t FaultMapVersionOffset = 0;
0032 static const size_t Reserved0Offset =
0033 FaultMapVersionOffset + sizeof(FaultMapVersionType);
0034 static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type);
0035 static const size_t NumFunctionsOffset =
0036 Reserved1Offset + sizeof(Reserved1Type);
0037 static const size_t FunctionInfosOffset =
0038 NumFunctionsOffset + sizeof(NumFunctionsType);
0039
0040 const uint8_t *P;
0041 const uint8_t *E;
0042
0043 template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
0044 assert(P + sizeof(T) <= E && "out of bounds read!");
0045 return support::endian::read<T, llvm::endianness::little>(P);
0046 }
0047
0048 public:
0049 enum FaultKind {
0050 FaultingLoad = 1,
0051 FaultingLoadStore,
0052 FaultingStore,
0053 FaultKindMax
0054 };
0055
0056 class FunctionFaultInfoAccessor {
0057 using FaultKindType = uint32_t;
0058 using FaultingPCOffsetType = uint32_t;
0059 using HandlerPCOffsetType = uint32_t;
0060
0061 static const size_t FaultKindOffset = 0;
0062 static const size_t FaultingPCOffsetOffset =
0063 FaultKindOffset + sizeof(FaultKindType);
0064 static const size_t HandlerPCOffsetOffset =
0065 FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType);
0066
0067 const uint8_t *P;
0068 const uint8_t *E;
0069
0070 public:
0071 static const size_t Size =
0072 HandlerPCOffsetOffset + sizeof(HandlerPCOffsetType);
0073
0074 explicit FunctionFaultInfoAccessor(const uint8_t *P, const uint8_t *E)
0075 : P(P), E(E) {}
0076
0077 FaultKindType getFaultKind() const {
0078 return read<FaultKindType>(P + FaultKindOffset, E);
0079 }
0080
0081 FaultingPCOffsetType getFaultingPCOffset() const {
0082 return read<FaultingPCOffsetType>(P + FaultingPCOffsetOffset, E);
0083 }
0084
0085 HandlerPCOffsetType getHandlerPCOffset() const {
0086 return read<HandlerPCOffsetType>(P + HandlerPCOffsetOffset, E);
0087 }
0088 };
0089
0090 class FunctionInfoAccessor {
0091 using FunctionAddrType = uint64_t;
0092 using NumFaultingPCsType = uint32_t;
0093 using ReservedType = uint32_t;
0094
0095 static const size_t FunctionAddrOffset = 0;
0096 static const size_t NumFaultingPCsOffset =
0097 FunctionAddrOffset + sizeof(FunctionAddrType);
0098 static const size_t ReservedOffset =
0099 NumFaultingPCsOffset + sizeof(NumFaultingPCsType);
0100 static const size_t FunctionFaultInfosOffset =
0101 ReservedOffset + sizeof(ReservedType);
0102 static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset;
0103
0104 const uint8_t *P = nullptr;
0105 const uint8_t *E = nullptr;
0106
0107 public:
0108 FunctionInfoAccessor() = default;
0109
0110 explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E)
0111 : P(P), E(E) {}
0112
0113 FunctionAddrType getFunctionAddr() const {
0114 return read<FunctionAddrType>(P + FunctionAddrOffset, E);
0115 }
0116
0117 NumFaultingPCsType getNumFaultingPCs() const {
0118 return read<NumFaultingPCsType>(P + NumFaultingPCsOffset, E);
0119 }
0120
0121 FunctionFaultInfoAccessor getFunctionFaultInfoAt(uint32_t Index) const {
0122 assert(Index < getNumFaultingPCs() && "index out of bounds!");
0123 const uint8_t *Begin = P + FunctionFaultInfosOffset +
0124 FunctionFaultInfoAccessor::Size * Index;
0125 return FunctionFaultInfoAccessor(Begin, E);
0126 }
0127
0128 FunctionInfoAccessor getNextFunctionInfo() const {
0129 size_t MySize = FunctionInfoHeaderSize +
0130 getNumFaultingPCs() * FunctionFaultInfoAccessor::Size;
0131
0132 const uint8_t *Begin = P + MySize;
0133 assert(Begin < E && "out of bounds!");
0134 return FunctionInfoAccessor(Begin, E);
0135 }
0136 };
0137
0138 explicit FaultMapParser(const uint8_t *Begin, const uint8_t *End)
0139 : P(Begin), E(End) {}
0140
0141 FaultMapVersionType getFaultMapVersion() const {
0142 auto Version = read<FaultMapVersionType>(P + FaultMapVersionOffset, E);
0143 assert(Version == 1 && "only version 1 supported!");
0144 return Version;
0145 }
0146
0147 NumFunctionsType getNumFunctions() const {
0148 return read<NumFunctionsType>(P + NumFunctionsOffset, E);
0149 }
0150
0151 FunctionInfoAccessor getFirstFunctionInfo() const {
0152 const uint8_t *Begin = P + FunctionInfosOffset;
0153 return FunctionInfoAccessor(Begin, E);
0154 }
0155 };
0156
0157 raw_ostream &operator<<(raw_ostream &OS,
0158 const FaultMapParser::FunctionFaultInfoAccessor &);
0159
0160 raw_ostream &operator<<(raw_ostream &OS,
0161 const FaultMapParser::FunctionInfoAccessor &);
0162
0163 raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &);
0164
0165 }
0166
0167 #endif