2
0

ARMException.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file contains support for writing DWARF exception info into asm files.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "DwarfException.h"
  14. #include "llvm/ADT/SmallString.h"
  15. #include "llvm/ADT/StringExtras.h"
  16. #include "llvm/ADT/Twine.h"
  17. #include "llvm/CodeGen/AsmPrinter.h"
  18. #include "llvm/CodeGen/MachineFrameInfo.h"
  19. #include "llvm/CodeGen/MachineFunction.h"
  20. #include "llvm/CodeGen/MachineModuleInfo.h"
  21. #include "llvm/IR/DataLayout.h"
  22. #include "llvm/IR/Mangler.h"
  23. #include "llvm/IR/Module.h"
  24. #include "llvm/MC/MCAsmInfo.h"
  25. #include "llvm/MC/MCContext.h"
  26. #include "llvm/MC/MCExpr.h"
  27. #include "llvm/MC/MCSection.h"
  28. #include "llvm/MC/MCStreamer.h"
  29. #include "llvm/MC/MCSymbol.h"
  30. #include "llvm/Support/CommandLine.h"
  31. #include "llvm/Support/Dwarf.h"
  32. #include "llvm/Support/FormattedStream.h"
  33. #include "llvm/Target/TargetFrameLowering.h"
  34. #include "llvm/Target/TargetOptions.h"
  35. #include "llvm/Target/TargetRegisterInfo.h"
  36. using namespace llvm;
  37. ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
  38. ARMException::~ARMException() {}
  39. ARMTargetStreamer &ARMException::getTargetStreamer() {
  40. MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer();
  41. return static_cast<ARMTargetStreamer &>(TS);
  42. }
  43. /// endModule - Emit all exception information that should come after the
  44. /// content.
  45. void ARMException::endModule() {
  46. if (shouldEmitCFI)
  47. Asm->OutStreamer->EmitCFISections(false, true);
  48. }
  49. void ARMException::beginFunction(const MachineFunction *MF) {
  50. if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
  51. getTargetStreamer().emitFnStart();
  52. // See if we need call frame info.
  53. AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
  54. assert(MoveType != AsmPrinter::CFI_M_EH &&
  55. "non-EH CFI not yet supported in prologue with EHABI lowering");
  56. if (MoveType == AsmPrinter::CFI_M_Debug) {
  57. shouldEmitCFI = true;
  58. Asm->OutStreamer->EmitCFIStartProc(false);
  59. }
  60. }
  61. /// endFunction - Gather and emit post-function exception information.
  62. ///
  63. void ARMException::endFunction(const MachineFunction *MF) {
  64. ARMTargetStreamer &ATS = getTargetStreamer();
  65. const Function *F = MF->getFunction();
  66. const Function *Per = nullptr;
  67. if (F->hasPersonalityFn())
  68. Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
  69. assert(!MMI->getPersonality() || Per == MMI->getPersonality());
  70. bool forceEmitPersonality =
  71. F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
  72. F->needsUnwindTableEntry();
  73. bool shouldEmitPersonality = forceEmitPersonality ||
  74. !MMI->getLandingPads().empty();
  75. if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
  76. !shouldEmitPersonality)
  77. ATS.emitCantUnwind();
  78. else if (shouldEmitPersonality) {
  79. // Emit references to personality.
  80. if (Per) {
  81. MCSymbol *PerSym = Asm->getSymbol(Per);
  82. Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
  83. ATS.emitPersonality(PerSym);
  84. }
  85. // Emit .handlerdata directive.
  86. ATS.emitHandlerData();
  87. // Emit actual exception table
  88. emitExceptionTable();
  89. }
  90. if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
  91. ATS.emitFnEnd();
  92. }
  93. void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
  94. const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
  95. const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
  96. bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
  97. int Entry = 0;
  98. // Emit the Catch TypeInfos.
  99. if (VerboseAsm && !TypeInfos.empty()) {
  100. Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
  101. Asm->OutStreamer->AddBlankLine();
  102. Entry = TypeInfos.size();
  103. }
  104. for (std::vector<const GlobalValue *>::const_reverse_iterator
  105. I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
  106. const GlobalValue *GV = *I;
  107. if (VerboseAsm)
  108. Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
  109. Asm->EmitTTypeReference(GV, TTypeEncoding);
  110. }
  111. // Emit the Exception Specifications.
  112. if (VerboseAsm && !FilterIds.empty()) {
  113. Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
  114. Asm->OutStreamer->AddBlankLine();
  115. Entry = 0;
  116. }
  117. for (std::vector<unsigned>::const_iterator
  118. I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
  119. unsigned TypeID = *I;
  120. if (VerboseAsm) {
  121. --Entry;
  122. if (TypeID != 0)
  123. Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
  124. }
  125. Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
  126. TTypeEncoding);
  127. }
  128. }