[Shrinker] Modified EXC_CallHandler

Robert Baruch autophile at starband.net
Wed Dec 19 12:50:00 CST 2001


Well, the assembly-coded EXC_CallHandler works (to my surprise), with a
little modification from what I described because after all, no plan
survives contact with the enemy.

However, we're still getting hit by one of the landmines in Shrinker. The
awful thing is that I can't debug this easily with gdb. The first
exception that's supposed to take place is a write fault to the code area.
But if I set a breakpoint in the process's code area, gdb is going to
remove the write protection from the code area because, I guess, it needs
to put a breakpoint in there (I thought it would use breakpoint registers
instead of int $3?)

Anyway, I don't want to release the EXC_CallHandler code until I find out
which landmine we're hitting, since I can't be certain the rest of
EXC_CallHandler works -- the stuff past calling the exception handler.

But if you're interested in a morbid "I-love-assembler" way, here it is:

static DWORD EXC_CallHandler(
    EXCEPTION_RECORD *record,
    EXCEPTION_FRAME *frame,
    CONTEXT *context,
    EXCEPTION_FRAME **dispatcher,
    PEXCEPTION_HANDLER handler,
    PEXCEPTION_HANDLER nested_handler)
{
    DWORD tmp = 0;

    __asm__ __volatile__(
        "push %1\n\t"   // ebp-1c = nested_handler
        "push %2\n\t"   // ebp-18 = handler
        "push %3\n\t"   // ebp-14 = dispatcher
        "push %4\n\t"   // ebp-10 = context
        "push %5\n\t"   // ebp-c  = frame
        "push %6\n\t"   // ebp-8  = record
        "push %%ebp\n\t" // ebp-4
        "push %%ecx\n\t" // ebp-0
        "movl %%esp,%%ebp\n\t"
        "movl 0x18(%%ebp),%%ecx\n\t"
        "pushl 0x1c(%%ebp)\n\t"
        "pushl %%fs:0\n\t"
        "movl %%esp,%%fs:0\n\t"
        "pushl 0x14(%%ebp)\n\t"
        "pushl 0x10(%%ebp)\n\t"
        "pushl 0x0c(%%ebp)\n\t"
        "pushl 0x08(%%ebp)\n\t"
        "call *%%ecx\n\t"
        "movl %%fs:0,%%esp\n\t"
        "popl %%fs:0\n\t"
        "movl %%ebp,%%esp\n\t"
        "popl %%ecx\n\t"
        "popl %%ebp\n\t"
        "popl %0\n\t"
        "popl %0\n\t"
        "popl %0\n\t"
        "popl %0\n\t"
        "popl %0\n\t"
        "popl %0\n\t"
        "movl %%eax,%0\n\t"
        : "=&g" (tmp)
        : "g" (nested_handler),
          "g" (handler),
          "g" (dispatcher),
          "g" (context),
          "g" (frame),
          "g" (record)
        : "memory"
        );
        return tmp;
}

--Rob




More information about the wine-devel mailing list