| diff -c -r linux.99pl12/linux//kernel/signal.c linux//kernel/signal.c |
| *** linux.99pl12/linux//kernel/signal.c Sat Aug 28 00:24:01 1993 |
| --- linux//kernel/signal.c Fri Aug 27 22:45:41 1993 |
| *************** |
| *** 195,201 **** |
| COPY(eip); COPY(eflags); |
| COPY(ecx); COPY(edx); |
| COPY(ebx); |
| ! COPY(esp); COPY(ebp); |
| COPY(edi); COPY(esi); |
| COPY(cs); COPY(ss); |
| COPY(ds); COPY(es); |
| --- 195,202 ---- |
| COPY(eip); COPY(eflags); |
| COPY(ecx); COPY(edx); |
| COPY(ebx); |
| ! regs->esp = context.esp_at_signal; /* Can be different with Wine */ |
| ! COPY(ebp); |
| COPY(edi); COPY(esi); |
| COPY(cs); COPY(ss); |
| COPY(ds); COPY(es); |
| *************** |
| *** 353,360 **** |
| frame = (unsigned long *) regs->esp; |
| signr = 1; |
| sa = current->sigaction; |
| ! if (regs->ss != USER_DS) |
| ! printk("Warning: signal handler with nonstandard stack segment\n"); |
| for (mask = 1 ; mask ; sa++,signr++,mask += mask) { |
| if (mask > handler_signal) |
| break; |
| --- 354,360 ---- |
| frame = (unsigned long *) regs->esp; |
| signr = 1; |
| sa = current->sigaction; |
| ! |
| for (mask = 1 ; mask ; sa++,signr++,mask += mask) { |
| if (mask > handler_signal) |
| break; |
| *************** |
| *** 365,370 **** |
| --- 365,381 ---- |
| sa->sa_handler = NULL; |
| /* force a supervisor-mode page-in of the signal handler to reduce races */ |
| __asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler)); |
| + |
| + /* If ss != USER_DS, we cannot rely upon the ss:esp as a */ |
| + /* stack. We will instead use USER_DS:sa->sa_restorer */ |
| + if (regs->ss != USER_DS) { |
| + frame = (unsigned long *) sa->sa_restorer; |
| + if(frame == NULL) { |
| + printk("No signal handler stack available\n"); |
| + do_exit(signr); |
| + }; |
| + }; |
| + |
| setup_frame(&frame,eip,regs,signr,sa_handler,oldmask); |
| eip = sa_handler; regs->cs = USER_CS; |
| current->blocked |= sa->sa_mask; |
| *************** |
| *** 371,376 **** |
| --- 382,392 ---- |
| oldmask |= sa->sa_mask; |
| } |
| regs->esp = (unsigned long) frame; |
| + /* When running the Wine program, the segment registers may be holding |
| + unusual values */ |
| + regs->ss = USER_DS; /* Make sure that this is correct */ |
| + regs->ds = USER_DS; /* And the same here */ |
| + regs->es = USER_DS; /* And here again */ |
| regs->eip = eip; /* "return" to the first handler */ |
| return 1; |
| } |
| diff -c -r linux.99pl12/linux//kernel/traps.c linux//kernel/traps.c |
| *** linux.99pl12/linux//kernel/traps.c Thu Aug 19 00:34:24 1993 |
| --- linux//kernel/traps.c Fri Aug 27 09:11:01 1993 |
| *************** |
| *** 66,71 **** |
| --- 66,76 ---- |
| |
| if ((regs->eflags & VM_MASK) || ((0xffff & regs->cs) == USER_CS)) |
| return; |
| + |
| + /* See if we are using the LDT. If so, pass along the signal. */ |
| + if((7 & regs->cs) == 7 && current->ldt && (regs->cs >> 3) < 512) |
| + return; |
| + |
| printk("%s: %04x\n", str, err & 0xffff); |
| printk("EIP: %04x:%p\nEFLAGS: %p\n", 0xffff & regs->cs,regs->eip,regs->eflags); |
| printk("eax: %08x ebx: %08x ecx: %08x edx: %08x\n", |