LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DwarfCFIException.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 68 69 98.6 %
Date: 2018-02-22 04:41:24 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
       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             : // This file contains support for writing DWARF exception info into asm files.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "DwarfException.h"
      15             : #include "llvm/ADT/Twine.h"
      16             : #include "llvm/BinaryFormat/Dwarf.h"
      17             : #include "llvm/CodeGen/AsmPrinter.h"
      18             : #include "llvm/CodeGen/MachineFunction.h"
      19             : #include "llvm/CodeGen/MachineModuleInfo.h"
      20             : #include "llvm/CodeGen/TargetLoweringObjectFile.h"
      21             : #include "llvm/IR/DataLayout.h"
      22             : #include "llvm/IR/Mangler.h"
      23             : #include "llvm/IR/Module.h"
      24             : #include "llvm/MC/MCAsmInfo.h"
      25             : #include "llvm/MC/MCContext.h"
      26             : #include "llvm/MC/MCExpr.h"
      27             : #include "llvm/MC/MCSection.h"
      28             : #include "llvm/MC/MCStreamer.h"
      29             : #include "llvm/MC/MCSymbol.h"
      30             : #include "llvm/MC/MachineLocation.h"
      31             : #include "llvm/Support/ErrorHandling.h"
      32             : #include "llvm/Support/FormattedStream.h"
      33             : #include "llvm/Target/TargetOptions.h"
      34             : using namespace llvm;
      35             : 
      36       15845 : DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A)
      37       15845 :     : EHStreamer(A), shouldEmitCFI(false), hasEmittedCFISections(false) {}
      38             : 
      39      144446 : void DwarfCFIExceptionBase::markFunctionEnd() {
      40      144446 :   endFragment();
      41             : 
      42             :   // Map all labels and get rid of any dead landing pads.
      43      288892 :   if (!Asm->MF->getLandingPads().empty()) {
      44             :     MachineFunction *NonConstMF = const_cast<MachineFunction*>(Asm->MF);
      45        2565 :     NonConstMF->tidyLandingPads();
      46             :   }
      47      144446 : }
      48             : 
      49      144446 : void DwarfCFIExceptionBase::endFragment() {
      50      144446 :   if (shouldEmitCFI)
      51      192826 :     Asm->OutStreamer->EmitCFIEndProc();
      52      144446 : }
      53             : 
      54       14024 : DwarfCFIException::DwarfCFIException(AsmPrinter *A)
      55             :     : DwarfCFIExceptionBase(A), shouldEmitPersonality(false),
      56             :       forceEmitPersonality(false), shouldEmitLSDA(false),
      57       14024 :       shouldEmitMoves(false) {}
      58             : 
      59       27928 : DwarfCFIException::~DwarfCFIException() {}
      60             : 
      61             : /// endModule - Emit all exception information that should come after the
      62             : /// content.
      63       13964 : void DwarfCFIException::endModule() {
      64             :   // SjLj uses this pass and it doesn't need this info.
      65       13964 :   if (!Asm->MAI->usesCFIForEH())
      66             :     return;
      67             : 
      68       13257 :   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
      69             : 
      70       13257 :   unsigned PerEncoding = TLOF.getPersonalityEncoding();
      71             : 
      72       13257 :   if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
      73             :     return;
      74             : 
      75             :   // Emit references to all used personality functions
      76        5412 :   for (const Function *Personality : MMI->getPersonalities()) {
      77         112 :     if (!Personality)
      78           0 :       continue;
      79         112 :     MCSymbol *Sym = Asm->getSymbol(Personality);
      80         224 :     TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
      81             :   }
      82             : }
      83             : 
      84        2501 : static MCSymbol *getExceptionSym(AsmPrinter *Asm) {
      85        2501 :   return Asm->getCurExceptionSym();
      86             : }
      87             : 
      88      134043 : void DwarfCFIException::beginFunction(const MachineFunction *MF) {
      89      134043 :   shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
      90      134043 :   const Function &F = MF->getFunction();
      91             : 
      92             :   // If any landing pads survive, we need an EH table.
      93      134043 :   bool hasLandingPads = !MF->getLandingPads().empty();
      94             : 
      95             :   // See if we need frame move info.
      96      134043 :   AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
      97             : 
      98      134044 :   shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
      99             : 
     100      134044 :   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
     101      134044 :   unsigned PerEncoding = TLOF.getPersonalityEncoding();
     102             :   const Function *Per = nullptr;
     103      134044 :   if (F.hasPersonalityFn())
     104        2867 :     Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
     105             : 
     106             :   // Emit a personality function even when there are no landing pads
     107      134044 :   forceEmitPersonality =
     108             :       // ...if a personality function is explicitly specified
     109             :       F.hasPersonalityFn() &&
     110             :       // ... and it's not known to be a noop in the absence of invokes
     111      134084 :       !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
     112             :       // ... and we're not explicitly asked not to emit it
     113          40 :       F.needsUnwindTableEntry();
     114             : 
     115      134044 :   shouldEmitPersonality =
     116      134005 :       (forceEmitPersonality ||
     117      136581 :        (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
     118             :       Per;
     119             : 
     120      134044 :   unsigned LSDAEncoding = TLOF.getLSDAEncoding();
     121      134044 :   shouldEmitLSDA = shouldEmitPersonality &&
     122             :     LSDAEncoding != dwarf::DW_EH_PE_omit;
     123             : 
     124      399869 :   shouldEmitCFI = MF->getMMI().getContext().getAsmInfo()->usesCFIForEH() &&
     125      129280 :                   (shouldEmitPersonality || shouldEmitMoves);
     126      268088 :   beginFragment(&*MF->begin(), getExceptionSym);
     127      134044 : }
     128             : 
     129      134044 : void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
     130             :                                       ExceptionSymbolProvider ESP) {
     131      134044 :   if (!shouldEmitCFI)
     132             :     return;
     133             : 
     134       96354 :   if (!hasEmittedCFISections) {
     135        8465 :     if (Asm->needsOnlyDebugCFIMoves())
     136         155 :       Asm->OutStreamer->EmitCFISections(false, true);
     137        8465 :     hasEmittedCFISections = true;
     138             :   }
     139             : 
     140      192708 :   Asm->OutStreamer->EmitCFIStartProc(/*IsSimple=*/false);
     141             : 
     142             :   // Indicate personality routine, if any.
     143       96354 :   if (!shouldEmitPersonality)
     144             :     return;
     145             : 
     146        2501 :   auto &F = MBB->getParent()->getFunction();
     147        2501 :   auto *P = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
     148             :   assert(P && "Expected personality function");
     149             : 
     150             :   // If we are forced to emit this personality, make sure to record
     151             :   // it because it might not appear in any landingpad
     152        2501 :   if (forceEmitPersonality)
     153          30 :     MMI->addPersonality(P);
     154             : 
     155        2501 :   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
     156        2501 :   unsigned PerEncoding = TLOF.getPersonalityEncoding();
     157        2501 :   const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
     158        5002 :   Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
     159             : 
     160             :   // Provide LSDA information.
     161        2501 :   if (shouldEmitLSDA)
     162        5002 :     Asm->OutStreamer->EmitCFILsda(ESP(Asm), TLOF.getLSDAEncoding());
     163             : }
     164             : 
     165             : /// endFunction - Gather and emit post-function exception information.
     166             : ///
     167      134044 : void DwarfCFIException::endFunction(const MachineFunction *MF) {
     168      134044 :   if (!shouldEmitPersonality)
     169             :     return;
     170             : 
     171        2536 :   emitExceptionTable();
     172             : }

Generated by: LCOV version 1.13