summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Corner <paul_c@users.sourceforge.net>2004-02-16 22:34:18 +0000
committerPaul Corner <paul_c@users.sourceforge.net>2004-02-16 22:34:18 +0000
commitd798374e275c9ea81829f8b65b36fc5e0c5d40c4 (patch)
tree31d3a305fd98b7c99d48d9acdb7cbeb74874858a
parent1feeebc579c49701def273b29ded2f9e11a47fd4 (diff)
downloadlinuxcnc-d798374e275c9ea81829f8b65b36fc5e0c5d40c4.tar.gz
linuxcnc-d798374e275c9ea81829f8b65b36fc5e0c5d40c4.zip
Tests for unresolved symbols when linking to libm
-rwxr-xr-xconfigure89
-rw-r--r--src/tests/mathtest.c150
2 files changed, 225 insertions, 14 deletions
diff --git a/configure b/configure
index 6e0d2172c..0f0cb7f99 100755
--- a/configure
+++ b/configure
@@ -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;
+}