xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp (revision c2de0116c80176829406289da3b79b6e70855ea4)
1  //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
2  //
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
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This file contains support for writing DWARF exception info into asm files.
10  //
11  //===----------------------------------------------------------------------===//
12  
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/Function.h"
18  #include "llvm/MC/MCAsmInfo.h"
19  #include "llvm/MC/MCStreamer.h"
20  using namespace llvm;
21  
22  ARMException::ARMException(AsmPrinter *A) : EHStreamer(A) {}
23  
24  ARMException::~ARMException() = default;
25  
26  ARMTargetStreamer &ARMException::getTargetStreamer() {
27    MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
28    return static_cast<ARMTargetStreamer &>(TS);
29  }
30  
31  void ARMException::beginFunction(const MachineFunction *MF) {
32    if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
33      getTargetStreamer().emitFnStart();
34    // See if we need call frame info.
35    AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
36    assert(CFISecType != AsmPrinter::CFISection::EH &&
37           "non-EH CFI not yet supported in prologue with EHABI lowering");
38  
39    if (CFISecType == AsmPrinter::CFISection::Debug) {
40      if (!hasEmittedCFISections) {
41        if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
42          Asm->OutStreamer->emitCFISections(false, true);
43        hasEmittedCFISections = true;
44      }
45  
46      shouldEmitCFI = true;
47      Asm->OutStreamer->emitCFIStartProc(false);
48    }
49  }
50  
51  void ARMException::markFunctionEnd() {
52    if (shouldEmitCFI)
53      Asm->OutStreamer->emitCFIEndProc();
54  }
55  
56  /// endFunction - Gather and emit post-function exception information.
57  ///
58  void ARMException::endFunction(const MachineFunction *MF) {
59    ARMTargetStreamer &ATS = getTargetStreamer();
60    const Function &F = MF->getFunction();
61    const Function *Per = nullptr;
62    if (F.hasPersonalityFn())
63      Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
64    bool forceEmitPersonality =
65      F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
66      F.needsUnwindTableEntry();
67    bool shouldEmitPersonality = forceEmitPersonality ||
68      !MF->getLandingPads().empty();
69    if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
70        !shouldEmitPersonality)
71      ATS.emitCantUnwind();
72    else if (shouldEmitPersonality) {
73      // Emit references to personality.
74      if (Per) {
75        MCSymbol *PerSym = Asm->getSymbol(Per);
76        ATS.emitPersonality(PerSym);
77      }
78  
79      // Emit .handlerdata directive.
80      ATS.emitHandlerData();
81  
82      // Emit actual exception table
83      emitExceptionTable();
84    }
85  
86    if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
87      ATS.emitFnEnd();
88  }
89  
90  void ARMException::emitTypeInfos(unsigned TTypeEncoding,
91                                   MCSymbol *TTBaseLabel) {
92    const MachineFunction *MF = Asm->MF;
93    const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
94    const std::vector<unsigned> &FilterIds = MF->getFilterIds();
95  
96    bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
97  
98    int Entry = 0;
99    // Emit the Catch TypeInfos.
100    if (VerboseAsm && !TypeInfos.empty()) {
101      Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
102      Asm->OutStreamer->addBlankLine();
103      Entry = TypeInfos.size();
104    }
105  
106    for (const GlobalValue *GV : reverse(TypeInfos)) {
107      if (VerboseAsm)
108        Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
109      Asm->emitTTypeReference(GV, TTypeEncoding);
110    }
111  
112    Asm->OutStreamer->emitLabel(TTBaseLabel);
113  
114    // Emit the Exception Specifications.
115    if (VerboseAsm && !FilterIds.empty()) {
116      Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
117      Asm->OutStreamer->addBlankLine();
118      Entry = 0;
119    }
120    for (std::vector<unsigned>::const_iterator
121           I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
122      unsigned TypeID = *I;
123      if (VerboseAsm) {
124        --Entry;
125        if (TypeID != 0)
126          Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
127      }
128  
129      Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
130                              TTypeEncoding);
131    }
132  }
133