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"
239fb823bbSChandler Carruth #include "llvm/IR/Module.h"
24a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCAsmInfo.h"
25a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCContext.h"
26a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCExpr.h"
27a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCSection.h"
28a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCStreamer.h"
29a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCSymbol.h"
30ed0881b2SChandler Carruth #include "llvm/Support/CommandLine.h"
31ed0881b2SChandler Carruth #include "llvm/Support/Dwarf.h"
32ed0881b2SChandler Carruth #include "llvm/Support/FormattedStream.h"
33a7ec2dceSAnton Korobeynikov #include "llvm/Target/Mangler.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 
39*6ecb1e78SBenjamin 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 
50a7ec2dceSAnton Korobeynikov void ARMException::EndModule() {
51a7ec2dceSAnton Korobeynikov }
52a7ec2dceSAnton Korobeynikov 
53a7ec2dceSAnton Korobeynikov /// BeginFunction - Gather pre-function exception information. Assumes it's
54a7ec2dceSAnton Korobeynikov /// being emitted immediately after the function entry point.
55a7ec2dceSAnton Korobeynikov void ARMException::BeginFunction(const MachineFunction *MF) {
56a7ec2dceSAnton Korobeynikov   Asm->OutStreamer.EmitFnStart();
57fc9bae6fSRafael Espindola   if (Asm->MF->getFunction()->needsUnwindTableEntry())
58a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
59a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
60a7ec2dceSAnton Korobeynikov }
61a7ec2dceSAnton Korobeynikov 
62a7ec2dceSAnton Korobeynikov /// EndFunction - Gather and emit post-function exception information.
63a7ec2dceSAnton Korobeynikov ///
64a7ec2dceSAnton Korobeynikov void ARMException::EndFunction() {
65fc9bae6fSRafael Espindola   if (!Asm->MF->getFunction()->needsUnwindTableEntry())
66a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitCantUnwind();
67a7ec2dceSAnton Korobeynikov   else {
68a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
69a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
70a7ec2dceSAnton Korobeynikov 
71b619a413SAnton Korobeynikov     if (EnableARMEHABIDescriptors) {
72b619a413SAnton Korobeynikov       // Map all labels and get rid of any dead landing pads.
73b619a413SAnton Korobeynikov       MMI->TidyLandingPads();
74b619a413SAnton Korobeynikov 
75b619a413SAnton Korobeynikov       if (!MMI->getLandingPads().empty()) {
76a7ec2dceSAnton Korobeynikov         // Emit references to personality.
77a7ec2dceSAnton Korobeynikov         if (const Function * Personality =
78a7ec2dceSAnton Korobeynikov             MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
79a7ec2dceSAnton Korobeynikov           MCSymbol *PerSym = Asm->Mang->getSymbol(Personality);
80a7ec2dceSAnton Korobeynikov           Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
81a7ec2dceSAnton Korobeynikov           Asm->OutStreamer.EmitPersonality(PerSym);
82a7ec2dceSAnton Korobeynikov         }
83a7ec2dceSAnton Korobeynikov 
84b619a413SAnton Korobeynikov         // Emit .handlerdata directive.
85a7ec2dceSAnton Korobeynikov         Asm->OutStreamer.EmitHandlerData();
86a7ec2dceSAnton Korobeynikov 
87a7ec2dceSAnton Korobeynikov         // Emit actual exception table
88a7ec2dceSAnton Korobeynikov         EmitExceptionTable();
89a7ec2dceSAnton Korobeynikov       }
9033a7e2f2SEvgeniy Stepanov     }
91b619a413SAnton Korobeynikov   }
92a7ec2dceSAnton Korobeynikov 
93a7ec2dceSAnton Korobeynikov   Asm->OutStreamer.EmitFnEnd();
94a7ec2dceSAnton Korobeynikov }
95f65a638dSAnton Korobeynikov 
96f65a638dSAnton Korobeynikov void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
97f65a638dSAnton Korobeynikov   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
98f65a638dSAnton Korobeynikov   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
99f65a638dSAnton Korobeynikov 
100f65a638dSAnton Korobeynikov   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
101f65a638dSAnton Korobeynikov 
102f65a638dSAnton Korobeynikov   int Entry = 0;
103f65a638dSAnton Korobeynikov   // Emit the Catch TypeInfos.
104f65a638dSAnton Korobeynikov   if (VerboseAsm && !TypeInfos.empty()) {
105f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
106f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
107f65a638dSAnton Korobeynikov     Entry = TypeInfos.size();
108f65a638dSAnton Korobeynikov   }
109f65a638dSAnton Korobeynikov 
110f65a638dSAnton Korobeynikov   for (std::vector<const GlobalVariable *>::const_reverse_iterator
111f65a638dSAnton Korobeynikov          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
112f65a638dSAnton Korobeynikov     const GlobalVariable *GV = *I;
113f65a638dSAnton Korobeynikov     if (VerboseAsm)
114f65a638dSAnton Korobeynikov       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
115f65a638dSAnton Korobeynikov     Asm->EmitTTypeReference(GV, TTypeEncoding);
116f65a638dSAnton Korobeynikov   }
117f65a638dSAnton Korobeynikov 
118f65a638dSAnton Korobeynikov   // Emit the Exception Specifications.
119f65a638dSAnton Korobeynikov   if (VerboseAsm && !FilterIds.empty()) {
120f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
121f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
122f65a638dSAnton Korobeynikov     Entry = 0;
123f65a638dSAnton Korobeynikov   }
124f65a638dSAnton Korobeynikov   for (std::vector<unsigned>::const_iterator
125f65a638dSAnton Korobeynikov          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
126f65a638dSAnton Korobeynikov     unsigned TypeID = *I;
127f65a638dSAnton Korobeynikov     if (VerboseAsm) {
128f65a638dSAnton Korobeynikov       --Entry;
129f65a638dSAnton Korobeynikov       if (TypeID != 0)
130f65a638dSAnton Korobeynikov         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
131f65a638dSAnton Korobeynikov     }
132f65a638dSAnton Korobeynikov 
133097b0e9dSAnton Korobeynikov     Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
134097b0e9dSAnton Korobeynikov                             TTypeEncoding);
135f65a638dSAnton Korobeynikov   }
136f65a638dSAnton Korobeynikov }
137