From cc07f2350dc260a2a4eaf4ff05f32939c55a9893 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Thu, 25 Jan 2001 21:19:46 +0000 Subject: Clean up atexit.c; make sure sysconf and atexit agree; link in ref'd libgcc.a objects with shared uClibc; allow disabling long long support. --- Makefile | 1 + extra/scripts/get-needed-libgcc-objects.sh | 70 ++++++++++++++++++++++++++++++ include/search.h | 5 +++ include/stdlib.h | 3 +- libc/misc/internals/Makefile | 7 ++- libc/stdlib/Makefile | 5 ++- libc/stdlib/atexit.c | 49 ++++++++------------- libc/sysdeps/linux/arm/bits/confname.h | 5 ++- libc/sysdeps/linux/i386/bits/confname.h | 5 ++- libc/sysdeps/linux/m68k/bits/confname.h | 5 ++- libc/unistd/sysconf.c | 4 +- 11 files changed, 118 insertions(+), 41 deletions(-) create mode 100755 extra/scripts/get-needed-libgcc-objects.sh diff --git a/Makefile b/Makefile index 23c76bb90..fa943e6fc 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ shared: libc.a @rm -rf tmp @mkdir tmp @(cd tmp; ar -x ../libc.a) + @(cd tmp; CC=$(CC) /bin/sh ../extra/scripts/get-needed-libgcc-objects.sh) $(CC) -s -nostdlib -shared -o libuClibc.so.1 -Wl,-soname,libuClibc.so.1 tmp/*.o @rm -rf tmp diff --git a/extra/scripts/get-needed-libgcc-objects.sh b/extra/scripts/get-needed-libgcc-objects.sh new file mode 100755 index 000000000..e4fa96a78 --- /dev/null +++ b/extra/scripts/get-needed-libgcc-objects.sh @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Manuel Novoa III Jan 2001 +# +# The purpose of this script is to extract the object files from libgcc.a +# that are needed by the shared uClibc so that they won't be linked with +# each application. +# +# I'm sure people with better shell programming skills can improve this. +# Feel free! ;-) At this point though, it gets the job done for me. +# +# Possible problems (paranioa mode): Are any of the objects in libgcc.a +# needed to actually load the shared library on any archs? + +LIBGCC=`$CC -print-libgcc-file-name` + +echo Finding missing symbols in libc.a ... +echo " partial linking..." +rm -f libc.ldr +ld -r -o libc.ldr ../crt0.o *.o + +if nm -s libc.ldr | grep -v " main$" | grep " U " > sym.need ; then + rm -f obj.need + touch obj.need + for SYM in `cat sym.need | sed -e 's/ U //g'` ; do + if nm -s $LIBGCC | grep -q $SYM" in " ; then + nm -s $LIBGCC | grep $SYM" in " | cut -d' ' -f3 >> obj.need + else + echo Symbol $SYM needed by libc.a but not found in libgcc.a + fi + done +else + echo No missing symbols found. + exit 0 +fi + +rm -rf tmp-gcc +mkdir tmp-gcc +(cd tmp-gcc ; ar -x $LIBGCC) +rm libgcc.ldr + +echo Extracting referenced libgcc.a objects ... + +rm -f obj.need.0 +touch obj.need.0 +while [ -s obj.need ] && ! cmp -s obj.need obj.need.0 ; do + (cd tmp-gcc ; cat ../obj.need | xargs ld -r -o ../libgcc.ldr) + cp obj.need obj.need.0 + if nm -s libgcc.ldr | grep " U " > sym.need ; then + for SYM in `cat sym.need | sed -e 's/ U //g'` ; do + if nm -s $LIBGCC | grep -q $SYM" in " ; then + nm -s $LIBGCC | grep $SYM" in " | cut -d' ' -f3 >> obj.need + fi + done + fi +done + +cat obj.need | sort | uniq > obj.need.0 +(cd tmp-gcc ; cp `cat ../obj.need` ..) + +echo Objects added from $LIBGCC: +cat obj.need.0 + +if [ -s sym.need ] ; then + echo Symbols missing from libgcc.a: + cat sym.need +else + echo Done +fi +exit 0 \ No newline at end of file diff --git a/include/search.h b/include/search.h index b9c8a1785..b3b498543 100644 --- a/include/search.h +++ b/include/search.h @@ -34,12 +34,17 @@ For now the file can be distributed under the LGPL. */ #define __need_NULL #include +/* Get __compar_fn_t from stdlib.h */ +#include + __BEGIN_DECLS +#if 0 #ifndef __COMPAR_FN_T #define __COMPAR_FN_T typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t)); #endif +#endif /* for use with hsearch(3) */ diff --git a/include/stdlib.h b/include/stdlib.h index 18a32e62f..54c2a6fa7 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -93,7 +93,8 @@ extern int setenv __P ((__const char *__name, __const char *__value, extern int system __P ((__const char *__command)); extern void unsetenv __P ((__const char *__name)); - +/* The following is used by uClibc in atexit.c and sysconf.c */ +#define __UCLIBC_MAX_ATEXIT 20 /* Search and sort functions */ extern __ptr_t bsearch __P ((__const __ptr_t __key, __const __ptr_t __base, diff --git a/libc/misc/internals/Makefile b/libc/misc/internals/Makefile index da693ce51..863d32401 100644 --- a/libc/misc/internals/Makefile +++ b/libc/misc/internals/Makefile @@ -24,9 +24,12 @@ TOPDIR=../../ include $(TOPDIR)Rules.mak LIBC=$(TOPDIR)libc.a -CSRC=ultostr.c ltostr.c ulltostr.c lltostr.c zoicheck.c +CSRC=ultostr.c ltostr.c ifeq ($(HAS_FLOATS),true) - CSRC += dtostr.c + CSRC += dtostr.c zoicheck.c +endif +ifeq ($(HAS_LONG_LONG),true) + CSRC += ulltostr.c lltostr.c endif COBJS=$(patsubst %.c,%.o, $(CSRC)) diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile index 06d87c674..6ea292d5b 100644 --- a/libc/stdlib/Makefile +++ b/libc/stdlib/Makefile @@ -45,7 +45,10 @@ endif COBJS=$(patsubst %.c,%.o, $(CSRC)) -OBJS=$(MOBJ) $(MOBJ1) $(MOBJ2) $(COBJS) +OBJS=$(MOBJ) $(MOBJ2) $(COBJS) +ifeq ($(HAS_LONG_LONG),true) + OBJS += $(MOBJ1) +endif all: $(OBJS) $(LIBC) diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index 5079692af..a7ec0fb1f 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -12,45 +12,17 @@ * Combined atexit and __do_exit into one object file. */ +#include #include -/* ATEXIT.H */ - -/* - * NOTE!!! The following should match the value returned by - * by sysconf(_SC_ATEXIT_MAX) in unistd/sysconf.c - */ -#define MAXATEXIT 20 /* AIUI Posix requires 10 */ - typedef void (*vfuncp) (void); - extern vfuncp __cleanup; -extern void __do_exit(); -extern void _exit __P((int __status)) __attribute__ ((__noreturn__)); - -extern vfuncp __atexit_table[MAXATEXIT]; -extern int __atexit_count; - -/* End ATEXIT.H */ #ifdef L_atexit -int atexit(vfuncp ptr) -{ - if ((__atexit_count < 0) || (__atexit_count >= MAXATEXIT)) { - errno = ENOMEM; - return -1; - } - if (ptr) { - __cleanup = __do_exit; - __atexit_table[__atexit_count++] = ptr; - } - return 0; -} +static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT]; +static int __atexit_count = 0; -vfuncp __atexit_table[MAXATEXIT]; -int __atexit_count = 0; - -void __do_exit(int rv) +static void __do_exit(void) { int count = __atexit_count - 1; @@ -62,6 +34,19 @@ void __do_exit(int rv) (*__atexit_table[count])(); } } + +int atexit(vfuncp ptr) +{ + if ((__atexit_count < 0) || (__atexit_count >= __UCLIBC_MAX_ATEXIT)) { + errno = ENOMEM; + return -1; + } + if (ptr) { + __cleanup = __do_exit; + __atexit_table[__atexit_count++] = ptr; + } + return 0; +} #endif #ifdef L_exit diff --git a/libc/sysdeps/linux/arm/bits/confname.h b/libc/sysdeps/linux/arm/bits/confname.h index 229088d67..a649e52f2 100644 --- a/libc/sysdeps/linux/arm/bits/confname.h +++ b/libc/sysdeps/linux/arm/bits/confname.h @@ -335,8 +335,11 @@ enum #define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY _SC_XOPEN_REALTIME, #define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME - _SC_XOPEN_REALTIME_THREADS + _SC_XOPEN_REALTIME_THREADS, #define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + /* MUST BE LAST VALUE!!! */ + _UCLIBC_SYSCONF_NUM_VALID_ARGS }; #if (defined __USE_POSIX2 || defined __USE_UNIX98 \ diff --git a/libc/sysdeps/linux/i386/bits/confname.h b/libc/sysdeps/linux/i386/bits/confname.h index 229088d67..a649e52f2 100644 --- a/libc/sysdeps/linux/i386/bits/confname.h +++ b/libc/sysdeps/linux/i386/bits/confname.h @@ -335,8 +335,11 @@ enum #define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY _SC_XOPEN_REALTIME, #define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME - _SC_XOPEN_REALTIME_THREADS + _SC_XOPEN_REALTIME_THREADS, #define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + /* MUST BE LAST VALUE!!! */ + _UCLIBC_SYSCONF_NUM_VALID_ARGS }; #if (defined __USE_POSIX2 || defined __USE_UNIX98 \ diff --git a/libc/sysdeps/linux/m68k/bits/confname.h b/libc/sysdeps/linux/m68k/bits/confname.h index 229088d67..a649e52f2 100644 --- a/libc/sysdeps/linux/m68k/bits/confname.h +++ b/libc/sysdeps/linux/m68k/bits/confname.h @@ -335,8 +335,11 @@ enum #define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY _SC_XOPEN_REALTIME, #define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME - _SC_XOPEN_REALTIME_THREADS + _SC_XOPEN_REALTIME_THREADS, #define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + /* MUST BE LAST VALUE!!! */ + _UCLIBC_SYSCONF_NUM_VALID_ARGS }; #if (defined __USE_POSIX2 || defined __USE_UNIX98 \ diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index d5c6f6b9d..032311378 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -658,8 +659,7 @@ long int sysconf(int name) #endif case _SC_ATEXIT_MAX: - /* See stdlib/atexit.c */ - return 20; + return __UCLIBC_MAX_ATEXIT; case _SC_PASS_MAX: /* We have no limit but since the return value might be used to -- cgit v1.2.3