Coverage Report

Created: 2019-07-24 05:18

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