From owner-freebsd-hackers Sun Oct 22 23:26:48 1995 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id XAA23856 for hackers-outgoing; Sun, 22 Oct 1995 23:26:48 -0700 Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id XAA23851 for ; Sun, 22 Oct 1995 23:26:44 -0700 Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.9/8.6.9) id QAA15714; Mon, 23 Oct 1995 16:25:25 +1000 Date: Mon, 23 Oct 1995 16:25:25 +1000 From: Bruce Evans Message-Id: <199510230625.QAA15714@godzilla.zeta.org.au> To: freebsd-hackers@freebsd.org, peter@citylink.dinoex.sub.org Subject: Re: modf.S (in libc.a): stack access fault Sender: owner-hackers@freebsd.org Precedence: bulk >The funktion modf() (in libc.a, from lib/libc/i386/gen/modf.S) seems to >dismangle the program stack. This is the reason why ingres cannot handle >float values with FreeBSD (and other OS's - i reported that here, somewhen >about May). If linked with lib/msun/src/s_modf.c instead, it does work. >To reproduce the error, try the following code: >---------------------------------------------------------------------- >#include >main() >{ > double arg = 0.0, fj; > int i; > char *p, buf[21]; > p = buf; > for(i=0; i < 20; i++) { > arg *= 10; > (void)modf(arg, &fj); > arg -= fj; > *p++ = (int)fj + '0'; > } > *p = '\0'; > printf("%s\n", buf); >} >---------------------------------------------------------------------- $ cc -Wall prog.c prog.c:4: warning: return-type defaults to `int' prog.c: In function `main': prog.c:12: warning: implicit declaration of function `modf' prog.c:18: warning: control reaches end of non-void function `modf' is not declared and so the compiler has to assume that it returns `int'. Since it actually returns double, the behaviour is undefined. `modf' is declared in include to fix the problem. The actual behaviour when the modf() in libc.a is called under FreeBSD is that each call leaves a double on the floating point stack. On the 8th call, the stack has 7 registers full of junk so there is no space for the 2 registers used by modf() and a stack exception occurs. Under FreeBSD, stack exceptions are trapped, so a SIGFPE is generated on the next floating point instruction after the one for which the stack exception was recorded. The behaviour when the modf() in libm.a is called should be similar. It is the same here. The math routines in lib/libc/i386/gen (fabs, frexp, ldexp and modf) are of lower quality than the ones in lib/msun/src and probably shouldn't exist. Bruce