EhFrame.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. typedef BYTE ubyte;
  7. typedef uint16 uhalf;
  8. typedef uint32 uword;
  9. CompileAssert(sizeof(ubyte) == 1);
  10. CompileAssert(sizeof(uhalf) == 2);
  11. CompileAssert(sizeof(uword) == 4);
  12. BYTE* EmitLEB128(BYTE* pc, unsigned value);
  13. BYTE* EmitLEB128(BYTE* pc, int value);
  14. ubyte GetDwarfRegNum(ubyte regNum);
  15. template <class T>
  16. class LEB128Wrapper
  17. {
  18. private:
  19. T value;
  20. public:
  21. LEB128Wrapper(T value): value(value)
  22. {}
  23. BYTE* Write(BYTE* pc) const
  24. {
  25. return EmitLEB128(pc, value);
  26. }
  27. };
  28. typedef LEB128Wrapper<unsigned> ULEB128;
  29. typedef LEB128Wrapper<int> LEB128;
  30. //
  31. // EhFrame emits .eh_frame unwind data for our JIT code. We emit only one CIE
  32. // followed by one FDE for each JIT function.
  33. //
  34. class EhFrame
  35. {
  36. // Simple buffer writer. Must operate on a buffer of sufficient size.
  37. class Writer
  38. {
  39. private:
  40. BYTE* buffer; // original buffer head
  41. BYTE* cur; // current output position
  42. const size_t size; // original size of buffer, for debug only
  43. public:
  44. Writer(BYTE* buffer, size_t size) : buffer(buffer), cur(buffer), size(size)
  45. {}
  46. // Write a value, and advance cur position
  47. template <class T>
  48. void Write(T value)
  49. {
  50. *reinterpret_cast<T*>(cur) = value;
  51. cur += sizeof(value);
  52. Assert(Count() <= size);
  53. }
  54. // Write a ULEB128 or LEB128 value, and advance cur position
  55. template <class T>
  56. void Write(const LEB128Wrapper<T>& leb128)
  57. {
  58. cur = leb128.Write(cur);
  59. Assert(Count() <= size);
  60. }
  61. // Write a value at an absolute position
  62. template <class T>
  63. void Write(size_t offset, T value)
  64. {
  65. Assert(offset + sizeof(value) <= size);
  66. *reinterpret_cast<T*>(buffer + offset) = value;
  67. }
  68. // Get original buffer head
  69. BYTE* Buffer() const
  70. {
  71. return buffer;
  72. }
  73. // Get count of written bytes (== offset of cur position)
  74. size_t Count() const
  75. {
  76. return cur - buffer;
  77. }
  78. };
  79. // Base class for CIE and FDE
  80. class Entry
  81. {
  82. protected:
  83. Writer* writer;
  84. size_t beginOffset; // where we'll update "length" record
  85. // To limit supported value types
  86. void Emit(ubyte value) { writer->Write(value); }
  87. void Emit(uhalf value) { writer->Write(value); }
  88. void Emit(uword value) { writer->Write(value); }
  89. void Emit(const void* absptr) { writer->Write(absptr); }
  90. void Emit(LEB128 value) { writer->Write(value); }
  91. void Emit(ULEB128 value) { writer->Write(value); }
  92. template <class T1>
  93. void Emit(ubyte op, T1 arg1)
  94. {
  95. Emit(op);
  96. Emit(arg1);
  97. }
  98. template <class T1, class T2>
  99. void Emit(ubyte op, T1 arg1, T2 arg2)
  100. {
  101. Emit(op, arg1);
  102. Emit(arg2);
  103. }
  104. public:
  105. Entry(Writer* writer) : writer(writer), beginOffset(-1)
  106. {}
  107. void Begin();
  108. void End();
  109. #define ENTRY(name, op) \
  110. void cfi_##name() \
  111. { Emit(static_cast<ubyte>(op)); }
  112. #define ENTRY1(name, op, arg1_type) \
  113. void cfi_##name(arg1_type arg1) \
  114. { Emit(op, arg1); }
  115. #define ENTRY2(name, op, arg1_type, arg2_type) \
  116. void cfi_##name(arg1_type arg1, arg2_type arg2) \
  117. { Emit(op, arg1, arg2); }
  118. #define ENTRY_SM1(name, op, arg1_type) \
  119. void cfi_##name(arg1_type arg1) \
  120. { Assert((arg1) <= 0x3F); Emit(static_cast<ubyte>((op) | arg1)); }
  121. #define ENTRY_SM2(name, op, arg1_type, arg2_type) \
  122. void cfi_##name(arg1_type arg1, arg2_type arg2) \
  123. { Assert((arg1) <= 0x3F); Emit((op) | arg1, arg2); }
  124. #include "EhFrameCFI.inc"
  125. void cfi_advance(uword advance);
  126. };
  127. // Common Information Entry
  128. class CIE : public Entry
  129. {
  130. public:
  131. CIE(Writer* writer) : Entry(writer)
  132. {}
  133. void Begin();
  134. };
  135. // Frame Description Entry
  136. class FDE: public Entry
  137. {
  138. private:
  139. size_t pcBeginOffset;
  140. public:
  141. FDE(Writer* writer) : Entry(writer)
  142. {}
  143. void Begin();
  144. void UpdateAddressRange(const void* pcBegin, size_t pcRange);
  145. };
  146. private:
  147. Writer writer;
  148. FDE fde;
  149. public:
  150. EhFrame(BYTE* buffer, size_t size);
  151. Writer* GetWriter()
  152. {
  153. return &writer;
  154. }
  155. FDE* GetFDE()
  156. {
  157. return &fde;
  158. }
  159. void End();
  160. BYTE* Buffer() const
  161. {
  162. return writer.Buffer();
  163. }
  164. size_t Count() const
  165. {
  166. return writer.Count();
  167. }
  168. };