ARMException.cpp 4.3 KB

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