1a7ec2dceSAnton Korobeynikov //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
2a7ec2dceSAnton Korobeynikov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7ec2dceSAnton Korobeynikov //
7a7ec2dceSAnton Korobeynikov //===----------------------------------------------------------------------===//
8a7ec2dceSAnton Korobeynikov //
9a7ec2dceSAnton Korobeynikov // This file contains support for writing DWARF exception info into asm files.
10a7ec2dceSAnton Korobeynikov //
11a7ec2dceSAnton Korobeynikov //===----------------------------------------------------------------------===//
12a7ec2dceSAnton Korobeynikov 
13a7ec2dceSAnton Korobeynikov #include "DwarfException.h"
14ed0881b2SChandler Carruth #include "llvm/ADT/Twine.h"
15a7ec2dceSAnton Korobeynikov #include "llvm/CodeGen/AsmPrinter.h"
16a7ec2dceSAnton Korobeynikov #include "llvm/CodeGen/MachineFunction.h"
17ed98c1b3Sserge-sans-paille #include "llvm/IR/Function.h"
18a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCAsmInfo.h"
19a7ec2dceSAnton Korobeynikov #include "llvm/MC/MCStreamer.h"
20a7ec2dceSAnton Korobeynikov using namespace llvm;
21a7ec2dceSAnton Korobeynikov 
ARMException(AsmPrinter * A)22a6001790SRafael Espindola ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
23a7ec2dceSAnton Korobeynikov 
243a8c5148SKazu Hirata ARMException::~ARMException() = default;
25a7ec2dceSAnton Korobeynikov 
getTargetStreamer()26a17151adSRafael Espindola ARMTargetStreamer &ARMException::getTargetStreamer() {
279ff69c8fSLang Hames   MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
28a17151adSRafael Espindola   return static_cast<ARMTargetStreamer &>(TS);
29a17151adSRafael Espindola }
30a17151adSRafael Espindola 
beginFunction(const MachineFunction * MF)31119f3073STimur Iskhodzhanov void ARMException::beginFunction(const MachineFunction *MF) {
323c10817bSJoerg Sonnenberger   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
33a17151adSRafael Espindola     getTargetStreamer().emitFnStart();
34f6830f47SArtyom Skrobov   // See if we need call frame info.
3563cfab4fSRamNalamothu   AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
3663cfab4fSRamNalamothu   assert(CFISecType != AsmPrinter::CFISection::EH &&
37f6830f47SArtyom Skrobov          "non-EH CFI not yet supported in prologue with EHABI lowering");
387b83732aSJoerg Sonnenberger 
3963cfab4fSRamNalamothu   if (CFISecType == AsmPrinter::CFISection::Debug) {
407b83732aSJoerg Sonnenberger     if (!hasEmittedCFISections) {
4163cfab4fSRamNalamothu       if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
42bcd24b2dSFangrui Song         Asm->OutStreamer->emitCFISections(false, true);
437b83732aSJoerg Sonnenberger       hasEmittedCFISections = true;
447b83732aSJoerg Sonnenberger     }
457b83732aSJoerg Sonnenberger 
46f6830f47SArtyom Skrobov     shouldEmitCFI = true;
47bcd24b2dSFangrui Song     Asm->OutStreamer->emitCFIStartProc(false);
48f6830f47SArtyom Skrobov   }
49a7ec2dceSAnton Korobeynikov }
50a7ec2dceSAnton Korobeynikov 
51119f3073STimur Iskhodzhanov /// endFunction - Gather and emit post-function exception information.
52a7ec2dceSAnton Korobeynikov ///
endFunction(const MachineFunction * MF)53a6001790SRafael Espindola void ARMException::endFunction(const MachineFunction *MF) {
54a17151adSRafael Espindola   ARMTargetStreamer &ATS = getTargetStreamer();
55f1caa283SMatthias Braun   const Function &F = MF->getFunction();
56aff703a2SKeno Fischer   const Function *Per = nullptr;
57f1caa283SMatthias Braun   if (F.hasPersonalityFn())
58f1caa283SMatthias Braun     Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
59aff703a2SKeno Fischer   bool forceEmitPersonality =
60f1caa283SMatthias Braun     F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
61f1caa283SMatthias Braun     F.needsUnwindTableEntry();
62aff703a2SKeno Fischer   bool shouldEmitPersonality = forceEmitPersonality ||
63d0ee66c2SMatthias Braun     !MF->getLandingPads().empty();
64f1caa283SMatthias Braun   if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
65aff703a2SKeno Fischer       !shouldEmitPersonality)
66a17151adSRafael Espindola     ATS.emitCantUnwind();
67aff703a2SKeno Fischer   else if (shouldEmitPersonality) {
68a7ec2dceSAnton Korobeynikov     // Emit references to personality.
69aff703a2SKeno Fischer     if (Per) {
70aff703a2SKeno Fischer       MCSymbol *PerSym = Asm->getSymbol(Per);
71a17151adSRafael Espindola       ATS.emitPersonality(PerSym);
72a7ec2dceSAnton Korobeynikov     }
73a7ec2dceSAnton Korobeynikov 
74b619a413SAnton Korobeynikov     // Emit .handlerdata directive.
75a17151adSRafael Espindola     ATS.emitHandlerData();
76a7ec2dceSAnton Korobeynikov 
77a7ec2dceSAnton Korobeynikov     // Emit actual exception table
788076cab0SSaleem Abdulrasool     emitExceptionTable();
79a7ec2dceSAnton Korobeynikov   }
80a7ec2dceSAnton Korobeynikov 
813c10817bSJoerg Sonnenberger   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
82a17151adSRafael Espindola     ATS.emitFnEnd();
83a7ec2dceSAnton Korobeynikov }
84f65a638dSAnton Korobeynikov 
emitTypeInfos(unsigned TTypeEncoding,MCSymbol * TTBaseLabel)85d09b4169SRafael Espindola void ARMException::emitTypeInfos(unsigned TTypeEncoding,
86d09b4169SRafael Espindola                                  MCSymbol *TTBaseLabel) {
87d0ee66c2SMatthias Braun   const MachineFunction *MF = Asm->MF;
88d0ee66c2SMatthias Braun   const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
89d0ee66c2SMatthias Braun   const std::vector<unsigned> &FilterIds = MF->getFilterIds();
90f65a638dSAnton Korobeynikov 
919ff69c8fSLang Hames   bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
92f65a638dSAnton Korobeynikov 
93f65a638dSAnton Korobeynikov   int Entry = 0;
94f65a638dSAnton Korobeynikov   // Emit the Catch TypeInfos.
95f65a638dSAnton Korobeynikov   if (VerboseAsm && !TypeInfos.empty()) {
969ff69c8fSLang Hames     Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
97*15d82c62SFangrui Song     Asm->OutStreamer->addBlankLine();
98f65a638dSAnton Korobeynikov     Entry = TypeInfos.size();
99f65a638dSAnton Korobeynikov   }
100f65a638dSAnton Korobeynikov 
101f3159f3cSPete Cooper   for (const GlobalValue *GV : reverse(TypeInfos)) {
102f65a638dSAnton Korobeynikov     if (VerboseAsm)
1039ff69c8fSLang Hames       Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
1041d49eb00SFangrui Song     Asm->emitTTypeReference(GV, TTypeEncoding);
105f65a638dSAnton Korobeynikov   }
106f65a638dSAnton Korobeynikov 
1076d2d589bSFangrui Song   Asm->OutStreamer->emitLabel(TTBaseLabel);
108d09b4169SRafael Espindola 
109f65a638dSAnton Korobeynikov   // Emit the Exception Specifications.
110f65a638dSAnton Korobeynikov   if (VerboseAsm && !FilterIds.empty()) {
1119ff69c8fSLang Hames     Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
112*15d82c62SFangrui Song     Asm->OutStreamer->addBlankLine();
113f65a638dSAnton Korobeynikov     Entry = 0;
114f65a638dSAnton Korobeynikov   }
115f65a638dSAnton Korobeynikov   for (std::vector<unsigned>::const_iterator
116f65a638dSAnton Korobeynikov          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
117f65a638dSAnton Korobeynikov     unsigned TypeID = *I;
118f65a638dSAnton Korobeynikov     if (VerboseAsm) {
119f65a638dSAnton Korobeynikov       --Entry;
120f65a638dSAnton Korobeynikov       if (TypeID != 0)
1219ff69c8fSLang Hames         Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
122f65a638dSAnton Korobeynikov     }
123f65a638dSAnton Korobeynikov 
1241d49eb00SFangrui Song     Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
125097b0e9dSAnton Korobeynikov                             TTypeEncoding);
126f65a638dSAnton Korobeynikov   }
127f65a638dSAnton Korobeynikov }
128