[ros-kernel] Macro SEH support, version 2 (Help needed:translating to AT&T assembler syntax)

Casper Hornstrup chorns at users.sourceforge.net
Sun Nov 2 19:42:47 CET 2003


Maybe you can assemble it and disassemble it again with objdump?
IIRC objdump disassembles in AT&T style.

Casper

> -----Oprindelig meddelelse-----
> Fra: ros-kernel-bounces at reactos.com 
> [mailto:ros-kernel-bounces at reactos.com] På vegne af Filip Navara
> Sendt: 2. november 2003 18:29
> Til: ReactOS Kernel List
> Emne: Re: [ros-kernel] Macro SEH support,version 2 (Help 
> needed:translating to AT&T assembler syntax)
> 
> 
> I tried to do the job of translating it to AT&T syntax, but 
> unfortunetly I never used it and I gave up after few minutes. 
> The already finished part is at 
> www.volny.cz/xnavara/sehatat.c, if anybody wants to continue 
> with that.
> 
> Filip
> ----- Original Message ----- 
> From: "Vizzini" <vizzini at plasmic.com>
> To: "ReactOS Kernel List" <ros-kernel at reactos.com>
> Sent: Sunday, November 02, 2003 7:07 AM
> Subject: Re: [ros-kernel] Macro SEH support, version 2 (Help 
> needed:translating to AT&T assembler syntax)
> 
> 
> > I think it is really critical to get some exception handling 
> > implemented in our system call handlers.  At this point, 
> it's trivial 
> > to crash the whole operating system with a misbehaving 
> user-mode app.  
> > This macro system, while not optimal, will tide us over until the 
> > MinGW exception-handling work is complete.
> >
> > Are there any assembler people out there who need a weekend 
> project? 
> > This isn't terribly long, but it does need somebody who knows what 
> > they're doing.  If you've been lurking for a while waiting to find 
> > something you can contribute, this might just be the 
> ticket!  Mail the 
> > list or me directly if you're interested and I'll point you in the 
> > right direction.
> >
> > Nice work, Skywing.
> >
> >  -Vizzini
> >
> > On Mon, 2003-10-27 at 10:16, Skywing wrote:
> > > I've done a significant amount of reworking on the macro 
> SEH support
> that I
> > > introduced on the mailinglist some time ago.  It now passes every 
> > > test I
> can
> > > throw at it with flying colors, including interoperating with 
> > > VC-style
> SEH.
> > > This includes unwinding and nested exception handlers.  
> This release
> fixes a
> > > number of bugs with the original implementation.
> > >
> > > Request for help:  I don't know AT&T assembler, so 
> somebody needs to
> port
> > > this if it's to be used with MinGW (which is the primary 
> purpose for 
> > > me writing it).  Unless somebody is willing to lend a hand with 
> > > GNU-ASM'ing
> it,
> > > this will probably not benefit the ReactOS project much.
> > >
> > > I've tried to code this as defensively as possible, so 
> that any code 
> > > in
> the
> > > handler or filter areas will properly run without any special 
> > > knowledge about the values of the stack/other registers 
> while in an 
> > > exception
> handler.
> > > I'm pretty sure that the macros are virtually bulletproof against 
> > > the compiler generating code that doesn't work inside of them, 
> > > provided you follow these rules: Enable frame pointer 
> generation.  
> > > This is absolutely crucial to any SEH implementation; 
> without frame 
> > > pointers, the macros
> will
> > > fall over and die. Preferably, exit the SEH exception 
> handler with 
> > > fallthrough.  If you must exit it otherwise, you can try using the
> > > ExceptCleanup() macro before leaving the handler with a return or
> similar
> > > statement.  Exiting the SEH handler inside the filter 
> expression is
> probably
> > > a Bad Idea and may not work, as the "panic stack" will be used 
> > > through
> the
> > > remainder of the function.
> > >
> > > Additionally, GetExceptionCode() and 
> GetExceptionPointers() should 
> > > be available at the proper scopes.  You ought to get an undefined
> identifier
> > > error if you try to use them elsewhere.
> > >
> > > The macros work with "heap-based" SEH in order to work around the
> Borland
> > > patent.  There are some limitations with using this with regular
> Microsoft
> > > Windows (see below), but it should be no problem to 
> modify ReactOS 
> > > to
> work
> > > with this scheme if necessary.
> > >
> > > The semantics for using the macros are as follows:
> > > TRY
> > > {
> > >   try-protected-code;
> > > }
> > > EXCEPT(( filter-expression )) /* Note that double parens 
> are needed 
> > > */ { handler-code; } EXCEPT_END();
> > >
> > > Issues with "heap-based" SEH:
> > > The default Microsoft RtlUnwind implementation will not call an
> exception
> > > handler if the exception registration is not within the threads 
> > > stack limits.  It would be a good idea to ensure that the ReactOS 
> > > RtlUnwind implementation does not have this limitation if 
> we wish to 
> > > use
> "heap-based"
> > > SEH and not "stack-based" SEH.
> > >
> > > Issues with the macros and MSVC++:
> > > The VC compiler crashes if you use if(0) { code; } or 
> goto label; {
> code; }
> > > label: instead of __asm jmp label; { code; } label; to prevent the
> exception
> > > handler from being executed by fallthrough.  I think that this is
> because
> > > the optimizer decides that the exception handler is 
> unreachable and
> removes
> > > it, despite an existing reference to code in the handler 
> (the label 
> > > for
> the
> > > start of the OS-invoked SEH handler function itself).  Later this 
> > > causes
> the
> > > compiler to crash, hence my workaround with __asm jmp
> EXCEPT_EndOfExcept.
> > >
> > > ----- Macro definitions follow -----
> > >
> > > #define ExceptCleanup() { \ 
> ExFreePool(EXCEPT_ExceptionPointers); \
> > > __asm { \
> > > __asm push eax \
> > > __asm mov eax, dword ptr fs:[0x00000000] \
> > > __asm mov eax, dword ptr [eax] \
> > > __asm mov dword ptr fs:[0x00000000], eax \
> > > __asm pop eax \
> > > } \
> > > }
> > > #define GetExceptionCode() ((DWORD)(EXCEPT_ExceptionCode))
> > > #define GetExceptionPointers()
> > > ((PEXCEPTION_POINTERS)(&EXCEPT_ExceptionPointers))
> > >
> > > #define EH_NONCONTINUABLE 0x00000001
> > > #define EH_UNWINDING 0x00000002
> > > #define EH_EXIT_UNWIND 0x00000004
> > > #define EH_STACK_INVALID 0x00000008
> > > #define EH_NESTED_CALL 0x00000010
> > > #define EH_UNWIND_CONTEXT EH_UNWINDING | EH_EXIT_UNWIND
> > >
> > > #define _TRY_SAVED_EBP 0x08
> > > #define _TRY_SAVED_EBX 0x0c
> > > #define _TRY_SAVED_ESI 0x10
> > > #define _TRY_SAVED_EDI 0x14
> > > #define _TRY_SAVED_ESP 0x18
> > >
> > > #if 0 // Enable if you don't have these in scope
> > > typedef enum {
> > > ExceptionContinueExecution,
> > > ExceptionContinueSearch,
> > > ExceptionNestedException,
> > > ExceptionCollidedUnwind
> > > } EXCEPTION_DISPOSITION;
> > > #endif
> > >
> > > #define TRY { \
> > > PVOID TRY_ExceptionRegistration = 
> ExAllocatePoolWithTag(PagedPool, 
> > > 28, ' HES'); \ volatile DWORD EXCEPT_ExceptionCode; \
> > > __asm { \
> > > __asm push eax \
> > > __asm push ecx \
> > > __asm mov eax, TRY_ExceptionRegistration \
> > > __asm mov ecx, dword ptr fs:[0] \
> > > __asm mov dword ptr [eax+0x00], ecx \
> > > __asm mov dword ptr fs:[0], eax \
> > > __asm lea ecx, EXCEPT_Handler \
> > > __asm mov dword ptr [eax+0x04], ecx \
> > > __asm mov dword ptr [eax+_TRY_SAVED_EBP], ebp
> > > \
> > > __asm mov dword ptr [eax+_TRY_SAVED_EBX], ebx
> > > \
> > > __asm mov dword ptr [eax+_TRY_SAVED_ESI], esi
> > > \
> > > __asm mov dword ptr [eax+_TRY_SAVED_EDI], edi
> > > \
> > > __asm mov dword ptr [eax+_TRY_SAVED_ESP], esp
> > > \
> > > __asm add dword ptr [eax+_TRY_SAVED_ESP], 0x08
> > > \
> > > __asm pop ecx \
> > > __asm pop eax \
> > > }
> > >
> > > #define EXCEPT_LOCALS TYPE CONTEXT + 20
> > > #define EXCEPT_CONTEXT_OFFSET 0
> > > #define EXCEPT_POINTERS_OFFSET TYPE CONTEXT
> > >
> > >
> > > #ifdef _MSC_VER
> > > #pragma comment(linker, "/INCLUDE:_RtlUnwind at 16")
> > > #endif
> > >
> > > #if 0 // Enable if not in scope
> > > // RtlUnwind unwinds procedure call stack frames.
> > > extern "C"
> > > NTSYSAPI
> > > VOID
> > > NTAPI
> > > RtlUnwind(
> > > IN OUT PVOID TargetFrame OPTIONAL,
> > > IN PVOID TargetIp OPTIONAL,
> > > IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
> > > IN PVOID ReturnValue
> > > );
> > > #endif
> > >
> > > #define EXCEPT(Expression) { __asm { jmp EXCEPT_EndOfExcept} \ 
> > > volatile EXCEPTION_POINTERS EXCEPT_ExceptionPointers; \
> > > EXCEPT_Handler: /* EXCEPTION_DISPOSITION __cdecl
> > > handler(EXCEPTION_RECORD* ExceptionRecord, void* EstablisherFrame,
> CONTEXT*
> > > ContextRecord, void* DispatcherContext) */ \
> > > __asm { \
> > > __asm mov eax, dword ptr [esp+0x04] \
> > > __asm test dword ptr
> > > [eax]EXCEPTION_RECORD.ExceptionFlags, EH_UNWIND_CONTEXT | 
> > > EH_NESTED_CALL
> \
> > > __asm je EXCEPT_DoHandler \
> > > \
> > > __asm xor eax, eax \
> > > __asm or eax, ExceptionContinueSearch \
> > > __asm ret \
> > > } \
> > > EXCEPT_DoHandler: /* Can't define this in inline asm 
> macro + __asm{} 
> > > block, or compiler complains. */ \ __asm { \
> > > __asm sub esp, EXCEPT_LOCALS \
> > > __asm mov [esp]CONTEXT.Ebp, ebp \
> > > __asm mov [esp]CONTEXT.Ebx, ebx \
> > > __asm mov [esp]CONTEXT.Edi, edi \
> > > __asm mov [esp]CONTEXT.Esi, esi \
> > > __asm pushfd \
> > > __asm pop ecx \
> > > __asm mov [esp]CONTEXT.EFlags, ecx \
> > > __asm mov ebp, dword ptr
> > > [esp+0x08+EXCEPT_LOCALS] \
> > > __asm mov ebp, dword ptr [ebp+0x08] \
> > > __asm lea edx, EXCEPT_ExceptionPointers \
> > > __asm mov ecx, dword ptr
> > > [esp+0x04+EXCEPT_LOCALS] \
> > > __asm mov
> > > [edx]EXCEPTION_POINTERS.ExceptionRecord, ecx \
> > > __asm mov ecx, dword ptr
> > > [esp+0x0c+EXCEPT_LOCALS] \
> > > __asm mov
> > > [edx]EXCEPTION_POINTERS.ContextRecord, ecx \
> > > __asm mov edx,
> > > [edx]EXCEPTION_POINTERS.ExceptionRecord \
> > > __asm mov edx,
> > > [edx]EXCEPTION_RECORD.ExceptionCode \
> > > __asm mov EXCEPT_ExceptionCode, edx \
> > > __asm mov ebp, dword ptr
> > > [esp+0x0c+EXCEPT_LOCALS] \
> > > __asm mov eax, [ebp]CONTEXT.EFlags \
> > > __asm push eax \
> > > __asm popfd \
> > > __asm mov ebp, dword ptr
> > > [esp+0x08+EXCEPT_LOCALS] \
> > > __asm mov ebx, dword ptr [ebp+_TRY_SAVED_EBX]
> > > \
> > > __asm mov esi, dword ptr [ebp+_TRY_SAVED_ESI]
> > > \
> > > __asm mov edi, dword ptr [ebp+_TRY_SAVED_EDI]
> > > \
> > > __asm mov ebp, dword ptr [ebp+_TRY_SAVED_EBP]
> > > \
> > > __asm cld \
> > > } \
> > > \
> > > switch( (Expression) ) { \
> > > \
> > > case EXCEPTION_CONTINUE_SEARCH: \
> > > ExFreePool(TRY_ExceptionRegistration); \
> > > __asm { \
> > > __asm mov ebp, [esp]CONTEXT.Ebp \
> > > __asm mov ebx, [esp]CONTEXT.Ebx \
> > > __asm mov edi, [esp]CONTEXT.Edi \
> > > __asm mov esi, [esp]CONTEXT.Esi \
> > > __asm add esp, EXCEPT_LOCALS \
> > > __asm xor eax, eax \
> > > __asm or eax, ExceptionContinueSearch
> > > \
> > > __asm ret \
> > > } \
> > > \
> > > case EXCEPTION_CONTINUE_EXECUTION: \
> > > ExFreePool(TRY_ExceptionRegistration); \
> > > __asm { \
> > > __asm mov eax, dword ptr
> > > [esp+0x08+EXCEPT_LOCALS] \
> > > __asm push 0 \
> > > __asm push 0 \
> > > __asm push
> > > __ret_label_CONTINUE_EXECUTION \
> > > __asm push eax \
> > > __asm call dword ptr [RtlUnwind] \
> > > } \
> > > __ret_label_CONTINUE_EXECUTION: \
> > > __asm { \
> > > __asm mov ebp, [esp]CONTEXT.Ebp \
> > > __asm mov ebx, [esp]CONTEXT.Ebx \
> > > __asm mov edi, [esp]CONTEXT.Edi \
> > > __asm mov esi, [esp]CONTEXT.Esi \
> > > __asm add esp, EXCEPT_LOCALS \
> > > __asm xor eax, eax \
> > > __asm or eax,
> > > ExceptionContinueExecution \
> > > __asm ret \
> > > } \
> > > \
> > > case EXCEPTION_EXECUTE_HANDLER: \
> > > __asm { \
> > > __asm pushad \
> > > __asm pushfd \
> > > __asm mov eax, dword ptr
> > > [esp+0x08+0x04+0x20+EXCEPT_LOCALS] \
> > > __asm push 0 \
> > > __asm push 0 \
> > > __asm push __ret_label_EXECUTE_HANDLER
> > > \
> > > __asm push eax \
> > > __asm call dword ptr [RtlUnwind] \
> > > } \
> > > __ret_label_EXECUTE_HANDLER: \
> > > __asm { \
> > > __asm popfd \
> > > __asm popad \
> > > } \
> > > break; \
> > > \
> > > default: \
> > > DPRINT("SEH: Invalid disposition returned from filter
> > > expression!\n"); \
> > > RtlRaiseStatus(STATUS_INVALID_DISPOSITION); \
> > > \
> > > } \
> > > \
> > > __asm { \
> > > __asm mov ebp, dword ptr
> > > [esp+0x08+EXCEPT_LOCALS] \
> > > __asm mov ebx, dword ptr [ebp+_TRY_SAVED_EBX]
> > > \
> > > __asm mov esi, dword ptr [ebp+_TRY_SAVED_ESI]
> > > \
> > > __asm mov edi, dword ptr [ebp+_TRY_SAVED_EDI]
> > > \
> > > __asm mov esp, dword ptr [ebp+_TRY_SAVED_ESP]
> > > \
> > > __asm mov ebp, dword ptr [ebp+0x08] \
> > > } }
> > >
> > > -- End --
> > >
> > >
> > > _______________________________________________
> > > Ros-kernel mailing list
> > > Ros-kernel at reactos.com 
> > > http://reactos.geldorp.nl:8080/mailman/listinfo/ros-kernel
> > >
> >
> > _______________________________________________
> > Ros-kernel mailing list
> > Ros-kernel at reactos.com 
> > http://reactos.geldorp.nl:8080/mailman/listinfo/ros-kernel
> >
> 
> _______________________________________________
> Ros-kernel mailing list
> Ros-kernel at reactos.com 
> http://reactos.geldorp.nl:8080/mailman/listinfo/ros-kernel
> 




More information about the Ros-kernel mailing list