/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 | } |