xref: /src/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
16b943ff3SDimitry Andric //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
26b943ff3SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66b943ff3SDimitry Andric //
76b943ff3SDimitry Andric //===----------------------------------------------------------------------===//
86b943ff3SDimitry Andric //
96b943ff3SDimitry Andric // This file contains support for writing DWARF exception info into asm files.
106b943ff3SDimitry Andric //
116b943ff3SDimitry Andric //===----------------------------------------------------------------------===//
126b943ff3SDimitry Andric 
136b943ff3SDimitry Andric #include "DwarfException.h"
144a16efa3SDimitry Andric #include "llvm/ADT/Twine.h"
156b943ff3SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
166b943ff3SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
17145449b1SDimitry Andric #include "llvm/IR/Function.h"
186b943ff3SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
196b943ff3SDimitry Andric #include "llvm/MC/MCStreamer.h"
206b943ff3SDimitry Andric using namespace llvm;
216b943ff3SDimitry Andric 
ARMException(AsmPrinter * A)22e3b55780SDimitry Andric ARMException::ARMException(AsmPrinter *A) : EHStreamer(A) {}
236b943ff3SDimitry Andric 
24145449b1SDimitry Andric ARMException::~ARMException() = default;
256b943ff3SDimitry Andric 
getTargetStreamer()26f8af5cf6SDimitry Andric ARMTargetStreamer &ARMException::getTargetStreamer() {
275a5ac124SDimitry Andric   MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
28f8af5cf6SDimitry Andric   return static_cast<ARMTargetStreamer &>(TS);
29f8af5cf6SDimitry Andric }
30f8af5cf6SDimitry Andric 
beginFunction(const MachineFunction * MF)315ca98fd9SDimitry Andric void ARMException::beginFunction(const MachineFunction *MF) {
325ca98fd9SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
33f8af5cf6SDimitry Andric     getTargetStreamer().emitFnStart();
345ca98fd9SDimitry Andric   // See if we need call frame info.
35344a3780SDimitry Andric   AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
36344a3780SDimitry Andric   assert(CFISecType != AsmPrinter::CFISection::EH &&
375ca98fd9SDimitry Andric          "non-EH CFI not yet supported in prologue with EHABI lowering");
38b915e9e0SDimitry Andric 
39344a3780SDimitry Andric   if (CFISecType == AsmPrinter::CFISection::Debug) {
40b915e9e0SDimitry Andric     if (!hasEmittedCFISections) {
41344a3780SDimitry Andric       if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
42cfca06d7SDimitry Andric         Asm->OutStreamer->emitCFISections(false, true);
43b915e9e0SDimitry Andric       hasEmittedCFISections = true;
44b915e9e0SDimitry Andric     }
45b915e9e0SDimitry Andric 
465ca98fd9SDimitry Andric     shouldEmitCFI = true;
47cfca06d7SDimitry Andric     Asm->OutStreamer->emitCFIStartProc(false);
485ca98fd9SDimitry Andric   }
496b943ff3SDimitry Andric }
506b943ff3SDimitry Andric 
markFunctionEnd()51e3b55780SDimitry Andric void ARMException::markFunctionEnd() {
52e3b55780SDimitry Andric   if (shouldEmitCFI)
53e3b55780SDimitry Andric     Asm->OutStreamer->emitCFIEndProc();
54e3b55780SDimitry Andric }
55e3b55780SDimitry Andric 
565ca98fd9SDimitry Andric /// endFunction - Gather and emit post-function exception information.
576b943ff3SDimitry Andric ///
endFunction(const MachineFunction * MF)585a5ac124SDimitry Andric void ARMException::endFunction(const MachineFunction *MF) {
59f8af5cf6SDimitry Andric   ARMTargetStreamer &ATS = getTargetStreamer();
60044eb2f6SDimitry Andric   const Function &F = MF->getFunction();
61ee8648bdSDimitry Andric   const Function *Per = nullptr;
62044eb2f6SDimitry Andric   if (F.hasPersonalityFn())
63044eb2f6SDimitry Andric     Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
64ee8648bdSDimitry Andric   bool forceEmitPersonality =
65044eb2f6SDimitry Andric     F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
66044eb2f6SDimitry Andric     F.needsUnwindTableEntry();
67ee8648bdSDimitry Andric   bool shouldEmitPersonality = forceEmitPersonality ||
68b915e9e0SDimitry Andric     !MF->getLandingPads().empty();
69044eb2f6SDimitry Andric   if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
70ee8648bdSDimitry Andric       !shouldEmitPersonality)
71f8af5cf6SDimitry Andric     ATS.emitCantUnwind();
72ee8648bdSDimitry Andric   else if (shouldEmitPersonality) {
736b943ff3SDimitry Andric     // Emit references to personality.
74ee8648bdSDimitry Andric     if (Per) {
75ee8648bdSDimitry Andric       MCSymbol *PerSym = Asm->getSymbol(Per);
76f8af5cf6SDimitry Andric       ATS.emitPersonality(PerSym);
776b943ff3SDimitry Andric     }
786b943ff3SDimitry Andric 
794a16efa3SDimitry Andric     // Emit .handlerdata directive.
80f8af5cf6SDimitry Andric     ATS.emitHandlerData();
816b943ff3SDimitry Andric 
826b943ff3SDimitry Andric     // Emit actual exception table
835ca98fd9SDimitry Andric     emitExceptionTable();
8463faed5bSDimitry Andric   }
856b943ff3SDimitry Andric 
865ca98fd9SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
87f8af5cf6SDimitry Andric     ATS.emitFnEnd();
886b943ff3SDimitry Andric }
894a16efa3SDimitry Andric 
emitTypeInfos(unsigned TTypeEncoding,MCSymbol * TTBaseLabel)90eb11fae6SDimitry Andric void ARMException::emitTypeInfos(unsigned TTypeEncoding,
91eb11fae6SDimitry Andric                                  MCSymbol *TTBaseLabel) {
92b915e9e0SDimitry Andric   const MachineFunction *MF = Asm->MF;
93b915e9e0SDimitry Andric   const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
94b915e9e0SDimitry Andric   const std::vector<unsigned> &FilterIds = MF->getFilterIds();
954a16efa3SDimitry Andric 
965a5ac124SDimitry Andric   bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
974a16efa3SDimitry Andric 
984a16efa3SDimitry Andric   int Entry = 0;
994a16efa3SDimitry Andric   // Emit the Catch TypeInfos.
1004a16efa3SDimitry Andric   if (VerboseAsm && !TypeInfos.empty()) {
1015a5ac124SDimitry Andric     Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
102145449b1SDimitry Andric     Asm->OutStreamer->addBlankLine();
1034a16efa3SDimitry Andric     Entry = TypeInfos.size();
1044a16efa3SDimitry Andric   }
1054a16efa3SDimitry Andric 
106dd58ef01SDimitry Andric   for (const GlobalValue *GV : reverse(TypeInfos)) {
1074a16efa3SDimitry Andric     if (VerboseAsm)
1085a5ac124SDimitry Andric       Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
109cfca06d7SDimitry Andric     Asm->emitTTypeReference(GV, TTypeEncoding);
1104a16efa3SDimitry Andric   }
1114a16efa3SDimitry Andric 
112cfca06d7SDimitry Andric   Asm->OutStreamer->emitLabel(TTBaseLabel);
113eb11fae6SDimitry Andric 
1144a16efa3SDimitry Andric   // Emit the Exception Specifications.
1154a16efa3SDimitry Andric   if (VerboseAsm && !FilterIds.empty()) {
1165a5ac124SDimitry Andric     Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
117145449b1SDimitry Andric     Asm->OutStreamer->addBlankLine();
1184a16efa3SDimitry Andric     Entry = 0;
1194a16efa3SDimitry Andric   }
1204a16efa3SDimitry Andric   for (std::vector<unsigned>::const_iterator
1214a16efa3SDimitry Andric          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
1224a16efa3SDimitry Andric     unsigned TypeID = *I;
1234a16efa3SDimitry Andric     if (VerboseAsm) {
1244a16efa3SDimitry Andric       --Entry;
1254a16efa3SDimitry Andric       if (TypeID != 0)
1265a5ac124SDimitry Andric         Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
1274a16efa3SDimitry Andric     }
1284a16efa3SDimitry Andric 
129cfca06d7SDimitry Andric     Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
1304a16efa3SDimitry Andric                             TTypeEncoding);
1314a16efa3SDimitry Andric   }
1324a16efa3SDimitry Andric }
133