diff options
author | Paul Corner <paul_c@users.sourceforge.net> | 2004-02-16 22:34:18 +0000 |
---|---|---|
committer | Paul Corner <paul_c@users.sourceforge.net> | 2004-02-16 22:34:18 +0000 |
commit | d798374e275c9ea81829f8b65b36fc5e0c5d40c4 (patch) | |
tree | 31d3a305fd98b7c99d48d9acdb7cbeb74874858a | |
parent | 1feeebc579c49701def273b29ded2f9e11a47fd4 (diff) | |
download | linuxcnc-d798374e275c9ea81829f8b65b36fc5e0c5d40c4.tar.gz linuxcnc-d798374e275c9ea81829f8b65b36fc5e0c5d40c4.zip |
Tests for unresolved symbols when linking to libm
-rwxr-xr-x | configure | 89 | ||||
-rw-r--r-- | src/tests/mathtest.c | 150 |
2 files changed, 225 insertions, 14 deletions
@@ -164,6 +164,7 @@ if [ "$RTDIR" = "" ] ; then RTAI=$(echo $rtai | grep buildvars | sed s^/.buildvars^^g) if [ "$RTAI" != "" ] ; then RTDIR=$RTAI + RTAI_VER=1 fi done fi @@ -177,15 +178,13 @@ fi # # check RTDIR for a valid RTOS signature # -if [ ! -f $RTDIR/rtl.mk ] ; then - if [ ! -f $RTDIR/bin/rtai-config ] ; then - if [ ! -f $RTDIR/.buildvars ] ; then +if [ ! -f $RTDIR/rtl.mk ] && \ + [ ! -f $RTDIR/bin/rtai-config ] && \ + [ ! -f $RTDIR/.buildvars ] ; then # no rtai or rtlinux signatures found, then exit.. - echo "No RTAI or RTLinux signatures found in $RTDIR" - usage - exit -1 - fi - fi + echo "No RTAI or RTLinux signatures found in $RTDIR" + usage + exit -1 fi # try to find out where man files are stored on this system. @@ -221,6 +220,53 @@ source "$TKCONFIG" fi +# Test the compatability of libm for realtimr or kernel modules. +if [ -r $RTDIR/modules/rtai_libm.o ] ; then + # RTAI_VER is set, so don't need to define MATHLIB + MATHLIB= + USE_RTLIBM=1 + echo "Using RTAI's libm kernel module" +else + echo "Testing for a suitable libm... Some symbols may be printed if a test fails." + # With RTAI we will assume that rtai_libm (or rtai_math) will + # work. For RTLinux, a couple of tests need to be done. + rm -f src/tests/mathtest.o src/tests/mathtest 2>/dev/null + # compile a sample first. + gcc -O0 -c src/tests/mathtest.c -o src/tests/mathtest.o + + DIET_DIR=$(find /usr/lib -maxdepth 2 -name diet* | head -n1) + if [ "$DIET_DIR" != "" ] ; then + # Run a test to see if it will work... + ld -r -static src/tests/mathtest.o -o src/tests/mathtest -L$DIET_DIR/lib-i386 -lm + if ! nm -u src/tests/mathtest | grep -v ende ; then + echo "diet lib OK to use." + USE_DIET=1 + MATHLIB="-L$DIET_DIR/lib-i386 -lm" + MATHINC="-I$DIET_DIR/include" + fi + fi + if [ "$USE_DIET" = "" ] ; then + # Test the standard libm + rm -f src/tests/mathtest 2>/dev/null + ld -r -static src/tests/mathtest.o -o src/tests/mathtest -L/usr/lib -lm + if ! nm -u src/tests/mathtest ; then + echo "libm OK to use." + USE_LIBM=1 + MATHLIB="-L/usr/lib -lm" + else + # We need to link to mathstubs if we are to use the glibc libm + echo "libm tests failed - Using glibc libm with mathstubs." + echo "If unresolved symbols are reported when loading kernel modules" + echo "please file a bug report." + USE_LIBM=1 + USE_STUBS=1 + MATHLIB="-L/usr/lib -lm \$(RTTMP_DIR)/mathstubs.o" + fi + fi + rm -f src/tests/mathtest.o src/tests/mathtest 2>/dev/null +fi + + # Go on to write out the Makefile.inc DATE=$(date) @@ -249,16 +295,14 @@ if [ -f $RTDIR/.buildvars ] ; then echo found an RTAI installation in $RTDIR echo "RTNAME = rtai" >> Makefile.inc echo "RTPREFIX = rtai" >> Makefile.inc - echo "RTAI = 1" >> Makefile.inc + echo "RTAI = $RTAI_VER" >> Makefile.inc # Added a "sed s/' = '/'='/" here (and elsewhere) because the awk split # fails when it finds "FOO = bar" - So we need to make sure it finds # "FOO=bar" instead. KERNEL=$(cat $RTFILE | grep LINUXDIR | sed s/' = '/'='/ | awk '{split($1, A, "=")}{print A[2]}') 2> /dev/null #' KERNELDIR=$(cd $KERNEL ; pwd -P ) - MATHLIB="" elif [ -f $RTDIR/bin/rtai-config ] ; then -# RTFILE=$RTDIR/.buildvars echo found an RTAI installation in $RTDIR echo "RTNAME = rtai-3.0" >> Makefile.inc echo "RTPREFIX = rtai" >> Makefile.inc @@ -277,7 +321,6 @@ elif [ -f $RTDIR/rtl.mk ] ; then # There is probably a better way of doing this without using sed ! KERNEL=$(cat $RTFILE | grep RTLINUX_DIR | sed s/' = '/'='/ | awk '{split($1, A, "=")}{print A[2]}') 2> /dev/null #' KERNELDIR=$(cd $KERNEL ; pwd -P ) - MATHLIB="-L/usr/lib -lm" fi echo "KERNELDIR = $KERNELDIR" >> Makefile.inc @@ -286,12 +329,27 @@ if [ "$RTFILE" != "" ] ; then cat $RTFILE | grep CFLAGS | sed s/CFLAGS/RTFLAGS/ >> Makefile.inc fi -echo "RTFLAGS := -I\$(INC_DIR) -I$RTDIR/include -I. \$(RTFLAGS) -DRTAPI" >> Makefile.inc -echo "MATHLIB = $MATHLIB" >> Makefile.inc +echo "RTFLAGS := $MATHINC -I\$(INC_DIR) -I$RTDIR/include -I. \$(RTFLAGS) -DRTAPI" >> Makefile.inc if [ "$RTFILE" != "" ] ; then CC=$(cat $RTFILE | grep CC | sed s/' = '/'='/ | awk '{split($1, A, "=")}{print A[2]}') 2> /dev/null #' fi + +# Set the MATHLIB link options. +if [ "$USE_DIET" != "" ] ; then + echo "USE_DIET = $USE_DIET" >> Makefile.inc +elif [ "$USE_RTLIBM" != "" ] ; then + echo "USE_RTLIBM = $USE_RTLIBM" >> Makefile.inc +elif [ "$USE_LIBM" != "" ] ; then + if [ "$USE_STUBS" != "" ] ; then + echo "libm tests failed - Using glibc libm with mathstubs." >> Makefile.inc + echo "If unresolved symbols are reported when loading kernel modules" >> Makefile.inc + echo "please file a bug report." >> Makefile.inc + fi + echo "USE_LIBM = $USE_LIBM" >> Makefile.inc +fi +echo "MATHLIB = $MATHLIB" >> Makefile.inc + if [ "$CC" = "" ] ; then CC=cc fi @@ -376,5 +434,8 @@ for i in bin include lib rtlib ; do done # terminate normally +echo +echo " Configure finished - Please check Makefile.inc for errors." +echo exit 0 diff --git a/src/tests/mathtest.c b/src/tests/mathtest.c new file mode 100644 index 000000000..400593ccd --- /dev/null +++ b/src/tests/mathtest.c @@ -0,0 +1,150 @@ +/******************************************************************** +* Description: mathtest.c - A small file to test for unresolved +* symbols in loadable kernel modules. +* +* Author: Paul_C - Derived from a file by Fred Proctor. +* Created at: Mon Feb 16 20:39:42 GMT 2004 +* Computer: Morphix +* System: Linux +* +* Copyright (c) 2004 All rights reserved. +* +* Last change: +* $Author$ +* $Date$ +********************************************************************/ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define MODULE +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/version.h> +#include <math.h> /* sin(), cos(), isnan() etc. */ +#include <float.h> /* DBL_MAX */ +#include <errno.h> /* errno, EDOM */ + +/* + math functions are: + + extern double sin(double); used in posemath, siggen, & noncartesian kins + extern double cos(double); used in posemath, siggen, & noncartesian kins + extern double tan(double); not used in RT + extern double asin(double); not used in RT + extern double acos(double); used in posemath & noncartesian kins + extern double atan2(double, double); used in posemath & noncartesian kins + extern double sinh(double); not used in RT + extern double cosh(double); not used in RT + extern double tanh(double); not used in RT + extern double exp(double); not used in RT + extern double log(double); not used in RT + extern double log10(double); not used in RT + extern double pow(double, double); not used in RT + extern double sqrt(double); used in tc, segmot, & noncartesean kins. + extern double ceil(double); used in segmot & emcpid + extern double floor(double); used by siggen & segmot + extern double fabs(double); used a lot in RT + extern double ldexp(double, int); not used in RT + extern double frexp(double, int *); not used in RT + extern double modf(double, double *); not used in RT + extern double fmod(double, double); not used in RT + + extern double sincos(double, double *, double *); Is called at four places in + posemath - None of the resulting + functions are used in EMC. + Extras: + + extern int isnan(double); Not used directly in RT - But is called + by several (all ?) of the floating point + math functions. +*/ + +/* Declare as volatile and gcc *shouldn't* optimize too much... */ +volatile double a = 0; +volatile double b = 0; +volatile double c = 0; +volatile double x; +double d; +int n; + +/* + isnan() - C99 extensions to the math library functions + + IEEE double-precision floating point: + + N = (-1)^S * 2^(E-1023) * 1.F + + where S, E and F are composed of bits as labeled in these 8 bytes: + + [7] [6] [5] [0] + SEEEEEEE EEEEFFFF FFFFFFFF ... FFFFFFFF + + If E = 2047 and F is nonzero, N = Not a Number (NaN) + If E = 2047 and F = 0 and S = 1, N = -Inf + If E = 2047 and F = 0 and S = 0, N = Inf + If 0 < E < 2047, N = (-1)^S * 2^(E-1023) * 1.F + If E = 0 and F is nonzero, N = (-1)^S * 2^(-1022) * 0.F ("unnormalized") + If E = 0 and F = 0 and S = 1, N = -0 + If E = 0 and F = 0 and S = 0, N = 0 + + Example: for N = -1, S = 1, E = 1023, F = 0, and + byte[0] = 10111111 = BF + byte[1] = 11110000 = F0 + byte[2-7] = 0 +*/ + +int isnan(double d) +{ + int e; + unsigned char * c = (unsigned char *) &d; + + e = (int) (c[7] & 0x7F); + e <<= 4; + e += (int) ((c[6] & 0xF0) >> 4); + + return (e == 2047) && (c[0] || c[1] || c[2] || c[3] || + c[4] || c[5] || (c[6] & 0x0F)); +} + +int math_test(void) +{ + double v, u; + a = 1.00039276; + b = 1.9999 * a; + c = a / 2; + + /* force a domain error, EDOM, and check that we got it */ + x = acos(b); + if (isnan(x)) x = 0.0; + + /* force a range error, ERANGE, and check that we got it */ + x = pow(DBL_MAX, b); + if (isnan(x)) x = 0.0; + + /* do some legit math */ + x = sin(a) + cos(a) + tan(a) + + asin(c) + acos(c) + atan2(a, b) + + sinh(a) + cosh(a) + tanh(a) + + exp(a) + log(a) + log10(a) + + pow(a, b) + sqrt(a) + ceil(a) + + floor(a) + fabs(a) + ldexp(a, b) + + frexp(c, &n) + modf(c, &d) + fmod(a, b); + + /* Test the sincos func */ + sincos(x, &v, &u); + + return 0; +} |