1 //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains support for writing DWARF exception info into asm files.
11 //===----------------------------------------------------------------------===//
13 #include "DwarfException.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/CodeGen/AsmPrinter.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/Mangler.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/MC/MCAsmInfo.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Support/FormattedStream.h"
26 #include "llvm/Target/TargetOptions.h"
29 ARMException::ARMException(AsmPrinter
*A
) : DwarfCFIExceptionBase(A
) {}
31 ARMException::~ARMException() {}
33 ARMTargetStreamer
&ARMException::getTargetStreamer() {
34 MCTargetStreamer
&TS
= *Asm
->OutStreamer
->getTargetStreamer();
35 return static_cast<ARMTargetStreamer
&>(TS
);
38 void ARMException::beginFunction(const MachineFunction
*MF
) {
39 if (Asm
->MAI
->getExceptionHandlingType() == ExceptionHandling::ARM
)
40 getTargetStreamer().emitFnStart();
41 // See if we need call frame info.
42 AsmPrinter::CFISection CFISecType
= Asm
->getFunctionCFISectionType(*MF
);
43 assert(CFISecType
!= AsmPrinter::CFISection::EH
&&
44 "non-EH CFI not yet supported in prologue with EHABI lowering");
46 if (CFISecType
== AsmPrinter::CFISection::Debug
) {
47 if (!hasEmittedCFISections
) {
48 if (Asm
->getModuleCFISectionType() == AsmPrinter::CFISection::Debug
)
49 Asm
->OutStreamer
->emitCFISections(false, true);
50 hasEmittedCFISections
= true;
54 Asm
->OutStreamer
->emitCFIStartProc(false);
58 /// endFunction - Gather and emit post-function exception information.
60 void ARMException::endFunction(const MachineFunction
*MF
) {
61 ARMTargetStreamer
&ATS
= getTargetStreamer();
62 const Function
&F
= MF
->getFunction();
63 const Function
*Per
= nullptr;
64 if (F
.hasPersonalityFn())
65 Per
= dyn_cast
<Function
>(F
.getPersonalityFn()->stripPointerCasts());
66 bool forceEmitPersonality
=
67 F
.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per
)) &&
68 F
.needsUnwindTableEntry();
69 bool shouldEmitPersonality
= forceEmitPersonality
||
70 !MF
->getLandingPads().empty();
71 if (!Asm
->MF
->getFunction().needsUnwindTableEntry() &&
72 !shouldEmitPersonality
)
74 else if (shouldEmitPersonality
) {
75 // Emit references to personality.
77 MCSymbol
*PerSym
= Asm
->getSymbol(Per
);
78 ATS
.emitPersonality(PerSym
);
81 // Emit .handlerdata directive.
82 ATS
.emitHandlerData();
84 // Emit actual exception table
88 if (Asm
->MAI
->getExceptionHandlingType() == ExceptionHandling::ARM
)
92 void ARMException::emitTypeInfos(unsigned TTypeEncoding
,
93 MCSymbol
*TTBaseLabel
) {
94 const MachineFunction
*MF
= Asm
->MF
;
95 const std::vector
<const GlobalValue
*> &TypeInfos
= MF
->getTypeInfos();
96 const std::vector
<unsigned> &FilterIds
= MF
->getFilterIds();
98 bool VerboseAsm
= Asm
->OutStreamer
->isVerboseAsm();
101 // Emit the Catch TypeInfos.
102 if (VerboseAsm
&& !TypeInfos
.empty()) {
103 Asm
->OutStreamer
->AddComment(">> Catch TypeInfos <<");
104 Asm
->OutStreamer
->AddBlankLine();
105 Entry
= TypeInfos
.size();
108 for (const GlobalValue
*GV
: reverse(TypeInfos
)) {
110 Asm
->OutStreamer
->AddComment("TypeInfo " + Twine(Entry
--));
111 Asm
->emitTTypeReference(GV
, TTypeEncoding
);
114 Asm
->OutStreamer
->emitLabel(TTBaseLabel
);
116 // Emit the Exception Specifications.
117 if (VerboseAsm
&& !FilterIds
.empty()) {
118 Asm
->OutStreamer
->AddComment(">> Filter TypeInfos <<");
119 Asm
->OutStreamer
->AddBlankLine();
122 for (std::vector
<unsigned>::const_iterator
123 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
124 unsigned TypeID
= *I
;
128 Asm
->OutStreamer
->AddComment("FilterInfo " + Twine(Entry
));
131 Asm
->emitTTypeReference((TypeID
== 0 ? nullptr : TypeInfos
[TypeID
- 1]),