27#define STACK_REFPLUS 1
44#define WIN32_LEAN_AND_MEAN
47#pragma optimize("", off)
48#pragma warning(disable:4731)
49#pragma warning(disable:4733)
124#define GREENLET_NEEDS_EXCEPTION_STATE_SAVED
127typedef struct _GExceptionRegistration {
128 struct _GExceptionRegistration* prev;
130} GExceptionRegistration;
133slp_set_exception_state(
const void *
const seh_state)
141 GExceptionRegistration* current_seh_state = (GExceptionRegistration*)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
142 current_seh_state->prev = (GExceptionRegistration*)seh_state;
146static GExceptionRegistration*
147x86_slp_get_third_oldest_handler()
149 GExceptionRegistration* a = NULL;
150 GExceptionRegistration* b = NULL;
151 GExceptionRegistration* c = NULL;
152 GExceptionRegistration* seh_state = (GExceptionRegistration*)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
153 a = b = c = seh_state;
155 while (seh_state && seh_state != (GExceptionRegistration*)0xFFFFFFFF) {
156 if ((
void*)seh_state->prev < (
void*)100) {
157 fprintf(stderr,
"\tERROR: Broken SEH chain.\n");
164 seh_state = seh_state->prev;
166 return a ? a : (b ? b : c);
171slp_get_exception_state()
183 return x86_slp_get_third_oldest_handler();
192 int *stackref, stsizediff;
194 DWORD seh_state = __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
195 __asm mov stackref, esp;
200 SLP_SAVE_STATE(stackref, stsizediff);
208 __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), seh_state);
213#pragma optimize("", on)
214#pragma warning(default:4731)
215#pragma warning(default:4733)
229#define CANNOT_READ_MEM(p, bytes) IsBadReadPtr(p, bytes)
231static int IS_ON_STACK(
void*p)
234 int stackbase = ((int)&stackref) & 0xfffff000;
235 return (
int)p >= stackbase && (int)p < stackbase + 0x00100000;
239x86_slp_show_seh_chain()
241 GExceptionRegistration* seh_state = (GExceptionRegistration*)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
242 fprintf(stderr,
"====== SEH Chain ======\n");
243 while (seh_state && seh_state != (GExceptionRegistration*)0xFFFFFFFF) {
244 fprintf(stderr,
"\tSEH_chain addr: %p handler: %p prev: %p\n",
246 seh_state->handler_f, seh_state->prev);
247 if ((
void*)seh_state->prev < (
void*)100) {
248 fprintf(stderr,
"\tERROR: Broken chain.\n");
251 seh_state = seh_state->prev;
253 fprintf(stderr,
"====== End SEH Chain ======\n");
265GreenletVectorHandler(PEXCEPTION_POINTERS ExceptionInfo)
274 PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
277 "GOT VECTORED EXCEPTION:\n"
278 "\tExceptionCode : %p\n"
279 "\tExceptionFlags : %p\n"
280 "\tExceptionAddr : %p\n"
281 "\tNumberparams : %ld\n",
282 ExceptionRecord->ExceptionCode,
283 ExceptionRecord->ExceptionFlags,
284 ExceptionRecord->ExceptionAddress,
285 ExceptionRecord->NumberParameters
287 if (ExceptionRecord->ExceptionFlags & 1) {
288 fprintf(stderr,
"\t\tEH_NONCONTINUABLE\n" );
290 if (ExceptionRecord->ExceptionFlags & 2) {
291 fprintf(stderr,
"\t\tEH_UNWINDING\n" );
293 if (ExceptionRecord->ExceptionFlags & 4) {
294 fprintf(stderr,
"\t\tEH_EXIT_UNWIND\n" );
296 if (ExceptionRecord->ExceptionFlags & 8) {
297 fprintf(stderr,
"\t\tEH_STACK_INVALID\n" );
299 if (ExceptionRecord->ExceptionFlags & 0x10) {
300 fprintf(stderr,
"\t\tEH_NESTED_CALL\n" );
302 if (ExceptionRecord->ExceptionFlags & 0x20) {
303 fprintf(stderr,
"\t\tEH_TARGET_UNWIND\n" );
305 if (ExceptionRecord->ExceptionFlags & 0x40) {
306 fprintf(stderr,
"\t\tEH_COLLIDED_UNWIND\n" );
308 fprintf(stderr,
"\n");
310 for(DWORD i = 0; i < ExceptionRecord->NumberParameters; i++) {
311 fprintf(stderr,
"\t\t\tParam %ld: %lX\n", i, ExceptionRecord->ExceptionInformation[i]);
314 if (ExceptionRecord->NumberParameters == 3) {
315 fprintf(stderr,
"\tAbout to traverse SEH chain\n");
317 x86_slp_show_seh_chain();
320 return EXCEPTION_CONTINUE_SEARCH;