AIXException.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //===-- CodeGen/AsmPrinter/AIXException.cpp - AIX 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 AIX exception info into asm files.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "DwarfException.h"
  13. #include "llvm/CodeGen/AsmPrinter.h"
  14. #include "llvm/CodeGen/MachineModuleInfo.h"
  15. #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
  16. #include "llvm/MC/MCSectionXCOFF.h"
  17. #include "llvm/MC/MCStreamer.h"
  18. #include "llvm/Target/TargetLoweringObjectFile.h"
  19. #include "llvm/Target/TargetMachine.h"
  20. namespace llvm {
  21. AIXException::AIXException(AsmPrinter *A) : EHStreamer(A) {}
  22. void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
  23. const MCSymbol *PerSym) {
  24. // Generate EH Info Table.
  25. // The EH Info Table, aka, 'compat unwind section' on AIX, have the following
  26. // format: struct eh_info_t {
  27. // unsigned version; /* EH info verion 0 */
  28. // #if defined(__64BIT__)
  29. // char _pad[4]; /* padding */
  30. // #endif
  31. // unsigned long lsda; /* Pointer to LSDA */
  32. // unsigned long personality; /* Pointer to the personality routine */
  33. // }
  34. auto *EHInfo =
  35. cast<MCSectionXCOFF>(Asm->getObjFileLowering().getCompactUnwindSection());
  36. if (Asm->TM.getFunctionSections()) {
  37. // If option -ffunction-sections is on, append the function name to the
  38. // name of EH Info Table csect so that each function has its own EH Info
  39. // Table csect. This helps the linker to garbage-collect EH info of unused
  40. // functions.
  41. SmallString<128> NameStr = EHInfo->getName();
  42. raw_svector_ostream(NameStr) << '.' << Asm->MF->getFunction().getName();
  43. EHInfo = Asm->OutContext.getXCOFFSection(NameStr, EHInfo->getKind(),
  44. EHInfo->getCsectProp());
  45. }
  46. Asm->OutStreamer->switchSection(EHInfo);
  47. MCSymbol *EHInfoLabel =
  48. TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF);
  49. Asm->OutStreamer->emitLabel(EHInfoLabel);
  50. // Version number.
  51. Asm->emitInt32(0);
  52. const DataLayout &DL = MMI->getModule()->getDataLayout();
  53. const unsigned PointerSize = DL.getPointerSize();
  54. // Add necessary paddings in 64 bit mode.
  55. Asm->OutStreamer->emitValueToAlignment(Align(PointerSize));
  56. // LSDA location.
  57. Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext),
  58. PointerSize);
  59. // Personality routine.
  60. Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(PerSym, Asm->OutContext),
  61. PointerSize);
  62. }
  63. void AIXException::endFunction(const MachineFunction *MF) {
  64. // There is no easy way to access register information in `AIXException`
  65. // class. when ShouldEmitEHBlock is false and VRs are saved, A dumy eh info
  66. // table are emitted in PPCAIXAsmPrinter::emitFunctionBodyEnd.
  67. if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF))
  68. return;
  69. const MCSymbol *LSDALabel = emitExceptionTable();
  70. const Function &F = MF->getFunction();
  71. assert(F.hasPersonalityFn() &&
  72. "Landingpads are presented, but no personality routine is found.");
  73. const auto *Per =
  74. cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
  75. const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
  76. emitExceptionInfoTable(LSDALabel, PerSym);
  77. }
  78. } // End of namespace llvm