DwarfCFIException.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf 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/MC/MachineLocation.h"
  31. #include "llvm/Support/Dwarf.h"
  32. #include "llvm/Support/ErrorHandling.h"
  33. #include "llvm/Support/FormattedStream.h"
  34. #include "llvm/Target/TargetFrameLowering.h"
  35. #include "llvm/Target/TargetLoweringObjectFile.h"
  36. #include "llvm/Target/TargetMachine.h"
  37. #include "llvm/Target/TargetOptions.h"
  38. #include "llvm/Target/TargetRegisterInfo.h"
  39. using namespace llvm;
  40. DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A)
  41. : EHStreamer(A), shouldEmitCFI(false) {}
  42. void DwarfCFIExceptionBase::markFunctionEnd() {
  43. if (shouldEmitCFI)
  44. Asm->OutStreamer->EmitCFIEndProc();
  45. if (MMI->getLandingPads().empty())
  46. return;
  47. // Map all labels and get rid of any dead landing pads.
  48. MMI->TidyLandingPads();
  49. }
  50. DwarfCFIException::DwarfCFIException(AsmPrinter *A)
  51. : DwarfCFIExceptionBase(A), shouldEmitPersonality(false),
  52. shouldEmitLSDA(false), shouldEmitMoves(false),
  53. moveTypeModule(AsmPrinter::CFI_M_None) {}
  54. DwarfCFIException::~DwarfCFIException() {}
  55. /// endModule - Emit all exception information that should come after the
  56. /// content.
  57. void DwarfCFIException::endModule() {
  58. if (moveTypeModule == AsmPrinter::CFI_M_Debug)
  59. Asm->OutStreamer->EmitCFISections(false, true);
  60. // SjLj uses this pass and it doesn't need this info.
  61. if (!Asm->MAI->usesCFIForEH())
  62. return;
  63. const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  64. unsigned PerEncoding = TLOF.getPersonalityEncoding();
  65. if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
  66. return;
  67. // Emit references to all used personality functions
  68. const std::vector<const Function*> &Personalities = MMI->getPersonalities();
  69. for (size_t i = 0, e = Personalities.size(); i != e; ++i) {
  70. if (!Personalities[i])
  71. continue;
  72. MCSymbol *Sym = Asm->getSymbol(Personalities[i]);
  73. TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->TM, Sym);
  74. }
  75. }
  76. void DwarfCFIException::beginFunction(const MachineFunction *MF) {
  77. shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
  78. const Function *F = MF->getFunction();
  79. // If any landing pads survive, we need an EH table.
  80. bool hasLandingPads = !MMI->getLandingPads().empty();
  81. // See if we need frame move info.
  82. AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
  83. if (MoveType == AsmPrinter::CFI_M_EH ||
  84. (MoveType == AsmPrinter::CFI_M_Debug &&
  85. moveTypeModule == AsmPrinter::CFI_M_None))
  86. moveTypeModule = MoveType;
  87. shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
  88. const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  89. unsigned PerEncoding = TLOF.getPersonalityEncoding();
  90. const Function *Per = nullptr;
  91. if (F->hasPersonalityFn())
  92. Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
  93. assert(!MMI->getPersonality() || Per == MMI->getPersonality());
  94. // Emit a personality function even when there are no landing pads
  95. bool forceEmitPersonality =
  96. // ...if a personality function is explicitly specified
  97. F->hasPersonalityFn() &&
  98. // ... and it's not known to be a noop in the absence of invokes
  99. !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
  100. // ... and we're not explicitly asked not to emit it
  101. F->needsUnwindTableEntry();
  102. shouldEmitPersonality =
  103. (forceEmitPersonality ||
  104. (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
  105. Per;
  106. unsigned LSDAEncoding = TLOF.getLSDAEncoding();
  107. shouldEmitLSDA = shouldEmitPersonality &&
  108. LSDAEncoding != dwarf::DW_EH_PE_omit;
  109. shouldEmitCFI = shouldEmitPersonality || shouldEmitMoves;
  110. if (!shouldEmitCFI)
  111. return;
  112. Asm->OutStreamer->EmitCFIStartProc(/*IsSimple=*/false);
  113. // Indicate personality routine, if any.
  114. if (!shouldEmitPersonality)
  115. return;
  116. // If we are forced to emit this personality, make sure to record
  117. // it because it might not appear in any landingpad
  118. if (forceEmitPersonality)
  119. MMI->addPersonality(Per);
  120. const MCSymbol *Sym =
  121. TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
  122. Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
  123. // Provide LSDA information.
  124. if (!shouldEmitLSDA)
  125. return;
  126. Asm->OutStreamer->EmitCFILsda(Asm->getCurExceptionSym(), LSDAEncoding);
  127. }
  128. /// endFunction - Gather and emit post-function exception information.
  129. ///
  130. void DwarfCFIException::endFunction(const MachineFunction *) {
  131. if (!shouldEmitPersonality)
  132. return;
  133. emitExceptionTable();
  134. }