ARMException.cpp 4.4 KB

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