Merging MinGW changes

This commit is contained in:
Earnie Boyd
2002-05-28 13:13:45 +00:00
parent ad39fa8cb0
commit 4ad1e6fedb
46 changed files with 1877 additions and 1877 deletions

View File

@ -1,112 +1,112 @@
int
__except_handler3(
struct _EXCEPTION_RECORD* pExceptionRecord,
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
LONG filterFuncRet;
LONG trylevel;
EXCEPTION_POINTERS exceptPtrs;
PSCOPETABLE pScopeTable;
CLD // Clear the direction flag (make no assumptions!)
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
// is set... This is true the first time through the handler (the
// non-unwinding case)
if ( ! (pExceptionRecord->ExceptionFlags
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
) )
{
// Build the EXCEPTION_POINTERS structure on the stack
exceptPtrs.ExceptionRecord = pExceptionRecord;
exceptPtrs.ContextRecord = pContextRecord;
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
// establisher frame. See ASM code for GetExceptionInformation
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
// Get initial "trylevel" value
trylevel = pRegistrationFrame->trylevel
// Get a pointer to the scopetable array
scopeTable = pRegistrationFrame->scopetable;
search_for_handler:
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
{
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
{
PUSH EBP // Save this frame EBP
// !!!Very Important!!! Switch to original EBP. This is
// what allows all locals in the frame to have the same
// value as before the exception occurred.
EBP = &pRegistrationFrame->_ebp
// Call the filter function
filterFuncRet = scopetable[trylevel].lpfnFilter();
POP EBP // Restore handler frame EBP
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
{
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
return ExceptionContinueExecution;
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
scopetable == pRegistrationFrame->scopetable
// Does the actual OS cleanup of registration frames
// Causes this function to recurse
__global_unwind2( pRegistrationFrame );
// Once we get here, everything is all cleaned up, except
// for the last frame, where we'll continue execution
EBP = &pRegistrationFrame->_ebp
__local_unwind2( pRegistrationFrame, trylevel );
// NLG == "non-local-goto" (setjmp/longjmp stuff)
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
// Set the current trylevel to whatever SCOPETABLE entry
// was being used when a handler was found
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
// Call the _except {} block. Never returns.
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
}
}
scopeTable = pRegistrationFrame->scopetable;
trylevel = scopeTable->previousTryLevel
goto search_for_handler;
}
else // trylevel == TRYLEVEL_NONE
{
retvalue == DISPOSITION_CONTINUE_SEARCH;
}
}
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
{
PUSH EBP // Save EBP
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
POP EBP // Restore EBP
retvalue == DISPOSITION_CONTINUE_SEARCH;
}
}
int
__except_handler3(
struct _EXCEPTION_RECORD* pExceptionRecord,
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
LONG filterFuncRet;
LONG trylevel;
EXCEPTION_POINTERS exceptPtrs;
PSCOPETABLE pScopeTable;
CLD // Clear the direction flag (make no assumptions!)
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
// is set... This is true the first time through the handler (the
// non-unwinding case)
if ( ! (pExceptionRecord->ExceptionFlags
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
) )
{
// Build the EXCEPTION_POINTERS structure on the stack
exceptPtrs.ExceptionRecord = pExceptionRecord;
exceptPtrs.ContextRecord = pContextRecord;
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
// establisher frame. See ASM code for GetExceptionInformation
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
// Get initial "trylevel" value
trylevel = pRegistrationFrame->trylevel
// Get a pointer to the scopetable array
scopeTable = pRegistrationFrame->scopetable;
search_for_handler:
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
{
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
{
PUSH EBP // Save this frame EBP
// !!!Very Important!!! Switch to original EBP. This is
// what allows all locals in the frame to have the same
// value as before the exception occurred.
EBP = &pRegistrationFrame->_ebp
// Call the filter function
filterFuncRet = scopetable[trylevel].lpfnFilter();
POP EBP // Restore handler frame EBP
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
{
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
return ExceptionContinueExecution;
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
scopetable == pRegistrationFrame->scopetable
// Does the actual OS cleanup of registration frames
// Causes this function to recurse
__global_unwind2( pRegistrationFrame );
// Once we get here, everything is all cleaned up, except
// for the last frame, where we'll continue execution
EBP = &pRegistrationFrame->_ebp
__local_unwind2( pRegistrationFrame, trylevel );
// NLG == "non-local-goto" (setjmp/longjmp stuff)
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
// Set the current trylevel to whatever SCOPETABLE entry
// was being used when a handler was found
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
// Call the _except {} block. Never returns.
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
}
}
scopeTable = pRegistrationFrame->scopetable;
trylevel = scopeTable->previousTryLevel
goto search_for_handler;
}
else // trylevel == TRYLEVEL_NONE
{
retvalue == DISPOSITION_CONTINUE_SEARCH;
}
}
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
{
PUSH EBP // Save EBP
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
POP EBP // Restore EBP
retvalue == DISPOSITION_CONTINUE_SEARCH;
}
}

View File

