Line data Source code
1 : //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI 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"
15 : #include "llvm/ADT/Twine.h"
16 : #include "llvm/CodeGen/AsmPrinter.h"
17 : #include "llvm/CodeGen/MachineFunction.h"
18 : #include "llvm/IR/DataLayout.h"
19 : #include "llvm/IR/Mangler.h"
20 : #include "llvm/IR/Module.h"
21 : #include "llvm/MC/MCAsmInfo.h"
22 : #include "llvm/MC/MCExpr.h"
23 : #include "llvm/MC/MCSection.h"
24 : #include "llvm/MC/MCStreamer.h"
25 : #include "llvm/MC/MCSymbol.h"
26 : #include "llvm/Support/FormattedStream.h"
27 : #include "llvm/Target/TargetOptions.h"
28 : using namespace llvm;
29 :
30 1959 : ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
31 :
32 1934 : ARMException::~ARMException() {}
33 :
34 0 : ARMTargetStreamer &ARMException::getTargetStreamer() {
35 11815 : MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
36 0 : return static_cast<ARMTargetStreamer &>(TS);
37 : }
38 :
39 11815 : void ARMException::beginFunction(const MachineFunction *MF) {
40 11815 : if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
41 11815 : getTargetStreamer().emitFnStart();
42 : // See if we need call frame info.
43 11815 : AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
44 : assert(MoveType != AsmPrinter::CFI_M_EH &&
45 : "non-EH CFI not yet supported in prologue with EHABI lowering");
46 :
47 11815 : if (MoveType == AsmPrinter::CFI_M_Debug) {
48 59 : if (!hasEmittedCFISections) {
49 31 : if (Asm->needsOnlyDebugCFIMoves())
50 31 : Asm->OutStreamer->EmitCFISections(false, true);
51 31 : hasEmittedCFISections = true;
52 : }
53 :
54 59 : shouldEmitCFI = true;
55 118 : Asm->OutStreamer->EmitCFIStartProc(false);
56 : }
57 11815 : }
58 :
59 : /// endFunction - Gather and emit post-function exception information.
60 : ///
61 11815 : void ARMException::endFunction(const MachineFunction *MF) {
62 : ARMTargetStreamer &ATS = getTargetStreamer();
63 11815 : const Function &F = MF->getFunction();
64 : const Function *Per = nullptr;
65 11815 : if (F.hasPersonalityFn())
66 31 : Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
67 : bool forceEmitPersonality =
68 11816 : F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
69 1 : F.needsUnwindTableEntry();
70 11814 : bool shouldEmitPersonality = forceEmitPersonality ||
71 : !MF->getLandingPads().empty();
72 11815 : if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
73 : !shouldEmitPersonality)
74 3869 : ATS.emitCantUnwind();
75 7946 : else if (shouldEmitPersonality) {
76 : // Emit references to personality.
77 31 : if (Per) {
78 31 : MCSymbol *PerSym = Asm->getSymbol(Per);
79 62 : Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
80 31 : ATS.emitPersonality(PerSym);
81 : }
82 :
83 : // Emit .handlerdata directive.
84 31 : ATS.emitHandlerData();
85 :
86 : // Emit actual exception table
87 31 : emitExceptionTable();
88 : }
89 :
90 11815 : if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
91 11815 : ATS.emitFnEnd();
92 11815 : }
93 :
94 30 : void ARMException::emitTypeInfos(unsigned TTypeEncoding,
95 : MCSymbol *TTBaseLabel) {
96 30 : const MachineFunction *MF = Asm->MF;
97 : const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
98 : const std::vector<unsigned> &FilterIds = MF->getFilterIds();
99 :
100 30 : bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
101 :
102 : int Entry = 0;
103 : // Emit the Catch TypeInfos.
104 30 : if (VerboseAsm && !TypeInfos.empty()) {
105 87 : Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
106 58 : Asm->OutStreamer->AddBlankLine();
107 58 : Entry = TypeInfos.size();
108 : }
109 :
110 60 : for (const GlobalValue *GV : reverse(TypeInfos)) {
111 30 : if (VerboseAsm)
112 58 : Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
113 30 : Asm->EmitTTypeReference(GV, TTypeEncoding);
114 : }
115 :
116 60 : Asm->OutStreamer->EmitLabel(TTBaseLabel);
117 :
118 : // Emit the Exception Specifications.
119 30 : if (VerboseAsm && !FilterIds.empty()) {
120 3 : Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
121 2 : Asm->OutStreamer->AddBlankLine();
122 : Entry = 0;
123 : }
124 : for (std::vector<unsigned>::const_iterator
125 32 : I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
126 2 : unsigned TypeID = *I;
127 2 : if (VerboseAsm) {
128 2 : --Entry;
129 2 : if (TypeID != 0)
130 2 : Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
131 : }
132 :
133 2 : Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
134 : TTypeEncoding);
135 : }
136 30 : }
|