diff options
70 files changed, 990 insertions, 842 deletions
@@ -28,7 +28,15 @@ noconfig_targets := menuconfig config oldconfig randconfig \ TOPDIR=./ include Rules.mak -DIRS = ldso libc libcrypt libresolv libnsl libutil libm libpthread librt +ALL_SUBDIRS = ldso libc libcrypt libresolv libnsl libutil librt libm libpthread libintl test utils # extra + +DIRS = ldso libc libcrypt libresolv libnsl libutil librt +ifeq ($(strip $(UCLIBC_HAS_FLOATS)),y) + DIRS += libm +endif +ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) + DIRS += libpthread +endif ifeq ($(strip $(UCLIBC_HAS_GETTEXT_AWARENESS)),y) DIRS += libintl endif @@ -40,23 +48,13 @@ all: headers pregen subdirs shared finished # In this section, we need .config -include .config.cmd -shared: subdirs +shared: $(patsubst %, _shared_dir_%, $(DIRS)) +$(patsubst %, _shared_dir_%, $(DIRS)): subdirs ifeq ($(strip $(HAVE_SHARED)),y) $(SECHO) $(SECHO) Building shared libraries ... $(SECHO) - @$(MAKE) -C libc shared - @$(MAKE) -C ldso shared - @$(MAKE) -C libcrypt shared - @$(MAKE) -C libresolv shared - @$(MAKE) -C libnsl shared - @$(MAKE) -C libutil shared - @$(MAKE) -C libm shared - @$(MAKE) -C libpthread shared - @$(MAKE) -C librt shared -ifeq ($(strip $(UCLIBC_HAS_GETTEXT_AWARENESS)),y) - @$(MAKE) -C libintl shared -endif + $(MAKE) -C $(patsubst _shared_dir_%, %, $@) shared else $(SECHO) $(SECHO) Not building shared libraries ... @@ -120,24 +118,11 @@ headers: include/bits/uClibc_config.h else \ mv -f include/bits/sysnum.h.new include/bits/sysnum.h; \ fi +ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) + $(MAKE) -C libpthread headers +endif $(MAKE) -C libc/sysdeps/linux/common headers $(MAKE) -C libc/sysdeps/linux/$(TARGET_ARCH) headers -ifeq ($(strip $(PTHREADS_NATIVE)),y) - (cd include; \ - $(LN) -fs ../libpthread/nptl/sysdeps/pthread/pthread.h .; \ - $(LN) -fs ../libpthread/nptl/semaphore.h .); - (cd include/bits; \ - $(LN) -fs ../../libpthread/nptl/sysdeps/pthread/bits/libc-lock.h .; \ - $(LN) -fs ../../libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h .; \ - $(LN) -fs ../../libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/bits/pthreadtypes.h .; \ - $(LN) -fs ../../libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/bits/semaphore.h .); -else - (cd include; \ - $(LN) -fs ../libpthread/linuxthreads/sysdeps/pthread/pthread.h .; \ - $(LN) -fs ../libpthread/linuxthreads/semaphore.h .); - (cd include/bits; \ - $(LN) -fs ../../libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h .); -endif # Command used to download source code WGET:=wget --passive-ftp @@ -181,6 +166,7 @@ install_dev: fi ; \ tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \ | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX) + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/ssp-internal.h ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y) # Remove floating point related headers since float support is disabled. $(RM) $(PREFIX)$(DEVEL_PREFIX)include/complex.h @@ -188,6 +174,7 @@ ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y) $(RM) $(PREFIX)$(DEVEL_PREFIX)include/ieee754.h $(RM) $(PREFIX)$(DEVEL_PREFIX)include/math.h $(RM) $(PREFIX)$(DEVEL_PREFIX)include/tgmath.h + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/bits/uClibc_fpmax.h endif ifneq ($(strip $(UCLIBC_HAS_WCHAR)),y) # Remove wide char headers since wide char support is disabled. @@ -232,9 +219,19 @@ ifneq ($(strip $(UCLIBC_HAS_GNU_GETOPT)),y) $(RM) $(PREFIX)$(DEVEL_PREFIX)include/getopt.h endif ifneq ($(strip $(HAS_SHADOW)),y) - # Remove getopt header since shadow password support is disabled. + # Remove shadow header since shadow password support is disabled. $(RM) $(PREFIX)$(DEVEL_PREFIX)include/shadow.h endif +ifneq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) + # Remove thread_db header since thread debug support is disabled. + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/thread_db.h +endif +ifneq ($(strip $(UCLIBC_HAS_THREADS)),y) + # Remove pthread headers since thread support is disabled. + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/*thread*.h + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/semaphore.h + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/bits/*thread*.h +endif -@for i in `find $(PREFIX)$(DEVEL_PREFIX) -type d` ; do \ chmod 755 $$i; chmod 644 $$i/*.h > /dev/null 2>&1; \ done; @@ -252,14 +249,16 @@ ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) endif # # If we build shared libraries then the static libs are PIC... # # Make _pic.a symlinks to make mklibs.py and similar tools happy. + if [ -d lib ] ; then \ for i in `find lib/ -type f -name '*.a' | sed -e 's/lib\///'` ; do \ $(LN) -sf $$i $(PREFIX)$(DEVEL_PREFIX)lib/`echo $$i \ | sed -e 's/\.a$$/_pic.a/'`; \ - done; + done ; \ + fi # Ugh!!! Remember that libdl.a and libdl_pic.a are different. Since # libdl is pretty small, and not likely to benefit from mklibs.py and # similar, lets just remove libdl_pic.a and avoid the issue - rm -f $(PREFIX)$(DEVEL_PREFIX)lib/libdl_pic.a + $(RM) $(PREFIX)$(DEVEL_PREFIX)lib/libdl_pic.a endif @@ -278,22 +277,12 @@ ifeq ($(strip $(HAVE_SHARED)),y) fi; endif -.PHONY: utils -ifeq ($(strip $(HAVE_SHARED)),y) utils: $(MAKE) CROSS="$(CROSS)" CC="$(CC)" -C utils -else -utils: dummy -endif # Installs helper applications, such as 'ldd' and 'ldconfig' install_utils: utils $(MAKE) CROSS="$(CROSS)" CC="$(CC)" -C utils install -#ifeq ($(strip $(UCLIBC_HAS_LOCALE)),y) -# @$(MAKE) -C libc/misc/wchar iconv.target -# $(INSTALL) -d $(PREFIX)$(RUNTIME_PREFIX)/usr/bin; -# $(INSTALL) -m 755 libc/misc/wchar/iconv.target $(PREFIX)$(RUNTIME_PREFIX)/usr/bin/iconv -#endif finished2: $(SECHO) @@ -316,6 +305,7 @@ menuconfig: extra/config/mconf $(RM) -r include/bits $(INSTALL) -d include/bits @./extra/config/mconf extra/Configs/Config.in + $(MAKE) headers config: extra/config/conf $(RM) -r include/bits @@ -353,19 +343,15 @@ defconfig: extra/config/conf $(INSTALL) -d include/bits @./extra/config/conf -d extra/Configs/Config.in -clean: +subdirs_clean: $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) +$(patsubst %, _dirclean_%, $(ALL_SUBDIRS)): dummy + $(MAKE) -C $(patsubst _dirclean_%, %, $@) clean + +clean: subdirs_clean - find . \( -name \*.o -o -name \*.a -o -name \*.so -o -name core -o -name .\#\* \) -exec $(RM) {} \; - @$(RM) -r tmp lib include/bits libc/tmp _install - $(RM) libc/obj.* libc/obj-* headers - $(MAKE) -C test clean - $(MAKE) -C ldso clean + @$(RM) -r lib include/bits $(MAKE) -C libc/misc/internals clean - $(MAKE) -C libc/misc/wchar clean - $(MAKE) -C libc/unistd clean - $(MAKE) -C libc/sysdeps/linux/common clean $(MAKE) -C extra/locale clean - $(MAKE) -C utils clean - $(MAKE) -C libpthread clean @set -e; \ for i in `(cd $(TOPDIR)/libc/sysdeps/linux/common/sys; ls *.h)` ; do \ $(RM) include/sys/$$i; \ @@ -376,7 +362,6 @@ clean: done; \ fi; @$(RM) include/linux include/asm* - @$(RM) include/pthread.h include/semaphore.h @if [ -d libc/sysdeps/linux/$(TARGET_ARCH) ]; then \ $(MAKE) -C libc/sysdeps/linux/$(TARGET_ARCH) clean; \ fi; diff --git a/docs/uclibc.org/developer.html b/docs/uclibc.org/developer.html index 949e3cae4..0bf1b070a 100644 --- a/docs/uclibc.org/developer.html +++ b/docs/uclibc.org/developer.html @@ -3,14 +3,6 @@ <h3>Subversion Read/Write Access</h3> -If you want to be able to commit things to Subversion, first contribute some -stuff to show you are serious. Then, very nicely ask <a -href="mailto:andersen@codepoet.org">Erik Andersen</a> if he will set you up -with an commit access to the Subversion repository. To access Subversion, you -will want to add the following to set up your environment: - -<p> - To obtain commit access, you will need to demonstrate you are serious by submitting a few good patches first. Then, you will need to select a username to use when committing changes to SVN, you will need to send me the username @@ -18,7 +10,7 @@ you have selected, you must send me your preferred contact email address, and finally, you must send me an ssh version 2 DSA key with 1024 bits (the default) or more. If you do not currently have an ssh version 2 DSA key, you can generate a key using the command<pre>ssh-keygen -t dsa</pre> This will -create the files <pre>/home/<USERNAME>/ssh/id_dsa +create the files <pre>/home/<USERNAME>/.ssh/id_dsa /home/<USERNAME>/.ssh/id_dsa.pub</pre> You must then send the content of 'id_dsa.pub' to me so I can setup your account. The content of 'id_dsa' should of course be kept secret. diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 61b6bbf77..036a48b33 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1217,9 +1217,6 @@ choice "segfault" use SIGSEGV to block offending programs. Use this for debugging. - "kill" use SIGKILL to block offending programs. - Perhaps the best for security. - If unsure, answer "abort". config PROPOLICE_BLOCK_ABRT @@ -1228,9 +1225,6 @@ config PROPOLICE_BLOCK_ABRT config PROPOLICE_BLOCK_SEGV bool "segfault" -config PROPOLICE_BLOCK_KILL - bool "kill" - endchoice config UCLIBC_BUILD_SSP diff --git a/extra/Makefile b/extra/Makefile index 2371a8146..9b46ada51 100644 --- a/extra/Makefile +++ b/extra/Makefile @@ -23,8 +23,6 @@ TOPDIR=../ include $(TOPDIR)Rules.mak -LIBC=$(TOPDIR)libc.a - DIRS = EXTRA_DIRS_TO_CLEAN = config diff --git a/include/ssp-internal.h b/include/ssp-internal.h new file mode 100644 index 000000000..c82debbd5 --- /dev/null +++ b/include/ssp-internal.h @@ -0,0 +1,90 @@ +/* + * Distributed under the terms of the GNU Lesser General Public License + * $Header: $ + */ + +#ifndef _SSP_INTERNAL_H +#define _SSP_INTERNAL_H 1 + +#ifdef __SSP__ +#error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector" +#endif + +#ifdef __PROPOLICE_BLOCK_SEGV__ +# define SSP_SIGTYPE SIGSEGV +#else +# define SSP_SIGTYPE SIGABRT +#endif + +#include <sys/types.h> +#include <sys/time.h> +#include <signal.h> +#include <linux/unistd.h> + +#ifdef __SSP_USE_ERANDOM__ +# include <sys/sysctl.h> +#if 1 +# define SYSCTL __sysctl +#else +#define __NR__kernel_sysctl __NR_sysctl +static __always_inline _syscall6(int,__kernel_sysctl,int *,name,int,nlen,void *,oldval,size_t *,oldlenp,void *,newval,size_t,newlen); +#define SYSCTL(name,nlen,oldval,oldlenp,newval,newlen) __kernel_sysctl(name,nlen,oldval,oldlenp,newval,newlen) +#endif +#endif + +#ifndef __SSP_QUICK_CANARY__ +#define __NR___kernel_open __NR_open +static __always_inline _syscall2(int,__kernel_open,const char *,path,int,flags); +#define OPEN(path, flags) __kernel_open(path, flags) + +/* void * = __ptr_t */ +#define __NR___kernel_read __NR_read +static __always_inline _syscall3(ssize_t,__kernel_read,int,fd,void *,buf,size_t,count); +#define READ(fd, buf, count) __kernel_read(fd, buf, count) + +#define __NR___kernel_close __NR_close +static __always_inline _syscall1(int,__kernel_close,int,fd); +#define CLOSE(fd) __kernel_close(fd) +#endif + +/* const void * = const __ptr_t */ +#define __NR___kernel_write __NR_write +static __always_inline _syscall3(ssize_t,__kernel_write,int,fd,const void *,buf,size_t,count); +#define WRITE(fd, buf, count) __kernel_write(fd, buf, count) + +/* not using __NR_ */ +#define __NR___kernel_gettimeofday __NR_gettimeofday +static __always_inline _syscall2(int,__kernel_gettimeofday,struct timeval *,tv,struct timezone *,tz); +#define GETTIMEOFDAY(tv, tz) __kernel_gettimeofday(tv, tz) + +#define __NR___kernel_getpid __NR_getpid +static __always_inline _syscall0(pid_t,__kernel_getpid); +#define GETPID() __kernel_getpid() + +//#ifdef __NR_rt_sigaction +//#define __NR___kernel_sigaction __NR_rt_sigaction +//static __always_inline _syscall4(...); +//#else +#define __NR___kernel_sigaction __NR_sigaction +static __always_inline _syscall3(int,__kernel_sigaction,int,signum,const struct sigaction *,act,struct sigaction *,oldact); +//#endif +#define SIGACTION(signum, act, oldact) __kernel_sigaction(signum, act, oldact) + +//#ifdef __NR_rt_sigprocmask +//#define __NR___kernel_sigprocmask __NR_rt_sigprocmask +//static __always_inline _syscall4(...); +//#else +#define __NR___kernel_sigprocmask __NR_sigprocmask +static __always_inline _syscall3(int,__kernel_sigprocmask,int,how,const sigset_t *,set,sigset_t *,oldset); +//#endif +#define SIGPROCMASK(how, set, oldset) __kernel_sigprocmask(how, set, oldset) + +#define __NR___kernel_kill __NR_kill +static __always_inline _syscall2(int,__kernel_kill,__kernel_pid_t,pid,int,sig); +#define KILL(pid, sig) __kernel_kill(pid, sig) + +#define __NR___kernel_exit __NR_exit +static __always_inline _syscall1(void,__kernel_exit,int,status); +#define EXIT(status) __kernel_exit(status) + +#endif /* _SSP_INTERNAL_H */ diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index 185cdc799..cdaea10f0 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -49,6 +49,9 @@ struct elf_resolve{ ElfW(Addr) relro_addr; size_t relro_size; + dev_t st_dev; /* device */ + ino_t st_ino; /* inode */ + #if USE_TLS /* Thread-local storage related info. */ diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 9f922f1fa..83485608e 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -32,7 +32,9 @@ #include <dl-elf.h> #include <dl-hash.h> /* Defines USE_TLS */ +#if defined(__PTHREADS_NATIVE__) #include <tls.h> +#endif /* For INIT/FINI dependency sorting. */ struct init_fini_list { diff --git a/ldso/ldso/arm/dl-syscalls.h b/ldso/ldso/arm/dl-syscalls.h index f0f4baed8..4b42a57e0 100644 --- a/ldso/ldso/arm/dl-syscalls.h +++ b/ldso/ldso/arm/dl-syscalls.h @@ -1,6 +1,7 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" diff --git a/ldso/ldso/cris/dl-syscalls.h b/ldso/ldso/cris/dl-syscalls.h index dc0cc6164..996bb87c6 100644 --- a/ldso/ldso/cris/dl-syscalls.h +++ b/ldso/ldso/cris/dl-syscalls.h @@ -1,5 +1,6 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" diff --git a/ldso/ldso/frv/dl-syscalls.h b/ldso/ldso/frv/dl-syscalls.h index 4ee1992a5..8e08d9e6c 100644 --- a/ldso/ldso/frv/dl-syscalls.h +++ b/ldso/ldso/frv/dl-syscalls.h @@ -20,9 +20,10 @@ USA. */ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" #include <sys/mman.h> /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */ diff --git a/ldso/ldso/i386/dl-syscalls.h b/ldso/ldso/i386/dl-syscalls.h index dc0cc6164..996bb87c6 100644 --- a/ldso/ldso/i386/dl-syscalls.h +++ b/ldso/ldso/i386/dl-syscalls.h @@ -1,5 +1,6 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" diff --git a/ldso/ldso/m68k/dl-syscalls.h b/ldso/ldso/m68k/dl-syscalls.h index dc0cc6164..996bb87c6 100644 --- a/ldso/ldso/m68k/dl-syscalls.h +++ b/ldso/ldso/m68k/dl-syscalls.h @@ -1,5 +1,6 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" diff --git a/ldso/ldso/mips/dl-syscalls.h b/ldso/ldso/mips/dl-syscalls.h index a97ff562c..afb1cd630 100644 --- a/ldso/ldso/mips/dl-syscalls.h +++ b/ldso/ldso/mips/dl-syscalls.h @@ -1,7 +1,8 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" #define MMAP_HAS_6_ARGS diff --git a/ldso/ldso/sh/dl-syscalls.h b/ldso/ldso/sh/dl-syscalls.h index a97ff562c..afb1cd630 100644 --- a/ldso/ldso/sh/dl-syscalls.h +++ b/ldso/ldso/sh/dl-syscalls.h @@ -1,7 +1,8 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" #define MMAP_HAS_6_ARGS diff --git a/ldso/ldso/sh64/dl-syscalls.h b/ldso/ldso/sh64/dl-syscalls.h index 1db7b6719..4fe50fac4 100644 --- a/ldso/ldso/sh64/dl-syscalls.h +++ b/ldso/ldso/sh64/dl-syscalls.h @@ -1,8 +1,9 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" #undef __syscall_return #define __syscall_return(type, res) \ diff --git a/ldso/ldso/x86_64/dl-syscalls.h b/ldso/ldso/x86_64/dl-syscalls.h index a97ff562c..afb1cd630 100644 --- a/ldso/ldso/x86_64/dl-syscalls.h +++ b/ldso/ldso/x86_64/dl-syscalls.h @@ -1,7 +1,8 @@ /* We can't use the real errno in ldso, since it has not yet * been dynamicly linked in yet. */ +#include "sys/syscall.h" extern int _dl_errno; +#undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} -#include "sys/syscall.h" #define MMAP_HAS_6_ARGS diff --git a/libc/Makefile b/libc/Makefile index 56669dd64..231c8112e 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -39,7 +39,7 @@ VERSION_SCRIPT:=${shell if [ -f sysdeps/linux/$(TARGET_ARCH)/libc.map ] ; then \ LIBNAME_TARGET:=$(TOPDIR)lib/$(LIBNAME) -all: halfclean $(LIBNAME_TARGET) $(DO_SHARED) +all: halfclean $(LIBNAME_TARGET) # Some functions are duplicated across subdirs, and when you pass $(AR) # the same object file more than once, it'll add it to the archive multiple @@ -85,7 +85,6 @@ shared: shared_$(LIBNAME) --whole-archive shared_$(LIBNAME) \ $(TOPDIR)libc/misc/internals/interp.o --no-whole-archive \ -init __uClibc_init $(TOPDIR)lib/$(UCLIBC_LDSO) $(LIBGCC) $(LDADD_LIBFLOAT) - @true #$(RM) -r tmp $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(SHARED_FULLNAME) $(INSTALL) -m 644 $(SHARED_FULLNAME) $(TOPDIR)lib @@ -93,15 +92,12 @@ shared: shared_$(LIBNAME) $(LN) -sf $(SHARED_FULLNAME) $(TOPDIR)lib/$(SHARED_MAJORNAME) halfclean: - @$(RM) $(LIBNAME) shared_$(LIBNAME) uClibc_config.h - @$(RM) $(SHARED_FULLNAME) $(SHARED_MAJORNAME) uClibc-0.* libc.so* + $(RM) $(LIBNAME) shared_$(LIBNAME) $(SHARED_FULLNAME) tags: ctags -R clean: subdirs_clean halfclean - @$(RM) -r tmp - $(RM) include/asm include/linux include/bits $(RM) obj.* obj-* subdirs: $(patsubst %, _dir_%, $(DIRS)) diff --git a/libc/misc/internals/Makefile b/libc/misc/internals/Makefile index 803181a8f..fee3eca70 100644 --- a/libc/misc/internals/Makefile +++ b/libc/misc/internals/Makefile @@ -27,6 +27,8 @@ include $(TOPDIR)Rules.mak CSRC=__uClibc_main.c tempname.c errno.c __errno_location.c __h_errno_location.c COBJS=$(patsubst %.c,%.o, $(CSRC)) +__uClibc_main.o: CFLAGS += $(SSP_DISABLE_FLAGS) + OBJS=$(COBJS) OBJ_LIST=../../obj.misc.internals diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index c9f3d0e40..1ed05c6b2 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -3,7 +3,7 @@ * Erik Andersen 2002-2004 * * __uClibc_main is the routine to be called by all the arch-specific - * versions of crt0.S in uClibc. + * versions of crt1.S in uClibc. * * It is meant to handle any special initialization needed by the library * such as setting the global variable(s) __environ (environ) and @@ -26,9 +26,10 @@ #include <sys/stat.h> #include <sys/sysmacros.h> #ifdef __UCLIBC_HAS_SSP__ -extern void __guard_setup(void); -#endif +#include <ssp-internal.h> +unsigned long __guard = 0UL; +#endif /* * Prototypes. @@ -106,6 +107,62 @@ static int __check_suid(void) return 1; } +#ifdef __UCLIBC_HAS_SSP__ +static __always_inline void __guard_setup(void) +{ + if (__guard != 0UL) + return; + +#ifndef __SSP_QUICK_CANARY__ + + size_t size; + +# ifdef __SSP_USE_ERANDOM__ + { + int mib[3]; + /* Random is another depth in Linux, hence an array of 3. */ + mib[0] = CTL_KERN; + mib[1] = KERN_RANDOM; + mib[2] = RANDOM_ERANDOM; + + size = sizeof(unsigned long); + if (SYSCTL(mib, 3, &__guard, &size, NULL, 0) != (-1)) + if (__guard != 0UL) + return; + } +# endif /* ifdef __SSP_USE_ERANDOM__ */ + { + int fd; + +# ifdef __SSP_USE_ERANDOM__ + /* + * Attempt to open kernel pseudo random device if one exists before + * opening urandom to avoid system entropy depletion. + */ + if ((fd = OPEN("/dev/erandom", O_RDONLY)) == (-1)) +# endif + fd = OPEN("/dev/urandom", O_RDONLY); + if (fd != (-1)) { + size = READ(fd, (char *) &__guard, sizeof(__guard)); + CLOSE(fd); + if (size == sizeof(__guard)) + return; + } + } +#endif /* ifndef __SSP_QUICK_CANARY__ */ + + /* Start with the "terminator canary". */ + __guard = 0xFF0A0D00UL; + + /* Everything failed? Or we are using a weakened model of the + * terminator canary */ + { + struct timeval tv; + GETTIMEOFDAY(&tv, NULL); + __guard ^= tv.tv_usec ^ tv.tv_sec; + } +} +#endif /* __UCLIBC_HAS_SSP__ */ /* __uClibc_init completely initialize uClibc so it is ready to use. * @@ -117,7 +174,7 @@ static int __check_suid(void) * uClibc is the address of __uClibc_init * * In all other cases we call it from the main stub - * __uClibc_start_main. + * __uClibc_main. */ void __uClibc_init(void) @@ -133,7 +190,7 @@ void __uClibc_init(void) __pagesize = PAGE_SIZE; #ifdef __UCLIBC_HAS_THREADS__ - /* Before we start initialzing uClibc we have to call + /* Before we start initializing uClibc we have to call * __pthread_initialize_minimal so we can use pthread_locks * whenever they are needed. */ @@ -141,6 +198,10 @@ void __uClibc_init(void) __pthread_initialize_minimal(); #endif +#ifdef __UCLIBC_HAS_SSP__ + __guard_setup (); +#endif + #ifdef __UCLIBC_HAS_LOCALE__ /* Initialize the global locale structure. */ if (likely(_locale_init!=NULL)) @@ -162,8 +223,8 @@ void attribute_hidden (*__app_fini)(void) = NULL; void attribute_hidden (*__rtld_fini)(void) = NULL; -/* __uClibc_start_main is the new main stub for uClibc. This function is - * called from crt0 (version 0.9.16 or newer), after ALL shared libraries +/* __uClibc_main is the new main stub for uClibc. This function is + * called from crt1 (version 0.9.28 or newer), after ALL shared libraries * are initialized, just before we call the application's main function. */ void __attribute__ ((__noreturn__)) @@ -246,10 +307,6 @@ __uClibc_main(int (*main)(int, char **, char **), int argc, } #endif -#ifdef __UCLIBC_HAS_SSP__ - __guard_setup (); -#endif - /* Note: It is possible that any initialization done above could * have resulted in errno being set nonzero, so set it to 0 before * we call main. diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c index 8486dc203..6767cfffb 100644 --- a/libc/misc/pthread/weaks.c +++ b/libc/misc/pthread/weaks.c @@ -24,6 +24,18 @@ static int __pthread_return_0 __P ((void)); static int __pthread_return_1 __P ((void)); +static int +__pthread_return_0 (void) +{ + return 0; +} + +static int +__pthread_return_1 (void) +{ + return 1; +} + /**********************************************************************/ /* Weaks for application/library use. * @@ -105,15 +117,3 @@ weak_alias (__pthread_return_0, __pthread_mutex_trylock) weak_alias (__pthread_return_0, __pthread_mutex_unlock) /**********************************************************************/ - -static int -__pthread_return_0 (void) -{ - return 0; -} - -static int -__pthread_return_1 (void) -{ - return 1; -} diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c index 57ef2217a..914277698 100644 --- a/libc/misc/time/time.c +++ b/libc/misc/time/time.c @@ -713,15 +713,15 @@ struct tm *__time_localtime_tzi(register const time_t *__restrict timer, /**********************************************************************/ #ifdef L_mktime -/* Another name for `mktime'. */ -/* time_t timelocal(struct tm *tp) */ -weak_alias(mktime,timelocal); - time_t mktime(struct tm *timeptr) { return _time_mktime(timeptr, 1); } +/* Another name for `mktime'. */ +/* time_t timelocal(struct tm *tp) */ +weak_alias(mktime,timelocal); + #endif /**********************************************************************/ #ifdef L_timegm diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c index d1383c99f..e3553166d 100644 --- a/libc/misc/wchar/wchar.c +++ b/libc/misc/wchar/wchar.c @@ -261,9 +261,6 @@ int mbsinit(const mbstate_t *ps) /**********************************************************************/ #ifdef L_mbrlen -size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) - __attribute__ ((__weak__, __alias__("__mbrlen"))); - size_t __mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) { static mbstate_t mbstate; /* Rely on bss 0-init. */ @@ -271,6 +268,9 @@ size_t __mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) return mbrtowc(NULL, s, n, (ps != NULL) ? ps : &mbstate); } +size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) + __attribute__ ((__weak__, __alias__("__mbrlen"))); + #endif /**********************************************************************/ #ifdef L_mbrtowc @@ -679,10 +679,6 @@ size_t _wchar_wcsntoutf8s(char *__restrict s, size_t n, /* WARNING: We treat len as SIZE_MAX when dst is NULL! */ -size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, - size_t NMC, size_t len, mbstate_t *__restrict ps) - __attribute__ ((__weak__, __alias__("__mbsnrtowcs"))); - size_t __mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, size_t NMC, size_t len, mbstate_t *__restrict ps) { @@ -782,6 +778,10 @@ size_t __mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, return len - count; } +size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, + size_t NMC, size_t len, mbstate_t *__restrict ps) + __attribute__ ((__weak__, __alias__("__mbsnrtowcs"))); + #endif /**********************************************************************/ #ifdef L___wcsnrtombs @@ -791,10 +791,6 @@ size_t __mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, /* Note: We completely ignore ps in all currently supported conversions. * TODO: Check for valid state anyway? */ -size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, - size_t NWC, size_t len, mbstate_t *__restrict ps) - __attribute__ ((__weak__, __alias__("__wcsnrtombs"))); - size_t __wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, size_t NWC, size_t len, mbstate_t *__restrict ps) { @@ -904,6 +900,10 @@ size_t __wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, return len - count; } +size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, + size_t NWC, size_t len, mbstate_t *__restrict ps) + __attribute__ ((__weak__, __alias__("__wcsnrtombs"))); + #endif /**********************************************************************/ #ifdef L_wcswidth diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c index 91c0d83f5..e56b545d6 100644 --- a/libc/pwd_grp/pwd_grp.c +++ b/libc/pwd_grp/pwd_grp.c @@ -41,7 +41,10 @@ #include <ctype.h> #include <pwd.h> #include <grp.h> +#include <paths.h> +#ifdef __HAS_SHADOW__ #include <shadow.h> +#endif #ifdef __UCLIBC_HAS_THREADS__ #include <pthread.h> #endif diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 684380ef0..6e1a95f2f 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -58,9 +58,7 @@ CSRC += fopencookie.c fmemopen.c open_memstream.c endif # pthread functions -ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) CSRC += flockfile.c ftrylockfile.c funlockfile.c -endif ifeq ($(strip $(PTHREADS_NATIVE)),y) CSRC += fatal.c endif diff --git a/libc/stdio/asprintf.c b/libc/stdio/asprintf.c index 54998fa1d..36ed807a4 100644 --- a/libc/stdio/asprintf.c +++ b/libc/stdio/asprintf.c @@ -12,8 +12,6 @@ #warning Skipping asprintf and __asprintf since no vsnprintf! #else -weak_alias(__asprintf,asprintf) - int __asprintf(char **__restrict buf, const char * __restrict format, ...) { va_list arg; @@ -26,4 +24,6 @@ int __asprintf(char **__restrict buf, const char * __restrict format, ...) return rv; } +weak_alias(__asprintf,asprintf) + #endif diff --git a/libc/stdio/clearerr.c b/libc/stdio/clearerr.c index 177088a77..2772bed3c 100644 --- a/libc/stdio/clearerr.c +++ b/libc/stdio/clearerr.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__clearerr_unlocked,clearerr_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__clearerr_unlocked,clearerr); -#endif - void __clearerr_unlocked(register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -21,6 +16,11 @@ void __clearerr_unlocked(register FILE *stream) __CLEARERR_UNLOCKED(stream); } +weak_alias(__clearerr_unlocked,clearerr_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__clearerr_unlocked,clearerr); +#endif + #elif defined __UCLIBC_HAS_THREADS__ void clearerr(register FILE *stream) diff --git a/libc/stdio/feof.c b/libc/stdio/feof.c index e98e7e1c2..907872f7f 100644 --- a/libc/stdio/feof.c +++ b/libc/stdio/feof.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__feof_unlocked,feof_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__feof_unlocked,feof); -#endif - int __feof_unlocked(register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -21,6 +16,11 @@ int __feof_unlocked(register FILE *stream) return __FEOF_UNLOCKED(stream); } +weak_alias(__feof_unlocked,feof_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__feof_unlocked,feof); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int feof(register FILE *stream) diff --git a/libc/stdio/ferror.c b/libc/stdio/ferror.c index 3bfaf68ee..95014d3b0 100644 --- a/libc/stdio/ferror.c +++ b/libc/stdio/ferror.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__ferror_unlocked,ferror_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__ferror_unlocked,ferror); -#endif - int __ferror_unlocked(register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -21,6 +16,11 @@ int __ferror_unlocked(register FILE *stream) return __FERROR_UNLOCKED(stream); } +weak_alias(__ferror_unlocked,ferror_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__ferror_unlocked,ferror); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int ferror(register FILE *stream) diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c index 6baa0ec82..fa50db15a 100644 --- a/libc/stdio/fflush.c +++ b/libc/stdio/fflush.c @@ -7,19 +7,12 @@ #include "_stdio.h" -extern int __fflush_unlocked(register FILE *stream); - #ifdef __DO_UNLOCKED #ifdef __UCLIBC_MJN3_ONLY__ #warning WISHLIST: Add option to test for undefined behavior of fflush. #endif /* __UCLIBC_MJN3_ONLY__ */ -weak_alias(__fflush_unlocked,fflush_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fflush_unlocked,fflush); -#endif - #ifdef __UCLIBC_HAS_THREADS__ /* Even if the stream is set to user-locking, we still need to lock * when all (lbf) writing streams are flushed. */ @@ -133,6 +126,11 @@ int __fflush_unlocked(register FILE *stream) #endif /* __STDIO_BUFFERS */ } +weak_alias(__fflush_unlocked,fflush_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fflush_unlocked,fflush); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int fflush(register FILE *stream) diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c index c672d9fe9..c68c1fdb5 100644 --- a/libc/stdio/fgetc.c +++ b/libc/stdio/fgetc.c @@ -12,17 +12,8 @@ #undef getc #undef getc_unlocked -extern int __fgetc_unlocked(FILE *stream); - #ifdef __DO_UNLOCKED -weak_alias(__fgetc_unlocked,fgetc_unlocked); -weak_alias(__fgetc_unlocked,getc_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fgetc_unlocked,fgetc); -weak_alias(__fgetc_unlocked,getc); -#endif - int __fgetc_unlocked(FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -78,9 +69,14 @@ int __fgetc_unlocked(FILE *stream) return EOF; } -#elif defined __UCLIBC_HAS_THREADS__ +weak_alias(__fgetc_unlocked,fgetc_unlocked); +weak_alias(__fgetc_unlocked,getc_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fgetc_unlocked,fgetc); +weak_alias(__fgetc_unlocked,getc); +#endif -weak_alias(fgetc,getc); +#elif defined __UCLIBC_HAS_THREADS__ int fgetc(register FILE *stream) { @@ -95,4 +91,6 @@ int fgetc(register FILE *stream) } } +weak_alias(fgetc,getc); + #endif diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c index 6bcfc2957..4b32ad612 100644 --- a/libc/stdio/fgets.c +++ b/libc/stdio/fgets.c @@ -9,12 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fgets_unlocked,fgets_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fgets_unlocked,fgets); -#endif - - char *__fgets_unlocked(char *__restrict s, int n, register FILE * __restrict stream) { @@ -64,6 +58,12 @@ char *__fgets_unlocked(char *__restrict s, int n, return NULL; } +weak_alias(__fgets_unlocked,fgets_unlocked); + +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fgets_unlocked,fgets); +#endif + #elif defined __UCLIBC_HAS_THREADS__ char *fgets(char *__restrict s, int n, diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c index 9f1f9c481..a78f52212 100644 --- a/libc/stdio/fgetwc.c +++ b/libc/stdio/fgetwc.c @@ -9,13 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fgetwc_unlocked,fgetwc_unlocked); -weak_alias(__fgetwc_unlocked,getwc_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fgetwc_unlocked,fgetwc); -weak_alias(__fgetwc_unlocked,getwc); -#endif - static void munge_stream(register FILE *stream, unsigned char *buf) { stream->__bufend = stream->__bufstart = buf; @@ -113,9 +106,14 @@ wint_t __fgetwc_unlocked(register FILE *stream) return wi; } -#elif defined __UCLIBC_HAS_THREADS__ +weak_alias(__fgetwc_unlocked,fgetwc_unlocked); +weak_alias(__fgetwc_unlocked,getwc_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fgetwc_unlocked,fgetwc); +weak_alias(__fgetwc_unlocked,getwc); +#endif -weak_alias(fgetwc,getwc); +#elif defined __UCLIBC_HAS_THREADS__ wint_t fgetwc(register FILE *stream) { @@ -131,4 +129,6 @@ wint_t fgetwc(register FILE *stream) return retval; } +weak_alias(fgetwc,getwc); + #endif diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c index ec8547e25..16f8873b3 100644 --- a/libc/stdio/fgetws.c +++ b/libc/stdio/fgetws.c @@ -12,11 +12,6 @@ extern wchar_t *__fgetws_unlocked(wchar_t *__restrict ws, int n, #ifdef __DO_UNLOCKED -weak_alias(__fgetws_unlocked,fgetws_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fgetws_unlocked,fgetws); -#endif - wchar_t *__fgetws_unlocked(wchar_t *__restrict ws, int n, FILE *__restrict stream) { @@ -42,6 +37,11 @@ wchar_t *__fgetws_unlocked(wchar_t *__restrict ws, int n, return ws; } +weak_alias(__fgetws_unlocked,fgetws_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fgetws_unlocked,fgetws); +#endif + #elif defined __UCLIBC_HAS_THREADS__ wchar_t *fgetws(wchar_t *__restrict ws, int n, FILE *__restrict stream) diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c index fbfa66551..30ae90ad3 100644 --- a/libc/stdio/fileno.c +++ b/libc/stdio/fileno.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fileno_unlocked,fileno_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fileno_unlocked,fileno); -#endif - int __fileno_unlocked(register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -26,6 +21,11 @@ int __fileno_unlocked(register FILE *stream) return -1; } +weak_alias(__fileno_unlocked,fileno_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fileno_unlocked,fileno); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int fileno(register FILE *stream) diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c index 0cfb4f943..ad3c95517 100644 --- a/libc/stdio/fputc.c +++ b/libc/stdio/fputc.c @@ -14,13 +14,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fputc_unlocked,fputc_unlocked); -weak_alias(__fputc_unlocked,putc_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fputc_unlocked,fputc); -weak_alias(__fputc_unlocked,putc); -#endif - int __fputc_unlocked(int c, register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); @@ -76,9 +69,14 @@ int __fputc_unlocked(int c, register FILE *stream) return EOF; } -#elif defined __UCLIBC_HAS_THREADS__ +weak_alias(__fputc_unlocked,fputc_unlocked); +weak_alias(__fputc_unlocked,putc_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fputc_unlocked,fputc); +weak_alias(__fputc_unlocked,putc); +#endif -weak_alias(fputc,putc); +#elif defined __UCLIBC_HAS_THREADS__ int fputc(int c, register FILE *stream) { @@ -93,4 +91,6 @@ int fputc(int c, register FILE *stream) } } +weak_alias(fputc,putc); + #endif diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c index b3d77fa46..e4d10659f 100644 --- a/libc/stdio/fputs.c +++ b/libc/stdio/fputs.c @@ -14,11 +14,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fputs_unlocked,fputs_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fputs_unlocked,fputs); -#endif - int __fputs_unlocked(register const char * __restrict s, FILE * __restrict stream) { @@ -27,6 +22,11 @@ int __fputs_unlocked(register const char * __restrict s, return ((__fwrite_unlocked(s, 1, n, stream) == n) ? n : EOF); } +weak_alias(__fputs_unlocked,fputs_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fputs_unlocked,fputs); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int fputs(const char * __restrict s, register FILE * __restrict stream) diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c index fc980dcef..ef7a6d627 100644 --- a/libc/stdio/fputwc.c +++ b/libc/stdio/fputwc.c @@ -9,6 +9,11 @@ #ifdef __DO_UNLOCKED +wint_t __fputwc_unlocked(wchar_t wc, FILE *stream) +{ + return _wstdio_fwrite(&wc, 1, stream) ? wc : WEOF; +} + weak_alias(__fputwc_unlocked,fputwc_unlocked); weak_alias(__fputwc_unlocked,putwc_unlocked); #ifndef __UCLIBC_HAS_THREADS__ @@ -16,15 +21,8 @@ weak_alias(__fputwc_unlocked,fputwc); weak_alias(__fputwc_unlocked,putwc); #endif -wint_t __fputwc_unlocked(wchar_t wc, FILE *stream) -{ - return _wstdio_fwrite(&wc, 1, stream) ? wc : WEOF; -} - #elif defined __UCLIBC_HAS_THREADS__ -weak_alias(fputwc,putwc); - wint_t fputwc(wchar_t wc, register FILE *stream) { wint_t retval; @@ -39,4 +37,6 @@ wint_t fputwc(wchar_t wc, register FILE *stream) return retval; } +weak_alias(fputwc,putwc); + #endif diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c index 7b6456a09..f3270fde8 100644 --- a/libc/stdio/fputws.c +++ b/libc/stdio/fputws.c @@ -12,11 +12,6 @@ extern int __fputws_unlocked(const wchar_t *__restrict ws, #ifdef __DO_UNLOCKED -weak_alias(__fputws_unlocked,fputws_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fputws_unlocked,fputws); -#endif - int __fputws_unlocked(const wchar_t *__restrict ws, register FILE *__restrict stream) { @@ -25,6 +20,11 @@ int __fputws_unlocked(const wchar_t *__restrict ws, return (_wstdio_fwrite(ws, n, stream) == n) ? 0 : -1; } +weak_alias(__fputws_unlocked,fputws_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fputws_unlocked,fputws); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int fputws(const wchar_t *__restrict ws, register FILE *__restrict stream) diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 875c82616..73414e26c 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fread_unlocked,fread_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fread_unlocked,fread); -#endif - size_t __fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb, FILE * __restrict stream) { @@ -88,6 +83,11 @@ size_t __fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb, return 0; } +weak_alias(__fread_unlocked,fread_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fread_unlocked,fread); +#endif + #elif defined __UCLIBC_HAS_THREADS__ size_t fread(void * __restrict ptr, size_t size, size_t nmemb, diff --git a/libc/stdio/fseeko.c b/libc/stdio/fseeko.c index fed425730..48979a06b 100644 --- a/libc/stdio/fseeko.c +++ b/libc/stdio/fseeko.c @@ -19,15 +19,11 @@ # define FSEEK __fseeko64 # define OFFSET_TYPE __off64_t -weak_alias(__fseeko64,fseeko64); - #else # define FSEEK fseek # define OFFSET_TYPE long int -weak_alias(fseek,fseeko); - #endif @@ -87,3 +83,9 @@ int FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence) #endif } + +#ifdef __DO_LARGEFILE +weak_alias(__fseeko64,fseeko64); +#else +weak_alias(fseek,fseeko); +#endif diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c index 7092f34cf..38517acbd 100644 --- a/libc/stdio/ftello.c +++ b/libc/stdio/ftello.c @@ -15,15 +15,11 @@ # define FTELL __ftello64 # define OFFSET_TYPE __off64_t -weak_alias(__ftello64,ftello64); - #else # define FTELL ftell # define OFFSET_TYPE long int -weak_alias(ftell,ftello); - #endif OFFSET_TYPE FTELL(register FILE *stream) @@ -59,3 +55,9 @@ OFFSET_TYPE FTELL(register FILE *stream) #endif } + +#ifdef __DO_LARGEFILE +weak_alias(__ftello64,ftello64); +#else +weak_alias(ftell,ftello); +#endif diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index a5e8fd6bf..7bb0a8022 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -9,11 +9,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__fwrite_unlocked,fwrite_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__fwrite_unlocked,fwrite); -#endif - size_t __fwrite_unlocked(const void * __restrict ptr, size_t size, size_t nmemb, register FILE * __restrict stream) { @@ -39,6 +34,11 @@ size_t __fwrite_unlocked(const void * __restrict ptr, size_t size, return 0; } +weak_alias(__fwrite_unlocked,fwrite_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__fwrite_unlocked,fwrite); +#endif + #elif defined __UCLIBC_HAS_THREADS__ size_t fwrite(const void * __restrict ptr, size_t size, diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c index 49414eb70..902cec16e 100644 --- a/libc/stdio/getchar.c +++ b/libc/stdio/getchar.c @@ -12,11 +12,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__getchar_unlocked,getchar_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__getchar_unlocked,getchar); -#endif - int __getchar_unlocked(void) { register FILE *stream = stdin; @@ -24,6 +19,11 @@ int __getchar_unlocked(void) return __GETC_UNLOCKED_MACRO(stream); } +weak_alias(__getchar_unlocked,getchar_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__getchar_unlocked,getchar); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int getchar(void) diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c index fe388ee11..cf3cf4c10 100644 --- a/libc/stdio/getdelim.c +++ b/libc/stdio/getdelim.c @@ -18,8 +18,6 @@ * a reading. So space may be allocated even if initially at EOF. */ -weak_alias(__getdelim,getdelim); - #define GETDELIM_GROWBY 64 ssize_t __getdelim(char **__restrict lineptr, size_t *__restrict n, @@ -75,3 +73,5 @@ ssize_t __getdelim(char **__restrict lineptr, size_t *__restrict n, return pos; } + +weak_alias(__getdelim,getdelim); diff --git a/libc/stdio/getwchar.c b/libc/stdio/getwchar.c index 98d9fcba0..642162fed 100644 --- a/libc/stdio/getwchar.c +++ b/libc/stdio/getwchar.c @@ -7,20 +7,18 @@ #include "_stdio.h" -wint_t __getwchar_unlocked(void); - #ifdef __DO_UNLOCKED -weak_alias(__getwchar_unlocked,getwchar_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__getwchar_unlocked,getwchar); -#endif - wint_t __getwchar_unlocked(void) { return __fgetwc_unlocked(stdin); } +weak_alias(__getwchar_unlocked,getwchar_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__getwchar_unlocked,getwchar); +#endif + #elif defined __UCLIBC_HAS_THREADS__ wint_t getwchar(void) diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c index 20f5aadcc..fa6d6c372 100644 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -12,11 +12,6 @@ #ifdef __DO_UNLOCKED -weak_alias(__putchar_unlocked,putchar_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__putchar_unlocked,putchar); -#endif - int __putchar_unlocked(int c) { register FILE *stream = stdout; @@ -24,6 +19,11 @@ int __putchar_unlocked(int c) return __PUTC_UNLOCKED_MACRO(c, stream); } +weak_alias(__putchar_unlocked,putchar_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__putchar_unlocked,putchar); +#endif + #elif defined __UCLIBC_HAS_THREADS__ int putchar(int c) diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c index 9a563dcf0..47bc173e1 100644 --- a/libc/stdio/putwchar.c +++ b/libc/stdio/putwchar.c @@ -7,20 +7,18 @@ #include "_stdio.h" -extern wint_t __putwchar_unlocked(wchar_t wc); - #ifdef __DO_UNLOCKED -weak_alias(__putwchar_unlocked,putwchar_unlocked); -#ifndef __UCLIBC_HAS_THREADS__ -weak_alias(__putwchar_unlocked,putwchar); -#endif - wint_t __putwchar_unlocked(wchar_t wc) { return __fputwc_unlocked(wc, stdout); } +weak_alias(__putwchar_unlocked,putwchar_unlocked); +#ifndef __UCLIBC_HAS_THREADS__ +weak_alias(__putwchar_unlocked,putwchar); +#endif + #elif defined __UCLIBC_HAS_THREADS__ wint_t putwchar(wchar_t wc) diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c index 9e78fb24e..a749955e2 100644 --- a/libc/stdlib/stdlib.c +++ b/libc/stdlib/stdlib.c @@ -207,6 +207,11 @@ int abs(int j) /**********************************************************************/ #ifdef L_labs +long int labs(long int j) +{ + return (j >= 0) ? j : -j; +} + #if UINT_MAX == ULONG_MAX strong_alias(labs,abs) #endif @@ -219,26 +224,21 @@ strong_alias(labs,llabs) strong_alias(labs,imaxabs) #endif -long int labs(long int j) -{ - return (j >= 0) ? j : -j; -} - #endif /**********************************************************************/ #ifdef L_llabs #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -#if (ULLONG_MAX == UINTMAX_MAX) -strong_alias(llabs,imaxabs) -#endif - long long int llabs(long long int j) { return (j >= 0) ? j : -j; } +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(llabs,imaxabs) +#endif + #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ #endif @@ -258,6 +258,11 @@ int atoi(const char *nptr) /**********************************************************************/ #ifdef L_atol +long atol(const char *nptr) +{ + return strtol(nptr, (char **) NULL, 10); +} + #if UINT_MAX == ULONG_MAX strong_alias(atol,atoi) #endif @@ -266,11 +271,6 @@ strong_alias(atol,atoi) strong_alias(atol,atoll) #endif -long atol(const char *nptr) -{ - return strtol(nptr, (char **) NULL, 10); -} - #endif /**********************************************************************/ #ifdef L_atoll @@ -288,6 +288,12 @@ long long atoll(const char *nptr) /**********************************************************************/ #if defined(L_strtol) || defined(L_strtol_l) +long __XL(strtol)(const char * __restrict str, char ** __restrict endptr, + int base __LOCALE_PARAM ) +{ + return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG ); +} + #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtol_l) strong_alias(strtol,strtoimax) #endif @@ -296,12 +302,6 @@ strong_alias(strtol,strtoimax) strong_alias(__XL(strtol),__XL(strtoll)) #endif -long __XL(strtol)(const char * __restrict str, char ** __restrict endptr, - int base __LOCALE_PARAM ) -{ - return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG ); -} - __XL_ALIAS(strtol) #endif @@ -310,13 +310,6 @@ __XL_ALIAS(strtol) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -#if !defined(L_strtoll_l) -#if (ULLONG_MAX == UINTMAX_MAX) -strong_alias(strtoll,strtoimax) -#endif -strong_alias(strtoll,strtoq) -#endif - long long __XL(strtoll)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) @@ -325,6 +318,13 @@ long long __XL(strtoll)(const char * __restrict str, __LOCALE_ARG ); } +#if !defined(L_strtoll_l) +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(strtoll,strtoimax) +#endif +strong_alias(strtoll,strtoq) +#endif + __XL_ALIAS(strtoll) #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ @@ -333,6 +333,13 @@ __XL_ALIAS(strtoll) /**********************************************************************/ #if defined(L_strtoul) || defined(L_strtoul_l) +unsigned long __XL(strtoul)(const char * __restrict str, + char ** __restrict endptr, int base + __LOCALE_PARAM ) +{ + return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG ); +} + #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtoul_l) strong_alias(strtoul,strtoumax) #endif @@ -341,13 +348,6 @@ strong_alias(strtoul,strtoumax) strong_alias(__XL(strtoul),__XL(strtoull)) #endif -unsigned long __XL(strtoul)(const char * __restrict str, - char ** __restrict endptr, int base - __LOCALE_PARAM ) -{ - return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG ); -} - __XL_ALIAS(strtoul) #endif @@ -356,13 +356,6 @@ __XL_ALIAS(strtoul) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -#if !defined(L_strtoull_l) -#if (ULLONG_MAX == UINTMAX_MAX) -strong_alias(strtoull,strtoumax) -#endif -strong_alias(strtoull,strtouq) -#endif - unsigned long long __XL(strtoull)(const char * __restrict str, char ** __restrict endptr, int base __LOCALE_PARAM ) @@ -370,6 +363,13 @@ unsigned long long __XL(strtoull)(const char * __restrict str, return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0 __LOCALE_ARG ); } +#if !defined(L_strtoull_l) +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(strtoull,strtoumax) +#endif +strong_alias(strtoull,strtouq) +#endif + __XL_ALIAS(strtoull) #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ @@ -953,6 +953,12 @@ size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) /**********************************************************************/ #if defined(L_wcstol) || defined(L_wcstol_l) +long __XL(wcstol)(const wchar_t * __restrict str, + wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) +{ + return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG ); +} + #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstol_l) strong_alias(wcstol,wcstoimax) #endif @@ -961,12 +967,6 @@ strong_alias(wcstol,wcstoimax) strong_alias(__XL(wcstol),__XL(wcstoll)) #endif -long __XL(wcstol)(const wchar_t * __restrict str, - wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) -{ - return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG ); -} - __XL_ALIAS(wcstol) #endif @@ -975,13 +975,6 @@ __XL_ALIAS(wcstol) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -#if !defined(L_wcstoll_l) -#if (ULLONG_MAX == UINTMAX_MAX) -strong_alias(wcstoll,wcstoimax) -#endif -strong_alias(wcstoll,wcstoq) -#endif - long long __XL(wcstoll)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) @@ -990,6 +983,13 @@ long long __XL(wcstoll)(const wchar_t * __restrict str, __LOCALE_ARG ); } +#if !defined(L_wcstoll_l) +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(wcstoll,wcstoimax) +#endif +strong_alias(wcstoll,wcstoq) +#endif + __XL_ALIAS(wcstoll) #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ @@ -998,6 +998,13 @@ __XL_ALIAS(wcstoll) /**********************************************************************/ #if defined(L_wcstoul) || defined(L_wcstoul_l) +unsigned long __XL(wcstoul)(const wchar_t * __restrict str, + wchar_t ** __restrict endptr, int base + __LOCALE_PARAM ) +{ + return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG ); +} + #if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstoul_l) strong_alias(wcstoul,wcstoumax) #endif @@ -1006,13 +1013,6 @@ strong_alias(wcstoul,wcstoumax) strong_alias(__XL(wcstoul),__XL(wcstoull)) #endif -unsigned long __XL(wcstoul)(const wchar_t * __restrict str, - wchar_t ** __restrict endptr, int base - __LOCALE_PARAM ) -{ - return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG ); -} - __XL_ALIAS(wcstoul) #endif @@ -1021,13 +1021,6 @@ __XL_ALIAS(wcstoul) #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) -#if !defined(L_wcstoull_l) -#if (ULLONG_MAX == UINTMAX_MAX) -strong_alias(wcstoull,wcstoumax) -#endif -strong_alias(wcstoull,wcstouq) -#endif - unsigned long long __XL(wcstoull)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) @@ -1035,6 +1028,13 @@ unsigned long long __XL(wcstoull)(const wchar_t * __restrict str, return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG ); } +#if !defined(L_wcstoull_l) +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(wcstoull,wcstoumax) +#endif +strong_alias(wcstoull,wcstouq) +#endif + __XL_ALIAS(wcstoull) #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */ diff --git a/libc/string/generic/strcmp.c b/libc/string/generic/strcmp.c index 2af550d81..c8212f04b 100644 --- a/libc/string/generic/strcmp.c +++ b/libc/string/generic/strcmp.c @@ -23,10 +23,6 @@ #undef strcmp -#ifdef __LOCALE_C_ONLY -weak_alias(strcmp,strcoll); -#endif /* __LOCALE_C_ONLY */ - /* Compare S1 and S2, returning less than, equal to or greater than zero if S1 is lexicographically less than, equal to or greater than S2. */ @@ -50,3 +46,7 @@ strcmp (p1, p2) return c1 - c2; } + +#ifdef __LOCALE_C_ONLY +weak_alias(strcmp,strcoll); +#endif /* __LOCALE_C_ONLY */ diff --git a/libc/string/wstring.c b/libc/string/wstring.c index 6f54ae615..c9c8548fb 100644 --- a/libc/string/wstring.c +++ b/libc/string/wstring.c @@ -612,10 +612,6 @@ Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2, #ifdef L_memcmp -#ifndef L_wmemcmp -weak_alias(memcmp,bcmp); -#endif - int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n) { register const Wuchar *r1 = (const Wuchar *) s1; @@ -638,6 +634,10 @@ int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n) #endif } +#ifndef L_wmemcmp +weak_alias(memcmp,bcmp); +#endif + #endif /**********************************************************************/ #ifdef L_wcscmp @@ -649,14 +649,6 @@ int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n) #ifdef L_strcmp -#ifdef __LOCALE_C_ONLY -#ifdef L_wcscmp -weak_alias(wcscmp,wcscoll); -#else /* L_wcscmp */ -weak_alias(strcmp,strcoll); -#endif /* L_wcscmp */ -#endif /* __LOCALE_C_ONLY */ - int Wstrcmp(register const Wchar *s1, register const Wchar *s2) { #ifdef WANT_WIDE @@ -677,6 +669,15 @@ int Wstrcmp(register const Wchar *s1, register const Wchar *s2) return r; #endif } + +#ifdef __LOCALE_C_ONLY +#ifdef L_wcscmp +weak_alias(wcscmp,wcscoll); +#else /* L_wcscmp */ +weak_alias(strcmp,strcoll); +#endif /* L_wcscmp */ +#endif /* __LOCALE_C_ONLY */ + #endif /**********************************************************************/ #ifdef L_wcsncmp @@ -756,10 +757,6 @@ Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n) #ifdef L_strchr -#ifndef L_wcschr -weak_alias(strchr,index); -#endif - Wchar *Wstrchr(register const Wchar *s, Wint c) { do { @@ -771,6 +768,10 @@ Wchar *Wstrchr(register const Wchar *s, Wint c) return NULL; } +#ifndef L_wcschr +weak_alias(strchr,index); +#endif + #endif /**********************************************************************/ #ifdef L_wcscspn @@ -830,10 +831,6 @@ Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2) #ifdef L_strrchr -#ifndef L_wcsrchr -weak_alias(strrchr,rindex); -#endif - Wchar *Wstrrchr(register const Wchar *s, Wint c) { register const Wchar *p; @@ -848,6 +845,10 @@ Wchar *Wstrrchr(register const Wchar *s, Wint c) return (Wchar *) p; /* silence the warning */ } +#ifndef L_wcsrchr +weak_alias(strrchr,rindex); +#endif + #endif /**********************************************************************/ #ifdef L_wcsspn @@ -886,10 +887,6 @@ size_t Wstrspn(const Wchar *s1, const Wchar *s2) /* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */ -#ifdef L_wcsstr -weak_alias(wcsstr,wcswcs); -#endif - Wchar *Wstrstr(const Wchar *s1, const Wchar *s2) { register const Wchar *s = s1; @@ -912,6 +909,10 @@ Wchar *Wstrstr(const Wchar *s1, const Wchar *s2) } while (1); } +#ifdef L_wcsstr +weak_alias(wcsstr,wcswcs); +#endif + #endif /**********************************************************************/ #undef Wstrspn @@ -930,10 +931,6 @@ Wchar *Wstrstr(const Wchar *s1, const Wchar *s2) #ifdef L_strtok_r -#ifndef L_wcstok -weak_alias(__strtok_r,strtok_r); -#endif - Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2, Wchar ** __restrict next_start) { @@ -967,6 +964,10 @@ Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2, #endif } +#ifndef L_wcstok +weak_alias(__strtok_r,strtok_r); +#endif + #endif /**********************************************************************/ /* #ifdef L_wcstok */ @@ -1571,8 +1572,6 @@ int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen) /**********************************************************************/ #ifdef L___glibc_strerror_r -weak_alias(__glibc_strerror_r,__strerror_r); - char *__glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen) { __xpg_strerror_r(errnum, strerrbuf, buflen); @@ -1580,6 +1579,7 @@ char *__glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen) return strerrbuf; } +weak_alias(__glibc_strerror_r,__strerror_r); #endif /**********************************************************************/ #ifdef L_memmem @@ -1625,10 +1625,6 @@ void *memmem(const void *haystack, size_t haystacklen, #ifdef L_mempcpy -#ifndef L_wmempcpy -weak_alias(__mempcpy,mempcpy); -#endif - Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n) { register Wchar *r1 = s1; @@ -1648,6 +1644,10 @@ Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n) return r1; } +#ifndef L_wmempcpy +weak_alias(__mempcpy,mempcpy); +#endif + #endif /**********************************************************************/ #ifdef L_memrchr @@ -1737,7 +1737,6 @@ Wchar *Wstpncpy(register Wchar * __restrict s1, /**********************************************************************/ #ifdef L_bzero -weak_alias(__bzero,bzero); void __bzero(void *s, size_t n) { register unsigned char *p = s; @@ -1753,6 +1752,7 @@ void __bzero(void *s, size_t n) --np; } } +weak_alias(__bzero,bzero); #undef np #endif @@ -1902,15 +1902,13 @@ char *strsep(char ** __restrict s1, const char * __restrict s2) #ifdef L_strchrnul -extern Wchar *__Wstrchrnul(register const Wchar *s, Wint c); -weak_alias(__Wstrchrnul, Wstrchrnul); - Wchar *__Wstrchrnul(register const Wchar *s, Wint c) { --s; while (*++s && (*s != ((Wchar)c))); return (Wchar *) s; } +weak_alias(__Wstrchrnul, Wstrchrnul); #endif /**********************************************************************/ @@ -2069,18 +2067,12 @@ extern size_t __wcslcpy(wchar_t *__restrict dst, #ifdef L___wcslcpy #define L_strlcpy #define Wstrlcpy __wcslcpy -#ifdef __LOCALE_C_ONLY -weak_alias(__wcslcpy,wcsxfrm); -#endif #endif #ifdef L_strlcpy #ifndef L___wcslcpy #define Wstrlcpy strlcpy -#ifdef __LOCALE_C_ONLY -weak_alias(strlcpy,strxfrm); -#endif #endif /* OpenBSD function: @@ -2111,6 +2103,14 @@ size_t Wstrlcpy(register Wchar *__restrict dst, return src - src0; } +#ifdef __LOCALE_C_ONLY +#ifdef L___wcslcpy +weak_alias(__wcslcpy,wcsxfrm); +#else +weak_alias(strlcpy,strxfrm); +#endif +#endif + #endif /**********************************************************************/ #if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__) diff --git a/libc/sysdeps/linux/common/ssp.c b/libc/sysdeps/linux/common/ssp.c index 31833cbb9..899910c96 100644 --- a/libc/sysdeps/linux/common/ssp.c +++ b/libc/sysdeps/linux/common/ssp.c @@ -1,6 +1,6 @@ /* - * Distributed under the terms of the GNU General Public License v2 - * $Header: /var/cvs/uClibc/libc/sysdeps/linux/common/ssp.c,v 1.6 2005/01/11 17:01:53 vapier Exp $ + * Distributed under the terms of the GNU Lesser General Public License + * $Header: $ * * This is a modified version of Hiroaki Etoh's stack smashing routines * implemented for glibc. @@ -12,134 +12,61 @@ * Peter S. Mazinger - <ps.m[@]gmx.net> * Yoann Vandoorselaere - <yoann[@]prelude-ids.org> * Robert Connolly - <robert[@]linuxfromscratch.org> - * Cory Visi <cory@visi.name> - * + * Cory Visi <cory[@]visi.name> + * Mike Frysinger <vapier[@]gentoo.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef __SSP__ -# error ssp.c has to be built w/ -fno-stack-protector -#endif - -#include <stdio.h> #include <string.h> -#include <fcntl.h> #include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/un.h> #include <sys/syslog.h> -#include <sys/time.h> -#ifdef __SSP_USE_ERANDOM__ -# include <sys/sysctl.h> -#endif - -#ifdef __PROPOLICE_BLOCK_SEGV__ -# define SSP_SIGTYPE SIGSEGV -#elif __PROPOLICE_BLOCK_KILL__ -# define SSP_SIGTYPE SIGKILL -#else -# define SSP_SIGTYPE SIGABRT -#endif -unsigned long __guard = 0UL; +#include <ssp-internal.h> -/* Use of __* functions from the rest of glibc here avoids - * initialisation problems for executables preloaded with - * libraries that overload the associated standard library - * functions. - */ -#ifdef __UCLIBC__ -extern int __libc_open(__const char *file, int flags, ...); -extern ssize_t __libc_read(int fd, void *buf, size_t count); -extern int __libc_close(int fd); -#else -# define __libc_open(file, flags) __open(file, flags) -# define __libc_read(fd, buf, count) __read(fd, buf, count) -# define __libc_close(fd) __close(fd) -#endif - -void __guard_setup(void) __attribute__ ((constructor)); -void __guard_setup(void) +static __always_inline void block_signals(void) { - size_t size; - - if (__guard != 0UL) - return; + struct sigaction sa; + sigset_t mask; - /* Start with the "terminator canary". */ - __guard = 0xFF0A0D00UL; + sigfillset(&mask); -#ifndef __SSP_QUICK_CANARY__ -# ifdef __SSP_USE_ERANDOM__ - { - int mib[3]; - /* Random is another depth in Linux, hence an array of 3. */ - mib[0] = CTL_KERN; - mib[1] = KERN_RANDOM; - mib[2] = RANDOM_ERANDOM; + sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */ + SIGPROCMASK(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */ - size = sizeof(unsigned long); - if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1)) - if (__guard != 0UL) - return; - } -# endif /* ifdef __SSP_USE_ERANDOM__ */ - /* - * Attempt to open kernel pseudo random device if one exists before - * opening urandom to avoid system entropy depletion. - */ - { - int fd; + /* Make the default handler associated with the signal handler */ + memset(&sa, 0, sizeof(struct sigaction)); + sigfillset(&sa.sa_mask); /* Block all signals */ + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + SIGACTION(SSP_SIGTYPE, &sa, NULL); +} -# ifdef __SSP_USE_ERANDOM__ - if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1)) -# endif - fd = __libc_open("/dev/urandom", O_RDONLY); - if (fd != (-1)) { - size = __libc_read(fd, (char *) &__guard, sizeof(__guard)); - __libc_close(fd); - if (size == sizeof(__guard)) - return; - } - } -#endif /* ifndef __SSP_QUICK_CANARY__ */ +static __always_inline void ssp_write(int fd, const char *msg1, const char *msg2, const char *msg3) +{ + WRITE(fd, msg1, strlen(msg1)); + WRITE(fd, msg2, strlen(msg2)); + WRITE(fd, msg3, strlen(msg3)); + WRITE(fd, "()\n", 3); + openlog("ssp", LOG_CONS | LOG_PID, LOG_USER); + syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3); + closelog(); +} - /* Everything failed? Or we are using a weakened model of the - * terminator canary */ - { - struct timeval tv; - gettimeofday(&tv, NULL); - __guard ^= tv.tv_usec ^ tv.tv_sec; - } +static __always_inline void terminate(void) +{ + (void) KILL(GETPID(), SSP_SIGTYPE); + EXIT(127); } -void __stack_smash_handler(char func[], int damaged __attribute__ ((unused))); -void __stack_smash_handler(char func[], int damaged) +void __attribute__ ((noreturn)) __stack_smash_handler(char func[], int damaged __attribute__ ((unused))); +void __attribute__ ((noreturn)) __stack_smash_handler(char func[], int damaged) { extern char *__progname; const char message[] = ": stack smashing attack in function "; - struct sigaction sa; - sigset_t mask; - sigfillset(&mask); + block_signals(); - sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */ - sigprocmask(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */ - - /* Print error message to stderr and syslog */ - fprintf(stderr, "%s%s%s()\n", __progname, message, func); - syslog(LOG_INFO, "%s%s%s()", __progname, message, func); + ssp_write(STDERR_FILENO, __progname, message, func); - /* Make the default handler associated with the signal handler */ - memset(&sa, 0, sizeof(struct sigaction)); - sigfillset(&sa.sa_mask); /* Block all signals */ - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SSP_SIGTYPE, &sa, NULL); - (void) kill(getpid(), SSP_SIGTYPE); - _exit(127); + while(1) + terminate(); } diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c index 504f3764c..0dc0e0509 100644 --- a/libc/unistd/getopt.c +++ b/libc/unistd/getopt.c @@ -26,10 +26,13 @@ * Modified once again for uClibc by Erik Andersen 8/7/02 */ +#include <features.h> #include <stdio.h> #include <string.h> #include <stdlib.h> +#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ #include <libintl.h> +#endif #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Enable gettext awareness. diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index f5b49a10f..902697b45 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -29,7 +29,9 @@ #include <unistd.h> #include <sys/sysinfo.h> #include <sys/types.h> +#ifdef __UCLIBC_HAS_REGEX__ #include <regex.h> +#endif #ifndef __UCLIBC_CLK_TCK_CONST #error __UCLIBC_CLK_TCK_CONST not defined! diff --git a/libcrypt/Makefile b/libcrypt/Makefile index ec860dc18..d41309f3c 100644 --- a/libcrypt/Makefile +++ b/libcrypt/Makefile @@ -45,18 +45,16 @@ $(OBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o -$(OBJ): Makefile - shared: all $(LD) $(LDFLAGS) -soname=$(LIBCRYPT_SHARED).$(MAJOR_VERSION) \ -o $(LIBCRYPT_SHARED_FULLNAME) --whole-archive $(LIBCRYPT) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBCRYPT_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBCRYPT_SHARED).$(MAJOR_VERSION) - $(INSTALL) -m 644 $(LIBCRYPT_SHARED_FULLNAME) $(TOPDIR)lib; + $(INSTALL) -m 644 $(LIBCRYPT_SHARED_FULLNAME) $(TOPDIR)lib $(LN) -sf $(LIBCRYPT_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBCRYPT_SHARED) $(LN) -sf $(LIBCRYPT_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBCRYPT_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBCRYPT_SHARED)* $(LIBCRYPT_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBCRYPT) $(LIBCRYPT_SHARED_FULLNAME) diff --git a/libintl/Makefile b/libintl/Makefile index abb9c8fd3..8977b5ba9 100644 --- a/libintl/Makefile +++ b/libintl/Makefile @@ -53,7 +53,7 @@ shared: all $(LD) $(LDFLAGS) -soname=$(LIBINTL_SHARED).$(MAJOR_VERSION) \ -o $(LIBINTL_SHARED_FULLNAME) --whole-archive $(LIBINTL) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBINTL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBINTL_SHARED).$(MAJOR_VERSION) $(INSTALL) -m 644 $(LIBINTL_SHARED_FULLNAME) $(TOPDIR)lib @@ -61,4 +61,4 @@ shared: all $(LN) -sf $(LIBINTL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBINTL_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBINTL_SHARED)* $(LIBINTL_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBINTL) $(LIBINTL_SHARED_FULLNAME) diff --git a/libm/Makefile b/libm/Makefile index 7c8bf1d3e..d8927a89a 100644 --- a/libm/Makefile +++ b/libm/Makefile @@ -93,25 +93,16 @@ COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) $(FL_MOBJ) -ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y) -all: -else all: $(LIBM) subdirs -endif -ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y) -$(LIBM) ar-target: -else ar-target: $(OBJS) $(AR) $(ARFLAGS) $(LIBM) $(OBJS) $(LIBM): ar-target $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBM) $(INSTALL) -m 644 $(LIBM) $(TOPDIR)lib -endif shared: all -ifeq ($(strip $(UCLIBC_HAS_FLOATS)),y) $(LD) $(LDFLAGS) -soname=$(LIBM_SHARED).$(MAJOR_VERSION) \ -o $(LIBM_SHARED_FULLNAME) --whole-archive $(LIBM) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ @@ -121,7 +112,6 @@ ifeq ($(strip $(UCLIBC_HAS_FLOATS)),y) $(INSTALL) -m 644 $(LIBM_SHARED_FULLNAME) $(TOPDIR)lib $(LN) -sf $(LIBM_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBM_SHARED) $(LN) -sf $(LIBM_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBM_SHARED).$(MAJOR_VERSION) -endif $(COBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ @@ -131,13 +121,11 @@ $(FL_MOBJ): $(FL_MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o -$(OBJ): Makefile - tags: ctags -R clean: subdirs_clean - $(RM) *.[oa] *~ core $(LIBM_SHARED)* $(LIBM_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBM) $(LIBM_SHARED_FULLNAME) subdirs: $(patsubst %, _dir_%, $(DIRS)) subdirs_clean: $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) diff --git a/libm/powerpc/Makefile b/libm/powerpc/Makefile index 9e4a309da..342c182ba 100644 --- a/libm/powerpc/Makefile +++ b/libm/powerpc/Makefile @@ -38,7 +38,8 @@ LIBM=../libm.a CFLAGS+=-D_IEEE_LIBM -D_ISOC99_SOURCE -D_SVID_SOURCE ifeq ($(strip $(DO_C99_MATH)),y) -CSRC = s_ceil.c s_floor.c s_ldexp.c s_frexp.c s_logb.c s_modf.c w_scalb.c s_copysign.c s_rint.c +CSRC = s_ceil.c s_copysign.c s_floor.c s_frexp.c s_ldexp.c s_logb.c s_modf.c \ + s_nearbyint.c s_rint.c s_round.c s_trunc.c w_scalb.c else CSRC = endif diff --git a/libm/powerpc/s_modf.c b/libm/powerpc/s_modf.c index 403c54b79..f4344bda8 100644 --- a/libm/powerpc/s_modf.c +++ b/libm/powerpc/s_modf.c @@ -4,9 +4,8 @@ ** Contains: C source code for implementations of floating-point ** functions which round to integral value or format, as ** defined in header <fp.h>. In particular, this file -** contains implementations of functions rint, nearbyint, -** rinttol, round, roundtol, trunc, modf and modfl. This file -** targets PowerPC or Power platforms. +** contains implementations of functions rinttol, roundtol, +** modf and modfl. This file targets PowrPC or Power platforms. ** ** Written by: A. Sazegari, Apple AltiVec Group ** Created originally by Jon Okada, Apple Numerics Group @@ -66,44 +65,11 @@ typedef union static const unsigned long int signMask = 0x80000000ul; static const double twoTo52 = 4503599627370496.0; static const double doubleToLong = 4503603922337792.0; // 2^52 -static const DblInHex Huge = {{ 0x7FF00000, 0x00000000 }}; static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }}; /******************************************************************************* * * -* The function nearbyint rounds its double argument to integral value * -* according to the current rounding direction and returns the result in * -* double format. This function does not signal inexact. * -* * -******************************************************************************** -* * -* This function calls fabs and copysign. * -* * -*******************************************************************************/ - -double nearbyint ( double x ) - { - double y; - double OldEnvironment; - - y = twoTo52; - - asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ - - if ( fabs ( x ) >= y ) /* huge case is exact */ - return x; - if ( x < 0 ) y = -y; /* negative case */ - y = ( x + y ) - y; /* force rounding */ - if ( y == 0.0 ) /* zero results mirror sign of x */ - y = copysign ( y, x ); -// restore old flags - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); - return ( y ); - } - -/******************************************************************************* -* * * The function rinttol converts its double argument to integral value * * according to the current rounding direction and returns the result in * * long int format. This conversion signals invalid if the argument is a * @@ -197,99 +163,6 @@ long int rinttol ( double x ) /******************************************************************************* * * -* The function round rounds its double argument to integral value * -* according to the "add half to the magnitude and truncate" rounding of * -* Pascal's Round function and FORTRAN's ANINT function and returns the * -* result in double format. This function signals inexact if an ordered * -* return value is not equal to the operand. * -* * -*******************************************************************************/ - -double round ( double x ) - { - DblInHex argument, OldEnvironment; - register double y, z; - register unsigned long int xHead; - register long int target; - - argument.dbl = x; - xHead = argument.words.hi & 0x7fffffffUL; // xHead <- high half of |x| - target = ( argument.words.hi < signMask ); // flag positive sign - - if ( xHead < 0x43300000ul ) -/******************************************************************************* -* Is |x| < 2.0^52? * -*******************************************************************************/ - { - if ( xHead < 0x3ff00000ul ) -/******************************************************************************* -* Is |x| < 1.0? * -*******************************************************************************/ - { - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment - if ( xHead < 0x3fe00000ul ) -/******************************************************************************* -* Is |x| < 0.5? * -*******************************************************************************/ - { - if ( ( xHead | argument.words.lo ) != 0ul ) - OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); - if ( target ) - return ( 0.0 ); - else - return ( -0.0 ); - } -/******************************************************************************* -* Is 0.5 ² |x| < 1.0? * -*******************************************************************************/ - OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); - if ( target ) - return ( 1.0 ); - else - return ( -1.0 ); - } -/******************************************************************************* -* Is 1.0 < |x| < 2.0^52? * -*******************************************************************************/ - if ( target ) - { // positive x - y = ( x + twoTo52 ) - twoTo52; // round at binary point - if ( y == x ) // exact case - return ( x ); - z = x + 0.5; // inexact case - y = ( z + twoTo52 ) - twoTo52; // round at binary point - if ( y > z ) - return ( y - 1.0 ); - else - return ( y ); - } - -/******************************************************************************* -* Is x < 0? * -*******************************************************************************/ - else - { - y = ( x - twoTo52 ) + twoTo52; // round at binary point - if ( y == x ) - return ( x ); - z = x - 0.5; - y = ( z - twoTo52 ) + twoTo52; // round at binary point - if ( y < z ) - return ( y + 1.0 ); - else - return ( y ); - } - } -/******************************************************************************* -* |x| >= 2.0^52 or x is a NaN. * -*******************************************************************************/ - return ( x ); - } - -/******************************************************************************* -* * * The function roundtol converts its double argument to integral format * * according to the "add half to the magnitude and chop" rounding mode of * * Pascal's Round function and FORTRAN's NINT function. This conversion * @@ -392,73 +265,6 @@ long int roundtol ( double x ) } /******************************************************************************* -* * -* The function trunc truncates its double argument to integral value * -* and returns the result in double format. This function signals * -* inexact if an ordered return value is not equal to the operand. * -* * -*******************************************************************************/ - -double trunc ( double x ) - { - DblInHex argument,OldEnvironment; - register double y; - register unsigned long int xhi; - register long int target; - - argument.dbl = x; - xhi = argument.words.hi & 0x7fffffffUL; // xhi <- high half of |x| - target = ( argument.words.hi < signMask ); // flag positive sign - - if ( xhi < 0x43300000ul ) -/******************************************************************************* -* Is |x| < 2.0^53? * -*******************************************************************************/ - { - if ( xhi < 0x3ff00000ul ) -/******************************************************************************* -* Is |x| < 1.0? * -*******************************************************************************/ - { - if ( ( xhi | argument.words.lo ) != 0ul ) - { // raise deserved INEXACT - asm ("mffs %0" : "=f" (OldEnvironment.dbl)); - OldEnvironment.words.lo |= 0x02000000ul; - asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); - } - if ( target ) // return properly signed zero - return ( 0.0 ); - else - return ( -0.0 ); - } -/******************************************************************************* -* Is 1.0 < |x| < 2.0^52? * -*******************************************************************************/ - if ( target ) - { - y = ( x + twoTo52 ) - twoTo52; // round at binary point - if ( y > x ) - return ( y - 1.0 ); - else - return ( y ); - } - - else - { - y = ( x - twoTo52 ) + twoTo52; // round at binary point. - if ( y < x ) - return ( y + 1.0 ); - else - return ( y ); - } - } -/******************************************************************************* -* Is |x| >= 2.0^52 or x is a NaN. * -*******************************************************************************/ - return ( x ); - } - -/******************************************************************************* * The modf family of functions separate a floating-point number into its * * fractional and integral parts, returning the fractional part and writing * * the integral part in floating-point format to the object pointed to by a * diff --git a/libm/powerpc/s_nearbyint.c b/libm/powerpc/s_nearbyint.c new file mode 100644 index 000000000..f2d7ded35 --- /dev/null +++ b/libm/powerpc/s_nearbyint.c @@ -0,0 +1,36 @@ +#include <limits.h> +#include <math.h> + +/******************************************************************************* +* * +* The function nearbyint rounds its double argument to integral value * +* according to the current rounding direction and returns the result in * +* double format. This function does not signal inexact. * +* * +******************************************************************************** +* * +* This function calls fabs and copysign. * +* * +*******************************************************************************/ + +static const double twoTo52 = 4503599627370496.0; + +double nearbyint ( double x ) + { + double y; + double OldEnvironment; + + y = twoTo52; + + asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ + + if ( fabs ( x ) >= y ) /* huge case is exact */ + return x; + if ( x < 0 ) y = -y; /* negative case */ + y = ( x + y ) - y; /* force rounding */ + if ( y == 0.0 ) /* zero results mirror sign of x */ + y = copysign ( y, x ); +// restore old flags + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); + return ( y ); + } diff --git a/libm/powerpc/s_round.c b/libm/powerpc/s_round.c new file mode 100644 index 000000000..81f4d0fec --- /dev/null +++ b/libm/powerpc/s_round.c @@ -0,0 +1,112 @@ +#include <limits.h> +#include <math.h> + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +static const unsigned long int signMask = 0x80000000ul; +static const double twoTo52 = 4503599627370496.0; + +/******************************************************************************* +* * +* The function round rounds its double argument to integral value * +* according to the "add half to the magnitude and truncate" rounding of * +* Pascal's Round function and FORTRAN's ANINT function and returns the * +* result in double format. This function signals inexact if an ordered * +* return value is not equal to the operand. * +* * +*******************************************************************************/ + +double round ( double x ) + { + DblInHex argument, OldEnvironment; + register double y, z; + register unsigned long int xHead; + register long int target; + + argument.dbl = x; + xHead = argument.words.hi & 0x7fffffffUL; // xHead <- high half of |x| + target = ( argument.words.hi < signMask ); // flag positive sign + + if ( xHead < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^52? * +*******************************************************************************/ + { + if ( xHead < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + if ( xHead < 0x3fe00000ul ) +/******************************************************************************* +* Is |x| < 0.5? * +*******************************************************************************/ + { + if ( ( xHead | argument.words.lo ) != 0ul ) + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 0.0 ); + else + return ( -0.0 ); + } +/******************************************************************************* +* Is 0.5 ² |x| < 1.0? * +*******************************************************************************/ + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 1.0 ); + else + return ( -1.0 ); + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { // positive x + y = ( x + twoTo52 ) - twoTo52; // round at binary point + if ( y == x ) // exact case + return ( x ); + z = x + 0.5; // inexact case + y = ( z + twoTo52 ) - twoTo52; // round at binary point + if ( y > z ) + return ( y - 1.0 ); + else + return ( y ); + } + +/******************************************************************************* +* Is x < 0? * +*******************************************************************************/ + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary point + if ( y == x ) + return ( x ); + z = x - 0.5; + y = ( z - twoTo52 ) + twoTo52; // round at binary point + if ( y < z ) + return ( y + 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } diff --git a/libm/powerpc/s_trunc.c b/libm/powerpc/s_trunc.c new file mode 100644 index 000000000..4b61355ea --- /dev/null +++ b/libm/powerpc/s_trunc.c @@ -0,0 +1,86 @@ +#include <limits.h> +#include <math.h> + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +static const unsigned long int signMask = 0x80000000ul; +static const double twoTo52 = 4503599627370496.0; + +/******************************************************************************* +* * +* The function trunc truncates its double argument to integral value * +* and returns the result in double format. This function signals * +* inexact if an ordered return value is not equal to the operand. * +* * +*******************************************************************************/ + +double trunc ( double x ) + { + DblInHex argument,OldEnvironment; + register double y; + register unsigned long int xhi; + register long int target; + + argument.dbl = x; + xhi = argument.words.hi & 0x7fffffffUL; // xhi <- high half of |x| + target = ( argument.words.hi < signMask ); // flag positive sign + + if ( xhi < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^53? * +*******************************************************************************/ + { + if ( xhi < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + if ( ( xhi | argument.words.lo ) != 0ul ) + { // raise deserved INEXACT + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + } + if ( target ) // return properly signed zero + return ( 0.0 ); + else + return ( -0.0 ); + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { + y = ( x + twoTo52 ) - twoTo52; // round at binary point + if ( y > x ) + return ( y - 1.0 ); + else + return ( y ); + } + + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary point. + if ( y < x ) + return ( y + 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* Is |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } diff --git a/libnsl/Makefile b/libnsl/Makefile index 3550d0c23..28cff08dd 100644 --- a/libnsl/Makefile +++ b/libnsl/Makefile @@ -40,13 +40,11 @@ $(OBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o -$(OBJ): Makefile - shared: all $(LD) $(LDFLAGS) -soname=$(LIBNSL_SHARED).$(MAJOR_VERSION) \ -o $(LIBNSL_SHARED_FULLNAME) --whole-archive $(LIBNSL) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBNSL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBNSL_SHARED).$(MAJOR_VERSION) $(INSTALL) -m 644 $(LIBNSL_SHARED_FULLNAME) $(TOPDIR)lib @@ -54,4 +52,4 @@ shared: all $(LN) -sf $(LIBNSL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBNSL_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBNSL_SHARED)* $(LIBNSL_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBNSL) $(LIBNSL_SHARED_FULLNAME) diff --git a/libpthread/Makefile b/libpthread/Makefile index 9b33e5f15..66f8cc507 100644 --- a/libpthread/Makefile +++ b/libpthread/Makefile @@ -35,20 +35,17 @@ LIBTHREAD_DB_SHARED=libthread_db.so LIBTHREAD_DB_SHARED_FULLNAME=libthread_db-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so DIRS= -ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) ifeq ($(strip $(PTHREADS_NATIVE)),y) DIRS+=nptl -else - DIRS+=linuxthreads -endif ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) -ifeq ($(strip $(PTHREADS_NATIVE)),y) DIRS+=nptl_db +endif else + DIRS+=linuxthreads +ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) DIRS+=linuxthreads_db endif endif -endif ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y) SHARED_START_FILES = $(TOPDIR)lib/crti.o $(LIBGCC_DIR)crtbeginS.o @@ -66,12 +63,27 @@ LIBTHREAD_DB_LDFLAGS := $(subst -z defs,,$(LDFLAGS)) all: $(LIBPTHREAD) $(LIBTHREAD_DB) +headers: +ifeq ($(strip $(UCLIBC_HAS_THREADS_NATIVE)),y) + $(LN) -sf $(TOPDIR)libpthread/nptl/sysdeps/pthread/pthread.h $(TOPDIR)include/ + $(LN) -sf $(TOPDIR)libpthread/nptl/semaphore.h $(TOPDIR)include/ + $(LN) -sf ../$(TOPDIR)libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/bits/semaphore.h $(TOPDIR)include/bits/ + $(LN) -sf ../$(TOPDIR)libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/bits/pthreadtypes.h $(TOPDIR)include/bits/ + $(LN) -sf ../$(TOPDIR)libpthread/nptl/sysdeps/pthread/bits/libc-lock.h $(TOPDIR)include/bits/ + $(LN) -sf ../$(TOPDIR)libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h $(TOPDIR)include/bits/ +else + $(LN) -sf $(TOPDIR)libpthread/linuxthreads/sysdeps/pthread/pthread.h $(TOPDIR)include/ + $(LN) -sf $(TOPDIR)libpthread/linuxthreads/semaphore.h $(TOPDIR)include/ + $(LN) -sf ../$(TOPDIR)libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h $(TOPDIR)include/bits/ +ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) + $(LN) -sf $(TOPDIR)libpthread/linuxthreads_db/thread_db.h $(TOPDIR)include/ +endif +endif + $(LIBPTHREAD): subdirs -ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBPTHREAD) $(INSTALL) -m 644 $(LIBPTHREAD) $(TOPDIR)lib -endif $(LIBTHREAD_DB): subdirs ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) @@ -92,10 +104,7 @@ $(OBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o -$(OBJ): Makefile - shared: all -ifeq ($(strip $(UCLIBC_HAS_THREADS)),y) ifeq ($(strip $(PTHREADS_NATIVE)),y) $(LD) $(LDFLAGS_NOSTRIP) -soname=$(LIBPTHREAD_SHARED).$(MAJOR_VERSION) \ -o $(LIBPTHREAD_SHARED_FULLNAME) $(SHARED_START_FILES) --whole-archive $(LIBPTHREAD_SHARED_ARCHIVE) \ @@ -119,7 +128,6 @@ endif $(TOPDIR)lib/$(LIBPTHREAD_SHARED) $(LN) -sf $(LIBPTHREAD_SHARED_FULLNAME) \ $(TOPDIR)lib/$(LIBPTHREAD_SHARED).$(MAJOR_VERSION) -endif ifeq ($(strip $(PTHREADS_DEBUG_SUPPORT)),y) $(LD) $(LIBTHREAD_DB_LDFLAGS) --warn-unresolved-symbols -soname=$(LIBTHREAD_DB_SHARED).1 \ -o $(LIBTHREAD_DB_SHARED_FULLNAME) --whole-archive $(LIBTHREAD_DB) \ @@ -149,6 +157,10 @@ $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) : dummy clean: subdirs_clean $(RM) *.[oa] *~ core $(LIBPTHREAD) $(LIBPTHREAD_SHARED_FULLNAME) \ - $(LIBTHREAD_DB) $(LIBTHREAD_DB_SHARED_FULLNAME) + $(LIBTHREAD_DB) $(LIBTHREAD_DB_SHARED_FULLNAME) \ + $(TOPDIR)include/pthread.h $(TOPDIR)include/semaphore.h \ + $(TOPDIR)include/thread_db.h \ + $(TOPDIR)include/bits/pthreadtypes.h $(TOPDIR)include/bits/semaphore.h \ + $(TOPDIR)include/bits/libc-lock.h $(TOPDIR)include/bits/stdio-lock .PHONY: dummy diff --git a/libresolv/Makefile b/libresolv/Makefile index 32ca32d71..d6270fece 100644 --- a/libresolv/Makefile +++ b/libresolv/Makefile @@ -46,13 +46,11 @@ $(OBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o -$(OBJ): Makefile - shared: all $(LD) $(LDFLAGS) -soname=$(LIBRESOLV_SHARED).$(MAJOR_VERSION) \ -o $(LIBRESOLV_SHARED_FULLNAME) --whole-archive $(LIBRESOLV) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBRESOLV_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBRESOLV_SHARED).$(MAJOR_VERSION) $(INSTALL) -m 644 $(LIBRESOLV_SHARED_FULLNAME) $(TOPDIR)lib @@ -60,4 +58,4 @@ shared: all $(LN) -sf $(LIBRESOLV_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBRESOLV_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBRESOLV_SHARED)* $(LIBRESOLV_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBRESOLV) $(LIBRESOLV_SHARED_FULLNAME) diff --git a/librt/Makefile b/librt/Makefile index 10b371cb7..f820b6786 100644 --- a/librt/Makefile +++ b/librt/Makefile @@ -33,7 +33,7 @@ shared: all $(LD) $(LDFLAGS) -soname=$(LIBRT_SHARED).$(MAJOR_VERSION) \ -o $(LIBRT_SHARED_FULLNAME) --whole-archive $(LIBRT) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBRT_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBRT_SHARED).$(MAJOR_VERSION) $(INSTALL) -m 644 $(LIBRT_SHARED_FULLNAME) $(TOPDIR)lib @@ -41,4 +41,4 @@ shared: all $(LN) -sf $(LIBRT_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBRT_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBRT_SHARED)* $(LIBRT_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBRT) $(LIBRT_SHARED_FULLNAME) diff --git a/librt/kernel-posix-timers.h b/librt/kernel-posix-timers.h index 5724af01b..bf246c925 100644 --- a/librt/kernel-posix-timers.h +++ b/librt/kernel-posix-timers.h @@ -2,10 +2,13 @@ * kernel-posix-timers.h - kernel-dependent definitions for POSIX timers. */ +#include <features.h> #include <setjmp.h> #include <signal.h> #include <sys/types.h> +#ifdef __UCLIBC_HAS_THREADS__ #include <pthread.h> +#endif /* Type of timers in the kernel */ typedef int kernel_timer_t; @@ -27,5 +30,7 @@ struct timer { /* Parameters for the thread to be started for SIGEV_THREAD */ void (*thrfunc) (sigval_t); sigval_t sival; +#ifdef __UCLIBC_HAS_THREADS__ pthread_attr_t attr; +#endif }; diff --git a/libutil/Makefile b/libutil/Makefile index 8affcfde2..95f879786 100644 --- a/libutil/Makefile +++ b/libutil/Makefile @@ -52,7 +52,7 @@ shared: all $(LD) $(LDFLAGS) -soname=$(LIBUTIL_SHARED).$(MAJOR_VERSION) \ -o $(LIBUTIL_SHARED_FULLNAME) --whole-archive $(LIBUTIL) \ --no-whole-archive $(TOPDIR)libc/misc/internals/interp.o \ - -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC); + -L$(TOPDIR)lib -lc $(LDADD_LIBFLOAT) $(LIBGCC) $(INSTALL) -d $(TOPDIR)lib $(RM) $(TOPDIR)lib/$(LIBUTIL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBUTIL_SHARED).$(MAJOR_VERSION) $(INSTALL) -m 644 $(LIBUTIL_SHARED_FULLNAME) $(TOPDIR)lib @@ -60,4 +60,4 @@ shared: all $(LN) -sf $(LIBUTIL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBUTIL_SHARED).$(MAJOR_VERSION) clean: - $(RM) *.[oa] *~ core $(LIBUTIL_SHARED)* $(LIBUTIL_SHARED_FULLNAME)* + $(RM) *.[oa] *~ core $(LIBUTIL) $(LIBUTIL_SHARED_FULLNAME) diff --git a/utils/Makefile b/utils/Makefile index 7023a9b21..d13ab2e23 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -21,7 +21,7 @@ include $(TOPDIR)Rules.mak CFLAGS+=$(SSP_ALL_CFLAGS) -TARGETS = ldd ldconfig readelf +TARGETS = ldd ldconfig ifeq ($(strip $(UCLIBC_HAS_LOCALE)),y) TARGET_ICONV = iconv @@ -39,6 +39,7 @@ endif headers: @$(LN) -fs $(TOPDIR)include/elf.h + @$(LN) -fs $(TOPDIR)include/link.h readelf.c ldconfig.c ldd.c: headers @@ -58,15 +59,17 @@ ldconfig: ldconfig.c $^ -o $@ $(STRIPTOOL) -s -x -R .note -R .comment $@ +LDD_CFLAGS := $(PIEFLAG) $(LDPIEFLAG) ldd: ldd.c - $(CC) $(CFLAGS) $(PIEFLAG) $(LDPIEFLAG) \ + $(CC) $(CFLAGS) $(LDD_CFLAGS) \ -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \ $^ -o $@ $(STRIPTOOL) -s -x -R .note -R .comment $@ +ICONV_CFLAGS := $(PIEFLAG) $(LDPIEFLAG) iconv: ../libc/misc/wchar/wchar.c - $(CC) $(CFLAGS) $(PIEFLAG) $(LDPIEFLAG) \ + $(CC) $(CFLAGS) $(ICONV_CFLAGS) \ -DL_iconv_main \ $^ -o $@ $(STRIPTOOL) -s -x -R .note -R .comment $@ @@ -93,14 +96,14 @@ readelf.host: readelf.c $(HOSTCC) $(HOSTCFLAGS) -Wl,-s $^ -o $@ clean: - $(RM) $(TARGETS) *.o *~ core *.target elf.h iconv *.host + $(RM) $(TARGETS) *.o *~ core elf.h link.h readelf iconv *.host install: all ifeq ($(strip $(HAVE_SHARED)),y) $(INSTALL) -d $(PREFIX)$(RUNTIME_PREFIX)sbin $(INSTALL) -d $(PREFIX)$(RUNTIME_PREFIX)usr/bin $(INSTALL) -m 755 ldd $(PREFIX)$(RUNTIME_PREFIX)usr/bin/ldd - $(INSTALL) -m 755 ldconfig $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig; + $(INSTALL) -m 755 ldconfig $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig #$(INSTALL) -m 755 readelf $(PREFIX)$(RUNTIME_PREFIX)usr/bin/readelf endif ifeq ($(strip $(UCLIBC_HAS_LOCALE)),y) diff --git a/utils/ldd.c b/utils/ldd.c index 0dc12ad01..51451809c 100644 --- a/utils/ldd.c +++ b/utils/ldd.c @@ -33,6 +33,7 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <stdint.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> @@ -40,17 +41,19 @@ #include <sys/wait.h> #include "bswap.h" -#if defined (sun) #include "link.h" -#else #include "elf.h" -#endif #include "dl-defs.h" #ifdef DMALLOC #include <dmalloc.h> #endif +#if defined(__alpha__) +#define MATCH_MACHINE(x) (x == EM_ALPHA) +#define ELFCLASSM ELFCLASS64 +#endif + #if defined(__arm__) || defined(__thumb__) #define MATCH_MACHINE(x) (x == EM_ARM) #define ELFCLASSM ELFCLASS32 @@ -61,6 +64,15 @@ #define ELFCLASSM ELFCLASS32 #endif +#if defined(__hppa__) +#define MATCH_MACHINE(x) (x == EM_PARISC) +#if defined(__LP64__) +#define ELFCLASSM ELFCLASS64 +#else +#define ELFCLASSM ELFCLASS32 +#endif +#endif + #if defined(__i386__) #ifndef EM_486 #define MATCH_MACHINE(x) (x == EM_386) @@ -70,6 +82,11 @@ #define ELFCLASSM ELFCLASS32 #endif +#if defined(__ia64__) +#define MATCH_MACHINE(x) (x == EM_IA_64) +#define ELFCLASSM ELFCLASS64 +#endif + #if defined(__mc68000__) #define MATCH_MACHINE(x) (x == EM_68K) #define ELFCLASSM ELFCLASS32 @@ -80,7 +97,10 @@ #define ELFCLASSM ELFCLASS32 #endif -#if defined(__powerpc__) +#if defined(__powerpc64__) +#define MATCH_MACHINE(x) (x == EM_PPC64) +#define ELFCLASSM ELFCLASS64 +#elif defined(__powerpc__) #define MATCH_MACHINE(x) (x == EM_PPC) #define ELFCLASSM ELFCLASS32 #endif @@ -90,12 +110,12 @@ #define ELFCLASSM ELFCLASS32 #endif -#if defined (__v850e__) +#if defined(__v850e__) #define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850) #define ELFCLASSM ELFCLASS32 #endif -#if defined (__sparc__) +#if defined(__sparc__) #define MATCH_MACHINE(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS) #define ELFCLASSM ELFCLASS32 #endif @@ -105,8 +125,24 @@ #define ELFCLASSM ELFCLASS32 #endif +#if defined(__x86_64__) +#define MATCH_MACHINE(x) (x == EM_X86_64) +#define ELFCLASSM ELFCLASS64 +#endif + #ifndef MATCH_MACHINE -#warning "You really should add a MATCH_MACHINE() macro for your architecture" +# ifdef __linux__ +# include <asm/elf.h> +# endif +# ifdef ELF_ARCH +# define MATCH_MACHINE(x) (x == ELF_ARCH) +# endif +# ifdef ELF_CLASS +# define ELFCLASSM ELF_CLASS +# endif +#endif +#ifndef MATCH_MACHINE +# warning "You really should add a MATCH_MACHINE() macro for your architecture" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -123,7 +159,7 @@ struct library { }; struct library *lib_list = NULL; char not_found[] = "not found"; -char *interp = NULL; +char *interp_name = NULL; char *interp_dir = NULL; int byteswap; static int interpreter_already_found=0; @@ -136,26 +172,39 @@ inline uint32_t byteswap32_to_host(uint32_t value) return(value); } } +inline uint64_t byteswap64_to_host(uint64_t value) +{ + if (byteswap==1) { + return(bswap_64(value)); + } else { + return(value); + } +} +#if ELFCLASSM == ELFCLASS32 +# define byteswap_to_host(x) byteswap32_to_host(x) +#else +# define byteswap_to_host(x) byteswap64_to_host(x) +#endif -Elf32_Shdr * elf_find_section_type( int key, Elf32_Ehdr *ehdr) +ElfW(Shdr) * elf_find_section_type( int key, ElfW(Ehdr) *ehdr) { int j; - Elf32_Shdr *shdr; - shdr = (Elf32_Shdr *)(ehdr->e_shoff + (char *)ehdr); + ElfW(Shdr) *shdr; + shdr = (ElfW(Shdr) *)(ehdr->e_shoff + (char *)ehdr); for (j = ehdr->e_shnum; --j>=0; ++shdr) { - if (key==(int)byteswap32_to_host(shdr->sh_type)) { + if (key==byteswap32_to_host(shdr->sh_type)) { return shdr; } } return NULL; } -Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr) +ElfW(Phdr) * elf_find_phdr_type( int type, ElfW(Ehdr) *ehdr) { int j; - Elf32_Phdr *phdr = (Elf32_Phdr *)(ehdr->e_phoff + (char *)ehdr); + ElfW(Phdr) *phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (char *)ehdr); for (j = ehdr->e_phnum; --j>=0; ++phdr) { - if (type==(int)byteswap32_to_host(phdr->p_type)) { + if (type==byteswap32_to_host(phdr->p_type)) { return phdr; } } @@ -163,40 +212,40 @@ Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr) } /* Returns value if return_val==1, ptr otherwise */ -void * elf_find_dynamic(int const key, Elf32_Dyn *dynp, - Elf32_Ehdr *ehdr, int return_val) +void * elf_find_dynamic(int const key, ElfW(Dyn) *dynp, + ElfW(Ehdr) *ehdr, int return_val) { - Elf32_Phdr *pt_text = elf_find_phdr_type(PT_LOAD, ehdr); - unsigned tx_reloc = byteswap32_to_host(pt_text->p_vaddr) - byteswap32_to_host(pt_text->p_offset); - for (; DT_NULL!=byteswap32_to_host(dynp->d_tag); ++dynp) { - if (key == (int)byteswap32_to_host(dynp->d_tag)) { + ElfW(Phdr) *pt_text = elf_find_phdr_type(PT_LOAD, ehdr); + unsigned tx_reloc = byteswap_to_host(pt_text->p_vaddr) - byteswap_to_host(pt_text->p_offset); + for (; DT_NULL!=byteswap_to_host(dynp->d_tag); ++dynp) { + if (key == byteswap_to_host(dynp->d_tag)) { if (return_val == 1) - return (void *)(intptr_t)byteswap32_to_host(dynp->d_un.d_val); + return (void *)byteswap_to_host(dynp->d_un.d_val); else - return (void *)(byteswap32_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr ); + return (void *)(byteswap_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr ); } } return NULL; } -static char * elf_find_rpath(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic) +static char * elf_find_rpath(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic) { - Elf32_Dyn *dyns; + ElfW(Dyn) *dyns; - for (dyns=dynamic; byteswap32_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { - if (DT_RPATH == byteswap32_to_host(dyns->d_tag)) { + for (dyns=dynamic; byteswap_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { + if (DT_RPATH == byteswap_to_host(dyns->d_tag)) { char *strtab; strtab = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0); - return ((char*)strtab + byteswap32_to_host(dyns->d_un.d_val)); + return ((char*)strtab + byteswap_to_host(dyns->d_un.d_val)); } } return NULL; } -int check_elf_header(Elf32_Ehdr *const ehdr) +int check_elf_header(ElfW(Ehdr) *const ehdr) { - if (! ehdr || strncmp((void *)ehdr, ELFMAG, SELFMAG) != 0 || - ehdr->e_ident[EI_CLASS] != ELFCLASS32 || + if (! ehdr || strncmp((char *)ehdr, ELFMAG, SELFMAG) != 0 || + ehdr->e_ident[EI_CLASS] != ELFCLASSM || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { return 1; @@ -220,11 +269,11 @@ int check_elf_header(Elf32_Ehdr *const ehdr) /* Be vary lazy, and only byteswap the stuff we use */ if (byteswap==1) { - ehdr->e_type=bswap_16(ehdr->e_type); - ehdr->e_phoff=bswap_32(ehdr->e_phoff); - ehdr->e_shoff=bswap_32(ehdr->e_shoff); - ehdr->e_phnum=bswap_16(ehdr->e_phnum); - ehdr->e_shnum=bswap_16(ehdr->e_shnum); + ehdr->e_type = bswap_16(ehdr->e_type); + ehdr->e_phoff = byteswap_to_host(ehdr->e_phoff); + ehdr->e_shoff = byteswap_to_host(ehdr->e_shoff); + ehdr->e_phnum = bswap_16(ehdr->e_phnum); + ehdr->e_shnum = bswap_16(ehdr->e_shnum); } return 0; @@ -357,7 +406,7 @@ static void search_for_named_library(char *name, char *result, const char *path_ *result = '\0'; } -void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, struct library *lib) +void locate_library_file(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic, int is_suid, struct library *lib) { char *buf; char *path; @@ -452,7 +501,7 @@ void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, stru } } -static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char *s) +static int add_library(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic, int is_setuid, char *s) { char *tmp, *tmp1, *tmp2; struct library *cur, *newlib=lib_list; @@ -468,10 +517,10 @@ static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char } /* We add ldso elsewhere */ - if (interpreter_already_found && (tmp=strrchr(interp, '/')) != NULL) + if (interpreter_already_found && (tmp=strrchr(interp_name, '/')) != NULL) { int len = strlen(interp_dir); - if (strcmp(s, interp+1+len)==0) + if (strcmp(s, interp_name+1+len)==0) return 1; } @@ -512,41 +561,41 @@ static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char return 0; } -static void find_needed_libraries(Elf32_Ehdr* ehdr, - Elf32_Dyn* dynamic, int is_setuid) +static void find_needed_libraries(ElfW(Ehdr)* ehdr, + ElfW(Dyn)* dynamic, int is_setuid) { - Elf32_Dyn *dyns; + ElfW(Dyn) *dyns; - for (dyns=dynamic; byteswap32_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { - if (DT_NEEDED == byteswap32_to_host(dyns->d_tag)) { + for (dyns=dynamic; byteswap_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { + if (DT_NEEDED == byteswap_to_host(dyns->d_tag)) { char *strtab; strtab = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0); add_library(ehdr, dynamic, is_setuid, - (char*)strtab + byteswap32_to_host(dyns->d_un.d_val)); + (char*)strtab + byteswap_to_host(dyns->d_un.d_val)); } } } -static struct library * find_elf_interpreter(Elf32_Ehdr* ehdr) +static struct library * find_elf_interpreter(ElfW(Ehdr)* ehdr) { - Elf32_Phdr *phdr; + ElfW(Phdr) *phdr; - if (interpreter_already_found==1) + if (interpreter_already_found == 1) return NULL; phdr = elf_find_phdr_type(PT_INTERP, ehdr); if (phdr) { struct library *cur, *newlib=NULL; - char *s = (char*)ehdr + byteswap32_to_host(phdr->p_offset); + char *s = (char*)ehdr + byteswap_to_host(phdr->p_offset); char *tmp, *tmp1; - interp = strdup(s); + interp_name = strdup(s); interp_dir = strdup(s); tmp = strrchr(interp_dir, '/'); if (*tmp) *tmp = '\0'; else { free(interp_dir); - interp_dir = interp; + interp_dir = interp_name; } tmp1 = tmp = s; while (*tmp) { @@ -587,7 +636,7 @@ static struct library * find_elf_interpreter(Elf32_Ehdr* ehdr) cur->next = newlib; } #endif - interpreter_already_found=1; + interpreter_already_found = 1; return newlib; } return NULL; @@ -598,11 +647,11 @@ int find_dependancies(char* filename) { int is_suid = 0; FILE *thefile; - struct stat statbuf; - Elf32_Ehdr *ehdr = NULL; - Elf32_Shdr *dynsec = NULL; - Elf32_Dyn *dynamic = NULL; struct library *interp; + struct stat statbuf; + ElfW(Ehdr) *ehdr = NULL; + ElfW(Shdr) *dynsec = NULL; + ElfW(Dyn) *dynamic = NULL; if (filename == not_found) return 0; @@ -621,14 +670,14 @@ int find_dependancies(char* filename) return -1; } - if ((size_t)statbuf.st_size < sizeof(Elf32_Ehdr)) + if ((size_t)statbuf.st_size < sizeof(ElfW(Ehdr))) goto foo; if (!S_ISREG(statbuf.st_mode)) goto foo; /* mmap the file to make reading stuff from it effortless */ - ehdr = (Elf32_Ehdr *)mmap(0, statbuf.st_size, + ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0); if (ehdr == MAP_FAILED) { fclose(thefile); @@ -659,7 +708,7 @@ foo: fprintf(stderr, "%s: is setuid\n", filename); } - interpreter_already_found=0; + interpreter_already_found = 0; interp = find_elf_interpreter(ehdr); #ifdef __LDSO_LDD_SUPPORT__ @@ -700,7 +749,7 @@ foo: dynsec = elf_find_section_type(SHT_DYNAMIC, ehdr); if (dynsec) { - dynamic = (Elf32_Dyn*)(byteswap32_to_host(dynsec->sh_offset) + (intptr_t)ehdr); + dynamic = (ElfW(Dyn)*)(byteswap_to_host(dynsec->sh_offset) + (char *)ehdr); find_needed_libraries(ehdr, dynamic, is_suid); } @@ -731,7 +780,7 @@ int main( int argc, char** argv) continue; } - if(strcmp(*argv, "--help")==0) { + if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) { fprintf(stderr, "Usage: ldd [OPTION]... FILE...\n"); fprintf(stderr, "\t--help\t\tprint this help and exit\n"); exit(EXIT_FAILURE); @@ -773,8 +822,8 @@ int main( int argc, char** argv) got_em_all=1; printf("\t%s => %s (0x00000000)\n", cur->name, cur->path); } - if (interp && interpreter_already_found==1) - printf("\t%s => %s (0x00000000)\n", interp, interp); + if (interp_name && interpreter_already_found==1) + printf("\t%s => %s (0x00000000)\n", interp_name, interp_name); else printf("\tnot a dynamic executable\n"); @@ -791,4 +840,3 @@ int main( int argc, char** argv) return 0; } - diff --git a/utils/readelf.c b/utils/readelf.c index fcdd510ae..c7516ef4f 100644 --- a/utils/readelf.c +++ b/utils/readelf.c @@ -39,7 +39,7 @@ #include "bswap.h" #include "elf.h" - +#include "link.h" int byteswap; inline uint32_t byteswap32_to_host(uint32_t value) @@ -50,25 +50,38 @@ inline uint32_t byteswap32_to_host(uint32_t value) return(value); } } +inline uint64_t byteswap64_to_host(uint64_t value) +{ + if (byteswap==1) { + return(bswap_64(value)); + } else { + return(value); + } +} +#if __WORDSIZE == 64 +# define byteswap_to_host(x) byteswap64_to_host(x) +#else +# define byteswap_to_host(x) byteswap32_to_host(x) +#endif -Elf32_Shdr * elf_find_section_type( int key, Elf32_Ehdr *ehdr) +ElfW(Shdr) * elf_find_section_type( int key, ElfW(Ehdr) *ehdr) { int j; - Elf32_Shdr *shdr = (Elf32_Shdr *)(ehdr->e_shoff + (char *)ehdr); + ElfW(Shdr) *shdr = (ElfW(Shdr) *)(ehdr->e_shoff + (char *)ehdr); for (j = ehdr->e_shnum; --j>=0; ++shdr) { - if (key==(int)byteswap32_to_host(shdr->sh_type)) { + if (key==byteswap32_to_host(shdr->sh_type)) { return shdr; } } return NULL; } -Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr) +ElfW(Phdr) * elf_find_phdr_type( int type, ElfW(Ehdr) *ehdr) { int j; - Elf32_Phdr *phdr = (Elf32_Phdr *)(ehdr->e_phoff + (char *)ehdr); + ElfW(Phdr) *phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (char *)ehdr); for (j = ehdr->e_phnum; --j>=0; ++phdr) { - if (type==(int)byteswap32_to_host(phdr->p_type)) { + if (type==byteswap32_to_host(phdr->p_type)) { return phdr; } } @@ -76,26 +89,27 @@ Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr) } /* Returns value if return_val==1, ptr otherwise */ -void * elf_find_dynamic(int const key, Elf32_Dyn *dynp, - Elf32_Ehdr *ehdr, int return_val) +void * elf_find_dynamic(int const key, ElfW(Dyn) *dynp, + ElfW(Ehdr) *ehdr, int return_val) { - Elf32_Phdr *pt_text = elf_find_phdr_type(PT_LOAD, ehdr); - unsigned tx_reloc = byteswap32_to_host(pt_text->p_vaddr) - byteswap32_to_host(pt_text->p_offset); - for (; DT_NULL!=byteswap32_to_host(dynp->d_tag); ++dynp) { - if (key == (int)byteswap32_to_host(dynp->d_tag)) { + ElfW(Phdr) *pt_text = elf_find_phdr_type(PT_LOAD, ehdr); + ElfW(Addr) tx_reloc = byteswap_to_host(pt_text->p_vaddr) - byteswap_to_host(pt_text->p_offset); + for (; DT_NULL!=byteswap_to_host(dynp->d_tag); ++dynp) { + if (key == byteswap_to_host(dynp->d_tag)) { if (return_val == 1) - return (void *)(intptr_t)byteswap32_to_host(dynp->d_un.d_val); + return (void *)byteswap_to_host(dynp->d_un.d_val); else - return (void *)(byteswap32_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr ); + return (void *)(byteswap_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr ); } } return NULL; } -int check_elf_header(Elf32_Ehdr *const ehdr) +int check_elf_header(ElfW(Ehdr) *const ehdr) { if (! ehdr || strncmp((void *)ehdr, ELFMAG, SELFMAG) != 0 || - ehdr->e_ident[EI_CLASS] != ELFCLASS32 || + (ehdr->e_ident[EI_CLASS] != ELFCLASS32 && + ehdr->e_ident[EI_CLASS] != ELFCLASS64) || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { return 1; @@ -119,8 +133,8 @@ int check_elf_header(Elf32_Ehdr *const ehdr) if (byteswap==1) { ehdr->e_type=bswap_16(ehdr->e_type); ehdr->e_machine=bswap_16(ehdr->e_machine); - ehdr->e_phoff=bswap_32(ehdr->e_phoff); - ehdr->e_shoff=bswap_32(ehdr->e_shoff); + ehdr->e_phoff=byteswap_to_host(ehdr->e_phoff); + ehdr->e_shoff=byteswap_to_host(ehdr->e_shoff); ehdr->e_phnum=bswap_16(ehdr->e_phnum); ehdr->e_shnum=bswap_16(ehdr->e_shnum); } @@ -128,21 +142,7 @@ int check_elf_header(Elf32_Ehdr *const ehdr) } -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -#define ELFOSABI_NETBSD 2 /* NetBSD */ -#define ELFOSABI_LINUX 3 /* GNU/Linux */ -#define ELFOSABI_HURD 4 /* GNU/Hurd */ -#define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_AIX 7 /* AIX */ -#define ELFOSABI_IRIX 8 /* IRIX */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -#define ELFOSABI_ARM 97 /* ARM */ -static void describe_elf_hdr(Elf32_Ehdr* ehdr) +static void describe_elf_hdr(ElfW(Ehdr)* ehdr) { char *tmp, *tmp1; @@ -275,24 +275,24 @@ static void describe_elf_hdr(Elf32_Ehdr* ehdr) printf( "ABI Version:\t%d\n", ehdr->e_ident[EI_ABIVERSION]); } -static void list_needed_libraries(Elf32_Dyn* dynamic, char *strtab) +static void list_needed_libraries(ElfW(Dyn)* dynamic, char *strtab) { - Elf32_Dyn *dyns; + ElfW(Dyn) *dyns; printf("Dependancies:\n"); - for (dyns=dynamic; byteswap32_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { + for (dyns=dynamic; byteswap_to_host(dyns->d_tag)!=DT_NULL; ++dyns) { if (dyns->d_tag == DT_NEEDED) { - printf("\t%s\n", (char*)strtab + byteswap32_to_host(dyns->d_un.d_val)); + printf("\t%s\n", (char*)strtab + byteswap_to_host(dyns->d_un.d_val)); } } } -static void describe_elf_interpreter(Elf32_Ehdr* ehdr) +static void describe_elf_interpreter(ElfW(Ehdr)* ehdr) { - Elf32_Phdr *phdr; + ElfW(Phdr) *phdr; phdr = elf_find_phdr_type(PT_INTERP, ehdr); if (phdr) { - printf("Interpreter:\t%s\n", (char*)ehdr + byteswap32_to_host(phdr->p_offset)); + printf("Interpreter:\t%s\n", (char*)ehdr + byteswap_to_host(phdr->p_offset)); } } @@ -303,9 +303,9 @@ int main( int argc, char** argv) char *thefilename = argv[1]; FILE *thefile; struct stat statbuf; - Elf32_Ehdr *ehdr = 0; - Elf32_Shdr *dynsec; - Elf32_Dyn *dynamic; + ElfW(Ehdr) *ehdr = 0; + ElfW(Shdr) *dynsec; + ElfW(Dyn) *dynamic; if (argc < 2 || !thefilename) { fprintf(stderr, "No filename specified.\n"); @@ -320,11 +320,11 @@ int main( int argc, char** argv) exit(EXIT_FAILURE); } - if ((size_t)statbuf.st_size < sizeof(Elf32_Ehdr)) + if ((size_t)statbuf.st_size < sizeof(ElfW(Ehdr))) goto foo; /* mmap the file to make reading stuff from it effortless */ - ehdr = (Elf32_Ehdr *)mmap(0, statbuf.st_size, + ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0); foo: @@ -338,7 +338,7 @@ foo: dynsec = elf_find_section_type(SHT_DYNAMIC, ehdr); if (dynsec) { - dynamic = (Elf32_Dyn*)(byteswap32_to_host(dynsec->sh_offset) + (intptr_t)ehdr); + dynamic = (ElfW(Dyn)*)(byteswap_to_host(dynsec->sh_offset) + (char *)ehdr); dynstr = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0); list_needed_libraries(dynamic, dynstr); } |