@ -1,68 +1,68 @@
#include <stdlib.h>
#include <stdio.h>
#include <excpt.h>
#include <windows.h>
#include "exutil.h"
void
WalkExceptionHandlers ()
{
PEXCEPTION_REGISTRATION_RECORD p;
int i;
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
i = 0;
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
{
printf ("Registration %d at %08x : ", i, p);
printf ("Handler = %08x ", p->handler);
printf ("Next Registration = %08x\n", p->prev);
p = p->prev;
i++;
}
printf ("End of exception handler list.\n");
fflush (stdout);
}
void
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
{
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
pExRec->ExceptionFlags);
if (pExRec->ExceptionFlags)
{
printf (" ( ");
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
{
printf ("EH_NONCONTINUABLE ");
}
if (pExRec->ExceptionFlags & EH_UNWINDING)
{
printf ("EH_UNWINDING ");
}
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
{
printf ("EH_EXIT_UNWIND ");
}
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
{
printf ("EH_STACK_INVALID ");
}
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
{
printf ("EH_NESTED_CALL ");
}
printf (")\n");
}
else
{
printf ("\n");
}
fflush(stdout);
}
#include <stdlib.h>
#include <stdio.h>
#include <excpt.h>
#include <windows.h>
#include "exutil.h"
void
WalkExceptionHandlers ()
{
PEXCEPTION_REGISTRATION_RECORD p;
int i;
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
i = 0;
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
{
printf ("Registration %d at %08x : ", i, p);
printf ("Handler = %08x ", p->handler);
printf ("Next Registration = %08x\n", p->prev);
p = p->prev;
i++;
}
printf ("End of exception handler list.\n");
fflush (stdout);
}
void
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
{
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
pExRec->ExceptionFlags);
if (pExRec->ExceptionFlags)
{
printf (" ( ");
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
{
printf ("EH_NONCONTINUABLE ");
}
if (pExRec->ExceptionFlags & EH_UNWINDING)
{
printf ("EH_UNWINDING ");
}
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
{
printf ("EH_EXIT_UNWIND ");
}
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
{
printf ("EH_STACK_INVALID ");
}
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
{
printf ("EH_NESTED_CALL ");
}
printf (")\n");
}
else
{
printf ("\n");
}
fflush(stdout);
}

View File

@ -1,3 +1,3 @@
EXPORTS
WalkExceptionHandlers
DumpExceptionRecord
EXPORTS
WalkExceptionHandlers
DumpExceptionRecord

View File

