Hi there,

I come up with an idea about implementing stack unwinding for
the i686-w64-mingw32 target using native Windows Structured
Exception Handling (a.k.a SEH) for efficiency reasons.

Unlike DWARF and SEH for x64, SEH for x86 is stack-based
and works like the SJLJ exception model: The operating system
keeps a thread specific pointer to an SEH node on the stack
that must be installed/uninstalled during run time.

The SEH-head pointer is stored in `fs:[0]`.
Typecially, an SEH handler is installed like this, in Intel syntax:

    # typedef EXCEPTION_DISPOSITION
    #   filter_function(
    #     EXCEPTION_RECORD *record, void *establisher_frame,
    #     CONTEXT *machine_context, void *dispatcher_context)
    #   __attribute__((__cdecl__));
    # struct x86_seh_node_header {
    #   struct x86_seh_node_header *next;
    #   filter_function *filter;
    #   char extra_data[];
    # };

    sub esp, 8                  # struct x86_seh_node_header this_node;
    mov ecx, dword ptr fs:[0]   # 
    mov dword ptr[esp], ecx     # this_node.next = get_thread_seh_head();
    mov dword ptr[esp + 4], offset my_seh_filter
                                # this_node.filter = &my_seh_filter
    mov dword ptr fs:[0], esp   # set_thread_seh_head(&this_node);

Before the function exits and its frame is destroyed, the node
must be uninstalled like this:

    mov ecx, dword ptr fs:[0]   #
    mov dword ptr fs:[0], ecx   # set_thread_seh_head(this_node.next);

Since I am looking at the SJLJ exception model and it seems using
a slim, inlined version of `setjmp()` with `__builtin_longjmp()`
that only stores 3 or 4 pointers, extending that structure should be
a simple matter. The problem is that, installation and uninstallation
of SEH nodes require target-specific ASM code generation.

Is it possible to do in 'gcc/except.c' ?

                                
--------------
Best regards,
lh_mouse
2016-10-17

Reply via email to