SIGFPE handling

git-svn-id: svn://kolibrios.org@703 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-01-26 21:57:46 +00:00
parent 616f769298
commit 97918755c2
9 changed files with 1802 additions and 1612 deletions

View File

@ -4,10 +4,10 @@ projectIdent
VpeMain VpeMain
1 1
WRect WRect
-32 0
330 370
10304 10240
9950 9870
2 2
MProject MProject
3 3
@ -42,8 +42,8 @@ WRect
WFileName WFileName
10 10
clib_r.tgt clib_r.tgt
0 10
0 42
11 11
VComponent VComponent
12 12
@ -59,5 +59,5 @@ WFileName
7 7
crt.tgt crt.tgt
0 0
0 17
11 8

View File

@ -1,344 +1,191 @@
/**************************************************************************** /****************************************************************************
* *
* Open Watcom Project * Open Watcom Project
* *
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. * Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
* *
* ======================================================================== * ========================================================================
* *
* This file contains Original Code and/or Modifications of Original * This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom * Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file * Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO * except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is * ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also * provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource. * available at www.sybase.com/developer/opensource.
* *
* The Original Code and all software distributed under the License are * The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM * EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language * NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License. * governing rights and limitations under the License.
* *
* ======================================================================== * ========================================================================
* *
* Description: __chk8087 and other FPU related functions. * Description: __chk8087 and other FPU related functions.
* *
****************************************************************************/ ****************************************************************************/
#include "variety.h" #include "variety.h"
#include <stdlib.h> #include <stdlib.h>
#include <float.h> #include <float.h>
#if defined( __OS2__ ) #if defined( __OS2__ )
#endif #endif
#if defined( __WINDOWS__ ) #if defined( __WINDOWS__ )
#include <i86.h> #include <i86.h>
#endif #endif
#include "rtdata.h" #include "rtdata.h"
#include "exitwmsg.h" #include "exitwmsg.h"
#include "87state.h" #include "87state.h"
extern void __GrabFP87( void ); extern void __GrabFP87( void );
extern unsigned short __8087cw; extern unsigned short __8087cw;
#pragma aux __8087cw "*"; #pragma aux __8087cw "*";
#if defined( __DOS_086__ ) #if defined( __DOS_086__ )
extern unsigned char __dos87real; extern unsigned char __dos87real;
#pragma aux __dos87real "*"; #pragma aux __dos87real "*";
extern unsigned short __dos87emucall; extern unsigned short __dos87emucall;
#pragma aux __dos87emucall "*"; #pragma aux __dos87emucall "*";
#endif #endif
extern void __init_80x87( void ); extern void __init_80x87( void );
#if defined( __DOS_086__ ) #if defined( __DOS_086__ )
#pragma aux __init_80x87 "*" = \ #pragma aux __init_80x87 "*" = \
".8087" \ ".8087" \
"cmp __dos87real,0" \ "cmp __dos87real,0" \
"jz l1" \ "jz l1" \
"finit" \ "finit" \
"fldcw __8087cw" \ "fldcw __8087cw" \
"l1: cmp __dos87emucall,0" \ "l1: cmp __dos87emucall,0" \
"jz l2" \ "jz l2" \
"mov ax,1" \ "mov ax,1" \
"call __dos87emucall" \ "call __dos87emucall" \
"l2:" ; "l2:" ;
#else #else
#pragma aux __init_80x87 "*" = \ #pragma aux __init_80x87 "*" = \
".8087" \ ".8087" \
"finit" \ "finit" \
"fldcw __8087cw" ; "fldcw __8087cw" ;
#endif #endif
/* 0 => no 8087; 2 => 8087,287; 3=>387 */ /* 0 => no 8087; 2 => 8087,287; 3=>387 */
extern unsigned char _WCI86NEAR __x87id( void ); extern unsigned char _WCI86NEAR __x87id( void );
#pragma aux __x87id "*"; #pragma aux __x87id "*";
#if !defined( __UNIX__ ) && !defined( __OS2_386__ ) #if !defined( __UNIX__ ) && !defined( __OS2_386__ )
extern void __fsave( _87state * ); extern void __fsave( _87state * );
extern void __frstor( _87state * ); extern void __frstor( _87state * );
#if defined( __386__ ) #if defined( __386__ )
#pragma aux __fsave = \ #pragma aux __fsave = \
0x9b 0xdd 0x30 /* fsave [eax] ; save the 8087 state */ \ 0x9b 0xdd 0x30 /* fsave [eax] ; save the 8087 state */ \
0x9b /* wait */ \ 0x9b /* wait */ \
parm routine [eax]; parm routine [eax];
#pragma aux __frstor = \ #pragma aux __frstor = \
0xdd 0x20 /* frstor [eax] ; restore the 8087 */ \ 0xdd 0x20 /* frstor [eax] ; restore the 8087 */ \
0x9b /* wait ; wait */ \ 0x9b /* wait ; wait */ \
parm routine [eax]; parm routine [eax];
#else /* __286__ */ #else /* __286__ */
#if defined( __BIG_DATA__ ) #if defined( __BIG_DATA__ )
#pragma aux __fsave = \ #pragma aux __fsave = \
0x53 /* push bx */ \ 0x53 /* push bx */ \
0x1e /* push ds */ \ 0x1e /* push ds */ \
0x8e 0xda /* mov ds,dx */ \ 0x8e 0xda /* mov ds,dx */ \
0x8b 0xd8 /* mov bx,ax */ \ 0x8b 0xd8 /* mov bx,ax */ \
0x9b 0xdd 0x37 /* fsave [bx] */ \ 0x9b 0xdd 0x37 /* fsave [bx] */ \
0x90 0x9b /* fwait */ \ 0x90 0x9b /* fwait */ \
0x1f /* pop ds */ \ 0x1f /* pop ds */ \
0x5b /* pop bx */ \ 0x5b /* pop bx */ \
parm routine [dx ax]; parm routine [dx ax];
#else #else
#pragma aux __fsave = \ #pragma aux __fsave = \
0x53 /* push bx */ \ 0x53 /* push bx */ \
0x8b 0xd8 /* mov bx,ax */ \ 0x8b 0xd8 /* mov bx,ax */ \
0x9b 0xdd 0x37 /* fsave [bx] */ \ 0x9b 0xdd 0x37 /* fsave [bx] */ \
0x90 0x9b /* fwait */ \ 0x90 0x9b /* fwait */ \
0x5b /* pop bx */ \ 0x5b /* pop bx */ \
parm routine [ax]; parm routine [ax];
#endif #endif
#if defined( __BIG_DATA__ ) #if defined( __BIG_DATA__ )
#pragma aux __frstor = \ #pragma aux __frstor = \
0x53 /* push bx */ \ 0x53 /* push bx */ \
0x1e /* push ds */ \ 0x1e /* push ds */ \
0x8e 0xda /* mov ds,dx */ \ 0x8e 0xda /* mov ds,dx */ \
0x8b 0xd8 /* mov bx,ax */ \ 0x8b 0xd8 /* mov bx,ax */ \
0x9b 0xdd 0x27 /* frstor [bx] */ \ 0x9b 0xdd 0x27 /* frstor [bx] */ \
0x90 0x9b /* fwait */ \ 0x90 0x9b /* fwait */ \
0x1f /* pop ds */ \ 0x1f /* pop ds */ \
0x5b /* pop bx */ \ 0x5b /* pop bx */ \
parm routine [dx ax]; parm routine [dx ax];
#else #else
#pragma aux __frstor = \ #pragma aux __frstor = \
0x53 /* push bx */ \ 0x53 /* push bx */ \
0x8b 0xd8 /* mov bx,ax */ \ 0x8b 0xd8 /* mov bx,ax */ \
0x9b 0xdd 0x27 /* frstor [bx] */ \ 0x9b 0xdd 0x27 /* frstor [bx] */ \
0x90 0x9b /* fwait */ \ 0x90 0x9b /* fwait */ \
0x5b /* pop bx */ \ 0x5b /* pop bx */ \
parm routine [ax]; parm routine [ax];
#endif #endif
#endif #endif
static void __save_8087( _87state * __fs ) static void __save_8087( _87state * __fs )
{ {
__fsave( __fs ); __fsave( __fs );
} }
static void __rest_8087( _87state * __fs ) static void __rest_8087( _87state * __fs )
{ {
__frstor( __fs ); __frstor( __fs );
} }
#endif /* !__UNIX__ && && !__OS2__ */ #endif /* !__UNIX__ && && !__OS2__ */
_WCRTLINK void _fpreset( void ) _WCRTLINK void _fpreset( void )
{ {
if( _RWD_8087 != 0 ) { if( _RWD_8087 != 0 ) {
__init_80x87(); __init_80x87();
} }
} }
void __init_8087( void ) void __init_8087( void )
{ {
#if !defined( __UNIX__ ) && !defined( __OS2_386__ ) #if !defined( __UNIX__ ) && !defined( __OS2_386__ )
if( _RWD_real87 != 0 ) if( _RWD_real87 != 0 )
{ /* if our emulator, don't worry */ { /* if our emulator, don't worry */
_RWD_Save8087 = __save_8087; /* point to real save 8087 routine */ _RWD_Save8087 = __save_8087; /* point to real save 8087 routine */
_RWD_Rest8087 = __rest_8087; /* point to real restore 8087 routine */ _RWD_Rest8087 = __rest_8087; /* point to real restore 8087 routine */
} }
#endif #endif
_fpreset(); _fpreset();
} }
#if defined( __DOS__ ) || defined( __OS2_286__ ) #if defined( __DOS__ ) || defined( __OS2_286__ )
void _WCI86FAR __default_sigfpe_handler( int fpe_sig ) void _WCI86FAR __default_sigfpe_handler( int fpe_sig )
{ {
__fatal_runtime_error( "Floating point exception\r\n", EXIT_FAILURE ); __fatal_runtime_error( "Floating point exception\r\n", EXIT_FAILURE );
} }
#endif #endif
#if defined( __OS2__ ) void __chk8087( void )
/********************/
void __chk8087( void ) {
/********************/ _RWD_real87 = __x87id();
{ _RWD_8087 = _RWD_real87;
char devinfo; __init_8087();
__GrabFP87();
#if defined( __386__ ) }
DosDevConfig( &devinfo, DEVINFO_COPROCESSOR );
if( devinfo == 0 ) {
_RWD_real87 = 0;
} else {
_RWD_real87 = __x87id();
}
_RWD_8087 = _RWD_real87;
#else
if( _RWD_8087 == 0 ) {
DosDevConfig( &devinfo, 3, 0 );
if( devinfo == 0 ) {
_RWD_real87 = 0;
} else {
_RWD_real87 = __x87id();
}
_RWD_8087 = _RWD_real87;
}
if( _RWD_real87 ) {
__GrabFP87();
}
if( _RWD_8087 ) {
_RWD_FPE_handler = __default_sigfpe_handler;
}
#endif
_fpreset();
}
#elif defined( __QNX__ )
void __chk8087( void )
/********************/
{
extern char __87;
extern char __r87;
_RWD_real87 = __r87;
_RWD_8087 = __87;
_fpreset();
}
#elif defined( __LINUX__ )
void __chk8087( void )
/********************/
{
// TODO: We really need to call Linux and determine if the machine
// has a real FPU or not, so we can properly work with an FPU
// emulator.
_RWD_real87 = __x87id();
_RWD_8087 = _RWD_real87;
_fpreset();
}
#elif defined( __NETWARE__ )
extern short __87present( void );
#pragma aux __87present = \
"smsw ax ", \
"test ax, 4 ", \
"jne no_emu ", \
"xor ax, ax ", \
"no_emu: ", \
"mov ax, 1 " \
value [ ax ];
extern void __chk8087( void )
/*****************************/
{
if( _RWD_8087 == 0 ) {
if( __87present() ) {
_RWD_8087 = 3; /* 387 */
_RWD_real87 = 3;
}
__init_80x87();
}
}
#elif defined( __NT__ )
void __chk8087( void )
/********************/
{
_RWD_real87 = __x87id();
_RWD_8087 = _RWD_real87;
__init_8087();
}
#elif defined( __DOS__ )
void __chk8087( void )
/********************/
{
if( _RWD_8087 != 0 ) { /* if we already know we have an 80x87 */
#if !defined( __386__ )
if( __dos87real )
__GrabFP87();
#endif
_RWD_FPE_handler = __default_sigfpe_handler;
return; /* this prevents real87 from being set */
} /* when we have an emulator */
_RWD_real87 = __x87id(); /* if a coprocessor is present then we */
_RWD_8087 = _RWD_real87; /* initialize even when NO87 is defined */
#if !defined( __386__ )
__dos87real = _RWD_real87;
#endif
__init_8087(); /* this handles the fpi87 and NO87 case */
if( _RWD_no87 != 0 ) { /* if NO87 environment var is defined */
_RWD_8087 = 0; /* then we want to pretend that the */
_RWD_real87 = 0; /* coprocessor doesn't exist */
}
if( _RWD_real87 ) {
__GrabFP87();
}
if( _RWD_8087 ) {
_RWD_FPE_handler = __default_sigfpe_handler;
}
}
#elif defined( __WINDOWS__ )
void __chk8087( void )
/********************/
{
if( _RWD_8087 != 0 ) /* if we already know we have an 80x87 */
return; /* this prevents real87 from being set */
/* when we have an emulator */
if( GetWinFlags() & WF_80x87 ) { /* if a coprocessor is present then we */
#if defined( __386__ )
extern void pascal _FloatingPoint( void );
_FloatingPoint();
#endif
_RWD_real87 = __x87id(); /* initialize even when NO87 is defined */
_RWD_8087 = _RWD_real87; /* this handles the fpi87 and NO87 case */
__init_8087();
} else {
#if defined( __386__ )
// check to see if emulator is loaded
union REGS regs;
regs.w.ax = 0xfa00;
int86( 0x2f, &regs, &regs );
if( regs.w.ax == 0x0666 ) { /* check for emulator present */
_RWD_real87 = __x87id(); /* initialize even when NO87 is defined */
_RWD_8087 = _RWD_real87; /* this handles the fpi87 and NO87 case */
__init_8087();
}
#endif
}
if( _RWD_no87 != 0 ) { /* if NO87 environment var is defined */
_RWD_8087 = 0; /* then we want to pretend that the */
_RWD_real87 = 0; /* coprocessor doesn't exist */
}
}
#endif

View File

@ -0,0 +1,102 @@
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: Connect/disconnect 80x87 interrupt handler.
;*
;*****************************************************************************
.8087
.386p
include struct.inc
include mdef.inc
xref __FPE2Handler_
modstart fpe387
datasegment
Save87 dd 0
enddata
xdefp "C",__Init_FPE_handler
defp __Init_FPE_handler
_guess ; guess initialization required
cmp dword ptr Save87,0 ; - quit if already initialized
_quif ne ; - ...
_admit ; admit: already initialized
ret ; - return
_endguess ; endguess
push EAX ; save registers
push EBX ; ...
push ECX ; ...
mov EAX, 68
mov EBX, 15
lea ECX, __FPE2Handler_
int 40h ; set new #FPE handler
mov Save87, EAX ; save old handler
pop ECX ; ...
pop EBX ; ...
pop EAX ; ...
ret ; return
endproc __Init_FPE_handler
xdefp "C",__Fini_FPE_handler
defp __Fini_FPE_handler
cmp dword ptr Save87,0 ; if not initialized
_if e ; - then
ret ; - return
_endif ; endif
push EAX ; save registers
push EBX ; ...
push EDX ; ...
sub ESP,4 ; allocate space for control word
fstcw word ptr [ESP] ; get control word
fwait ; ...
mov byte ptr [ESP],7Fh ; disable exception interrupts
fldcw word ptr [ESP] ; ...
fwait ; ...
add ESP,4 ; remove temporary
mov EAX, 68
mov EBX, 15
mov ECX, dword ptr Save87
int 40h ; set new #FPE handler
pop EDX ; ...
pop EBX ; ...
pop EAX ; ...
ret
endproc __Fini_FPE_handler
endmod
end

View File

@ -1,374 +1,329 @@
;***************************************************************************** ;*****************************************************************************
;* ;*
;* Open Watcom Project ;* Open Watcom Project
;* ;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. ;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;* ;*
;* ======================================================================== ;* ========================================================================
;* ;*
;* This file contains Original Code and/or Modifications of Original ;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom ;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file ;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO ;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is ;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also ;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource. ;* available at www.sybase.com/developer/opensource.
;* ;*
;* The Original Code and all software distributed under the License are ;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM ;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF ;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language ;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License. ;* governing rights and limitations under the License.
;* ;*
;* ======================================================================== ;* ========================================================================
;* ;*
;* Description: 80x87 interrupt handler. ;* Description: 80x87 interrupt handler.
;* ;*
;***************************************************************************** ;*****************************************************************************
;;; //e:\watcom\src\bld\watcom\h;E:\WATCOM\H;E:\WATCOM\H\NT ;;; //e:\watcom\src\bld\watcom\h;E:\WATCOM\H;E:\WATCOM\H\NT
.8087 .8087
.386p .386p
include struct.inc include struct.inc
include mdef.inc include mdef.inc
include stword.inc include stword.inc
include env387.inc include env387.inc
include fstatus.inc include fstatus.inc
ifndef __NETWARE__ xref __8087 ; indicate that NDP instructions are present
xref __GETDS
endif modstart fpeinth
xref __8087 ; indicate that NDP instructions are present
datasegment
modstart fpeinth
extrn __FPE_exception_: proc
datasegment extrn "C",_STACKLOW : dword
extrn __FPE_exception_: proc TInf db 00h,00h,00h,00h,00h,00h,00h,80h,0ffh,7fh
extrn "C",_STACKLOW : dword F8Inf db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0efh,7fh
F4Inf db 0ffh,0ffh,7fh,7fh
TInf db 00h,00h,00h,00h,00h,00h,00h,80h,0ffh,7fh enddata
F8Inf db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0efh,7fh
F4Inf db 0ffh,0ffh,7fh,7fh ; User handler for 80x87 exceptions.
db 512 dup(0)
FPEStk label byte xdefp __FPEHandler_
SaveSS dw 0 defp __FPEHandler_
SaveESP dd 0
enddata public __FPE2Handler_
__FPE2Handler_ label byte
; Interrupt handler for 80x87 exceptions. push EAX ; save regs
push EBX ; ...
xdefp __FPEHandler_ push ECX ; ...
defp __FPEHandler_ push EDX ; ...
public "C",__FPEHandlerStart_ push ESI ; ...
__FPEHandlerStart_ label byte push EDI ; ...
push EAX ; save reg push EBP ; ...
mov AL,20h ; issue EOI to 8259 controller sub ESP,ENV_SIZE ; make room for environment information
out 20h,AL ; ... mov EBP,ESP ; point to buffer for 80x87 environment
out 0a0h,AL ; issue EOI to slave 8259 fnstenv [EBP] ; get 80x87 environment
xor AX,AX ; clear busy signal fwait ; wait for 80x87
out 0f0h,AL ; ... mov EDX,ENV_CW[EBP] ; get control word
pop EAX ; restore regs not EDX ; flip the mask bits
public __FPE2Handler_ mov DH,0FFh ; turn on top byte
__FPE2Handler_ label byte and EDX,ENV_SW[EBP] ; get status word
push EAX ; save regs mov EDI,ENV_IP[EBP] ; ...
push EBX ; ... opcode:
push ECX ; ... mov BX,[EDI] ; get opcode
push EDX ; ... inc EDI ; point to next opcode
push ESI ; ... cmp BL,0d8h ; check if its the opcode
push EDI ; ... jb opcode ; ...
push EBP ; ... cmp BL,0dfh ; ...
push DS ; ... ja opcode ; ...
push ES ; ... mov EDI,ENV_OP[EBP] ; ...
sub ESP,ENV_SIZE ; make room for environment information xchg BL,BH ; get opcode in right position
mov EBP,ESP ; point to buffer for 80x87 environment mov CL,FPE_OK ; assume exception to be ignored
fnstenv [EBP] ; get 80x87 environment _guess ; guess precision exception
fwait ; wait for 80x87 test DL,ST_EF_PR ; - check for precision exception
fdisi ; disable interrupts _quif e ; - quit if not precision exception
sti ; enable CPU interrupts mov CL,FPE_INEXACT ; - indicate precision exception
ifndef __NETWARE__ _admit ; guess stack under/overflow
; call __GETDS ; load DS test DL,ST_EF_SF ; - check for stack under/overflow
endif _quif e ; - quit if not stack under/overflow
ifdef __NETWARE__ test DX,ST_C1 ; - check if underflow
; push SS ; load DS _if e ; - if underflow
; pop DS ; ... mov CL,FPE_STACKUNDERFLOW ; - - indicate stack underflow
endif _else ; - else
mov EDX,ENV_CW[EBP] ; get control word mov CL,FPE_STACKOVERFLOW ; - - indicate stack overflow
not EDX ; flip the mask bits _endif ; - endif
mov DH,0FFh ; turn on top byte _admit ; guess invalid operation
and EDX,ENV_SW[EBP] ; get status word test DL,ST_EF_IO ; - check for invalid operation
; mov ES,ENV_IP+4[EBP] ; get intruction address _quif e ; - quit if not invalid operation
mov EDI,ENV_IP[EBP] ; ... call InvalidOp ; - process invalid operation
opcode: mov BX,[EDI] ; get opcode _admit ; guess denormal operand
inc EDI ; point to next opcode test DL,ST_EF_DO ; - check for denormal operand
cmp BL,0d8h ; check if its the opcode _quif e ; - quit if not denormal operand
jb opcode ; ... mov CL,FPE_DENORMAL ; - indicate underflow
cmp BL,0dfh ; ... _admit ; guess overflow
ja opcode ; ... test DL,ST_EF_OF ; - check for overflow
; mov ES,ENV_OP+4[EBP] ; get pointer to operand _quif e ; - quit if not overflow
mov EDI,ENV_OP[EBP] ; ... call KOOverFlow ; - process overflow exception
xchg BL,BH ; get opcode in right position mov CL,FPE_OVERFLOW ; - set floating point error code
mov CL,FPE_OK ; assume exception to be ignored _admit ; guess underflow
_guess ; guess precision exception test DL,ST_EF_UF ; - check for underflow
test DL,ST_EF_PR ; - check for precision exception _quif e ; - quit if not underflow
_quif e ; - quit if not precision exception mov CL,FPE_UNDERFLOW ; - indicate underflow
mov CL,FPE_INEXACT ; - indicate precision exception _admit ; guess divide by 0
_admit ; guess stack under/overflow test DL,ST_EF_ZD ; - check for divide by zero
test DL,ST_EF_SF ; - check for stack under/overflow _quif e ; - quit if not divide by zero
_quif e ; - quit if not stack under/overflow call GetInf ; - process divide by zero
test DX,ST_C1 ; - check if underflow mov CL,FPE_ZERODIVIDE ; - indicate divide by zero
_if e ; - if underflow _endguess ; endguess
mov CL,FPE_STACKUNDERFLOW ; - - indicate stack underflow _guess ; guess exception to be handled
_else ; - else cmp CL,FPE_OK ; - check if exception allowed
mov CL,FPE_STACKOVERFLOW ; - - indicate stack overflow _quif e ; - quit if exception not allowed
_endif ; - endif movzx EAX,CL ; - set floating point status
_admit ; guess invalid operation call __FPE_exception_ ; - call user's handler
test DL,ST_EF_IO ; - check for invalid operation _endguess ; endguess
_quif e ; - quit if not invalid operation fclex ; clear exceptions that may have
call InvalidOp ; - process invalid operation ; occurred as a result of handling the
_admit ; guess denormal operand ; exception
test DL,ST_EF_DO ; - check for denormal operand and word ptr ENV_CW[EBP],0FF72h
_quif e ; - quit if not denormal operand fldcw word ptr ENV_CW[EBP] ; enable interrupts
mov CL,FPE_DENORMAL ; - indicate underflow fwait ; ...
_admit ; guess overflow add ESP,ENV_SIZE ; clean up stack
test DL,ST_EF_OF ; - check for overflow pop EBP ; ...
_quif e ; - quit if not overflow pop EDI ; ...
call KOOverFlow ; - process overflow exception pop ESI ; ...
mov CL,FPE_OVERFLOW ; - set floating point error code pop EDX ; ...
_admit ; guess underflow pop ECX ; ...
test DL,ST_EF_UF ; - check for underflow pop EBX ; ...
_quif e ; - quit if not underflow pop EAX ; ...
mov CL,FPE_UNDERFLOW ; - indicate underflow ret ; return from interrupt handler
_admit ; guess divide by 0
test DL,ST_EF_ZD ; - check for divide by zero endproc __FPEHandler_
_quif e ; - quit if not divide by zero
call GetInf ; - process divide by zero ; Process invalid operation.
mov CL,FPE_ZERODIVIDE ; - indicate divide by zero
_endguess ; endguess InvalidOp proc near
_guess ; guess exception to be handled mov CL,FPE_INVALID ; assume invalid operation
cmp CL,FPE_OK ; - check if exception allowed _guess ; guess it's square root
_quif e ; - quit if exception not allowed cmp BX,0D9FAh ; - ...
; cmp SaveSS,0 ; - check if already in handler _quif ne ; - quit if it's not that instruction
; _quif ne ; - quit if already in handler mov CL,FPE_SQRTNEG ; - indicate sqrt(negative number)
push _STACKLOW ; - save old stack low ret ; - return
mov SaveSS,SS ; - save current stack pointer _endguess ; endguess
mov SaveESP,ESP ; - ... _guess ; guess it's square root
push DS ; - get new stack pointer cmp BX,0D9F1h ; - ...
pop SS ; - ... _quif ne ; - quit if it's not that instruction
lea ESP,FPEStk ; - ... mov CL,FPE_LOGERR ; - indicate sqrt(negative number)
lea EAX,FPEStk-512 ; - set stack low variable ret ; - return
mov _STACKLOW,EAX ; - set stack low variable _endguess ; endguess
movzx EAX,CL ; - set floating point status _guess ; guess: 'fprem' instruction
call __FPE_exception_ ; - call user's handler cmp BX,0D9F8h ; - check for 'fprem' 10-may-90
mov SS,SaveSS ; - restore stack pointer _if ne ; - if not 'fprem'
mov ESP,SaveESP ; - ... cmp BX,0D9F5h ; - - check for 'fprem1'
pop _STACKLOW ; - restore old stacklow _endif ; - endif
mov SaveSS,0 ; - indicate handler can be re-entered _quif ne ; - quit if not 'fprem' or 'fprem1'
_endguess ; endguess mov CL,FPE_MODERR ; - indicate mod(negative number)
fclex ; clear exceptions that may have _admit ; guess: integer overflow
; occurred as a result of handling the mov DX,BX ; - save op code
; exception and DX,0310h ; - check for fist/fistp instruction
and word ptr ENV_CW[EBP],0FF72h cmp DX,0310h ; - ...
fldcw word ptr ENV_CW[EBP] ; enable interrupts _quif ne ; - quit if its not that instruction
fwait ; ... mov CL,FPE_IOVERFLOW ; - indicate integer overflow
add ESP,ENV_SIZE ; clean up stack _admit ; guess it's floating point underflow
pop ES ; restore registers ;; mov DX,BX ; - save op code
pop DS ; ... and DX,0110h ; - check if fst or fstp instruction
pop EBP ; ... cmp DX,0110h ; - ...
pop EDI ; ... _quif ne ; - quit if it's not that instruction
pop ESI ; ... ; Destination is short or long real and source register is an unnormal
pop EDX ; ... ; with exponent in range.
pop ECX ; ... fstp st(0) ; - pop old result
pop EBX ; ... fldz ; - load zero
pop EAX ; ... mov DL,BL ; - save op code
iretd ; return from interrupt handler and DL,0C0h ; - check the MOD bits of instruction
public "C",__FPEHandlerEnd_ cmp DL,0C0h ; - ...
__FPEHandlerEnd_ label byte _if ne ; - if result to be placed in memory
endproc __FPEHandler_ call Store ; - - store result in memory
_endif ; - endif
test BL,08h ; - check if result to be popped
; Process invalid operation. _if ne ; - if result to be popped
fstp st(0) ; - - pop the result
InvalidOp proc near _endif ; - endif
mov CL,FPE_INVALID ; assume invalid operation mov CL,FPE_UNDERFLOW ; - indicate underflow
_guess ; guess it's square root _admit ; guess it's divide
cmp BX,0D9FAh ; - ... mov DX,BX ; - save op code
_quif ne ; - quit if it's not that instruction and DX,0130h ; - check for fdiv/fidiv instruction
mov CL,FPE_SQRTNEG ; - indicate sqrt(negative number) cmp DX,0030h ; - ...
ret ; - return _quif ne ; - quit if it's not that instruction
_endguess ; endguess mov DX,ENV_TW[EBP] ; - get tag word
_guess ; guess it's square root mov CL,AH ; - get stack pointer
cmp BX,0D9F1h ; - ... and CL,38h ; - ...
_quif ne ; - quit if it's not that instruction shr CL,2 ; - ...
mov CL,FPE_LOGERR ; - indicate sqrt(negative number) ror DX,CL ; - make stack top low order bits
ret ; - return and DL,05h ; - check if top two elements are 0
_endguess ; endguess cmp DL,05h ; - ...
_guess ; guess: 'fprem' instruction _quif ne ; - quif if they are not 0
cmp BX,0D9F8h ; - check for 'fprem' 10-may-90 mov CL,FPE_ZERODIVIDE ; - indicate divide by zero
_if ne ; - if not 'fprem' _endguess ; endguess
cmp BX,0D9F5h ; - - check for 'fprem1' ret
_endif ; - endif endproc InvalidOp
_quif ne ; - quit if not 'fprem' or 'fprem1'
mov CL,FPE_MODERR ; - indicate mod(negative number)
_admit ; guess: integer overflow ; Process overflow exception (note that only floating point overflows
mov DX,BX ; - save op code ; are handled - integer overflows are invalid operations).
and DX,0310h ; - check for fist/fistp instruction
cmp DX,0310h ; - ... KOOverFlow proc near
_quif ne ; - quit if its not that instruction _guess ; guess: fscale instruction 10-may-90
mov CL,FPE_IOVERFLOW ; - indicate integer overflow cmp BX,0D9FDh ; - quit if not 'fscale' instruction
_admit ; guess it's floating point underflow _quif ne ; - ...
;; mov DX,BX ; - save op code _admit ; guess: fst/fstp instruction
and DX,0110h ; - check if fst or fstp instruction mov DX,BX ; - save op code
cmp DX,0110h ; - ... and DX,0110h ; - check if fst or fstp instruction
_quif ne ; - quit if it's not that instruction cmp DX,0110h ; - ...
; Destination is short or long real and source register is an unnormal _quif ne ; - quit if not an fst/fstp instr.
; with exponent in range. call GetInf ; - load infinity
fstp st(0) ; - pop old result mov DL,BL ; - save op code
fldz ; - load zero and DL,0C0h ; - check the MOD bits of instruction
mov DL,BL ; - save op code cmp DL,0C0h ; - ...
and DL,0C0h ; - check the MOD bits of instruction _if ne ; - if result to be placed in memory
cmp DL,0C0h ; - ... call Store ; - - store infinity
_if ne ; - if result to be placed in memory _endif ; - endif
call Store ; - - store result in memory test BL,08h ; - check if result to be popped
_endif ; - endif _if ne ; - if result to be popped
test BL,08h ; - check if result to be popped fstp st(0) ; - - pop result
_if ne ; - if result to be popped _endif ; - endif
fstp st(0) ; - - pop the result _admit ; admit arithmetic operation
_endif ; - endif mov DL,BL ; - save op code
mov CL,FPE_UNDERFLOW ; - indicate underflow and DL,0C0h ; - check if both operands on stack
_admit ; guess it's divide cmp DL,0C0h ; - ...
mov DX,BX ; - save op code _quif ne ; - quif both operands not on stack
and DX,0130h ; - check for fdiv/fidiv instruction ;
cmp DX,0030h ; - ... ; This code handles overflow on the following intructions:
_quif ne ; - quit if it's not that instruction ; fxxx ST,ST(i)
mov DX,ENV_TW[EBP] ; - get tag word ; fxxx ST(i),ST where xxx is one of mul,div,sub or add
mov CL,AH ; - get stack pointer ; fxxxp ST(i),ST
and CL,38h ; - ... ;
shr CL,2 ; - ... lea ESI,TInf ; - load internal infinity
ror DX,CL ; - make stack top low order bits call Load ; - ...
and DL,05h ; - check if top two elements are 0 _admit ; admit
cmp DL,05h ; - ... ;
_quif ne ; - quif if they are not 0 ; This admit block is to handle overflow on the following intructions:
mov CL,FPE_ZERODIVIDE ; - indicate divide by zero ; fxxx short real
_endguess ; endguess ; fxxx long real where xxx is one of mul,div,sub or add
ret ;
endproc InvalidOp call GetInf ; - load infinity
_endguess ; endguess
ret ; return
; Process overflow exception (note that only floating point overflows endproc KOOverFlow
; are handled - integer overflows are invalid operations).
KOOverFlow proc near ; Replace the top element of the stack with the appropriate signed
_guess ; guess: fscale instruction 10-may-90 ; infinity.
cmp BX,0D9FDh ; - quit if not 'fscale' instruction
_quif ne ; - ... GetInf proc near
_admit ; guess: fst/fstp instruction ftst ; get sign of result
mov DX,BX ; - save op code fstsw word ptr ENV_OP[EBP]
and DX,0110h ; - check if fst or fstp instruction fstp st(0) ; pop argument off stack (does fwait)
cmp DX,0110h ; - ... test BH,04h ; check if single or double
_quif ne ; - quit if not an fst/fstp instr. _if ne ; if double
call GetInf ; - load infinity fld qword ptr F8Inf ; - load double precision infinity
mov DL,BL ; - save op code _else ; else
and DL,0C0h ; - check the MOD bits of instruction fld dword ptr F4Inf ; - load single precision infinity
cmp DL,0C0h ; - ... _endif ; endif
_if ne ; - if result to be placed in memory test word ptr ENV_OP[EBP],ST_C0
call Store ; - - store infinity _if ne ; if argument is negative
_endif ; - endif fchs ; - return negative infinity
test BL,08h ; - check if result to be popped _endif ; endif
_if ne ; - if result to be popped ret ; return
fstp st(0) ; - - pop result endproc GetInf
_endif ; - endif
_admit ; admit arithmetic operation
mov DL,BL ; - save op code ; Replace an element on the stack with internal zero or infinity.
and DL,0C0h ; - check if both operands on stack
cmp DL,0C0h ; - ... Load proc near
_quif ne ; - quif both operands not on stack test BH,04h ; check if result is top element
; _if e ; if result is not top element
; This code handles overflow on the following intructions: mov DL,0 ; - indicate we are at the top
; fxxx ST,ST(i) _else ; else
; fxxx ST(i),ST where xxx is one of mul,div,sub or add mov DL,BL ; - get st(i)
; fxxxp ST(i),ST and DL,07h ; - . . .
; _endif ; endif
lea ESI,TInf ; - load internal infinity push EDX ; save st(i)
call Load ; - ... _loop ; loop
_admit ; admit dec DL ; - decrement counter
; _quif l ; - quit if we are at st(i)
; This admit block is to handle overflow on the following intructions: fincstp ; - increment stack pointer
; fxxx short real _endloop ; endloop
; fxxx long real where xxx is one of mul,div,sub or add fstp st(0) ; free the stack element
; fld tbyte ptr [ESI] ; load internal zero
call GetInf ; - load infinity pop EDX ; get st(i)
_endguess ; endguess _loop ; loop
ret ; return dec DL ; - decrement counter
endproc KOOverFlow _quif l ; - quit if we are at st(i)
fdecstp ; - decrement stack pointer
_endloop ; endloop
; Replace the top element of the stack with the appropriate signed ret ; return
; infinity. endproc Load
GetInf proc near
ftst ; get sign of result ; Store the top element of the stack at ES:EDI.
fstsw word ptr ENV_OP[EBP]
fstp st(0) ; pop argument off stack (does fwait) Store proc near
test BH,04h ; check if single or double test BH,04h
_if ne ; if double _if ne ; if double
fld qword ptr F8Inf ; - load double precision infinity fst qword ptr [EDI] ; - store as double precision result
_else ; else _else ; else
fld dword ptr F4Inf ; - load single precision infinity fst dword ptr [EDI] ; - store as single precision result
_endif ; endif _endif ; endif
test word ptr ENV_OP[EBP],ST_C0 ret ; return
_if ne ; if argument is negative endproc Store
fchs ; - return negative infinity
_endif ; endif endmod
ret ; return end
endproc GetInf
; Replace an element on the stack with internal zero or infinity.
Load proc near
test BH,04h ; check if result is top element
_if e ; if result is not top element
mov DL,0 ; - indicate we are at the top
_else ; else
mov DL,BL ; - get st(i)
and DL,07h ; - . . .
_endif ; endif
push EDX ; save st(i)
_loop ; loop
dec DL ; - decrement counter
_quif l ; - quit if we are at st(i)
fincstp ; - increment stack pointer
_endloop ; endloop
fstp st(0) ; free the stack element
fld tbyte ptr [ESI] ; load internal zero
pop EDX ; get st(i)
_loop ; loop
dec DL ; - decrement counter
_quif l ; - quit if we are at st(i)
fdecstp ; - decrement stack pointer
_endloop ; endloop
ret ; return
endproc Load
; Store the top element of the stack at ES:EDI.
Store proc near
test BH,04h
_if ne ; if double
fst qword ptr ES:[EDI] ; - store as double precision result
_else ; else
fst dword ptr ES:[EDI] ; - store as single precision result
_endif ; endif
ret ; return
endproc Store
endmod
end

View File

@ -0,0 +1,43 @@
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: typedef for external signal routines and
* prototypes for other signal internal function
*
****************************************************************************/
#include "extfunc.h"
typedef void (*__sigfpe_func)( int, int );
#ifdef _M_IX86
#pragma aux (__outside_CLIB) __sig_func;
#pragma aux (__outside_CLIB) __sigfpe_func;
#endif
_WCRTLINK extern void __sigfpe_handler( int );
extern void __sigabort( void );
extern void __restore_FPE_handler( void );
extern void __grab_FPE_handler( void );

View File

@ -0,0 +1,33 @@
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#define __SIGNALTABLE SignalTable

View File

@ -36,24 +36,11 @@
extern void __Init_FPE_handler(); extern void __Init_FPE_handler();
extern void __Fini_FPE_handler(); extern void __Fini_FPE_handler();
#ifdef __DOS_386__
extern int __FPEHandlerStart_;
extern int __FPEHandlerEnd_;
extern int __DPMI_hosted(void);
#endif
void __GrabFP87( void ) void __GrabFP87( void )
{ {
#ifndef __WINDOWS__
if( _RWD_FPE_handler_exit != __Fini_FPE_handler ) { if( _RWD_FPE_handler_exit != __Fini_FPE_handler ) {
#ifdef __DOS_386__
if( !_IsPharLap() && ( __DPMI_hosted() == 1 )) {
DPMILockLinearRegion((long)&__FPEHandlerStart_,
((long)&__FPEHandlerEnd_ - (long)&__FPEHandlerStart_));
}
#endif
__Init_FPE_handler(); __Init_FPE_handler();
_RWD_FPE_handler_exit = __Fini_FPE_handler; _RWD_FPE_handler_exit = __Fini_FPE_handler;
} }
#endif
} }

View File

@ -0,0 +1,187 @@
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: signal handling ( for DOS, Windows 3.x and ? Netware )
*
****************************************************************************/
#include "variety.h"
#include <stdio.h>
#include <signal.h>
//#include <dos.h>
#include <errno.h>
#include <float.h>
#include "rtdata.h"
#include "sigtab.h"
#include "sigfunc.h"
#include "seterrno.h"
#ifndef __WINDOWS_386__
#ifndef __NETWARE__
//extern void __grab_int23( void );
//extern void __restore_int23( void );
//extern void __grab_int_ctrl_break( void );
//extern void __restore_int_ctrl_break( void );
#endif
#endif
#define __SIGLAST SIGIOVFL
static __sig_func SignalTable[] = {
SIG_IGN, /* unused */
SIG_DFL, /* SIGABRT */
SIG_DFL, /* SIGFPE */
SIG_DFL, /* SIGILL */
SIG_DFL, /* SIGINT */
SIG_DFL, /* SIGSEGV */
SIG_DFL, /* SIGTERM */
SIG_DFL, /* SIGBREAK */
SIG_IGN, /* SIGUSR1 */
SIG_IGN, /* SIGUSR2 */
SIG_IGN, /* SIGUSR3 */
SIG_DFL, /* SIGIDIVZ */
SIG_DFL /* SIGIOVFL */
};
static FPEhandler *__old_FPE_handler = NULL;
void __sigabort( void )
{
raise( SIGABRT );
}
//extern void _fpmath( void );
//#pragma aux _fpmath "__fpmath";
_WCRTLINK void __sigfpe_handler( int fpe_type )
{
__sig_func func;
func = SignalTable[ SIGFPE ];
if( func != SIG_IGN && func != SIG_DFL && func != SIG_ERR ) {
SignalTable[ SIGFPE ] = SIG_DFL; /* 09-nov-87 FWC */
(*(__sigfpe_func)func)( SIGFPE, fpe_type ); /* so we can pass 2'nd parm */
}
}
_WCRTLINK __sig_func signal( int sig, __sig_func func )
{
__sig_func prev_func;
if(( sig < 1 ) || ( sig > __SIGLAST )) {
__set_errno( EINVAL );
return( SIG_ERR );
}
_RWD_abort = __sigabort; /* change the abort rtn address */
if( sig == SIGINT ) {
if( func == SIG_DFL ) {
// __restore_int23();
} else if( func != SIG_ERR ) {
// __grab_int23();
}
} else if( sig == SIGBREAK ) {
if( func == SIG_DFL ) {
// __restore_int_ctrl_break();
} else if( func != SIG_ERR ) {
// __grab_int_ctrl_break();
}
} else if( sig == SIGFPE ) {
if( func == SIG_DFL ) {
__restore_FPE_handler();
} else if( func != SIG_ERR ) {
__grab_FPE_handler();
}
}
prev_func = _RWD_sigtab[ sig ];
_RWD_sigtab[ sig ] = func;
return( prev_func );
}
_WCRTLINK int raise( int sig )
{
__sig_func func;
func = _RWD_sigtab[ sig ];
switch( sig ) {
case SIGFPE:
__sigfpe_handler( FPE_EXPLICITGEN );
break;
case SIGABRT:
if( func == SIG_DFL ) {
__terminate();
}
case SIGINT:
if( func != SIG_IGN && func != SIG_DFL && func != SIG_ERR ) {
_RWD_sigtab[ sig ] = SIG_DFL; /* 09-nov-87 FWC */
// __restore_int23();
(*func)( sig );
}
break;
case SIGBREAK:
if( func != SIG_IGN && func != SIG_DFL && func != SIG_ERR ) {
_RWD_sigtab[ sig ] = SIG_DFL; /* 09-nov-87 FWC */
// __restore_int_ctrl_break();
(*func)( sig );
}
break;
case SIGILL:
case SIGSEGV:
case SIGTERM:
case SIGUSR1:
case SIGUSR2:
case SIGUSR3:
case SIGIDIVZ:
case SIGIOVFL:
if( func != SIG_IGN && func != SIG_DFL && func != SIG_ERR ) {
_RWD_sigtab[ sig ] = SIG_DFL; /* 09-nov-87 FWC */
(*func)( sig );
}
break;
default:
return( -1 );
}
return( 0 );
}
void __restore_FPE_handler( void )
{
if( __old_FPE_handler == NULL ) {
return;
}
__FPE_handler = __old_FPE_handler;
__old_FPE_handler = NULL;
}
void __grab_FPE_handler( void )
{
if( __old_FPE_handler == NULL ) {
__old_FPE_handler = __FPE_handler;
__FPE_handler = __sigfpe_handler;
}
}

File diff suppressed because it is too large Load Diff