LCOV - code coverage report
Current view: top level - lib/CodeGen - FaultMaps.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 55 59 93.2 %
Date: 2018-10-20 13:21:21 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- FaultMaps.cpp ------------------------------------------------------===//
       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             : #include "llvm/CodeGen/FaultMaps.h"
      11             : #include "llvm/ADT/Twine.h"
      12             : #include "llvm/CodeGen/AsmPrinter.h"
      13             : #include "llvm/MC/MCContext.h"
      14             : #include "llvm/MC/MCExpr.h"
      15             : #include "llvm/MC/MCObjectFileInfo.h"
      16             : #include "llvm/MC/MCStreamer.h"
      17             : #include "llvm/Support/Debug.h"
      18             : #include "llvm/Support/ErrorHandling.h"
      19             : #include "llvm/Support/Format.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : 
      22             : using namespace llvm;
      23             : 
      24             : #define DEBUG_TYPE "faultmaps"
      25             : 
      26             : static const int FaultMapVersion = 1;
      27             : const char *FaultMaps::WFMP = "Fault Maps: ";
      28             : 
      29       29740 : FaultMaps::FaultMaps(AsmPrinter &AP) : AP(AP) {}
      30             : 
      31          26 : void FaultMaps::recordFaultingOp(FaultKind FaultTy,
      32             :                                  const MCSymbol *HandlerLabel) {
      33          26 :   MCContext &OutContext = AP.OutStreamer->getContext();
      34          26 :   MCSymbol *FaultingLabel = OutContext.createTempSymbol();
      35             : 
      36          52 :   AP.OutStreamer->EmitLabel(FaultingLabel);
      37             : 
      38             :   const MCExpr *FaultingOffset = MCBinaryExpr::createSub(
      39             :       MCSymbolRefExpr::create(FaultingLabel, OutContext),
      40          26 :       MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext);
      41             : 
      42             :   const MCExpr *HandlerOffset = MCBinaryExpr::createSub(
      43             :       MCSymbolRefExpr::create(HandlerLabel, OutContext),
      44          26 :       MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext);
      45             : 
      46          26 :   FunctionInfos[AP.CurrentFnSym].emplace_back(FaultTy, FaultingOffset,
      47             :                                               HandlerOffset);
      48          26 : }
      49             : 
      50       14006 : void FaultMaps::serializeToFaultMapSection() {
      51       14006 :   if (FunctionInfos.empty())
      52             :     return;
      53             : 
      54           4 :   MCContext &OutContext = AP.OutStreamer->getContext();
      55             :   MCStreamer &OS = *AP.OutStreamer;
      56             : 
      57             :   // Create the section.
      58             :   MCSection *FaultMapSection =
      59           4 :       OutContext.getObjectFileInfo()->getFaultMapSection();
      60           4 :   OS.SwitchSection(FaultMapSection);
      61             : 
      62             :   // Emit a dummy symbol to force section inclusion.
      63           8 :   OS.EmitLabel(OutContext.getOrCreateSymbol(Twine("__LLVM_FaultMaps")));
      64             : 
      65             :   LLVM_DEBUG(dbgs() << "********** Fault Map Output **********\n");
      66             : 
      67             :   // Header
      68           4 :   OS.EmitIntValue(FaultMapVersion, 1); // Version.
      69           4 :   OS.EmitIntValue(0, 1);               // Reserved.
      70           4 :   OS.EmitIntValue(0, 2);               // Reserved.
      71             : 
      72             :   LLVM_DEBUG(dbgs() << WFMP << "#functions = " << FunctionInfos.size() << "\n");
      73           8 :   OS.EmitIntValue(FunctionInfos.size(), 4);
      74             : 
      75             :   LLVM_DEBUG(dbgs() << WFMP << "functions:\n");
      76             : 
      77          29 :   for (const auto &FFI : FunctionInfos)
      78          25 :     emitFunctionInfo(FFI.first, FFI.second);
      79             : }
      80             : 
      81          25 : void FaultMaps::emitFunctionInfo(const MCSymbol *FnLabel,
      82             :                                  const FunctionFaultInfos &FFI) {
      83          25 :   MCStreamer &OS = *AP.OutStreamer;
      84             : 
      85             :   LLVM_DEBUG(dbgs() << WFMP << "  function addr: " << *FnLabel << "\n");
      86          25 :   OS.EmitSymbolValue(FnLabel, 8);
      87             : 
      88             :   LLVM_DEBUG(dbgs() << WFMP << "  #faulting PCs: " << FFI.size() << "\n");
      89          50 :   OS.EmitIntValue(FFI.size(), 4);
      90             : 
      91          25 :   OS.EmitIntValue(0, 4); // Reserved
      92             : 
      93          51 :   for (auto &Fault : FFI) {
      94             :     LLVM_DEBUG(dbgs() << WFMP << "    fault type: "
      95             :                       << faultTypeToString(Fault.Kind) << "\n");
      96          26 :     OS.EmitIntValue(Fault.Kind, 4);
      97             : 
      98             :     LLVM_DEBUG(dbgs() << WFMP << "    faulting PC offset: "
      99             :                       << *Fault.FaultingOffsetExpr << "\n");
     100          26 :     OS.EmitValue(Fault.FaultingOffsetExpr, 4);
     101             : 
     102             :     LLVM_DEBUG(dbgs() << WFMP << "    fault handler PC offset: "
     103             :                       << *Fault.HandlerOffsetExpr << "\n");
     104          26 :     OS.EmitValue(Fault.HandlerOffsetExpr, 4);
     105             :   }
     106          25 : }
     107             : 
     108          18 : const char *FaultMaps::faultTypeToString(FaultMaps::FaultKind FT) {
     109          18 :   switch (FT) {
     110           0 :   default:
     111           0 :     llvm_unreachable("unhandled fault type!");
     112             :   case FaultMaps::FaultingLoad:
     113             :     return "FaultingLoad";
     114           0 :   case FaultMaps::FaultingLoadStore:
     115           0 :     return "FaultingLoadStore";
     116           2 :   case FaultMaps::FaultingStore:
     117           2 :     return "FaultingStore";
     118             :   }
     119             : }
     120             : 
     121          18 : raw_ostream &llvm::
     122             : operator<<(raw_ostream &OS,
     123             :            const FaultMapParser::FunctionFaultInfoAccessor &FFI) {
     124          18 :   OS << "Fault kind: "
     125          36 :      << FaultMaps::faultTypeToString((FaultMaps::FaultKind)FFI.getFaultKind())
     126          18 :      << ", faulting PC offset: " << FFI.getFaultingPCOffset()
     127          18 :      << ", handling PC offset: " << FFI.getHandlerPCOffset();
     128          18 :   return OS;
     129             : }
     130             : 
     131          18 : raw_ostream &llvm::
     132             : operator<<(raw_ostream &OS, const FaultMapParser::FunctionInfoAccessor &FI) {
     133          18 :   OS << "FunctionAddress: " << format_hex(FI.getFunctionAddr(), 8)
     134          18 :      << ", NumFaultingPCs: " << FI.getNumFaultingPCs() << "\n";
     135          36 :   for (unsigned i = 0, e = FI.getNumFaultingPCs(); i != e; ++i)
     136          36 :     OS << FI.getFunctionFaultInfoAt(i) << "\n";
     137          18 :   return OS;
     138             : }
     139             : 
     140           3 : raw_ostream &llvm::operator<<(raw_ostream &OS, const FaultMapParser &FMP) {
     141           3 :   OS << "Version: " << format_hex(FMP.getFaultMapVersion(), 2) << "\n";
     142           3 :   OS << "NumFunctions: " << FMP.getNumFunctions() << "\n";
     143             : 
     144           6 :   if (FMP.getNumFunctions() == 0)
     145             :     return OS;
     146             : 
     147           3 :   FaultMapParser::FunctionInfoAccessor FI;
     148             : 
     149          21 :   for (unsigned i = 0, e = FMP.getNumFunctions(); i != e; ++i) {
     150          18 :     FI = (i == 0) ? FMP.getFirstFunctionInfo() : FI.getNextFunctionInfo();
     151          18 :     OS << FI;
     152             :   }
     153             : 
     154             :   return OS;
     155             : }

Generated by: LCOV version 1.13