xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Object/FaultMapParser.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- FaultMapParser.h - Parser for 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_OBJECT_FAULTMAPPARSER_H
10 #define LLVM_OBJECT_FAULTMAPPARSER_H
11 
12 #include "llvm/Support/Compiler.h"
13 #include "llvm/Support/Endian.h"
14 #include <cassert>
15 #include <cstdint>
16 
17 namespace llvm {
18 
19 class raw_ostream;
20 
21 /// A parser for the __llvm_faultmaps section generated by the FaultMaps class
22 /// declared in llvm/CodeGen/FaultMaps.h.  This parser is version locked with
23 /// with the __llvm_faultmaps section generated by the version of LLVM that
24 /// includes it.  No guarantees are made with respect to forward or backward
25 /// compatibility.
26 class FaultMapParser {
27   using FaultMapVersionType = uint8_t;
28   using Reserved0Type = uint8_t;
29   using Reserved1Type = uint16_t;
30   using NumFunctionsType = uint32_t;
31 
32   static const size_t FaultMapVersionOffset = 0;
33   static const size_t Reserved0Offset =
34       FaultMapVersionOffset + sizeof(FaultMapVersionType);
35   static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type);
36   static const size_t NumFunctionsOffset =
37       Reserved1Offset + sizeof(Reserved1Type);
38   static const size_t FunctionInfosOffset =
39       NumFunctionsOffset + sizeof(NumFunctionsType);
40 
41   const uint8_t *P;
42   const uint8_t *E;
43 
read(const uint8_t * P,const uint8_t * E)44   template <typename T> static T read(const uint8_t *P, const uint8_t *E) {
45     assert(P + sizeof(T) <= E && "out of bounds read!");
46     return support::endian::read<T, llvm::endianness::little>(P);
47   }
48 
49 public:
50   enum FaultKind {
51     FaultingLoad = 1,
52     FaultingLoadStore,
53     FaultingStore,
54     FaultKindMax
55   };
56 
57   class FunctionFaultInfoAccessor {
58     using FaultKindType = uint32_t;
59     using FaultingPCOffsetType = uint32_t;
60     using HandlerPCOffsetType = uint32_t;
61 
62     static const size_t FaultKindOffset = 0;
63     static const size_t FaultingPCOffsetOffset =
64         FaultKindOffset + sizeof(FaultKindType);
65     static const size_t HandlerPCOffsetOffset =
66         FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType);
67 
68     const uint8_t *P;
69     const uint8_t *E;
70 
71   public:
72     static const size_t Size =
73         HandlerPCOffsetOffset + sizeof(HandlerPCOffsetType);
74 
FunctionFaultInfoAccessor(const uint8_t * P,const uint8_t * E)75     explicit FunctionFaultInfoAccessor(const uint8_t *P, const uint8_t *E)
76         : P(P), E(E) {}
77 
getFaultKind()78     FaultKindType getFaultKind() const {
79       return read<FaultKindType>(P + FaultKindOffset, E);
80     }
81 
getFaultingPCOffset()82     FaultingPCOffsetType getFaultingPCOffset() const {
83       return read<FaultingPCOffsetType>(P + FaultingPCOffsetOffset, E);
84     }
85 
getHandlerPCOffset()86     HandlerPCOffsetType getHandlerPCOffset() const {
87       return read<HandlerPCOffsetType>(P + HandlerPCOffsetOffset, E);
88     }
89   };
90 
91   class FunctionInfoAccessor {
92     using FunctionAddrType = uint64_t;
93     using NumFaultingPCsType = uint32_t;
94     using ReservedType = uint32_t;
95 
96     static const size_t FunctionAddrOffset = 0;
97     static const size_t NumFaultingPCsOffset =
98         FunctionAddrOffset + sizeof(FunctionAddrType);
99     static const size_t ReservedOffset =
100         NumFaultingPCsOffset + sizeof(NumFaultingPCsType);
101     static const size_t FunctionFaultInfosOffset =
102         ReservedOffset + sizeof(ReservedType);
103     static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset;
104 
105     const uint8_t *P = nullptr;
106     const uint8_t *E = nullptr;
107 
108   public:
109     FunctionInfoAccessor() = default;
110 
FunctionInfoAccessor(const uint8_t * P,const uint8_t * E)111     explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E)
112         : P(P), E(E) {}
113 
getFunctionAddr()114     FunctionAddrType getFunctionAddr() const {
115       return read<FunctionAddrType>(P + FunctionAddrOffset, E);
116     }
117 
getNumFaultingPCs()118     NumFaultingPCsType getNumFaultingPCs() const {
119       return read<NumFaultingPCsType>(P + NumFaultingPCsOffset, E);
120     }
121 
getFunctionFaultInfoAt(uint32_t Index)122     FunctionFaultInfoAccessor getFunctionFaultInfoAt(uint32_t Index) const {
123       assert(Index < getNumFaultingPCs() && "index out of bounds!");
124       const uint8_t *Begin = P + FunctionFaultInfosOffset +
125                              FunctionFaultInfoAccessor::Size * Index;
126       return FunctionFaultInfoAccessor(Begin, E);
127     }
128 
getNextFunctionInfo()129     FunctionInfoAccessor getNextFunctionInfo() const {
130       size_t MySize = FunctionInfoHeaderSize +
131                       getNumFaultingPCs() * FunctionFaultInfoAccessor::Size;
132 
133       const uint8_t *Begin = P + MySize;
134       assert(Begin < E && "out of bounds!");
135       return FunctionInfoAccessor(Begin, E);
136     }
137   };
138 
FaultMapParser(const uint8_t * Begin,const uint8_t * End)139   explicit FaultMapParser(const uint8_t *Begin, const uint8_t *End)
140       : P(Begin), E(End) {}
141 
getFaultMapVersion()142   FaultMapVersionType getFaultMapVersion() const {
143     auto Version = read<FaultMapVersionType>(P + FaultMapVersionOffset, E);
144     assert(Version == 1 && "only version 1 supported!");
145     return Version;
146   }
147 
getNumFunctions()148   NumFunctionsType getNumFunctions() const {
149     return read<NumFunctionsType>(P + NumFunctionsOffset, E);
150   }
151 
getFirstFunctionInfo()152   FunctionInfoAccessor getFirstFunctionInfo() const {
153     const uint8_t *Begin = P + FunctionInfosOffset;
154     return FunctionInfoAccessor(Begin, E);
155   }
156 };
157 
158 LLVM_ABI raw_ostream &
159 operator<<(raw_ostream &OS, const FaultMapParser::FunctionFaultInfoAccessor &);
160 
161 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
162                                  const FaultMapParser::FunctionInfoAccessor &);
163 
164 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &);
165 
166 } // namespace llvm
167 
168 #endif
169