1a7ec2dceSAnton Korobeynikov //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
2a7ec2dceSAnton Korobeynikov //
3a7ec2dceSAnton Korobeynikov //                     The LLVM Compiler Infrastructure
4a7ec2dceSAnton Korobeynikov //
5a7ec2dceSAnton Korobeynikov // This file is distributed under the University of Illinois Open Source
6a7ec2dceSAnton Korobeynikov // License. See LICENSE.TXT for details.
7a7ec2dceSAnton Korobeynikov //
8a7ec2dceSAnton Korobeynikov //===----------------------------------------------------------------------===//
9a7ec2dceSAnton Korobeynikov //
10a7ec2dceSAnton Korobeynikov // This file contains support for writing DWARF exception info into asm files.
11a7ec2dceSAnton Korobeynikov //
12a7ec2dceSAnton Korobeynikov //===----------------------------------------------------------------------===//
13a7ec2dceSAnton Korobeynikov 
14a7ec2dceSAnton Korobeynikov #include "DwarfException.h"
15ed0881b2SChandler Carruth #include "llvm/ADT/SmallString.h"
16ed0881b2SChandler Carruth #include "llvm/ADT/StringExtras.h"
17ed0881b2SChandler Carruth #include "llvm/ADT/Twine.h"
18a7ec2dceSAnton Korobeynikov #include "llvm/CodeGen/AsmPrinter.h"
19a7ec2dceSAnton Korobeynikov #include "llvm/CodeGen/MachineFrameInfo.h"
20a7ec2dceSAnton Korobeynikov #include "llvm/CodeGen/MachineFunction.h"
21ed0881b2SChandler Carruth #include "llvm/CodeGen/MachineModuleInfo.h"
229fb823bbSChandler Carruth #include "llvm/IR/DataLayout.h"
23894843cbSRafael Espindola #include "llvm/IR/Mangler.h"
249fb823bbSChandler Carruth #include "llvm/IR/Module.h"
25a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCAsmInfo.h"
26a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCContext.h"
27a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCExpr.h"
28a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCSection.h"
29a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCStreamer.h"
30a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCSymbol.h"
31ed0881b2SChandler Carruth #include "llvm/Support/CommandLine.h"
32ed0881b2SChandler Carruth #include "llvm/Support/Dwarf.h"
33ed0881b2SChandler Carruth #include "llvm/Support/FormattedStream.h"
34a7ec2dceSAnton Korobeynikov #include "llvm/Target/TargetFrameLowering.h"
35a7ec2dceSAnton Korobeynikov #include "llvm/Target/TargetOptions.h"
36a7ec2dceSAnton Korobeynikov #include "llvm/Target/TargetRegisterInfo.h"
37a7ec2dceSAnton Korobeynikov using namespace llvm;
38a7ec2dceSAnton Korobeynikov 
39a7ec2dceSAnton Korobeynikov ARMException::ARMException(AsmPrinter *A)
40*f6830f47SArtyom Skrobov   : DwarfException(A),
41*f6830f47SArtyom Skrobov     shouldEmitCFI(false) {}
42a7ec2dceSAnton Korobeynikov 
43a7ec2dceSAnton Korobeynikov ARMException::~ARMException() {}
44a7ec2dceSAnton Korobeynikov 
45a17151adSRafael Espindola ARMTargetStreamer &ARMException::getTargetStreamer() {
464a1a3606SRafael Espindola   MCTargetStreamer &TS = *Asm->OutStreamer.getTargetStreamer();
47a17151adSRafael Espindola   return static_cast<ARMTargetStreamer &>(TS);
48a17151adSRafael Espindola }
49a17151adSRafael Espindola 
50*f6830f47SArtyom Skrobov /// endModule - Emit all exception information that should come after the
51*f6830f47SArtyom Skrobov /// content.
52119f3073STimur Iskhodzhanov void ARMException::endModule() {
53*f6830f47SArtyom Skrobov   if (shouldEmitCFI)
54*f6830f47SArtyom Skrobov     Asm->OutStreamer.EmitCFISections(false, true);
55a7ec2dceSAnton Korobeynikov }
56a7ec2dceSAnton Korobeynikov 
57119f3073STimur Iskhodzhanov /// beginFunction - Gather pre-function exception information. Assumes it's
58a7ec2dceSAnton Korobeynikov /// being emitted immediately after the function entry point.
59119f3073STimur Iskhodzhanov void ARMException::beginFunction(const MachineFunction *MF) {
60a17151adSRafael Espindola   getTargetStreamer().emitFnStart();
61fc9bae6fSRafael Espindola   if (Asm->MF->getFunction()->needsUnwindTableEntry())
62a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
63a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
64*f6830f47SArtyom Skrobov   // See if we need call frame info.
65*f6830f47SArtyom Skrobov   AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
66*f6830f47SArtyom Skrobov   assert(MoveType != AsmPrinter::CFI_M_EH &&
67*f6830f47SArtyom Skrobov          "non-EH CFI not yet supported in prologue with EHABI lowering");
68*f6830f47SArtyom Skrobov   if (MoveType == AsmPrinter::CFI_M_Debug) {
69*f6830f47SArtyom Skrobov     shouldEmitCFI = true;
70*f6830f47SArtyom Skrobov     Asm->OutStreamer.EmitCFIStartProc(false);
71*f6830f47SArtyom Skrobov   }
72a7ec2dceSAnton Korobeynikov }
73a7ec2dceSAnton Korobeynikov 
74119f3073STimur Iskhodzhanov /// endFunction - Gather and emit post-function exception information.
75a7ec2dceSAnton Korobeynikov ///
761cd14444STimur Iskhodzhanov void ARMException::endFunction(const MachineFunction *) {
77*f6830f47SArtyom Skrobov   if (shouldEmitCFI)
78*f6830f47SArtyom Skrobov     Asm->OutStreamer.EmitCFIEndProc();
79*f6830f47SArtyom Skrobov 
80a17151adSRafael Espindola   ARMTargetStreamer &ATS = getTargetStreamer();
81fc9bae6fSRafael Espindola   if (!Asm->MF->getFunction()->needsUnwindTableEntry())
82a17151adSRafael Espindola     ATS.emitCantUnwind();
83a7ec2dceSAnton Korobeynikov   else {
84a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
85a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
86a7ec2dceSAnton Korobeynikov 
87b619a413SAnton Korobeynikov     // Map all labels and get rid of any dead landing pads.
88b619a413SAnton Korobeynikov     MMI->TidyLandingPads();
89b619a413SAnton Korobeynikov 
90b619a413SAnton Korobeynikov     if (!MMI->getLandingPads().empty()) {
91a7ec2dceSAnton Korobeynikov       // Emit references to personality.
92a7ec2dceSAnton Korobeynikov       if (const Function * Personality =
93a7ec2dceSAnton Korobeynikov           MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
9479858aa3SRafael Espindola         MCSymbol *PerSym = Asm->getSymbol(Personality);
95a7ec2dceSAnton Korobeynikov         Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
96a17151adSRafael Espindola         ATS.emitPersonality(PerSym);
97a7ec2dceSAnton Korobeynikov       }
98a7ec2dceSAnton Korobeynikov 
99b619a413SAnton Korobeynikov       // Emit .handlerdata directive.
100a17151adSRafael Espindola       ATS.emitHandlerData();
101a7ec2dceSAnton Korobeynikov 
102a7ec2dceSAnton Korobeynikov       // Emit actual exception table
103a7ec2dceSAnton Korobeynikov       EmitExceptionTable();
104a7ec2dceSAnton Korobeynikov     }
10533a7e2f2SEvgeniy Stepanov   }
106a7ec2dceSAnton Korobeynikov 
107a17151adSRafael Espindola   ATS.emitFnEnd();
108a7ec2dceSAnton Korobeynikov }
109f65a638dSAnton Korobeynikov 
110f65a638dSAnton Korobeynikov void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
111f65a638dSAnton Korobeynikov   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
112f65a638dSAnton Korobeynikov   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
113f65a638dSAnton Korobeynikov 
114f65a638dSAnton Korobeynikov   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
115f65a638dSAnton Korobeynikov 
116f65a638dSAnton Korobeynikov   int Entry = 0;
117f65a638dSAnton Korobeynikov   // Emit the Catch TypeInfos.
118f65a638dSAnton Korobeynikov   if (VerboseAsm && !TypeInfos.empty()) {
119f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
120f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
121f65a638dSAnton Korobeynikov     Entry = TypeInfos.size();
122f65a638dSAnton Korobeynikov   }
123f65a638dSAnton Korobeynikov 
124f65a638dSAnton Korobeynikov   for (std::vector<const GlobalVariable *>::const_reverse_iterator
125f65a638dSAnton Korobeynikov          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
126f65a638dSAnton Korobeynikov     const GlobalVariable *GV = *I;
127f65a638dSAnton Korobeynikov     if (VerboseAsm)
128f65a638dSAnton Korobeynikov       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
129f65a638dSAnton Korobeynikov     Asm->EmitTTypeReference(GV, TTypeEncoding);
130f65a638dSAnton Korobeynikov   }
131f65a638dSAnton Korobeynikov 
132f65a638dSAnton Korobeynikov   // Emit the Exception Specifications.
133f65a638dSAnton Korobeynikov   if (VerboseAsm && !FilterIds.empty()) {
134f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
135f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
136f65a638dSAnton Korobeynikov     Entry = 0;
137f65a638dSAnton Korobeynikov   }
138f65a638dSAnton Korobeynikov   for (std::vector<unsigned>::const_iterator
139f65a638dSAnton Korobeynikov          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
140f65a638dSAnton Korobeynikov     unsigned TypeID = *I;
141f65a638dSAnton Korobeynikov     if (VerboseAsm) {
142f65a638dSAnton Korobeynikov       --Entry;
143f65a638dSAnton Korobeynikov       if (TypeID != 0)
144f65a638dSAnton Korobeynikov         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
145f65a638dSAnton Korobeynikov     }
146f65a638dSAnton Korobeynikov 
147097b0e9dSAnton Korobeynikov     Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
148097b0e9dSAnton Korobeynikov                             TTypeEncoding);
149f65a638dSAnton Korobeynikov   }
150f65a638dSAnton Korobeynikov }
151