xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains support for writing DWARF exception info into asm files.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "DwarfException.h"
140b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
1781ad6265SDimitry Andric #include "llvm/IR/Function.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
200b57cec5SDimitry Andric using namespace llvm;
210b57cec5SDimitry Andric 
ARMException(AsmPrinter * A)22*bdd1243dSDimitry Andric ARMException::ARMException(AsmPrinter *A) : EHStreamer(A) {}
230b57cec5SDimitry Andric 
2481ad6265SDimitry Andric ARMException::~ARMException() = default;
250b57cec5SDimitry Andric 
getTargetStreamer()260b57cec5SDimitry Andric ARMTargetStreamer &ARMException::getTargetStreamer() {
270b57cec5SDimitry Andric   MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
280b57cec5SDimitry Andric   return static_cast<ARMTargetStreamer &>(TS);
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric 
beginFunction(const MachineFunction * MF)310b57cec5SDimitry Andric void ARMException::beginFunction(const MachineFunction *MF) {
320b57cec5SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
330b57cec5SDimitry Andric     getTargetStreamer().emitFnStart();
340b57cec5SDimitry Andric   // See if we need call frame info.
35fe6060f1SDimitry Andric   AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
36fe6060f1SDimitry Andric   assert(CFISecType != AsmPrinter::CFISection::EH &&
370b57cec5SDimitry Andric          "non-EH CFI not yet supported in prologue with EHABI lowering");
380b57cec5SDimitry Andric 
39fe6060f1SDimitry Andric   if (CFISecType == AsmPrinter::CFISection::Debug) {
400b57cec5SDimitry Andric     if (!hasEmittedCFISections) {
41fe6060f1SDimitry Andric       if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
425ffd83dbSDimitry Andric         Asm->OutStreamer->emitCFISections(false, true);
430b57cec5SDimitry Andric       hasEmittedCFISections = true;
440b57cec5SDimitry Andric     }
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric     shouldEmitCFI = true;
475ffd83dbSDimitry Andric     Asm->OutStreamer->emitCFIStartProc(false);
480b57cec5SDimitry Andric   }
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
markFunctionEnd()51*bdd1243dSDimitry Andric void ARMException::markFunctionEnd() {
52*bdd1243dSDimitry Andric   if (shouldEmitCFI)
53*bdd1243dSDimitry Andric     Asm->OutStreamer->emitCFIEndProc();
54*bdd1243dSDimitry Andric }
55*bdd1243dSDimitry Andric 
560b57cec5SDimitry Andric /// endFunction - Gather and emit post-function exception information.
570b57cec5SDimitry Andric ///
endFunction(const MachineFunction * MF)580b57cec5SDimitry Andric void ARMException::endFunction(const MachineFunction *MF) {
590b57cec5SDimitry Andric   ARMTargetStreamer &ATS = getTargetStreamer();
600b57cec5SDimitry Andric   const Function &F = MF->getFunction();
610b57cec5SDimitry Andric   const Function *Per = nullptr;
620b57cec5SDimitry Andric   if (F.hasPersonalityFn())
630b57cec5SDimitry Andric     Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
640b57cec5SDimitry Andric   bool forceEmitPersonality =
650b57cec5SDimitry Andric     F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
660b57cec5SDimitry Andric     F.needsUnwindTableEntry();
670b57cec5SDimitry Andric   bool shouldEmitPersonality = forceEmitPersonality ||
680b57cec5SDimitry Andric     !MF->getLandingPads().empty();
690b57cec5SDimitry Andric   if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
700b57cec5SDimitry Andric       !shouldEmitPersonality)
710b57cec5SDimitry Andric     ATS.emitCantUnwind();
720b57cec5SDimitry Andric   else if (shouldEmitPersonality) {
730b57cec5SDimitry Andric     // Emit references to personality.
740b57cec5SDimitry Andric     if (Per) {
750b57cec5SDimitry Andric       MCSymbol *PerSym = Asm->getSymbol(Per);
760b57cec5SDimitry Andric       ATS.emitPersonality(PerSym);
770b57cec5SDimitry Andric     }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric     // Emit .handlerdata directive.
800b57cec5SDimitry Andric     ATS.emitHandlerData();
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric     // Emit actual exception table
830b57cec5SDimitry Andric     emitExceptionTable();
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
870b57cec5SDimitry Andric     ATS.emitFnEnd();
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
emitTypeInfos(unsigned TTypeEncoding,MCSymbol * TTBaseLabel)900b57cec5SDimitry Andric void ARMException::emitTypeInfos(unsigned TTypeEncoding,
910b57cec5SDimitry Andric                                  MCSymbol *TTBaseLabel) {
920b57cec5SDimitry Andric   const MachineFunction *MF = Asm->MF;
930b57cec5SDimitry Andric   const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
940b57cec5SDimitry Andric   const std::vector<unsigned> &FilterIds = MF->getFilterIds();
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   int Entry = 0;
990b57cec5SDimitry Andric   // Emit the Catch TypeInfos.
1000b57cec5SDimitry Andric   if (VerboseAsm && !TypeInfos.empty()) {
1010b57cec5SDimitry Andric     Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
10281ad6265SDimitry Andric     Asm->OutStreamer->addBlankLine();
1030b57cec5SDimitry Andric     Entry = TypeInfos.size();
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   for (const GlobalValue *GV : reverse(TypeInfos)) {
1070b57cec5SDimitry Andric     if (VerboseAsm)
1080b57cec5SDimitry Andric       Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
1095ffd83dbSDimitry Andric     Asm->emitTTypeReference(GV, TTypeEncoding);
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
1125ffd83dbSDimitry Andric   Asm->OutStreamer->emitLabel(TTBaseLabel);
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   // Emit the Exception Specifications.
1150b57cec5SDimitry Andric   if (VerboseAsm && !FilterIds.empty()) {
1160b57cec5SDimitry Andric     Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
11781ad6265SDimitry Andric     Asm->OutStreamer->addBlankLine();
1180b57cec5SDimitry Andric     Entry = 0;
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric   for (std::vector<unsigned>::const_iterator
1210b57cec5SDimitry Andric          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
1220b57cec5SDimitry Andric     unsigned TypeID = *I;
1230b57cec5SDimitry Andric     if (VerboseAsm) {
1240b57cec5SDimitry Andric       --Entry;
1250b57cec5SDimitry Andric       if (TypeID != 0)
1260b57cec5SDimitry Andric         Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
1270b57cec5SDimitry Andric     }
1280b57cec5SDimitry Andric 
1295ffd83dbSDimitry Andric     Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
1300b57cec5SDimitry Andric                             TTypeEncoding);
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric }
133