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

Generated by: LCOV version 1.13