Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:18

0001 //===-- FaultMapParser.h - Parser for the  "FaultMaps" section --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 /// A parser for the __llvm_faultmaps section generated by the FaultMaps class
0021 /// declared in llvm/CodeGen/FaultMaps.h.  This parser is version locked with
0022 /// with the __llvm_faultmaps section generated by the version of LLVM that
0023 /// includes it.  No guarantees are made with respect to forward or backward
0024 /// compatibility.
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 } // namespace llvm
0166 
0167 #endif