Kevin O'Connor escreveu:
> On Sun, Jul 01, 2007 at 08:12:33PM +0100, Pedro Alves wrote:
>> Danny Backx wrote:
>>> void Handle(struct _EXCEPTION_RECORD *ExceptionRecord,
>>>             void *EstablisherFrame,
>>>             struct _CONTEXT *ContextRecord,
>>>             struct _DISPATCHER_CONTEXT *DispatcherContext)
>>> {
>>>     throw WindowsException(ExceptionRecord, EstablisherFrame, 
>>> ContextRecord, DispatcherContext);
>>> }
>> I'm not sure that is safe.  You are throwing away from a callback started
>> from the kernel.  I think the safest is to tweak the current threads
>> context with GetThreaContext/SetThreadContext to point the pc at a different
>> address like your registered handler, and return
>> EXCEPTION_CONTINUE_EXECUTION.  Then, in that handler, you're got the stack
>> setup as if the exception called directly into your handler, and it should be
>> safe to throw a c++ exception.  Take another look at cegcc's startup.c for
>> inspiration - It already does something similar.
> 
> Is it safe to enter an exception handler using the calling program's
> stack?  That is, if you set the pc to a handler and call
> EXCEPTION_CONTINUE_EXECUTION that handler will alter the stack and
> registers of the function that raised the exception.  Are we
> guarenteed that this is okay?
> 

Of course, just changing the pc is not enough.  We have to setup a
new stack frame.  Really, you should look at newlib/libc/sys/wince/startup.c:

DWORD* sp = (DWORD*)ContextRecord->Sp;
   *--sp = ContextRecord->Pc;
   *--sp = ContextRecord->Lr;
   *--sp = ContextRecord->Sp;
   *--sp = ContextRecord->R12;
   *--sp = ContextRecord->R11;
   *--sp = ContextRecord->R10;
   *--sp = ContextRecord->R9;
   *--sp = ContextRecord->R8;
   *--sp = ContextRecord->R7;
   *--sp = ContextRecord->R6;
   *--sp = ContextRecord->R5;
   *--sp = ContextRecord->R4;
   *--sp = ContextRecord->R3;
   *--sp = ContextRecord->R2;
   *--sp = ContextRecord->R1;
   *--sp = ContextRecord->R0;
   *--sp = ContextRecord->Psr;

   ContextRecord->Sp = (DWORD) sp;
   ContextRecord->Pc = (DWORD) _call_raise_asm;

   NestedException = 0;

   struct exception_map_t* expt = 
get_exception_map_for(ExceptionRecord->ExceptionCode);
   if (!expt)
   {
     printf("Unhandled kernel exception %x\n", ExceptionRecord->ExceptionCode);
     exit(-1);
   }
   printf("%s\n", expt->str);
   ContextRecord->R0 = expt->signal;

   /* raise(SIGSEGV); */
   __eh_continue(ContextRecord);

   /* NOT REACHED */

__eh_continue is implemented in asm.

Let me see if I can come up with something in the following days.

Cheers,
Pedro Alves


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Cegcc-devel mailing list
Cegcc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cegcc-devel

Reply via email to