@ -1,23 +1,23 @@
/*
* Definitions of some internal stuff for exception handling, including
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
*/
#ifndef _EXUTIL_H_
#define _EXUTIL_H_
#include <windows.h>
#include <excpt.h>
#ifdef __cplusplus
extern "C" {
#endif
void WalkExceptionHandlers ();
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
#ifdef __cplusplus
}
#endif
#endif
/*
* Definitions of some internal stuff for exception handling, including
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
*/
#ifndef _EXUTIL_H_
#define _EXUTIL_H_
#include <windows.h>
#include <excpt.h>
#ifdef __cplusplus
extern "C" {
#endif
void WalkExceptionHandlers ();
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,13 +1,13 @@
Dll exutil.dll : exutil.c ;
ImportLib libexutil.a : exutil.def ;
Main sehtest.exe : sehtest.c ;
Main sehfix.exe : sehfix.c ;
Main sehsub.exe : sehsub.c ;
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;
Dll exutil.dll : exutil.c ;
ImportLib libexutil.a : exutil.def ;
Main sehtest.exe : sehtest.c ;
Main sehfix.exe : sehfix.c ;
Main sehsub.exe : sehsub.c ;
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;

View File

@ -1,60 +1,60 @@
/*
* sehfix.c
*
* A test program involving an exception handler that fixes the exception
* causing condition.
*
* In this code we install an exception handler my_handler and then a piece
* of inline assembly attempts to write at the address marked in eax, after
* setting eax to 10. This should produce an exception. The handler then
* changes the eax register of the exception context to be the address of
* a static variable and restarts the code. This should allow everything
* to continue.
*/
#include <windows.h>
#include <excpt.h>
#include "exutil.h"
int x;
EXCEPTION_DISPOSITION
my_handler (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In my exception handler!\n");
DumpExceptionRecord (pExceptionRec);
pContextRecord->Eax = (DWORD) &x;
return ExceptionContinueExecution;
}
main ()
{
x = 2;
printf ("x = %d\n", x);
WalkExceptionHandlers();
__try1(my_handler)
WalkExceptionHandlers();
/* This assembly code should produce an exception. */
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
__except1
WalkExceptionHandlers();
printf ("x = %d\n", x);
printf ("Finished!\n");
}
/*
* sehfix.c
*
* A test program involving an exception handler that fixes the exception
* causing condition.
*
* In this code we install an exception handler my_handler and then a piece
* of inline assembly attempts to write at the address marked in eax, after
* setting eax to 10. This should produce an exception. The handler then
* changes the eax register of the exception context to be the address of
* a static variable and restarts the code. This should allow everything
* to continue.
*/
#include <windows.h>
#include <excpt.h>
#include "exutil.h"
int x;
EXCEPTION_DISPOSITION
my_handler (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In my exception handler!\n");
DumpExceptionRecord (pExceptionRec);
pContextRecord->Eax = (DWORD) &x;
return ExceptionContinueExecution;
}
main ()
{
x = 2;
printf ("x = %d\n", x);
WalkExceptionHandlers();
__try1(my_handler)
WalkExceptionHandlers();
/* This assembly code should produce an exception. */
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
__except1
WalkExceptionHandlers();
printf ("x = %d\n", x);
printf ("Finished!\n");
}

View File

@ -1,43 +1,43 @@
/*
* sehsub.c
*
* In an attempt to see what might be going on inside CRTDLL, this program
* walks the exception list after creating a new thread with _beginthread.
*
* It turns out that _beginthread DOES install an exception handler, as
* expected, but this handler is NOT exported by CRTDLL (it is certainly
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
* events.
*/
#include <windows.h>
#include <excpt.h>
#include <process.h>
#include "exutil.h"
extern void* __imp__except_handler3;
unsigned
my_thread (void * p)
{
printf ("In my thread.\n");
WalkExceptionHandlers();
return 0;
}
main ()
{
unsigned long h;
unsigned id;
printf ("In main.\n");
WalkExceptionHandlers();
printf ("Except_handler3 %08x\n", __imp__except_handler3);
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
WaitForSingleObject ((HANDLE) h, INFINITE);
CloseHandle ((HANDLE) h);
return;
}
/*
* sehsub.c
*
* In an attempt to see what might be going on inside CRTDLL, this program
* walks the exception list after creating a new thread with _beginthread.
*
* It turns out that _beginthread DOES install an exception handler, as
* expected, but this handler is NOT exported by CRTDLL (it is certainly
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
* events.
*/
#include <windows.h>
#include <excpt.h>
#include <process.h>
#include "exutil.h"
extern void* __imp__except_handler3;
unsigned
my_thread (void * p)
{
printf ("In my thread.\n");
WalkExceptionHandlers();
return 0;
}
main ()
{
unsigned long h;
unsigned id;
printf ("In main.\n");
WalkExceptionHandlers();
printf ("Except_handler3 %08x\n", __imp__except_handler3);
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
WaitForSingleObject ((HANDLE) h, INFINITE);
CloseHandle ((HANDLE) h);
return;
}

View File

@ -1,72 +1,72 @@
/*
* This file tests some of the basics of structured exception handling as
* implemented in excpt.h and the Windows API header files.
*
* The program installs two exception handlers, then attempts to write to
* a pointer to an invalid address. This causes an exception which passes
* through the exception handlers and on to the default system exception
* handler. That handler brings up the dialog box all Windows users know
* and love, and then the program is terminated.
*
* You might note that after the initial run up through our exception frames
* we get a second run up through them with the exception code
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
* I don't understand that bit particularly.
*/
#include <stdio.h>
#include <excpt.h>
#include "exutil.h"
EXCEPTION_DISPOSITION
my_handler (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In my exception handler!\n");
DumpExceptionRecord (pExceptionRec);
return ExceptionContinueSearch;
}
EXCEPTION_DISPOSITION
my_handler2 (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In top exception handler!\n");
DumpExceptionRecord (pExceptionRec);
return ExceptionContinueSearch;
}
main ()
{
char* x;
printf ("my_handler2 = %08x\n", my_handler2);
printf ("my_handler = %08x\n", my_handler);
WalkExceptionHandlers();
__try1(my_handler2)
x = (char*) 10;
WalkExceptionHandlers();
__try1(my_handler)
WalkExceptionHandlers();
*x = 1;
__except1
__except1
printf ("Finished!\n");
}
/*
* This file tests some of the basics of structured exception handling as
* implemented in excpt.h and the Windows API header files.
*
* The program installs two exception handlers, then attempts to write to
* a pointer to an invalid address. This causes an exception which passes
* through the exception handlers and on to the default system exception
* handler. That handler brings up the dialog box all Windows users know
* and love, and then the program is terminated.
*
* You might note that after the initial run up through our exception frames
* we get a second run up through them with the exception code
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
* I don't understand that bit particularly.
*/
#include <stdio.h>
#include <excpt.h>
#include "exutil.h"
EXCEPTION_DISPOSITION
my_handler (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In my exception handler!\n");
DumpExceptionRecord (pExceptionRec);
return ExceptionContinueSearch;
}
EXCEPTION_DISPOSITION
my_handler2 (
struct _EXCEPTION_RECORD* pExceptionRec,
void* pEstablisherFrame,
struct _CONTEXT* pContextRecord,
void* pDispatcherContext
)
{
printf ("In top exception handler!\n");
DumpExceptionRecord (pExceptionRec);
return ExceptionContinueSearch;
}
main ()
{
char* x;
printf ("my_handler2 = %08x\n", my_handler2);
printf ("my_handler = %08x\n", my_handler);
WalkExceptionHandlers();
__try1(my_handler2)
x = (char*) 10;
WalkExceptionHandlers();
__try1(my_handler)
WalkExceptionHandlers();
*x = 1;
__except1
__except1
printf ("Finished!\n");
}