Coverage Report

Created: 2017-10-03 07:32

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