unwind_arm_ehabi.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //===----------------------------------------------------------------------===//
  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. // C++ ABI Level 1 ABI documented at:
  9. // https://github.com/ARM-software/abi-aa/blob/main/ehabi32/ehabi32.rst
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef __ARM_EHABI_UNWIND_H__
  13. #define __ARM_EHABI_UNWIND_H__
  14. typedef uint32_t _Unwind_State;
  15. static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0;
  16. static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1;
  17. static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2;
  18. static const _Unwind_State _US_ACTION_MASK = 3;
  19. /* Undocumented flag for force unwinding. */
  20. static const _Unwind_State _US_FORCE_UNWIND = 8;
  21. typedef uint32_t _Unwind_EHT_Header;
  22. struct _Unwind_Control_Block;
  23. typedef struct _Unwind_Control_Block _Unwind_Control_Block;
  24. #define _Unwind_Exception _Unwind_Control_Block /* Alias */
  25. typedef uint8_t _Unwind_Exception_Class[8];
  26. struct _Unwind_Control_Block {
  27. _Unwind_Exception_Class exception_class;
  28. void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*);
  29. /* Unwinder cache, private fields for the unwinder's use */
  30. struct {
  31. uint32_t reserved1; /* init reserved1 to 0, then don't touch */
  32. uint32_t reserved2;
  33. uint32_t reserved3;
  34. uint32_t reserved4;
  35. uint32_t reserved5;
  36. } unwinder_cache;
  37. /* Propagation barrier cache (valid after phase 1): */
  38. struct {
  39. uint32_t sp;
  40. uint32_t bitpattern[5];
  41. } barrier_cache;
  42. /* Cleanup cache (preserved over cleanup): */
  43. struct {
  44. uint32_t bitpattern[4];
  45. } cleanup_cache;
  46. /* Pr cache (for pr's benefit): */
  47. struct {
  48. uint32_t fnstart; /* function start address */
  49. _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */
  50. uint32_t additional;
  51. uint32_t reserved1;
  52. } pr_cache;
  53. long long int :0; /* Enforce the 8-byte alignment */
  54. } __attribute__((__aligned__(8)));
  55. typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
  56. _Unwind_State state, _Unwind_Exception *exceptionObject,
  57. struct _Unwind_Context *context);
  58. #ifdef __cplusplus
  59. extern "C" {
  60. #endif
  61. //
  62. // The following are the base functions documented by the C++ ABI
  63. //
  64. #ifdef __USING_SJLJ_EXCEPTIONS__
  65. extern _Unwind_Reason_Code
  66. _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object);
  67. extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object);
  68. #else
  69. extern _Unwind_Reason_Code
  70. _Unwind_RaiseException(_Unwind_Exception *exception_object);
  71. extern void _Unwind_Resume(_Unwind_Exception *exception_object);
  72. #endif
  73. extern void _Unwind_DeleteException(_Unwind_Exception *exception_object);
  74. typedef enum {
  75. _UVRSC_CORE = 0, /* integer register */
  76. _UVRSC_VFP = 1, /* vfp */
  77. _UVRSC_WMMXD = 3, /* Intel WMMX data register */
  78. _UVRSC_WMMXC = 4, /* Intel WMMX control register */
  79. _UVRSC_PSEUDO = 5 /* Special purpose pseudo register */
  80. } _Unwind_VRS_RegClass;
  81. typedef enum {
  82. _UVRSD_UINT32 = 0,
  83. _UVRSD_VFPX = 1,
  84. _UVRSD_UINT64 = 3,
  85. _UVRSD_FLOAT = 4,
  86. _UVRSD_DOUBLE = 5
  87. } _Unwind_VRS_DataRepresentation;
  88. typedef enum {
  89. _UVRSR_OK = 0,
  90. _UVRSR_NOT_IMPLEMENTED = 1,
  91. _UVRSR_FAILED = 2
  92. } _Unwind_VRS_Result;
  93. extern void _Unwind_Complete(_Unwind_Exception* exception_object);
  94. extern _Unwind_VRS_Result
  95. _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
  96. uint32_t regno, _Unwind_VRS_DataRepresentation representation,
  97. void *valuep);
  98. extern _Unwind_VRS_Result
  99. _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
  100. uint32_t regno, _Unwind_VRS_DataRepresentation representation,
  101. void *valuep);
  102. extern _Unwind_VRS_Result
  103. _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
  104. uint32_t discriminator,
  105. _Unwind_VRS_DataRepresentation representation);
  106. #if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE)
  107. #define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern
  108. #else
  109. #define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__
  110. #endif
  111. // These are de facto helper functions for ARM, which delegate the function
  112. // calls to _Unwind_VRS_Get/Set(). These are not a part of ARM EHABI
  113. // specification, thus these function MUST be inlined. Please don't replace
  114. // these with the "extern" function declaration; otherwise, the program
  115. // including this <unwind.h> header won't be ABI compatible and will result in
  116. // link error when we are linking the program with libgcc.
  117. _LIBUNWIND_EXPORT_UNWIND_LEVEL1
  118. uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) {
  119. uintptr_t value = 0;
  120. _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
  121. return value;
  122. }
  123. _LIBUNWIND_EXPORT_UNWIND_LEVEL1
  124. void _Unwind_SetGR(struct _Unwind_Context *context, int index,
  125. uintptr_t value) {
  126. _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
  127. }
  128. _LIBUNWIND_EXPORT_UNWIND_LEVEL1
  129. uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
  130. // remove the thumb-bit before returning
  131. return _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
  132. }
  133. _LIBUNWIND_EXPORT_UNWIND_LEVEL1
  134. void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) {
  135. uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
  136. _Unwind_SetGR(context, 15, value | thumb_bit);
  137. }
  138. #ifdef __cplusplus
  139. }
  140. #endif
  141. #endif // __ARM_EHABI_UNWIND_H__