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"
22*9fb823bbSChandler Carruth #include "llvm/IR/DataLayout.h"
23*9fb823bbSChandler 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/TargetMachine.h"
36a7ec2dceSAnton Korobeynikov #include "llvm/Target/TargetOptions.h"
37a7ec2dceSAnton Korobeynikov #include "llvm/Target/TargetRegisterInfo.h"
38a7ec2dceSAnton Korobeynikov using namespace llvm;
39a7ec2dceSAnton Korobeynikov 
4033a7e2f2SEvgeniy Stepanov cl::opt<bool>
4133a7e2f2SEvgeniy Stepanov EnableARMEHABIDescriptors("arm-enable-ehabi-descriptors", cl::Hidden,
4233a7e2f2SEvgeniy Stepanov   cl::desc("Generate ARM EHABI tables with unwinding descriptors"),
4333a7e2f2SEvgeniy Stepanov   cl::init(false));
4433a7e2f2SEvgeniy Stepanov 
4533a7e2f2SEvgeniy Stepanov 
46a7ec2dceSAnton Korobeynikov ARMException::ARMException(AsmPrinter *A)
475be8f601SBenjamin Kramer   : DwarfException(A) {}
48a7ec2dceSAnton Korobeynikov 
49a7ec2dceSAnton Korobeynikov ARMException::~ARMException() {}
50a7ec2dceSAnton Korobeynikov 
51a7ec2dceSAnton Korobeynikov void ARMException::EndModule() {
52a7ec2dceSAnton Korobeynikov }
53a7ec2dceSAnton Korobeynikov 
54a7ec2dceSAnton Korobeynikov /// BeginFunction - Gather pre-function exception information. Assumes it's
55a7ec2dceSAnton Korobeynikov /// being emitted immediately after the function entry point.
56a7ec2dceSAnton Korobeynikov void ARMException::BeginFunction(const MachineFunction *MF) {
57a7ec2dceSAnton Korobeynikov   Asm->OutStreamer.EmitFnStart();
58fc9bae6fSRafael Espindola   if (Asm->MF->getFunction()->needsUnwindTableEntry())
59a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
60a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
61a7ec2dceSAnton Korobeynikov }
62a7ec2dceSAnton Korobeynikov 
63a7ec2dceSAnton Korobeynikov /// EndFunction - Gather and emit post-function exception information.
64a7ec2dceSAnton Korobeynikov ///
65a7ec2dceSAnton Korobeynikov void ARMException::EndFunction() {
66fc9bae6fSRafael Espindola   if (!Asm->MF->getFunction()->needsUnwindTableEntry())
67a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitCantUnwind();
68a7ec2dceSAnton Korobeynikov   else {
69a7ec2dceSAnton Korobeynikov     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
70a7ec2dceSAnton Korobeynikov                                                   Asm->getFunctionNumber()));
71a7ec2dceSAnton Korobeynikov 
72b619a413SAnton Korobeynikov     if (EnableARMEHABIDescriptors) {
73b619a413SAnton Korobeynikov       // Map all labels and get rid of any dead landing pads.
74b619a413SAnton Korobeynikov       MMI->TidyLandingPads();
75b619a413SAnton Korobeynikov 
76b619a413SAnton Korobeynikov       if (!MMI->getLandingPads().empty()) {
77a7ec2dceSAnton Korobeynikov         // Emit references to personality.
78a7ec2dceSAnton Korobeynikov         if (const Function * Personality =
79a7ec2dceSAnton Korobeynikov             MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
80a7ec2dceSAnton Korobeynikov           MCSymbol *PerSym = Asm->Mang->getSymbol(Personality);
81a7ec2dceSAnton Korobeynikov           Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
82a7ec2dceSAnton Korobeynikov           Asm->OutStreamer.EmitPersonality(PerSym);
83a7ec2dceSAnton Korobeynikov         }
84a7ec2dceSAnton Korobeynikov 
85b619a413SAnton Korobeynikov         // Emit .handlerdata directive.
86a7ec2dceSAnton Korobeynikov         Asm->OutStreamer.EmitHandlerData();
87a7ec2dceSAnton Korobeynikov 
88a7ec2dceSAnton Korobeynikov         // Emit actual exception table
89a7ec2dceSAnton Korobeynikov         EmitExceptionTable();
90a7ec2dceSAnton Korobeynikov       }
9133a7e2f2SEvgeniy Stepanov     }
92b619a413SAnton Korobeynikov   }
93a7ec2dceSAnton Korobeynikov 
94a7ec2dceSAnton Korobeynikov   Asm->OutStreamer.EmitFnEnd();
95a7ec2dceSAnton Korobeynikov }
96f65a638dSAnton Korobeynikov 
97f65a638dSAnton Korobeynikov void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
98f65a638dSAnton Korobeynikov   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
99f65a638dSAnton Korobeynikov   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
100f65a638dSAnton Korobeynikov 
101f65a638dSAnton Korobeynikov   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
102f65a638dSAnton Korobeynikov 
103f65a638dSAnton Korobeynikov   int Entry = 0;
104f65a638dSAnton Korobeynikov   // Emit the Catch TypeInfos.
105f65a638dSAnton Korobeynikov   if (VerboseAsm && !TypeInfos.empty()) {
106f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
107f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
108f65a638dSAnton Korobeynikov     Entry = TypeInfos.size();
109f65a638dSAnton Korobeynikov   }
110f65a638dSAnton Korobeynikov 
111f65a638dSAnton Korobeynikov   for (std::vector<const GlobalVariable *>::const_reverse_iterator
112f65a638dSAnton Korobeynikov          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
113f65a638dSAnton Korobeynikov     const GlobalVariable *GV = *I;
114f65a638dSAnton Korobeynikov     if (VerboseAsm)
115f65a638dSAnton Korobeynikov       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
116f65a638dSAnton Korobeynikov     Asm->EmitTTypeReference(GV, TTypeEncoding);
117f65a638dSAnton Korobeynikov   }
118f65a638dSAnton Korobeynikov 
119f65a638dSAnton Korobeynikov   // Emit the Exception Specifications.
120f65a638dSAnton Korobeynikov   if (VerboseAsm && !FilterIds.empty()) {
121f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
122f65a638dSAnton Korobeynikov     Asm->OutStreamer.AddBlankLine();
123f65a638dSAnton Korobeynikov     Entry = 0;
124f65a638dSAnton Korobeynikov   }
125f65a638dSAnton Korobeynikov   for (std::vector<unsigned>::const_iterator
126f65a638dSAnton Korobeynikov          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
127f65a638dSAnton Korobeynikov     unsigned TypeID = *I;
128f65a638dSAnton Korobeynikov     if (VerboseAsm) {
129f65a638dSAnton Korobeynikov       --Entry;
130f65a638dSAnton Korobeynikov       if (TypeID != 0)
131f65a638dSAnton Korobeynikov         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
132f65a638dSAnton Korobeynikov     }
133f65a638dSAnton Korobeynikov 
134097b0e9dSAnton Korobeynikov     Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
135097b0e9dSAnton Korobeynikov                             TTypeEncoding);
136f65a638dSAnton Korobeynikov   }
137f65a638dSAnton Korobeynikov }
138