xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
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"
170b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
180b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
190b57cec5SDimitry Andric #include "llvm/IR/Module.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
250b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
260b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric ARMException::~ARMException() {}
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric ARMTargetStreamer &ARMException::getTargetStreamer() {
340b57cec5SDimitry Andric   MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
350b57cec5SDimitry Andric   return static_cast<ARMTargetStreamer &>(TS);
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric void ARMException::beginFunction(const MachineFunction *MF) {
390b57cec5SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
400b57cec5SDimitry Andric     getTargetStreamer().emitFnStart();
410b57cec5SDimitry Andric   // See if we need call frame info.
42*fe6060f1SDimitry Andric   AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
43*fe6060f1SDimitry Andric   assert(CFISecType != AsmPrinter::CFISection::EH &&
440b57cec5SDimitry Andric          "non-EH CFI not yet supported in prologue with EHABI lowering");
450b57cec5SDimitry Andric 
46*fe6060f1SDimitry Andric   if (CFISecType == AsmPrinter::CFISection::Debug) {
470b57cec5SDimitry Andric     if (!hasEmittedCFISections) {
48*fe6060f1SDimitry Andric       if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
495ffd83dbSDimitry Andric         Asm->OutStreamer->emitCFISections(false, true);
500b57cec5SDimitry Andric       hasEmittedCFISections = true;
510b57cec5SDimitry Andric     }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric     shouldEmitCFI = true;
545ffd83dbSDimitry Andric     Asm->OutStreamer->emitCFIStartProc(false);
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric /// endFunction - Gather and emit post-function exception information.
590b57cec5SDimitry Andric ///
600b57cec5SDimitry Andric void ARMException::endFunction(const MachineFunction *MF) {
610b57cec5SDimitry Andric   ARMTargetStreamer &ATS = getTargetStreamer();
620b57cec5SDimitry Andric   const Function &F = MF->getFunction();
630b57cec5SDimitry Andric   const Function *Per = nullptr;
640b57cec5SDimitry Andric   if (F.hasPersonalityFn())
650b57cec5SDimitry Andric     Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
660b57cec5SDimitry Andric   bool forceEmitPersonality =
670b57cec5SDimitry Andric     F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
680b57cec5SDimitry Andric     F.needsUnwindTableEntry();
690b57cec5SDimitry Andric   bool shouldEmitPersonality = forceEmitPersonality ||
700b57cec5SDimitry Andric     !MF->getLandingPads().empty();
710b57cec5SDimitry Andric   if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
720b57cec5SDimitry Andric       !shouldEmitPersonality)
730b57cec5SDimitry Andric     ATS.emitCantUnwind();
740b57cec5SDimitry Andric   else if (shouldEmitPersonality) {
750b57cec5SDimitry Andric     // Emit references to personality.
760b57cec5SDimitry Andric     if (Per) {
770b57cec5SDimitry Andric       MCSymbol *PerSym = Asm->getSymbol(Per);
785ffd83dbSDimitry Andric       Asm->OutStreamer->emitSymbolAttribute(PerSym, MCSA_Global);
790b57cec5SDimitry Andric       ATS.emitPersonality(PerSym);
800b57cec5SDimitry Andric     }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric     // Emit .handlerdata directive.
830b57cec5SDimitry Andric     ATS.emitHandlerData();
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric     // Emit actual exception table
860b57cec5SDimitry Andric     emitExceptionTable();
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
900b57cec5SDimitry Andric     ATS.emitFnEnd();
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric void ARMException::emitTypeInfos(unsigned TTypeEncoding,
940b57cec5SDimitry Andric                                  MCSymbol *TTBaseLabel) {
950b57cec5SDimitry Andric   const MachineFunction *MF = Asm->MF;
960b57cec5SDimitry Andric   const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
970b57cec5SDimitry Andric   const std::vector<unsigned> &FilterIds = MF->getFilterIds();
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   int Entry = 0;
1020b57cec5SDimitry Andric   // Emit the Catch TypeInfos.
1030b57cec5SDimitry Andric   if (VerboseAsm && !TypeInfos.empty()) {
1040b57cec5SDimitry Andric     Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
1050b57cec5SDimitry Andric     Asm->OutStreamer->AddBlankLine();
1060b57cec5SDimitry Andric     Entry = TypeInfos.size();
1070b57cec5SDimitry Andric   }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   for (const GlobalValue *GV : reverse(TypeInfos)) {
1100b57cec5SDimitry Andric     if (VerboseAsm)
1110b57cec5SDimitry Andric       Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
1125ffd83dbSDimitry Andric     Asm->emitTTypeReference(GV, TTypeEncoding);
1130b57cec5SDimitry Andric   }
1140b57cec5SDimitry Andric 
1155ffd83dbSDimitry Andric   Asm->OutStreamer->emitLabel(TTBaseLabel);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   // Emit the Exception Specifications.
1180b57cec5SDimitry Andric   if (VerboseAsm && !FilterIds.empty()) {
1190b57cec5SDimitry Andric     Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
1200b57cec5SDimitry Andric     Asm->OutStreamer->AddBlankLine();
1210b57cec5SDimitry Andric     Entry = 0;
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric   for (std::vector<unsigned>::const_iterator
1240b57cec5SDimitry Andric          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
1250b57cec5SDimitry Andric     unsigned TypeID = *I;
1260b57cec5SDimitry Andric     if (VerboseAsm) {
1270b57cec5SDimitry Andric       --Entry;
1280b57cec5SDimitry Andric       if (TypeID != 0)
1290b57cec5SDimitry Andric         Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
1300b57cec5SDimitry Andric     }
1310b57cec5SDimitry Andric 
1325ffd83dbSDimitry Andric     Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
1330b57cec5SDimitry Andric                             TTypeEncoding);
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric }
136