On Wed, Jul 04, 2007 at 11:31:30PM +0100, Pedro Alves wrote:
> Kevin O'Connor wrote:
> > I think future versions of gcc wont guarantee function placement
> > relative to top-level asm statements.
> > 
> 
> Ah, you're paying attention. :)  It will certainly fail today if
> we use -ffunction-sections.  If this ever turns into a real problem,
> and we don't have real __try/__except support in the compiler,  we
> can craft an __attribute__((seh ("handler")) into gcc.  I think that
> is much easier.

I get things reordered today when using -O.  Also, I saw on the gcc
website (can't find link now) that they plan on being more aggressive
with this in the future.

> > I'll try to take some of the sample code and integrate it into haret.
> > 
> 
> Great, please do post here your findings.  I'd be curious if you take the
> simplest route of not tweaking the current thread's context and just longjmp
> from the seh handler, and if it brings any real problems (I don't think it's
> safe, but it would be great to be proved wrong).

Attached is what I've done.  Oddly, longjmp directly from the handler
seems to work, but returning via EXCEPTION_CONTINUE_EXECUTION fails.
Not sure what I'm doing wrong.

I use my new handlers with:

    struct eh_data ehd;
    if (start_ehandling(&ehd)) {
        while (wcount--)
            *vaddr++ = value;
        end_ehandling(&ehd);
    } else {
        Output(C_ERROR "EXCEPTION while writing %08x to address %p",
               value, vaddr);
    }

Finally, I call init_ehandling at startup.

-Kevin
#include <setjmp.h> // jmp_buf

struct eh_data {
    jmp_buf env;
};

int start_ehandling(struct eh_data *d);
void end_ehandling(struct eh_data *d);
void init_thread_ehandling(void);
void init_ehandling(void);
#include <windows.h> // TlsSetValue

#include "output.h" // Output

#include "exceptions.h"

static DWORD handler_tls;

int start_ehandling(struct eh_data *d)
{
    TlsSetValue(handler_tls, d);
    return !setjmp(d->env);
}

void end_ehandling(struct eh_data *d)
{
    TlsSetValue(handler_tls, NULL);
}

void init_thread_ehandling(void)
{
    TlsSetValue(handler_tls, NULL);
}

void init_ehandling(void)
{
    handler_tls = TlsAlloc();
}

extern "C" long
eh_handler(struct _EXCEPTION_RECORD *ExceptionRecord,
           void *EstablisherFrame,
           struct _CONTEXT *ContextRecord,
           struct _DISPATCHER_CONTEXT *DispatcherContext)
{
    Output("In handler");
    struct eh_data *d = (struct eh_data*)TlsGetValue(handler_tls);
    if (! d) {
        Output(C_ERROR "Terminating haret due to unhandled exception");
        exit(1);
    }
    end_ehandling(d);

    // XXX
    longjmp(d->env, 1);

    ContextRecord->Pc = (ulong)longjmp;
    ContextRecord->R0 = (ulong)d->env;
    ContextRecord->R1 = 1;
    Output("Leaving handler");
    return EXCEPTION_CONTINUE_EXECUTION;
}

__asm__(
    // Data to be placed at start of .text section
    "\t.section .init\n"
    "\t.word eh_handler\n"
    "\t.word 0\n"
    "start_eh_text:\n"

    // Data for exception handler
    "\t.section .pdata\n"
    "\t.word start_eh_text\n"
    "\t.word 0xc0000002 | (0xFFFFF << 8)\n" // max 22 bits for number of 
instructions

    "\t.text\n"
    );
-------------------------------------------------------------------------
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