ReXGlue SDK
Toggle main menu visibility
Loading...
Searching...
No Matches
seh.h
Go to the documentation of this file.
1
20
21
#pragma once
22
23
#include <atomic>
24
#include <cstdint>
25
#include <exception>
26
27
#include <
rex/platform.h
>
28
#include <
rex/platform/thread.h
>
29
#include <
rex/types.h
>
30
#include <
rex/utility.h
>
31
32
#if !REX_PLATFORM_WIN32
33
#include <setjmp.h>
34
#endif
35
36
namespace
rex::platform
{
37
38
#if !REX_PLATFORM_WIN32
40
struct
SEHScope
{
41
sigjmp_buf
env
;
42
SEHScope
*
outer
=
nullptr
;
43
u32
host_depth
= 0;
44
};
45
#endif
46
47
struct
SEHThreadState
{
48
u32
code
= 0;
49
uintptr_t
info
[2] = {0, 0};
50
#if !REX_PLATFORM_WIN32
51
SEHScope
* top =
nullptr
;
52
u32
host_depth
= 0;
53
#endif
54
};
55
57
REX_PPC_API
SEHThreadState
&
GetSEHThreadState
();
58
64
REX_PPC_API
int
SEHFilter
(u32 code,
void
* exception_pointers);
65
69
[[noreturn]]
REX_PPC_API
void
SEHRethrow
();
70
72
REX_PPC_API
void
SEHInitialize
();
73
74
#if !REX_PLATFORM_WIN32
80
inline
void
SEHEnter
(
SEHScope
& scope) {
81
SEHThreadState
& state =
GetSEHThreadState
();
82
scope.
outer
= state.top;
83
scope.
host_depth
= state.
host_depth
;
84
state.top = &scope;
85
}
86
92
inline
void
SEHLeave
(
SEHScope
& scope) {
93
SEHThreadState
& state =
GetSEHThreadState
();
94
if
(state.top == &scope) {
95
state.top = scope.
outer
;
96
}
97
}
98
100
class
HostCallDepth :
public
NonCopyable {
101
public
:
102
HostCallDepth() { ++
GetSEHThreadState
().
host_depth
; }
103
~HostCallDepth() { --
GetSEHThreadState
().
host_depth
; }
104
};
105
#endif
106
107
}
// namespace rex::platform
108
109
namespace
rex
{
110
112
class
SEHException :
public
std::exception {
113
public
:
115
enum
Code
: u32 {
116
kAccessViolation = 0xC0000005,
117
kInPageError
= 0xC0000006,
118
kIllegalInstruction = 0xC000001D,
119
kStackOverflow = 0xC00000FD,
120
kFloatDivideByZero
= 0xC000008E,
121
kIntegerDivideByZero = 0xC0000094,
122
kUnknown = 0xFFFFFFFF
123
};
124
125
explicit
SEHException
(
Code
code, uintptr_t address = 0) : code_(code), address_(address) {}
126
132
const
char
*
what
() const noexcept
override
{
133
switch
(code_) {
134
case
kAccessViolation:
135
return
"SEH: Access Violation"
;
136
case
kInPageError
:
137
return
"SEH: In-Page Error"
;
138
case
kIllegalInstruction:
139
return
"SEH: Illegal Instruction"
;
140
case
kStackOverflow:
141
return
"SEH: Stack Overflow"
;
142
case
kFloatDivideByZero
:
143
return
"SEH: Float Divide by Zero"
;
144
case
kIntegerDivideByZero:
145
return
"SEH: Integer Divide by Zero"
;
146
default
:
147
return
"SEH: Unknown Exception"
;
148
}
149
}
150
151
Code
GetCode() const noexcept {
return
code_; }
152
154
uintptr_t
GetAddress
() const noexcept {
return
address_; }
155
156
private
:
157
Code
code_;
158
uintptr_t address_;
159
};
160
161
inline
void
InitializeSEHThread() {
162
platform::GetSEHThreadState
() = {};
163
}
164
165
inline
void
InitializeSEH() {
166
platform::SEHInitialize
();
167
}
168
169
#if REX_PLATFORM_WIN32
170
183
#define REX_SEH_TRY __try {
185
#define REX_SEH_CATCH \
186
} \
187
__except (::rex::platform::SEHFilter(GetExceptionCode(), GetExceptionInformation())) {
189
#define REX_SEH_CATCH_ALL \
190
} \
191
__except (::rex::platform::SEHFilter(GetExceptionCode(), GetExceptionInformation())) {
193
#define REX_SEH_RETHROW ::rex::platform::SEHRethrow()
194
195
#define REX_SEH_END }
196
198
#define REX_SEH_RETURN return
199
200
#else
201
215
#define REX_SEH_TRY \
216
{ \
217
::rex::platform::SEHScope rex_seh_scope; \
218
::rex::platform::SEHEnter(rex_seh_scope); \
219
if (sigsetjmp(rex_seh_scope.env, 0) == 0)
220
222
#define REX_SEH_CATCH else
223
225
#define REX_SEH_CATCH_ALL else
226
228
#define REX_SEH_RETHROW ::rex::platform::SEHRethrow()
229
230
#define REX_SEH_END \
231
::rex::platform::SEHLeave(rex_seh_scope); \
232
}
233
235
#define REX_SEH_RETURN \
236
do { \
237
::rex::platform::SEHLeave(rex_seh_scope); \
238
return; \
239
} while (0)
240
241
#endif
// REX_PLATFORM_WIN32
242
243
}
// namespace rex
rex::SEHException
Definition
seh.h:112
rex::SEHException::what
const char * what() const noexcept override
Definition
seh.h:132
rex::SEHException::Code
Code
Definition
seh.h:115
rex::SEHException::kInPageError
@ kInPageError
Definition
seh.h:117
rex::SEHException::kFloatDivideByZero
@ kFloatDivideByZero
Definition
seh.h:120
rex::SEHException::GetAddress
uintptr_t GetAddress() const noexcept
Definition
seh.h:154
rex::platform
Definition
platform.h:345
rex::platform::SEHEnter
void SEHEnter(SEHScope &scope)
Definition
seh.h:80
rex::platform::GetSEHThreadState
REX_PPC_API SEHThreadState & GetSEHThreadState()
rex::platform::SEHLeave
void SEHLeave(SEHScope &scope)
Definition
seh.h:92
rex::platform::SEHFilter
REX_PPC_API int SEHFilter(u32 code, void *exception_pointers)
rex::platform::SEHInitialize
REX_PPC_API void SEHInitialize()
rex::platform::SEHRethrow
REX_PPC_API void SEHRethrow()
rex
Definition
app.h:36
thread.h
platform.h
Platform flags, packing macros and export markers.
REX_PPC_API
#define REX_PPC_API
Definition
platform.h:194
rex::platform::SEHScope
Definition
seh.h:40
rex::platform::SEHScope::outer
SEHScope * outer
Definition
seh.h:42
rex::platform::SEHScope::host_depth
u32 host_depth
Definition
seh.h:43
rex::platform::SEHScope::env
sigjmp_buf env
Definition
seh.h:41
rex::platform::SEHThreadState
Definition
seh.h:47
rex::platform::SEHThreadState::host_depth
u32 host_depth
Definition
seh.h:52
rex::platform::SEHThreadState::code
u32 code
Definition
seh.h:48
rex::platform::SEHThreadState::info
uintptr_t info[2]
Definition
seh.h:49
types.h
Integer types, byte order wrappers and size literals.
utility.h
Move only function, const propagating pointer and scope guard.
rex
ppc
seh.h
Generated by
1.18.0