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/IR/DataLayout.h"
21 : #include "llvm/IR/Mangler.h"
22 : #include "llvm/IR/Module.h"
23 : #include "llvm/MC/MCAsmInfo.h"
24 : #include "llvm/MC/MCContext.h"
25 : #include "llvm/MC/MCExpr.h"
26 : #include "llvm/MC/MCSection.h"
27 : #include "llvm/MC/MCStreamer.h"
28 : #include "llvm/MC/MCSymbol.h"
29 : #include "llvm/MC/MachineLocation.h"
30 : #include "llvm/Support/ErrorHandling.h"
31 : #include "llvm/Support/FormattedStream.h"
32 : #include "llvm/Target/TargetLoweringObjectFile.h"
33 : #include "llvm/Target/TargetOptions.h"
34 : using namespace llvm;
35 :
36 23684 : DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A)
37 1959 : : EHStreamer(A), shouldEmitCFI(false), hasEmittedCFISections(false) {}
38 :
39 376156 : void DwarfCFIExceptionBase::markFunctionEnd() {
40 376156 : endFragment();
41 :
42 : // Map all labels and get rid of any dead landing pads.
43 752312 : if (!Asm->MF->getLandingPads().empty()) {
44 : MachineFunction *NonConstMF = const_cast<MachineFunction*>(Asm->MF);
45 46756 : NonConstMF->tidyLandingPads();
46 : }
47 376156 : }
48 :
49 376156 : void DwarfCFIExceptionBase::endFragment() {
50 376156 : if (shouldEmitCFI)
51 633460 : Asm->OutStreamer->EmitCFIEndProc();
52 376156 : }
53 :
54 21725 : DwarfCFIException::DwarfCFIException(AsmPrinter *A)
55 : : DwarfCFIExceptionBase(A), shouldEmitPersonality(false),
56 : forceEmitPersonality(false), shouldEmitLSDA(false),
57 21725 : shouldEmitMoves(false) {}
58 :
59 21633 : DwarfCFIException::~DwarfCFIException() {}
60 :
61 : /// endModule - Emit all exception information that should come after the
62 : /// content.
63 21633 : void DwarfCFIException::endModule() {
64 : // SjLj uses this pass and it doesn't need this info.
65 21633 : if (!Asm->MAI->usesCFIForEH())
66 : return;
67 :
68 20923 : const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
69 :
70 20923 : unsigned PerEncoding = TLOF.getPersonalityEncoding();
71 :
72 20923 : if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
73 : return;
74 :
75 : // Emit references to all used personality functions
76 5987 : for (const Function *Personality : MMI->getPersonalities()) {
77 151 : if (!Personality)
78 : continue;
79 151 : MCSymbol *Sym = Asm->getSymbol(Personality);
80 151 : TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
81 : }
82 : }
83 :
84 46692 : static MCSymbol *getExceptionSym(AsmPrinter *Asm) {
85 46692 : return Asm->getCurExceptionSym();
86 : }
87 :
88 364341 : void DwarfCFIException::beginFunction(const MachineFunction *MF) {
89 364341 : shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
90 364341 : const Function &F = MF->getFunction();
91 :
92 : // If any landing pads survive, we need an EH table.
93 364341 : bool hasLandingPads = !MF->getLandingPads().empty();
94 :
95 : // See if we need frame move info.
96 364341 : AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
97 :
98 364341 : shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
99 :
100 364341 : const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
101 364341 : unsigned PerEncoding = TLOF.getPersonalityEncoding();
102 : const Function *Per = nullptr;
103 364341 : if (F.hasPersonalityFn())
104 59603 : Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
105 :
106 : // Emit a personality function even when there are no landing pads
107 364341 : 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 364390 : !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
112 : // ... and we're not explicitly asked not to emit it
113 49 : F.needsUnwindTableEntry();
114 :
115 364341 : shouldEmitPersonality =
116 364292 : (forceEmitPersonality ||
117 364341 : (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
118 : Per;
119 :
120 364341 : unsigned LSDAEncoding = TLOF.getLSDAEncoding();
121 364341 : shouldEmitLSDA = shouldEmitPersonality &&
122 : LSDAEncoding != dwarf::DW_EH_PE_omit;
123 :
124 364341 : shouldEmitCFI = MF->getMMI().getContext().getAsmInfo()->usesCFIForEH() &&
125 315342 : (shouldEmitPersonality || shouldEmitMoves);
126 728682 : beginFragment(&*MF->begin(), getExceptionSym);
127 364340 : }
128 :
129 364341 : void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
130 : ExceptionSymbolProvider ESP) {
131 364341 : if (!shouldEmitCFI)
132 : return;
133 :
134 316671 : if (!hasEmittedCFISections) {
135 15578 : if (Asm->needsOnlyDebugCFIMoves())
136 174 : Asm->OutStreamer->EmitCFISections(false, true);
137 15578 : hasEmittedCFISections = true;
138 : }
139 :
140 633342 : Asm->OutStreamer->EmitCFIStartProc(/*IsSimple=*/false);
141 :
142 : // Indicate personality routine, if any.
143 316670 : if (!shouldEmitPersonality)
144 : return;
145 :
146 46692 : auto &F = MBB->getParent()->getFunction();
147 46692 : 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 46692 : if (forceEmitPersonality)
153 40 : MMI->addPersonality(P);
154 :
155 46692 : const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
156 46692 : unsigned PerEncoding = TLOF.getPersonalityEncoding();
157 46692 : const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
158 93384 : Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
159 :
160 : // Provide LSDA information.
161 46692 : if (shouldEmitLSDA)
162 93384 : Asm->OutStreamer->EmitCFILsda(ESP(Asm), TLOF.getLSDAEncoding());
163 : }
164 :
165 : /// endFunction - Gather and emit post-function exception information.
166 : ///
167 364341 : void DwarfCFIException::endFunction(const MachineFunction *MF) {
168 364341 : if (!shouldEmitPersonality)
169 : return;
170 :
171 46728 : emitExceptionTable();
172 : }
|