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::CFIMoveType MoveType
= Asm
->needsCFIMoves();
43 assert(MoveType
!= AsmPrinter::CFI_M_EH
&&
44 "non-EH CFI not yet supported in prologue with EHABI lowering");
46 if (MoveType
== AsmPrinter::CFI_M_Debug
) {
47 if (!hasEmittedCFISections
) {
48 if (Asm
->needsOnlyDebugCFIMoves())
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 Asm
->OutStreamer
->EmitSymbolAttribute(PerSym
, MCSA_Global
);
79 ATS
.emitPersonality(PerSym
);
82 // Emit .handlerdata directive.
83 ATS
.emitHandlerData();
85 // Emit actual exception table
89 if (Asm
->MAI
->getExceptionHandlingType() == ExceptionHandling::ARM
)
93 void ARMException::emitTypeInfos(unsigned TTypeEncoding
,
94 MCSymbol
*TTBaseLabel
) {
95 const MachineFunction
*MF
= Asm
->MF
;
96 const std::vector
<const GlobalValue
*> &TypeInfos
= MF
->getTypeInfos();
97 const std::vector
<unsigned> &FilterIds
= MF
->getFilterIds();
99 bool VerboseAsm
= Asm
->OutStreamer
->isVerboseAsm();
102 // Emit the Catch TypeInfos.
103 if (VerboseAsm
&& !TypeInfos
.empty()) {
104 Asm
->OutStreamer
->AddComment(">> Catch TypeInfos <<");
105 Asm
->OutStreamer
->AddBlankLine();
106 Entry
= TypeInfos
.size();
109 for (const GlobalValue
*GV
: reverse(TypeInfos
)) {
111 Asm
->OutStreamer
->AddComment("TypeInfo " + Twine(Entry
--));
112 Asm
->EmitTTypeReference(GV
, TTypeEncoding
);
115 Asm
->OutStreamer
->EmitLabel(TTBaseLabel
);
117 // Emit the Exception Specifications.
118 if (VerboseAsm
&& !FilterIds
.empty()) {
119 Asm
->OutStreamer
->AddComment(">> Filter TypeInfos <<");
120 Asm
->OutStreamer
->AddBlankLine();
123 for (std::vector
<unsigned>::const_iterator
124 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
125 unsigned TypeID
= *I
;
129 Asm
->OutStreamer
->AddComment("FilterInfo " + Twine(Entry
));
132 Asm
->EmitTTypeReference((TypeID
== 0 ? nullptr : TypeInfos
[TypeID
- 1]),