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"
23*894843cbSRafael 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 
396ecb1e78SBenjamin Kramer static cl::opt<bool>
4033a7e2f2SEvgeniy Stepanov EnableARMEHABIDescriptors("arm-enable-ehabi-descriptors", cl::Hidden,
4133a7e2f2SEvgeniy Stepanov   cl::desc("Generate ARM EHABI tables with unwinding descriptors"),
4233a7e2f2SEvgeniy Stepanov   cl::init(false));
4333a7e2f2SEvgeniy Stepanov 
4433a7e2f2SEvgeniy Stepanov 
45a7ec2dceSAnton Korobeynikov ARMException::ARMException(AsmPrinter *A)
465be8f601SBenjamin Kramer   : DwarfException(A) {}
47a7ec2dceSAnton Korobeynikov 
48a7ec2dceSAnton Korobeynikov ARMException::~ARMException() {}
49a7ec2dceSAnton Korobeynikov 
50a17151adSRafael Espindola ARMTargetStreamer &ARMException::getTargetStreamer() {
51a17151adSRafael Espindola   MCTargetStreamer &TS = Asm->OutStreamer.getTargetStreamer();
52a17151adSRafael Espindola   return static_cast<ARMTargetStreamer &>(TS);
53a17151adSRafael Espindola }
54a17151adSRafael Espindola 
55119f3073STimur Iskhodzhanov void ARMException::endModule() {
56a7ec2dceSAnton Korobeynikov }
57a7ec2dceSAnton Korobeynikov 
58119f3073STimur Iskhodzhanov /// beginFunction - Gather pre-function exception information. Assumes it's
59a7ec2dceSAnton Korobeynikov /// being emitted immediately after the function entry point.
60119f3073STimur Iskhodzhanov void ARMException::beginFunction(const MachineFunction *MF) {
61a17151adSRafael Espindola   getTargetStreamer().emitFnStart();
62fc9bae6fSRafael Espindola   if (Asm->MF->getFunction()->needsUnwindTableEntry())
63a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
64a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
65a7ec2dceSAnton Korobeynikov }
66a7ec2dceSAnton Korobeynikov 
67119f3073STimur Iskhodzhanov /// endFunction - Gather and emit post-function exception information.
68a7ec2dceSAnton Korobeynikov ///
691cd14444STimur Iskhodzhanov void ARMException::endFunction(const MachineFunction *) {
70a17151adSRafael Espindola   ARMTargetStreamer &ATS = getTargetStreamer();
71fc9bae6fSRafael Espindola   if (!Asm->MF->getFunction()->needsUnwindTableEntry())
72a17151adSRafael Espindola     ATS.emitCantUnwind();
73a7ec2dceSAnton Korobeynikov   else {
74a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
75a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
76a7ec2dceSAnton Korobeynikov 
77b619a413SAnton Korobeynikov     if (EnableARMEHABIDescriptors) {
78b619a413SAnton Korobeynikov       // Map all labels and get rid of any dead landing pads.
79b619a413SAnton Korobeynikov       MMI->TidyLandingPads();
80b619a413SAnton Korobeynikov 
81b619a413SAnton Korobeynikov       if (!MMI->getLandingPads().empty()) {
82a7ec2dceSAnton Korobeynikov         // Emit references to personality.
83a7ec2dceSAnton Korobeynikov         if (const Function * Personality =
84a7ec2dceSAnton Korobeynikov             MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
8579858aa3SRafael Espindola           MCSymbol *PerSym = Asm->getSymbol(Personality);
86a7ec2dceSAnton Korobeynikov           Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
87a17151adSRafael Espindola           ATS.emitPersonality(PerSym);
88a7ec2dceSAnton Korobeynikov         }
89a7ec2dceSAnton Korobeynikov 
90b619a413SAnton Korobeynikov         // Emit .handlerdata directive.
91a17151adSRafael Espindola         ATS.emitHandlerData();
92a7ec2dceSAnton Korobeynikov 
93a7ec2dceSAnton Korobeynikov         // Emit actual exception table
94a7ec2dceSAnton Korobeynikov         EmitExceptionTable();
95a7ec2dceSAnton Korobeynikov       }
9633a7e2f2SEvgeniy Stepanov     }
97b619a413SAnton Korobeynikov   }
98a7ec2dceSAnton Korobeynikov 
99a17151adSRafael Espindola   ATS.emitFnEnd();
100a7ec2dceSAnton Korobeynikov }
101f65a638dSAnton Korobeynikov 
102f65a638dSAnton Korobeynikov void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
103f65a638dSAnton Korobeynikov   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
104f65a638dSAnton Korobeynikov   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
105f65a638dSAnton Korobeynikov 
106f65a638dSAnton Korobeynikov   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
107f65a638dSAnton Korobeynikov 
108f65a638dSAnton Korobeynikov   int Entry = 0;
109f65a638dSAnton Korobeynikov   // Emit the Catch TypeInfos.
110f65a638dSAnton Korobeynikov   if (VerboseAsm && !TypeInfos.empty()) {
111f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
112f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
113f65a638dSAnton Korobeynikov     Entry = TypeInfos.size();
114f65a638dSAnton Korobeynikov   }
115f65a638dSAnton Korobeynikov 
116f65a638dSAnton Korobeynikov   for (std::vector<const GlobalVariable *>::const_reverse_iterator
117f65a638dSAnton Korobeynikov          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
118f65a638dSAnton Korobeynikov     const GlobalVariable *GV = *I;
119f65a638dSAnton Korobeynikov     if (VerboseAsm)
120f65a638dSAnton Korobeynikov       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
121f65a638dSAnton Korobeynikov     Asm->EmitTTypeReference(GV, TTypeEncoding);
122f65a638dSAnton Korobeynikov   }
123f65a638dSAnton Korobeynikov 
124f65a638dSAnton Korobeynikov   // Emit the Exception Specifications.
125f65a638dSAnton Korobeynikov   if (VerboseAsm && !FilterIds.empty()) {
126f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
127f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
128f65a638dSAnton Korobeynikov     Entry = 0;
129f65a638dSAnton Korobeynikov   }
130f65a638dSAnton Korobeynikov   for (std::vector<unsigned>::const_iterator
131f65a638dSAnton Korobeynikov          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
132f65a638dSAnton Korobeynikov     unsigned TypeID = *I;
133f65a638dSAnton Korobeynikov     if (VerboseAsm) {
134f65a638dSAnton Korobeynikov       --Entry;
135f65a638dSAnton Korobeynikov       if (TypeID != 0)
136f65a638dSAnton Korobeynikov         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
137f65a638dSAnton Korobeynikov     }
138f65a638dSAnton Korobeynikov 
139097b0e9dSAnton Korobeynikov     Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
140097b0e9dSAnton Korobeynikov                             TTypeEncoding);
141f65a638dSAnton Korobeynikov   }
142f65a638dSAnton Korobeynikov }
143