abi.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use core::ffi::c_void;
  2. use core::ops;
  3. use crate::util::*;
  4. #[cfg(not(feature = "unwinder"))]
  5. use crate::arch::Arch;
  6. #[cfg(feature = "unwinder")]
  7. pub use crate::unwinder::*;
  8. #[repr(transparent)]
  9. #[derive(Clone, Copy, PartialEq, Eq)]
  10. pub struct UnwindReasonCode(pub c_int);
  11. #[allow(unused)]
  12. impl UnwindReasonCode {
  13. pub const NO_REASON: Self = Self(0);
  14. pub const FOREIGN_EXCEPTION_CAUGHT: Self = Self(1);
  15. pub const FATAL_PHASE2_ERROR: Self = Self(2);
  16. pub const FATAL_PHASE1_ERROR: Self = Self(3);
  17. pub const NORMAL_STOP: Self = Self(4);
  18. pub const END_OF_STACK: Self = Self(5);
  19. pub const HANDLER_FOUND: Self = Self(6);
  20. pub const INSTALL_CONTEXT: Self = Self(7);
  21. pub const CONTINUE_UNWIND: Self = Self(8);
  22. }
  23. #[repr(transparent)]
  24. #[derive(Clone, Copy, PartialEq, Eq)]
  25. pub struct UnwindAction(pub c_int);
  26. impl UnwindAction {
  27. pub const SEARCH_PHASE: Self = Self(1);
  28. pub const CLEANUP_PHASE: Self = Self(2);
  29. pub const HANDLER_FRAME: Self = Self(4);
  30. pub const FORCE_UNWIND: Self = Self(8);
  31. pub const END_OF_STACK: Self = Self(16);
  32. }
  33. impl ops::BitOr for UnwindAction {
  34. type Output = Self;
  35. #[inline]
  36. fn bitor(self, rhs: Self) -> Self {
  37. Self(self.0 | rhs.0)
  38. }
  39. }
  40. impl UnwindAction {
  41. #[inline]
  42. pub const fn empty() -> Self {
  43. Self(0)
  44. }
  45. #[inline]
  46. pub const fn contains(&self, other: Self) -> bool {
  47. self.0 & other.0 != 0
  48. }
  49. }
  50. pub type UnwindExceptionCleanupFn = unsafe extern "C" fn(UnwindReasonCode, *mut UnwindException);
  51. pub type UnwindStopFn = extern "C" fn(
  52. c_int,
  53. UnwindAction,
  54. u64,
  55. &mut UnwindException,
  56. &mut UnwindContext<'_>,
  57. *mut c_void,
  58. ) -> UnwindReasonCode;
  59. #[cfg(not(feature = "unwinder"))]
  60. #[repr(C)]
  61. pub struct UnwindException {
  62. pub exception_class: u64,
  63. pub exception_cleanup: Option<UnwindExceptionCleanupFn>,
  64. private: [usize; Arch::UNWIND_PRIVATE_DATA_SIZE],
  65. }
  66. pub type UnwindTraceFn =
  67. extern "C" fn(ctx: &mut UnwindContext<'_>, arg: *mut c_void) -> UnwindReasonCode;
  68. #[cfg(not(feature = "unwinder"))]
  69. #[repr(C)]
  70. pub struct UnwindContext<'a> {
  71. opaque: usize,
  72. phantom: core::marker::PhantomData<&'a ()>,
  73. }
  74. pub type PersonalityRoutine = extern "C" fn(
  75. c_int,
  76. UnwindAction,
  77. u64,
  78. &mut UnwindException,
  79. &mut UnwindContext<'_>,
  80. ) -> UnwindReasonCode;
  81. #[cfg(not(feature = "unwinder"))]
  82. macro_rules! binding {
  83. ($(extern $abi: literal $([$t:tt])? fn $name: ident ($($arg: ident : $arg_ty: ty),*$(,)?) $(-> $ret: ty)?;)*) => {
  84. $(
  85. #[allow(non_snake_case)]
  86. #[inline]
  87. pub $($t)? fn $name($($arg: $arg_ty),*) $(-> $ret)? {
  88. extern $abi {
  89. fn $name($($arg: $arg_ty),*) $(-> $ret)?;
  90. }
  91. unsafe { $name($($arg),*) }
  92. }
  93. )*
  94. };
  95. }
  96. #[cfg(not(feature = "unwinder"))]
  97. binding! {
  98. extern "C" fn _Unwind_GetGR(unwind_ctx: &UnwindContext<'_>, index: c_int) -> usize;
  99. extern "C" fn _Unwind_GetCFA(unwind_ctx: &UnwindContext<'_>) -> usize;
  100. extern "C" fn _Unwind_SetGR(
  101. unwind_ctx: &mut UnwindContext<'_>,
  102. index: c_int,
  103. value: usize,
  104. );
  105. extern "C" fn _Unwind_GetIP(unwind_ctx: &UnwindContext<'_>) -> usize;
  106. extern "C" fn _Unwind_GetIPInfo(
  107. unwind_ctx: &UnwindContext<'_>,
  108. ip_before_insn: &mut c_int,
  109. ) -> usize;
  110. extern "C" fn _Unwind_SetIP(
  111. unwind_ctx: &mut UnwindContext<'_>,
  112. value: usize,
  113. );
  114. extern "C" fn _Unwind_GetLanguageSpecificData(unwind_ctx: &UnwindContext<'_>) -> *mut c_void;
  115. extern "C" fn _Unwind_GetRegionStart(unwind_ctx: &UnwindContext<'_>) -> usize;
  116. extern "C" fn _Unwind_GetTextRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
  117. extern "C" fn _Unwind_GetDataRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
  118. extern "C" fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
  119. extern "C-unwind" fn _Unwind_RaiseException(
  120. exception: &mut UnwindException,
  121. ) -> UnwindReasonCode;
  122. extern "C-unwind" fn _Unwind_ForceUnwind(
  123. exception: &mut UnwindException,
  124. stop: UnwindStopFn,
  125. stop_arg: *mut c_void,
  126. ) -> UnwindReasonCode;
  127. extern "C-unwind" fn _Unwind_Resume(exception: &mut UnwindException) -> !;
  128. extern "C-unwind" fn _Unwind_Resume_or_Rethrow(
  129. exception: &mut UnwindException,
  130. ) -> UnwindReasonCode;
  131. extern "C" [unsafe] fn _Unwind_DeleteException(exception: *mut UnwindException);
  132. extern "C-unwind" fn _Unwind_Backtrace(
  133. trace: UnwindTraceFn,
  134. trace_argument: *mut c_void,
  135. ) -> UnwindReasonCode;
  136. }