ARMWinEHPrinter.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //===--- ARMWinEHPrinter.h - Windows on ARM Unwind Information Printer ----===//
  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. #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
  9. #define LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
  10. #include "llvm/Object/COFF.h"
  11. #include "llvm/Support/ErrorOr.h"
  12. #include "llvm/Support/ScopedPrinter.h"
  13. namespace llvm {
  14. namespace ARM {
  15. namespace WinEH {
  16. class RuntimeFunction;
  17. class RuntimeFunctionARM64;
  18. class Decoder {
  19. static const size_t PDataEntrySize;
  20. ScopedPrinter &SW;
  21. raw_ostream &OS;
  22. bool isAArch64;
  23. struct RingEntry {
  24. uint8_t Mask;
  25. uint8_t Value;
  26. uint8_t Length;
  27. bool (Decoder::*Routine)(const uint8_t *, unsigned &, unsigned, bool);
  28. };
  29. static const RingEntry Ring[];
  30. static const RingEntry Ring64[];
  31. bool opcode_0xxxxxxx(const uint8_t *Opcodes, unsigned &Offset,
  32. unsigned Length, bool Prologue);
  33. bool opcode_10Lxxxxx(const uint8_t *Opcodes, unsigned &Offset,
  34. unsigned Length, bool Prologue);
  35. bool opcode_1100xxxx(const uint8_t *Opcodes, unsigned &Offset,
  36. unsigned Length, bool Prologue);
  37. bool opcode_11010Lxx(const uint8_t *Opcodes, unsigned &Offset,
  38. unsigned Length, bool Prologue);
  39. bool opcode_11011Lxx(const uint8_t *Opcodes, unsigned &Offset,
  40. unsigned Length, bool Prologue);
  41. bool opcode_11100xxx(const uint8_t *Opcodes, unsigned &Offset,
  42. unsigned Length, bool Prologue);
  43. bool opcode_111010xx(const uint8_t *Opcodes, unsigned &Offset,
  44. unsigned Length, bool Prologue);
  45. bool opcode_1110110L(const uint8_t *Opcodes, unsigned &Offset,
  46. unsigned Length, bool Prologue);
  47. bool opcode_11101110(const uint8_t *Opcodes, unsigned &Offset,
  48. unsigned Length, bool Prologue);
  49. bool opcode_11101111(const uint8_t *Opcodes, unsigned &Offset,
  50. unsigned Length, bool Prologue);
  51. bool opcode_11110101(const uint8_t *Opcodes, unsigned &Offset,
  52. unsigned Length, bool Prologue);
  53. bool opcode_11110110(const uint8_t *Opcodes, unsigned &Offset,
  54. unsigned Length, bool Prologue);
  55. bool opcode_11110111(const uint8_t *Opcodes, unsigned &Offset,
  56. unsigned Length, bool Prologue);
  57. bool opcode_11111000(const uint8_t *Opcodes, unsigned &Offset,
  58. unsigned Length, bool Prologue);
  59. bool opcode_11111001(const uint8_t *Opcodes, unsigned &Offset,
  60. unsigned Length, bool Prologue);
  61. bool opcode_11111010(const uint8_t *Opcodes, unsigned &Offset,
  62. unsigned Length, bool Prologue);
  63. bool opcode_11111011(const uint8_t *Opcodes, unsigned &Offset,
  64. unsigned Length, bool Prologue);
  65. bool opcode_11111100(const uint8_t *Opcodes, unsigned &Offset,
  66. unsigned Length, bool Prologue);
  67. bool opcode_11111101(const uint8_t *Opcodes, unsigned &Offset,
  68. unsigned Length, bool Prologue);
  69. bool opcode_11111110(const uint8_t *Opcodes, unsigned &Offset,
  70. unsigned Length, bool Prologue);
  71. bool opcode_11111111(const uint8_t *Opcodes, unsigned &Offset,
  72. unsigned Length, bool Prologue);
  73. // ARM64 unwind codes start here.
  74. bool opcode_alloc_s(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  75. bool Prologue);
  76. bool opcode_save_r19r20_x(const uint8_t *Opcodes, unsigned &Offset,
  77. unsigned Length, bool Prologue);
  78. bool opcode_save_fplr(const uint8_t *Opcodes, unsigned &Offset,
  79. unsigned Length, bool Prologue);
  80. bool opcode_save_fplr_x(const uint8_t *Opcodes, unsigned &Offset,
  81. unsigned Length, bool Prologue);
  82. bool opcode_alloc_m(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  83. bool Prologue);
  84. bool opcode_save_regp(const uint8_t *Opcodes, unsigned &Offset,
  85. unsigned Length, bool Prologue);
  86. bool opcode_save_regp_x(const uint8_t *Opcodes, unsigned &Offset,
  87. unsigned Length, bool Prologue);
  88. bool opcode_save_reg(const uint8_t *Opcodes, unsigned &Offset,
  89. unsigned Length, bool Prologue);
  90. bool opcode_save_reg_x(const uint8_t *Opcodes, unsigned &Offset,
  91. unsigned Length, bool Prologue);
  92. bool opcode_save_lrpair(const uint8_t *Opcodes, unsigned &Offset,
  93. unsigned Length, bool Prologue);
  94. bool opcode_save_fregp(const uint8_t *Opcodes, unsigned &Offset,
  95. unsigned Length, bool Prologue);
  96. bool opcode_save_fregp_x(const uint8_t *Opcodes, unsigned &Offset,
  97. unsigned Length, bool Prologue);
  98. bool opcode_save_freg(const uint8_t *Opcodes, unsigned &Offset,
  99. unsigned Length, bool Prologue);
  100. bool opcode_save_freg_x(const uint8_t *Opcodes, unsigned &Offset,
  101. unsigned Length, bool Prologue);
  102. bool opcode_alloc_l(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  103. bool Prologue);
  104. bool opcode_setfp(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  105. bool Prologue);
  106. bool opcode_addfp(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  107. bool Prologue);
  108. bool opcode_nop(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  109. bool Prologue);
  110. bool opcode_end(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  111. bool Prologue);
  112. bool opcode_end_c(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  113. bool Prologue);
  114. bool opcode_save_next(const uint8_t *Opcodes, unsigned &Offset,
  115. unsigned Length, bool Prologue);
  116. bool opcode_trap_frame(const uint8_t *Opcodes, unsigned &Offset,
  117. unsigned Length, bool Prologue);
  118. bool opcode_machine_frame(const uint8_t *Opcodes, unsigned &Offset,
  119. unsigned Length, bool Prologue);
  120. bool opcode_context(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
  121. bool Prologue);
  122. bool opcode_clear_unwound_to_call(const uint8_t *Opcodes, unsigned &Offset,
  123. unsigned Length, bool Prologue);
  124. void decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
  125. bool Prologue);
  126. void printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask);
  127. ErrorOr<object::SectionRef>
  128. getSectionContaining(const object::COFFObjectFile &COFF, uint64_t Address);
  129. ErrorOr<object::SymbolRef>
  130. getSymbol(const object::COFFObjectFile &COFF, uint64_t Address,
  131. bool FunctionOnly = false);
  132. ErrorOr<object::SymbolRef>
  133. getRelocatedSymbol(const object::COFFObjectFile &COFF,
  134. const object::SectionRef &Section, uint64_t Offset);
  135. ErrorOr<object::SymbolRef>
  136. getSymbolForLocation(const object::COFFObjectFile &COFF,
  137. const object::SectionRef &Section,
  138. uint64_t OffsetInSection, uint64_t ImmediateOffset,
  139. uint64_t &SymbolAddress, uint64_t &SymbolOffset,
  140. bool FunctionOnly = false);
  141. object::SymbolRef getPreferredSymbol(const object::COFFObjectFile &COFF,
  142. object::SymbolRef Sym,
  143. uint64_t &SymbolOffset);
  144. bool dumpXDataRecord(const object::COFFObjectFile &COFF,
  145. const object::SectionRef &Section,
  146. uint64_t FunctionAddress, uint64_t VA);
  147. bool dumpUnpackedEntry(const object::COFFObjectFile &COFF,
  148. const object::SectionRef Section, uint64_t Offset,
  149. unsigned Index, const RuntimeFunction &Entry);
  150. bool dumpPackedEntry(const object::COFFObjectFile &COFF,
  151. const object::SectionRef Section, uint64_t Offset,
  152. unsigned Index, const RuntimeFunction &Entry);
  153. bool dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
  154. const object::SectionRef Section, uint64_t Offset,
  155. unsigned Index, const RuntimeFunctionARM64 &Entry);
  156. bool dumpProcedureDataEntry(const object::COFFObjectFile &COFF,
  157. const object::SectionRef Section, unsigned Entry,
  158. ArrayRef<uint8_t> Contents);
  159. void dumpProcedureData(const object::COFFObjectFile &COFF,
  160. const object::SectionRef Section);
  161. public:
  162. Decoder(ScopedPrinter &SW, bool isAArch64) : SW(SW),
  163. OS(SW.getOStream()),
  164. isAArch64(isAArch64) {}
  165. Error dumpProcedureData(const object::COFFObjectFile &COFF);
  166. };
  167. }
  168. }
  169. }
  170. #endif