LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - FaultMaps.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 18 18 100.0 %
Date: 2018-07-13 00:08:38 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13