]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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" | |
970d7e83 LB |
15 | #include "llvm/ADT/SmallString.h" |
16 | #include "llvm/ADT/StringExtras.h" | |
17 | #include "llvm/ADT/Twine.h" | |
223e47cc | 18 | #include "llvm/CodeGen/AsmPrinter.h" |
223e47cc LB |
19 | #include "llvm/CodeGen/MachineFrameInfo.h" |
20 | #include "llvm/CodeGen/MachineFunction.h" | |
970d7e83 LB |
21 | #include "llvm/CodeGen/MachineModuleInfo.h" |
22 | #include "llvm/IR/DataLayout.h" | |
1a4d82fc | 23 | #include "llvm/IR/Mangler.h" |
970d7e83 | 24 | #include "llvm/IR/Module.h" |
223e47cc LB |
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" | |
970d7e83 LB |
31 | #include "llvm/MC/MachineLocation.h" |
32 | #include "llvm/Support/Dwarf.h" | |
33 | #include "llvm/Support/ErrorHandling.h" | |
34 | #include "llvm/Support/FormattedStream.h" | |
223e47cc LB |
35 | #include "llvm/Target/TargetFrameLowering.h" |
36 | #include "llvm/Target/TargetLoweringObjectFile.h" | |
37 | #include "llvm/Target/TargetMachine.h" | |
38 | #include "llvm/Target/TargetOptions.h" | |
39 | #include "llvm/Target/TargetRegisterInfo.h" | |
223e47cc LB |
40 | using namespace llvm; |
41 | ||
42 | DwarfCFIException::DwarfCFIException(AsmPrinter *A) | |
1a4d82fc JJ |
43 | : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false), |
44 | shouldEmitMoves(false), moveTypeModule(AsmPrinter::CFI_M_None) {} | |
223e47cc LB |
45 | |
46 | DwarfCFIException::~DwarfCFIException() {} | |
47 | ||
1a4d82fc | 48 | /// endModule - Emit all exception information that should come after the |
223e47cc | 49 | /// content. |
1a4d82fc | 50 | void DwarfCFIException::endModule() { |
223e47cc LB |
51 | if (moveTypeModule == AsmPrinter::CFI_M_Debug) |
52 | Asm->OutStreamer.EmitCFISections(false, true); | |
53 | ||
85aaf69f | 54 | if (!Asm->MAI->usesItaniumLSDAForExceptions()) |
223e47cc LB |
55 | return; |
56 | ||
57 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | |
58 | ||
59 | unsigned PerEncoding = TLOF.getPersonalityEncoding(); | |
60 | ||
1a4d82fc | 61 | if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect) |
223e47cc LB |
62 | return; |
63 | ||
64 | // Emit references to all used personality functions | |
223e47cc LB |
65 | const std::vector<const Function*> &Personalities = MMI->getPersonalities(); |
66 | for (size_t i = 0, e = Personalities.size(); i != e; ++i) { | |
67 | if (!Personalities[i]) | |
68 | continue; | |
1a4d82fc | 69 | MCSymbol *Sym = Asm->getSymbol(Personalities[i]); |
223e47cc | 70 | TLOF.emitPersonalityValue(Asm->OutStreamer, Asm->TM, Sym); |
223e47cc LB |
71 | } |
72 | } | |
73 | ||
1a4d82fc | 74 | /// beginFunction - Gather pre-function exception information. Assumes it's |
223e47cc | 75 | /// being emitted immediately after the function entry point. |
1a4d82fc | 76 | void DwarfCFIException::beginFunction(const MachineFunction *MF) { |
223e47cc LB |
77 | shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; |
78 | ||
79 | // If any landing pads survive, we need an EH table. | |
80 | bool hasLandingPads = !MMI->getLandingPads().empty(); | |
81 | ||
82 | // See if we need frame move info. | |
83 | AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); | |
84 | if (MoveType == AsmPrinter::CFI_M_EH || | |
85 | (MoveType == AsmPrinter::CFI_M_Debug && | |
86 | moveTypeModule == AsmPrinter::CFI_M_None)) | |
87 | moveTypeModule = MoveType; | |
88 | ||
89 | shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None; | |
90 | ||
91 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | |
92 | unsigned PerEncoding = TLOF.getPersonalityEncoding(); | |
93 | const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()]; | |
94 | ||
95 | shouldEmitPersonality = hasLandingPads && | |
96 | PerEncoding != dwarf::DW_EH_PE_omit && Per; | |
97 | ||
98 | unsigned LSDAEncoding = TLOF.getLSDAEncoding(); | |
99 | shouldEmitLSDA = shouldEmitPersonality && | |
100 | LSDAEncoding != dwarf::DW_EH_PE_omit; | |
101 | ||
102 | if (!shouldEmitPersonality && !shouldEmitMoves) | |
103 | return; | |
104 | ||
1a4d82fc | 105 | Asm->OutStreamer.EmitCFIStartProc(/*IsSimple=*/false); |
223e47cc LB |
106 | |
107 | // Indicate personality routine, if any. | |
108 | if (!shouldEmitPersonality) | |
109 | return; | |
110 | ||
1a4d82fc JJ |
111 | const MCSymbol *Sym = |
112 | TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); | |
223e47cc LB |
113 | Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding); |
114 | ||
1a4d82fc JJ |
115 | MCSymbol *EHBegin = |
116 | Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); | |
117 | if (Asm->MAI->useAssignmentForEHBegin()) { | |
118 | MCContext &Ctx = Asm->OutContext; | |
119 | MCSymbol *CurPos = Ctx.CreateTempSymbol(); | |
120 | Asm->OutStreamer.EmitLabel(CurPos); | |
121 | Asm->OutStreamer.EmitAssignment(EHBegin, | |
122 | MCSymbolRefExpr::Create(CurPos, Ctx)); | |
123 | } else { | |
124 | Asm->OutStreamer.EmitLabel(EHBegin); | |
125 | } | |
223e47cc LB |
126 | |
127 | // Provide LSDA information. | |
128 | if (!shouldEmitLSDA) | |
129 | return; | |
130 | ||
131 | Asm->OutStreamer.EmitCFILsda(Asm->GetTempSymbol("exception", | |
132 | Asm->getFunctionNumber()), | |
133 | LSDAEncoding); | |
134 | } | |
135 | ||
1a4d82fc | 136 | /// endFunction - Gather and emit post-function exception information. |
223e47cc | 137 | /// |
1a4d82fc | 138 | void DwarfCFIException::endFunction(const MachineFunction *) { |
223e47cc LB |
139 | if (!shouldEmitPersonality && !shouldEmitMoves) |
140 | return; | |
141 | ||
142 | Asm->OutStreamer.EmitCFIEndProc(); | |
143 | ||
144 | if (!shouldEmitPersonality) | |
145 | return; | |
146 | ||
147 | Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", | |
148 | Asm->getFunctionNumber())); | |
149 | ||
150 | // Map all labels and get rid of any dead landing pads. | |
151 | MMI->TidyLandingPads(); | |
152 | ||
1a4d82fc | 153 | emitExceptionTable(); |
223e47cc | 154 | } |