Sophie

Sophie

distrib > Mageia > 6 > x86_64 > by-pkgid > ee1dfd807ccb6557308e06e14c3640e0 > files > 18

dietlibc-0.33-4.20120825.8.mga6.src.rpm

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0a72698
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.cvsps
diff --git a/Makefile b/Makefile
index c06adf3..d0aa174 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ LIBDIR=${prefix}/lib
 BINDIR=${prefix}/bin
 MAN1DIR=${prefix}/man/man1
 
-MYARCH:=$(shell uname -m | sed -e 's/i[4-9]86/i386/' -e 's/armv[3-6]t\?e\?[lb]/arm/')
+MYARCH:=$(shell uname -m | sed -e 's/i[4-9]86/i386/' -e 's/armv[3-7]t\?[eh]\?[lb]/arm/')
 
 # This extra-ugly cruft is here so make will not run uname and sed each
 # time it looks at $(OBJDIR).  This alone sped up running make when
@@ -88,7 +88,7 @@ ILIBDIR=$(LIBDIR)-$(ARCH)
 
 HOME=$(shell pwd)
 
-WHAT=	$(OBJDIR) $(OBJDIR)/start.o $(OBJDIR)/dyn_start.o $(OBJDIR)/dyn_stop.o \
+WHAT=	$(OBJDIR)/start.o $(OBJDIR)/dyn_start.o $(OBJDIR)/dyn_stop.o \
 	$(OBJDIR)/dietlibc.a $(OBJDIR)/liblatin1.a \
 	$(OBJDIR)/libcompat.a $(OBJDIR)/libm.a \
 	$(OBJDIR)/librpc.a $(OBJDIR)/libpthread.a \
@@ -105,6 +105,7 @@ CROSS=
 
 CC=gcc
 INC=-I. -isystem include
+STRIP=$(CROSS)strip
 
 VPATH=lib:libstdio:libugly:libcruft:libcrypt:libshell:liblatin1:libcompat:libdl:librpc:libregex:libm:profiling
 
@@ -128,6 +129,8 @@ LIBPTHREAD_OBJS=$(patsubst libpthread/%.c,$(OBJDIR)/%.o,$(shell ./threadsafe.sh)
 
 LIBGMON_OBJS=$(OBJDIR)/__mcount.o $(OBJDIR)/monitor.o $(OBJDIR)/profil.o
 
+NO_STACK_PROTECTOR=stackgap.o __get_elf_aux_value.o
+
 include $(ARCH)/Makefile.add
 
 LIBMATHOBJ=$(patsubst %,$(OBJDIR)/%,$(LIBMATH))
@@ -141,6 +144,7 @@ CFLAGS = -g
 COMMENT = :
 endif
 CFLAGS += -W -Wall -Wextra -Wchar-subscripts -Wmissing-prototypes -Wmissing-declarations -Wno-switch -Wno-unused -Wredundant-decls
+XCFLAGS = -Wa,--noexecstack
 
 PWD=$(shell pwd)
 
@@ -150,34 +154,36 @@ PWD=$(shell pwd)
 # added real dynamic dietlibc.so
 PICODIR = pic-$(ARCH)
 
-$(OBJDIR) $(PICODIR):
-	mkdir $@
-
 % :: %,v
 
-$(OBJDIR)/%: $(OBJDIR)
+%/.dirstamp:
+	mkdir $*
+	@touch $@
 
 ifeq ($(CC),tcc)
-$(OBJDIR)/%.o: %.S $(ARCH)/syscalls.h
+$(OBJDIR)/%.o: %.S $(ARCH)/syscalls.h $(OBJDIR)/.dirstamp
 	$(CROSS)cpp $(INC) $< | $(CROSS)as -o $@
 
-$(OBJDIR)/%.o: %.c
+$(OBJDIR)/%.o: %.c $(OBJDIR)/.dirstamp
 	tcc -I. -Iinclude -c $< -o $@
-	$(COMMENT) -$(CROSS)strip -x -R .comment -R .note $@
+	$(COMMENT) -$(STRIP) -x -R .comment -R .note $@
 else
-$(OBJDIR)/pstart.o: start.S
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -DPROFILING -c $< -o $@
+$(OBJDIR)/pstart.o: start.S $(OBJDIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -DPROFILING -c $< -o $@
+
+$(OBJDIR)/%.o: %.S $(ARCH)/syscalls.h $(OBJDIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -c $< -o $@
 
-$(OBJDIR)/%.o: %.S $(ARCH)/syscalls.h
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -c $< -o $@
+$(OBJDIR)/pthread_%.o: libpthread/pthread_%.c $(OBJDIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -c $< -o $@
+	$(COMMENT) -$(STRIP) -x -R .comment -R .note $@
+$(OBJDIR)/stack_smash_handler2.o:	XCFLAGS:=-fno-omit-frame-pointer
 
-$(OBJDIR)/pthread_%.o: libpthread/pthread_%.c
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -c $< -o $@
-	$(COMMENT) -$(CROSS)strip -x -R .comment -R .note $@
+$(OBJDIR)/%.o: %.c $(OBJDIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -c $< -o $@ -D__dietlibc__
+	$(COMMENT) -$(STRIP) -x -R .comment -R .note $@
 
-$(OBJDIR)/%.o: %.c
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -c $< -o $@ -D__dietlibc__
-	$(COMMENT) -$(CROSS)strip -x -R .comment -R .note $@
+$(addprefix $(OBJDIR)/,$(NO_STACK_PROTECTOR)):	XCFLAGS+=-fno-stack-protector
 endif
 
 ifeq ($(shell $(CC) -v 2>&1 | grep "gcc version"),gcc version 4.0.0)
@@ -190,8 +196,8 @@ endif
 
 CC+=-D__dietlibc__
 
-$(OBJDIR)/crypt.o: libcrypt/crypt.c
-	$(CROSS)$(CC) $(INC) $(SAFER_CFLAGS) -c $< -o $@
+$(OBJDIR)/crypt.o: libcrypt/crypt.c $(OBJDIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(SAFER_CFLAGS) $(XCFLAGS) -c $< -o $@
 
 DIETLIBC_OBJ = $(OBJDIR)/unified.o \
 $(SYSCALLOBJ) $(LIBOBJ) $(LIBSTDIOOBJ) $(LIBUGLYOBJ) \
@@ -205,7 +211,7 @@ $(OBJDIR)/dietlibc.a: $(DIETLIBC_OBJ) $(OBJDIR)/start.o
 $(OBJDIR)/librpc.a: $(LIBRPCOBJ)
 	$(CROSS)ar cru $@ $(LIBRPCOBJ)
 
-$(OBJDIR)/libcrypt.a:
+$(OBJDIR)/libcrypt.a: $(OBJDIR)/.dirstamp
 	touch dummy.c
 	$(CROSS)$(CC) -c dummy.c
 	$(CROSS)ar cru $@ dummy.o
@@ -237,28 +243,28 @@ dyn: dyn_lib
 $(OBJDIR)/libdl.a: $(LIBDLOBJ)
 	$(CROSS)ar cru $@ $(LIBDLOBJ)
 
-dyn_lib: $(PICODIR) $(PICODIR)/libc.so $(PICODIR)/dstart.o \
+dyn_lib: $(PICODIR)/libc.so $(PICODIR)/dstart.o \
 	$(PICODIR)/dyn_so_start.o $(PICODIR)/dyn_start.o $(PICODIR)/dyn_stop.o \
 	$(PICODIR)/libpthread.so $(PICODIR)/libdl.so $(PICODIR)/libcompat.so \
 	$(PICODIR)/libm.so $(PICODIR)/diet-dyn $(PICODIR)/diet-dyn-i
 
-$(PICODIR)/%.o: %.S $(ARCH)/syscalls.h
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
+$(PICODIR)/%.o: %.S $(ARCH)/syscalls.h $(PICODIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
 
-$(PICODIR)/pthread_%.o: libpthread/pthread_%.c
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
-	$(COMMENT) $(CROSS)strip -x -R .comment -R .note $@
+$(PICODIR)/pthread_%.o: libpthread/pthread_%.c $(PICODIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
+	$(COMMENT) $(STRIP) -x -R .comment -R .note $@
 
-$(PICODIR)/%.o: %.c
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
-	$(COMMENT) $(CROSS)strip -x -R .comment -R .note $@
+$(PICODIR)/%.o: %.c $(PICODIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
+	$(COMMENT) $(STRIP) -x -R .comment -R .note $@
 
-$(PICODIR)/dstart.o: start.S
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
+$(PICODIR)/dstart.o: start.S $(PICODIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -fPIC -D__DYN_LIB -c $< -o $@
 
-$(PICODIR)/dyn_so_start.o: dyn_start.c
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -fPIC -D__DYN_LIB -D__DYN_LIB_SHARED -c $< -o $@
-	$(COMMENT) $(CROSS)strip -x -R .comment -R .note $@
+$(PICODIR)/dyn_so_start.o: dyn_start.c $(PICODIR)/.dirstamp
+	$(CROSS)$(CC) $(INC) $(CFLAGS) $(XCFLAGS) -fPIC -D__DYN_LIB -D__DYN_LIB_SHARED -c $< -o $@
+	$(COMMENT) $(STRIP) -x -R .comment -R .note $@
 
 DYN_LIBC_PIC = $(LIBOBJ) $(LIBSTDIOOBJ) $(LIBUGLYOBJ) \
 $(LIBCRUFTOBJ) $(LIBCRYPTOBJ) $(LIBSHELLOBJ) $(LIBREGEXOBJ)
@@ -274,13 +280,13 @@ DYN_LIBCOMPAT_OBJS = $(patsubst $(OBJDIR)/%.o,$(PICODIR)/%.o,$(LIBCOMPATOBJ))
 
 DYN_LIBMATH_OBJS = $(patsubst $(OBJDIR)/%.o,$(PICODIR)/%.o,$(LIBMATHOBJ))
 
-$(PICODIR)/libc.so: $(PICODIR) $(DYN_LIBC_OBJ)
+$(PICODIR)/libc.so: $(DYN_LIBC_OBJ)
 	$(LD_UNSET) $(CROSS)$(CC) -nostdlib -shared -o $@ $(CFLAGS) -fPIC $(DYN_LIBC_OBJ) -lgcc -Wl,-soname=libc.so
 
 $(PICODIR)/libpthread.so: $(DYN_PTHREAD_OBJS) dietfeatures.h
 	$(LD_UNSET) $(CROSS)$(CC) -nostdlib -shared -o $@ $(CFLAGS) -fPIC $(DYN_PTHREAD_OBJS) -L$(PICODIR) -lc -Wl,-soname=libpthread.so
 
-$(PICODIR)/libdl.so: libdl/_dl_main.c dietfeatures.h
+$(PICODIR)/libdl.so: libdl/_dl_main.c dietfeatures.h $(PICODIR)/.dirstamp
 	$(LD_UNSET) $(CROSS)$(CC) -D__OD_CLEAN_ROOM -DNODIETREF -fPIC -nostdlib -shared -Bsymbolic -Wl,-Bsymbolic \
 		-o $@ $(SAFE_CFLAGS) $(INC) libdl/_dl_main.c -Wl,-soname=libdl.so
 
@@ -310,19 +316,19 @@ CURNAME=$(notdir $(shell pwd))
 
 $(OBJDIR)/diet: $(OBJDIR)/start.o $(OBJDIR)/dyn_start.o diet.c $(OBJDIR)/dietlibc.a $(OBJDIR)/dyn_stop.o
 	$(CROSS)$(CC) -isystem include $(CFLAGS) -nostdlib -o $@ $^ -DDIETHOME=\"$(HOME)\" -DVERSION=\"$(VERSION)\" -lgcc
-	$(CROSS)strip -R .comment -R .note $@
+	$(STRIP) -R .comment -R .note $@
 
 $(OBJDIR)/diet-i: $(OBJDIR)/start.o $(OBJDIR)/dyn_start.o diet.c $(OBJDIR)/dietlibc.a $(OBJDIR)/dyn_stop.o
 	$(CROSS)$(CC) -isystem include $(CFLAGS) -nostdlib -o $@ $^ -DDIETHOME=\"$(prefix)\" -DVERSION=\"$(VERSION)\" -DINSTALLVERSION -lgcc
-	$(CROSS)strip -R .comment -R .note $@
+	$(STRIP) -R .comment -R .note $@
 
 $(PICODIR)/diet-dyn: $(PICODIR)/start.o $(PICODIR)/dyn_start.o diet.c
 	$(LD_UNSET) $(CROSS)$(CC) -isystem include $(CFLAGS) -fPIC -nostdlib -o $@ $^ -DDIETHOME=\"$(HOME)\" -D__DYN_LIB -DVERSION=\"$(VERSION)\" -L$(PICODIR) -lc -lgcc $(PICODIR)/dyn_stop.o -Wl,-dynamic-linker=$(HOME)/$(PICODIR)/libdl.so
-	$(CROSS)strip -R .command -R .note $@
+	$(STRIP) -R .command -R .note $@
 
 $(PICODIR)/diet-dyn-i: $(PICODIR)/start.o $(PICODIR)/dyn_start.o diet.c
 	$(LD_UNSET) $(CROSS)$(CC) -isystem include $(CFLAGS) -fPIC -nostdlib -o $@ $^ -DDIETHOME=\"$(prefix)\" -D__DYN_LIB -DVERSION=\"$(VERSION)\" -L$(PICODIR) -lc -lgcc $(PICODIR)/dyn_stop.o -Wl,-dynamic-linker=$(ILIBDIR)/libdl.so -DINSTALLVERSION
-	$(CROSS)strip -R .command -R .note $@
+	$(STRIP) -R .command -R .note $@
 
 $(OBJDIR)/djb: $(OBJDIR)/compile $(OBJDIR)/load
 
@@ -335,7 +341,7 @@ $(OBJDIR)/load:
 	chmod 755 $@
 
 clean:
-	rm -f *.o *.a t t1 compile load elftrunc exports mapfile libdietc.so
+	rm -f *.o *.a t t1 compile load elftrunc exports mapfile libdietc.so .dirstamp
 	rm -rf bin-* pic-*
 	$(MAKE) -C examples clean
 	$(MAKE) -C dynlinker clean
@@ -531,11 +537,12 @@ $(LIBPTHREAD_OBJS): include/pthread.h
 # WANT_LARGEFILE_BACKCOMPAT
 $(OBJDIR)/fcntl64.o: dietfeatures.h
 
-# WANT_SSP
-# This facepalm brought to you by: Ubuntu!
-$(OBJDIR)/stackgap.o: lib/stackgap.c dietfeatures.h
-	$(CROSS)$(CC) $(INC) $(CFLAGS) -c lib/stackgap.c -o $@ -D__dietlibc__ -fno-stack-protector
-	$(COMMENT) -$(CROSS)strip -x -R .comment -R .note $@
-
 # WANT_MALLOC_ZERO
 $(OBJDIR)/strndup.o: dietfeatures.h
+
+
+GIT_CVSIMPORT=git cvsimport
+CVS_EXTRA_bigo.ensc.de=;proxy=www-cache;proxyport=3128
+CVS_EXTRA=$(CVS_EXTRA_$(shell hostname -d))
+cvsimport:
+	$(GIT_CVSIMPORT) -k -p '--cvs-direct' -d ':pserver$(CVS_EXTRA):cvs@cvs.fefe.de:/cvs' dietlibc
diff --git a/alpha/start.S b/alpha/start.S
index 7e7cf9b..b13c9c9 100644
--- a/alpha/start.S
+++ b/alpha/start.S
@@ -24,6 +24,15 @@ _start:
 
 	stq	$18, environ
 
+#ifdef WANT_ELFINFO
+#  warning "MAKE ME alpha ASSEMBLER!"
+1:	ldq	$19, $18	; load *envp into $19
+	addq	$18,  1,  $18	; increment *envp
+	orr	$19, $19, $19
+	jne	1b
+	stq	$18, __elfinfo
+#endif
+
 #ifdef WANT_DYNAMIC
 /* in v0 ($0) is the ld.so _fini pointer */
 	mov	 $0, $19	/* mov v0(dynload) to a3 */
diff --git a/arm/__aeabi_unwind_cpp.S b/arm/__aeabi_unwind_cpp.S
index ca631bc..9334eee 100644
--- a/arm/__aeabi_unwind_cpp.S
+++ b/arm/__aeabi_unwind_cpp.S
@@ -1,21 +1,14 @@
-.text
-.global __aeabi_unwind_cpp_pr0
-.hidden __aeabi_unwind_cpp_pr0
-.type __aeabi_unwind_cpp_pr0, %function
+#include "arm-features.h"
 
-.global __aeabi_unwind_cpp_pr1
+FUNC_START __aeabi_unwind_cpp_pr0
+FUNC_START __aeabi_unwind_cpp_pr1
+FUNC_START __aeabi_unwind_cpp_pr2
+.hidden __aeabi_unwind_cpp_pr0
 .hidden __aeabi_unwind_cpp_pr1
-.type __aeabi_unwind_cpp_pr1, %function
-
-.global __aeabi_unwind_cpp_pr2
 .hidden __aeabi_unwind_cpp_pr2
-.type __aeabi_unwind_cpp_pr2, %function
 
-__aeabi_unwind_cpp_pr0:
-__aeabi_unwind_cpp_pr1:
-__aeabi_unwind_cpp_pr2:
-	mov	pc, lr	@ return from subroutine
+	RET
 
-.size __aeabi_unwind_cpp_pr0,.-__aeabi_unwind_cpp_pr0
-.size __aeabi_unwind_cpp_pr1,.-__aeabi_unwind_cpp_pr1
-.size __aeabi_unwind_cpp_pr2,.-__aeabi_unwind_cpp_pr2
+FUNC_END  __aeabi_unwind_cpp_pr2
+FUNC_END  __aeabi_unwind_cpp_pr1
+FUNC_END  __aeabi_unwind_cpp_pr0
diff --git a/arm/__fadvise.c b/arm/__fadvise.c
index 0aa1246..c6748c4 100644
--- a/arm/__fadvise.c
+++ b/arm/__fadvise.c
@@ -1,7 +1,10 @@
-#include <fcntl.h>
 #include "syscalls.h"
 
 #ifndef __NR_fadvise64
+#define _LINUX_SOURCE
+#include <fcntl.h>
+#include <unistd.h>
+
 long fadvise64_64(int fd, off64_t offset, off64_t len, int advice)
 {
   extern long __arm_fadvise64_64(int fd, int advice, off64_t offset, off64_t len);
diff --git a/arm/__guard.S b/arm/__guard.S
index 7218d13..a4e53aa 100644
--- a/arm/__guard.S
+++ b/arm/__guard.S
@@ -1,4 +1,5 @@
 .data
+.align 2
 .type __guard,#object
 .global __guard
 .type __stack_chk_guard,#object
@@ -7,3 +8,5 @@ __guard:
 __stack_chk_guard:
 .long 0xaff00
 
+.size __guard, . - __guard
+.size __stack_chk_guard, . - __stack_chk_guard
diff --git a/arm/__longjmp.S b/arm/__longjmp.S
index 31307bd..095093e 100644
--- a/arm/__longjmp.S
+++ b/arm/__longjmp.S
@@ -1,11 +1,24 @@
-.text
-.global __longjmp
-.type __longjmp,function
-__longjmp:
+#include "arm-features.h"
+
+FUNC_START	__longjmp
 	mov	ip, r0
 	movs	r0, r1
 	moveq	r0, #1
-#ifndef	__SOFTFP__
-	lfm	f4, 4, [ip], #48
+
+#ifndef __SOFTFP__
+# if __ARM_ARCH__ == 7
+	vldm	ip!, {d0-d15}
+#   ifdef __ARM_NEON__
+	vldm	ip!, {d16-d31}
+#   endif
+# else
+	lfm	f4, 4, [ip]!
+# endif
 #endif
-	ldmia   ip, {r4-r11, sp, pc}
+
+#ifdef __IWMMXT__
+#  warning "sigjmp will not restore iwmmxt coprocessor registers"
+#endif
+
+	ldmia   ip!, {r4-r11, sp, pc}
+FUNC_END	__longjmp
diff --git a/arm/__testandset.S b/arm/__testandset.S
index d9c5764..3b62c51 100644
--- a/arm/__testandset.S
+++ b/arm/__testandset.S
@@ -1,7 +1,15 @@
-.text
-.global __testandset
-__testandset:
+#include "arm-features.h"
+
+FUNC_START	__testandset
 	mov	r2, r0
 	mov	r1, #1
+# if __ARM_ARCH__ < 6
 	swp	r0, r1, [r2]
-	mov	pc, lr
+# else
+1:	ldrex	r0, [r2]
+	strex	r3, r1, [r2]
+	cmp	r3, #0
+	bne	1b
+# endif
+	RET
+FUNC_END	__testandset
diff --git a/arm/arm-features.h b/arm/arm-features.h
new file mode 100644
index 0000000..fa5d045
--- /dev/null
+++ b/arm/arm-features.h
@@ -0,0 +1,110 @@
+/* --*- asm -*-- */
+
+#ifndef H_DIETLIBC_ARM_FEATURES_H
+#define H_DIETLIBC_ARM_FEATURES_H
+
+/* Stolen from gcc (gcc/config/arm/lib1funcs.asm) */
+#if defined(__ARM_ARCH_2__)
+# define __ARM_ARCH__ 2
+#endif
+
+#if defined(__ARM_ARCH_3__)
+# define __ARM_ARCH__ 3
+#endif
+
+#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
+        || defined(__ARM_ARCH_4T__)
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+        || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+        || defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+        || defined(__ARM_ARCH_6M__)
+# define __ARM_ARCH__ 6
+#endif
+
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
+# define __ARM_ARCH__ 7
+#endif
+
+#ifndef __ARM_ARCH__
+#error Unable to determine architecture.
+#endif
+
+#define DIET_JMPBUFSZ_REGS_REGULAR	10*32/8	/* r4-r11, sp, pc */
+#define DIET_JMPBUFSZ_REGS_FPv4		16*64/8 /* d0-d15 */
+
+#if !defined(__SOFTFP__) || defined(__IWMMXT__)
+#  define DIET_HAVE_COPROC_REGS	1
+#else
+#  undef  DIET_HAVE_COPROC_REGS
+#endif
+
+#ifdef __ASSEMBLER__
+
+.macro	FUNC_START name
+	.text
+	.align	0
+	.global	\name
+	.type	\name, %function
+\name:
+.endm
+
+.macro	FUNC_START_WEAK name
+	.text
+	.align	0
+	.weak	\name
+	.type	\name, %function
+\name:
+.endm
+
+.macro	FUNC_END name
+	.size	\name, . - \name
+.endm
+
+.macro	RET
+#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
+	bx	lr
+#else
+	mov	pc, lr
+#endif
+.endm
+
+.macro	SWI_UNIFIED	name
+#ifdef __ARM_EABI__
+	b	__unified_syscall_swi
+#else
+	swi	\name
+	b	__unified_syscall
+#endif
+.endm
+
+.macro	SWI_UNIFIED4
+#ifdef __ARM_EABI__
+	b	__unified_syscall_swi
+#else
+	swi	\name
+	b	__unified_syscall4
+#endif
+.endm
+
+.macro	LOAD_ARG4_5
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5T__)
+	ldr	r4, [sp,#16]
+	ldr	r5, [sp,#20]
+#else
+	ldrd	r4, [sp,#16]
+#endif
+.endm
+
+#endif	/* __ASSEMBLER__ */
+
+#endif	/* H_DIETLIBC_ARM_FEATURES_H */
diff --git a/arm/clone.S b/arm/clone.S
index 4a4b2f4..b2ef450 100644
--- a/arm/clone.S
+++ b/arm/clone.S
@@ -1,11 +1,8 @@
 
 #include <errno.h>
 #include "syscalls.h"
+#include "arm-features.h"
 
-	.text
-	.weak 	clone
-	.global __clone
-	
 @
 @ Some slightly tricky stuff here... edit with care :-)
 @
@@ -19,9 +16,8 @@
 @ ;  don't do this yet
 @#define RESET_PID
 
-		
-clone:
-__clone:
+FUNC_START_WEAK	clone
+FUNC_START	__clone
 	@ ; start with a sanity check
 	cmp	r0, #0
 	cmpne	r1, #0
@@ -51,7 +47,8 @@ __clone:
 	beq	1f
 	ldmfd	sp!, {r4, r7}	
 	blt	__unified_syscall	@ (return code < 0): handle as an error
-	bx	lr
+	RET
+
 1:	
 #ifdef RESET_PID		
 	tst	ip, #CLONE_THREAD
@@ -76,12 +73,13 @@ __clone:
 	
 	@ ; and we're done, passing return value through r0
 	b	_exit			@ branch to _exit (PIC safe)
+FUNC_END	__clone
+FUNC_END	clone
 
-	
 #else
 		
-clone:
-__clone:
+FUNC_START_WEAK	clone
+FUNC_START	__clone
 	movs	r12, r0			@ check function pointer
 	cmpne	r1, #0			@ if function check for stack pointer
 	moveq	r0, #-EINVAL		@ if one is not available set errno value
@@ -101,5 +99,7 @@ __clone:
 	ldmia	sp!, { r0, pc } 	@ load function param and jump to thread function
 
 1:	b	_exit			@ branch to _exit (PIC safe)
+FUNC_END	__clone
+FUNC_END	clone
 
 #endif
diff --git a/arm/dyn_syscalls.S b/arm/dyn_syscalls.S
index a4baf28..e9b7ddd 100644
--- a/arm/dyn_syscalls.S
+++ b/arm/dyn_syscalls.S
@@ -8,11 +8,15 @@
 
 #include <dietfeatures.h>
 #include "syscalls.h"
+#include "arm-features.h"
 
-.text
-__unified_syscall4:
+#ifdef __ARM_EABI__
+# error "dyn_syscall.S not ported for EABI yet"
+#endif
+
+FUNC_START	__unified_syscall4
 	ldmfd	sp!, {r4, r5, r6}
-__unified_syscall:
+FUNC_START	__unified_syscall
 	cmn	r0, #4096
 	movcc	pc, lr
 	rsb	r1, r0, #0
@@ -25,7 +29,9 @@ __unified_syscall:
 
 	mvn	r0, #0
 #include "dietuglyweaks.h"
-	mov	pc, lr
+	RET
+FUNC_END	__unified_syscall
+FUNC_END	__unified_syscall4
 
 /* ok now include all syscalls.s (*.S) and sysdep *.S */
 #include "mmap.S"
@@ -104,7 +110,6 @@ __unified_syscall:
 #include "../syscalls.s/n_sigprocmask.S"
 #include "../syscalls.s/n_sigsuspend.S"
 #include "../syscalls.s/nanosleep.S"
-#include "../syscalls.s/nice.S"
 #include "../syscalls.s/open.S"
 #include "../syscalls.s/pause.S"
 #include "../syscalls.s/personality.S"
@@ -280,9 +285,11 @@ __unified_syscall:
 #include "../syscalls.s/fgetxattr.S"
 
 /* other asm-files w.o. changes ... */
-__exit:
+FUNC_START	__exit
 	swi	$__NR_exit
 	eor	pc,lr,lr
+FUNC_END	__exit
+
 #define _exit __exit
 #include "clone.S"
 #undef _exit
diff --git a/arm/mcount.S b/arm/mcount.S
index a397e92..2e25adf 100644
--- a/arm/mcount.S
+++ b/arm/mcount.S
@@ -1,4 +1,4 @@
-
+#include "arm-features.h"
 @
 @ mcount.S: ARM assembler implementation of mcount
 @
@@ -27,11 +27,7 @@
 @
 @
 
-.text
-
-.global mcount
-
-mcount:
+FUNC_START	mcount
     mov     ip,  sp
     stmdb   sp!, { r0 - r3, fp, ip, lr, pc }    @ build stack frame
     sub     fp,  ip, #4                         @ setup new fp
@@ -43,4 +39,4 @@ mcount:
     bl      __mcount                            @ call __mcount
 
     ldmdb   fp,  { r0 - r3, fp, sp, pc }        @ restore context from stack frame and return.
-
+FUNC_END	mcount
diff --git a/arm/md5asm.S b/arm/md5asm.S
index 370b503..1498899 100644
--- a/arm/md5asm.S
+++ b/arm/md5asm.S
@@ -50,45 +50,35 @@
 *****************************************************************************/
 
 #include <endian.h>
+#include "arm-features.h"
 
 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
 
-   .global MD5Init
-   .global MD5Update
-
-   .text
-#ifdef __ARM_EABI__
-   .align  4
-#else		
-   .align  2
-#endif
-	
     @ --
     @ void MD5Init (MD5_CTX* context);
     @ --
 
-MD5Init:
-
+FUNC_START	MD5Init
     adr     r1, 1f                          @ r1 = base address of MD5InitData array
     ldmia   r1, { r1 - r3, r12 }            @ load 4 elements from MD5InitData array
     stmia   r0, { r1 - r3, r12 }            @ store into MD5 context->state[0..3]
     mov     r1, #0
     str     r1, [r0, #0x10]                 @ initial count[0] = 0
-    str     r1, [r0, #0x14]                 @ initial count[1] = 0
-    mov     pc, lr                          @ return
-
-1: .word    0x67452301                      @ initial MD5 context->state[0]
-   .word    0xefcdab89                      @ initial MD5 context->state[1]
-   .word    0x98badcfe                      @ initial MD5 context->state[2]
+    str     r1, [r0, #0x14]                 @ initial count[1] = 0
+    RET
+
+   .align   3
+1: .word    0x67452301                      @ initial MD5 context->state[0]
+   .word    0xefcdab89                      @ initial MD5 context->state[1]
+   .word    0x98badcfe                      @ initial MD5 context->state[2]
    .word    0x10325476                      @ initial MD5 context->state[3]
-
+FUNC_END	MD5Init
 
     @ --
     @ void MD5Update (MD5_CTX* context, const uint8_t* buf, signed int len);
     @ --
 
-MD5Update:
-
+FUNC_START	MD5Update
     stmdb   sp!, { r4 - r8, lr }
     add     r4, r0, #(6 * 4)                @ r4 = &context->buffer[0]
     ldmdb   r4, { r0, r3 }                  @ r0 = count[0], r3 = count[1]
@@ -122,12 +112,13 @@ MD5Update:
     sub     r2, r8, r2
 2:  ldmia   sp!, { r4 - r8, lr }
     b       memcpy                          @ classic tail-call optimisation...
-
+FUNC_END	MD5Update
 
     @ --
     @ static void __MD5Transform (uint32_t *buf, const uint32_t *in, int repeat);
     @ --
 
+   .align    3
 MD5MagicData:
 
 1: .word     0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee
@@ -148,6 +139,7 @@ MD5MagicData:
    .word     0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, (17f-19f-4)
    .word     0x6e4120A9, 0x20657264, 0x7543634d, 0x00796472, (19f-19f-4)
 
+   .align   2
 __MD5Transform:
 
     cmp     r2, #0
diff --git a/arm/mmap.S b/arm/mmap.S
deleted file mode 100644
index d3ea131..0000000
--- a/arm/mmap.S
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <errno.h>
-#include "syscalls.h"
-
-.text
-
-@
-@ mmap takes 6 parameters - ie more than can be passed in registers via the
-@ regular syscall interface. Instead, parameters are passed on the stack.
-@
-@ On entry, the compiler will have already placed the fifth and sixth
-@ parameters on the stack - all we need do here is push the first four and
-@ call the syscall.
-@
-
-.global mmap
-
-#ifdef __ARM_EABI__
-
-mmap:
-	str     r5, [sp, #-4]!
-	ldr     r5, [sp, #8]
-	str     r4, [sp, #-4]!
-	ldr     r4, [sp, #8]
-	mov	ip, r7
-	mov	r7, #__NR_mmap2
-	svc	0x00000000
-	mov	r7, ip
-	ldr     r4, [sp], #4
-	ldr     r5, [sp], #4
-	cmn	r0, #4096
-	mov	pc, lr			@ return
-
-#else	
-		
-mmap:
-	stmdb	sp!, {r0, r1, r2, r3}
-	mov	r0, sp
-	swi	__NR_mmap
-	add	sp, sp, #16
-	b	__unified_syscall
-
-#endif
diff --git a/arm/setjmp.S b/arm/setjmp.S
index 6b850d4..e56e615 100644
--- a/arm/setjmp.S
+++ b/arm/setjmp.S
@@ -1,17 +1,40 @@
-.text
-.weak setjmp
-setjmp:
-.global __setjmp
-__setjmp:
+#include "arm-features.h"
+
+FUNC_START_WEAK	setjmp
+FUNC_START	__setjmp
 	mov	r1, #0
-.global __sigsetjmp
-__sigsetjmp:
-.weak sigsetjmp
-sigsetjmp:
-#ifndef	__SOFTFP__
-	sfm	f4, 4, [r0], #48
+FUNC_END	__setjmp
+FUNC_END	setjmp
+
+FUNC_START_WEAK	sigsetjmp
+FUNC_START	__sigsetjmp
+
+#ifdef DIET_HAVE_COPROC_REGS
+	/* we have to work on a copy of 'r0' (jmpbuf *) */
+	mov	ip, r0
 #endif
+
+#ifndef __SOFTFP__
+# if __ARM_ARCH__ >= 7
+	vstmia	ip!, {d0-d15}
+#   ifdef __ARM_NEON__
+	vstmia	ip!, {d16-d31}
+#   endif
+# else
+	sfm	f4, 4, [ip]!
+# endif
+#endif
+
+#ifdef __IWMMXT__
+#  warning "setjmp will not save iwmmxt coprocessor registers"
+#endif
+
+#ifndef DIET_HAVE_COPROC_REGS
 	stmia	r0, {r4-r11, sp, lr}
-	sub	r0, r0, #48
-	b	__sigjmp_save
+#else
+	stmia	ip!, {r4-r11, sp, lr}
+#endif
 
+	b	__sigjmp_save
+FUNC_END	__sigsetjmp
+FUNC_END	sigsetjmp
diff --git a/arm/start.S b/arm/start.S
index d68d49d..cfb298c 100644
--- a/arm/start.S
+++ b/arm/start.S
@@ -1,23 +1,11 @@
 
 #include "dietfeatures.h"
 #include "syscalls.h"
+#include "arm-features.h"
 
-	.text
 #ifdef __ARM_EABI__
-	.align 4
-#else
-	.align 2
-#endif
-	
-	.global _start
-	.weak 	exit
-	.global _exit
-
-
-#ifdef __ARM_EABI__
-
-_start:
 
+FUNC_START	_start
 	mov	fp, #0			@ clear the frame pointer
 	ldr	a1, [sp]		@ argc
 	add	a2, sp, #4		@ argv
@@ -25,6 +13,17 @@ _start:
 	add	a3, a2, a1, lsl #2	@ &argv[argc]
 	add	a3, a3, #4		@ envp	
 	str	a3, [ip, #0]		@ environ = envp
+
+#ifdef WANT_ELFINFO
+	mov	r6, a3			@ work on a copy of a3 so that common
+					@ 'main(argc, argv, envp)' function
+					@ stays valid
+1:	ldr	r5, [r6], #4		@ load *envp and increment it
+	cmp	r5, #0			@ read value==0?
+	bne	1b
+	str	r6, [ip, #4]		@ __elfinfo = envp
+#endif
+
 	bl	main
 		
 @
@@ -32,21 +31,22 @@ _start:
 @ We need to branch to 'exit' in case we have linked with 'atexit'.
 @
 	bl	exit
+FUNC_END	_start
 
-exit:
-_exit:
-
+FUNC_START	_exit
+FUNC_START_WEAK	exit
 	mov	r7, #__NR_exit		
 	swi	0			@ never returns.
 
+	.align	2
 .L3:	.word 	environ
-
+FUNC_END	exit
+FUNC_END	_exit
 	
 #else	
 
 	
-_start:
-
+FUNC_START	_start
 #ifdef WANT_DYNAMIC
 	mov	a4, a1			@ save dynamic ld.so _fini
 #endif
@@ -59,11 +59,25 @@ _start:
 #ifdef __DYN_LIB
 	ldr	sl, .L4
 1:	add	sl, pc, sl
-	str	a3, [sl, ip]		@ environ = envp
+	str	a3, [ip, sl]!		@ environ = envp; ip = GOT(environ)
 #else
 	str	a3, [ip, #0]		@ environ = envp
 #endif
 
+#ifdef WANT_ELFINFO
+	mov	r6, a3			@ work on a copy of a3 so that common
+					@ 'main(argc, argv, envp)' function
+					@ stays valid
+1:	ldr	r5, [r6], #4		@ load *envp and increment it
+	cmp	r5, #0			@ read value==0?
+	bne	1b
+#ifdef __DYN_LIB
+	str	r6, [ip, sl]		@ __elfinfo = envp
+#else
+	str	r6, [ip, #4]		@ __elfinfo = envp
+#endif
+#endif
+
 #ifdef PROFILING
 	stmdb	sp!, { r0 - r3 }
 	ldr	r0, .L5
@@ -83,18 +97,21 @@ _start:
 @ We need to branch to 'exit' in case we have linked with 'atexit'.
 @
 	bl	exit
+FUNC_END	_start
 
-exit:
-_exit:
-
+FUNC_START	_exit
+FUNC_START_WEAK	exit
 #ifdef PROFILING
 	mov	r4, r0			@ save a copy of exit status
 	bl	_stop_monitor
 	mov	r0, r4
 #endif
 	swi	$__NR_exit		@ never returns.
+FUNC_END	exit
+FUNC_END	_exit
 
 
+	.align	2
 #ifdef __DYN_LIB
 .L3:	.word 	environ(GOT)
 .L4:	.word 	_GLOBAL_OFFSET_TABLE_-(1b+8)
diff --git a/arm/strcpy.S b/arm/strcpy.S
index 20e1029..7a86562 100644
--- a/arm/strcpy.S
+++ b/arm/strcpy.S
@@ -1,10 +1,7 @@
 #include "dietfeatures.h"
+#include "arm-features.h"
 
-.text
-	.align	2
-	.global	strcpy
-
-strcpy:
+FUNC_START	strcpy
 #ifndef WANT_SMALL_STRING_ROUTINES
 	mov	ip, r0
 	ands	r2, r1, #3
@@ -61,6 +58,5 @@ strcpy:
 	ldrneb	r2, [r1], #1
 #endif
 	bne	.Lloop
-	mov	pc, lr
-.Lfe1:
-	.size	 strcpy,.Lfe1-strcpy
+	RET
+FUNC_END	strcpy
diff --git a/arm/strlen.S b/arm/strlen.S
index 6b2b459..a6af8f0 100644
--- a/arm/strlen.S
+++ b/arm/strlen.S
@@ -1,12 +1,7 @@
 #include "dietfeatures.h"
+#include "arm-features.h"
 
-	.text
-	.align	2
-
-	.global	strlen
-
-strlen:
-
+FUNC_START	strlen
 #if 0
 	teq	a1, #0			@ is string pointer NULL ??
 	moveq	pc, lr			@ if so, return 0
@@ -61,12 +56,10 @@ strlen:
 	sub	a1, a1, a2
 #endif
 
-	mov	pc, lr
+	RET
 
 #ifndef WANT_SMALL_STRING_ROUTINES
 .Lmagic:
 	.word	0x01010101
 #endif
-
-.Lstrlen:
-	.size	strlen,.Lstrlen-strlen
+FUNC_END	strlen
diff --git a/arm/syscalls.h b/arm/syscalls.h
index d092f55..21a6dcc 100644
--- a/arm/syscalls.h
+++ b/arm/syscalls.h
@@ -700,9 +700,9 @@
 #define __ARGS_getpeername		0
 #define __ARGS_socketpair		0
 #define __ARGS_send			0
-#define __ARGS_sendto			0
+#define __ARGS_sendto			6
 #define __ARGS_recv			0
-#define __ARGS_recvfrom			0
+#define __ARGS_recvfrom			6
 #define __ARGS_shutdown			0
 #define __ARGS_setsockopt		0
 #define __ARGS_getsockopt		0
@@ -771,70 +771,30 @@
 
 #ifdef __ASSEMBLER__
 
-#ifdef __ARM_EABI__
+#include "arm-features.h"
 
 #define syscall_weak(name,wsym,sym) __syscall_weak __NR_##name, wsym, sym, __ARGS_##name
 .macro __syscall_weak name wsym sym typ
-.text
-.type \wsym,function
-.weak \wsym
-\wsym:
-.type \sym,function
-.global \sym
-\sym:
-        stmfd	sp!,{r4,r5,r7,lr}
-	ldr	r4, [sp,#16]
-	ldr	r5, [sp,#20]
-        ldr     r7, =\name
-	swi	0
-	b	__unified_syscall
+FUNC_START_WEAK	\wsym
+__syscall	\name, \sym, \typ
+FUNC_END	\wsym
 .endm
 
+#ifdef __ARM_EABI__
 
 #define syscall(name,sym) __syscall __NR_##name, sym, __ARGS_##name
 .macro __syscall name sym typ
-.text
-.type \sym,function
-.global \sym
-\sym:
-        stmfd	sp!,{r4,r5,r7,lr}
-	ldr	r4, [sp,#16]
-	ldr	r5, [sp,#20]
-        ldr     r7, =\name
-	swi	0
-	b	__unified_syscall
+FUNC_START	\sym
+        ldr     ip, =\name
+	b	__unified_syscall_swi
+FUNC_END	\sym
 .endm
 
 #else
 
-#define syscall_weak(name,wsym,sym) __syscall_weak $__NR_##name, wsym, sym, __ARGS_##name
-.macro __syscall_weak name wsym sym typ
-.text
-.type \wsym,function
-.weak \wsym
-\wsym:
-.type \sym,function
-.global \sym
-\sym:
-.ifgt \typ
-	mov	ip, sp
-	stmfd	sp!,{r4, r5, r6}
-	ldmia	ip, {r4, r5, r6}
-.endif
-	swi	\name
-.ifgt \typ
-	b	__unified_syscall4
-.else
-	b	__unified_syscall
-.endif
-.endm
-
 #define syscall(name,sym) __syscall $__NR_##name, sym, __ARGS_##name
 .macro __syscall name sym typ
-.text
-.type \sym,function
-.global \sym
-\sym:
+FUNC_START	\sym
 .ifgt \typ
 	mov	ip, sp
 	stmfd	sp!,{r4, r5, r6}
@@ -846,6 +806,7 @@
 .else
 	b	__unified_syscall
 .endif
+FUNC_END	\sym
 .endm
 
 #endif
diff --git a/arm/unified.S b/arm/unified.S
index e6ea3f6..bd5b987 100644
--- a/arm/unified.S
+++ b/arm/unified.S
@@ -1,21 +1,28 @@
 
 #include <dietfeatures.h>
+#include "arm-features.h"
 
-	.text
 #ifdef __ARM_EABI__
-	.align 4
-#else
-	.align 2
-#endif 	
-	.global __unified_syscall
-	.global __unified_syscall4
-
 
-#ifdef __ARM_EABI__
+/* expects:
+ * r0-r3 ... syscall arguments 0-3
+ * ip    ... syscall number
+ */
+FUNC_START	__unified_syscall_swi
+	.hidden	__unified_syscall_swi
+        stmfd	sp!,{r4,r5,r7,lr}
+	mov	r7, ip
+	LOAD_ARG4_5
+	swi	0
+	/* fallthrough to __unified4_syscall */
+FUNC_END	__unified_syscall_swi
 
-__unified_syscall4:
-__unified_syscall:
-	
+/* expects:
+ * r0    ... syscall return value
+ * original r4-r7 + lr on stack
+ */
+FUNC_START	__unified_syscall
+	.hidden	__unified_syscall
         cmn     r0, #4096
         rsbcs   r2, r0, #0
         ldrcs   r3, 1f
@@ -25,17 +32,18 @@ __unified_syscall:
 	.balign 4
 1:
         .word   errno
+FUNC_END	__unified_syscall
 	
-/* here we go and "reuse" the return for weak-void functions */
 #include "dietuglyweaks.h"
 
-	mov	pc, lr			@ return
+	RET
 
 #else	
 	
-__unified_syscall4:
+FUNC_START	__unified_syscall4
 	ldmia	sp!, {r4, r5, r6}
-__unified_syscall:
+
+FUNC_START	__unified_syscall
 	cmn	r0, #4096
 	movcc	pc, lr			@ return value comes direct from kernel.
 
@@ -53,10 +61,13 @@ __unified_syscall:
 /* here we go and "reuse" the return for weak-void functions */
 #include "dietuglyweaks.h"
 
-	mov	pc, lr			@ return
+	RET
 
 #ifndef WANT_THREAD_SAFE
+	.align	2
 .L0:	.long 	errno
 #endif
+FUNC_END	__unified_syscall
+FUNC_END	__unified_syscall4
 
 #endif
diff --git a/arm/waitpid.S b/arm/waitpid.S
index 2c3a75b..0d099a8 100644
--- a/arm/waitpid.S
+++ b/arm/waitpid.S
@@ -1,15 +1,8 @@
-.text
-#ifdef __ARM_EABI__
-.align	4
-#else	
-.align	2
-#endif
-.weak	waitpid
-.type	waitpid, %function
-waitpid:
-.global	__libc_waitpid
-.type	__libc_waitpid, %function
-__libc_waitpid:
+#include "arm-features.h"
+
+FUNC_START_WEAK	waitpid
+FUNC_START	__libc_waitpid
 	mov	r3, #0
 	b	wait4
-	.size	waitpid, .-waitpid
+FUNC_END	__libc_waitpid
+FUNC_END	waitpid
diff --git a/dietdirent.h b/dietdirent.h
index dbd7206..3e823f8 100644
--- a/dietdirent.h
+++ b/dietdirent.h
@@ -1,8 +1,12 @@
 #include <sys/shm.h>
 
+#include "dietpagesize.h"
+
 struct __dirstream {
   int fd;
-  char buf[PAGE_SIZE-(sizeof (int)*3)];
   unsigned int num;
   unsigned int cur;
+  char buf[] __attribute__((__aligned__(8)));
 };				/* stream data from opendir() */
+
+#define __DIRSTREAM_BUF_SIZE	(__DIET_PAGE_SIZE - offsetof(struct __dirstream, buf))
diff --git a/dietelfinfo.h b/dietelfinfo.h
new file mode 100644
index 0000000..de8c717
--- /dev/null
+++ b/dietelfinfo.h
@@ -0,0 +1,20 @@
+#include "dietfeatures.h"
+
+#ifdef WANT_ELFINFO
+#include <elf.h>
+#include <endian.h>
+#include <stdint.h>
+
+/* TODO: exported interface from <linux/elf.h> has been changed in 2.6.25 so
+ * the 'elf_addr_t' type is not available anymore. Hence, derive it from
+ * __WORDSIZE__. */
+
+#if __WORDSIZE == 64
+typedef uint64_t	__diet_elf_addr_t;
+#elif __WORDSIZE == 32
+typedef uint32_t	__diet_elf_addr_t;
+#endif
+
+__diet_elf_addr_t const *	__get_elf_aux_value(unsigned int tag)
+	__attribute__((__visibility__("hidden"),__const__)) __pure;
+#endif
diff --git a/dietfeatures.h b/dietfeatures.h
index c05e0ad..23ff5ca 100644
--- a/dietfeatures.h
+++ b/dietfeatures.h
@@ -142,6 +142,16 @@
 #define WANT_SSP
 #endif
 
+/* Some platforms like x86_64, ppc* or mips do not have a fixed PAGE_SIZE.
+ * Select WANT_DYN_PAGESIZE to detect the current PAGE_SIZE at runtime. Else,
+ * define WANT_STATIC_PAGESIZE to a proper value (must be a power of 2)
+ * matching the configured pagesize of the kernel where your binaries are
+ * running on.
+ *
+ * Selecting WANT_DYN_PAGESIZE enlarges the startup code by around 1-3
+ * instructions and might add an additional __elfinfo symbol */
+#define WANT_DYN_PAGESIZE
+/* #define WANT_STATIC_PAGESIZE 0x10000UL */
 
 
 /* stop uncommenting here ;-) */
@@ -179,4 +189,8 @@
 #endif
 #endif
 
+#ifdef WANT_DYN_PAGESIZE
+#define WANT_ELFINFO
+#endif
+
 #endif
diff --git a/dietpagesize.h b/dietpagesize.h
new file mode 100644
index 0000000..8ce6ce7
--- /dev/null
+++ b/dietpagesize.h
@@ -0,0 +1,31 @@
+#ifndef H_DIETLIBC_DIETPAGESIZE_H
+#define H_DIETLIBC_DIETPAGESIZE_H
+
+#include <strings.h>
+#include "dietfeatures.h"
+
+extern size_t __libc_getpagesize(void) __attribute__((__const__)) __pure;
+
+#if defined(WANT_STATIC_PAGESIZE)
+#  define __DIET_PAGE_SIZE_PREDEF	(WANT_STATIC_PAGESIZE)
+#  define __DIET_PAGE_SHIFT_PREDEF	(ffs(__DIET_PAGE_SIZE_PREDEF)-1)
+#elif defined(__alpha__) || defined(__sparc__)
+#  define __DIET_PAGE_SIZE_PREDEF	(8192UL)
+#  define __DIET_PAGE_SHIFT_PREDEF	(13)
+#elif defined(__powerpc64__)
+#  define __DIET_PAGE_SIZE_PREDEF	(65536UL)
+#  define __DIET_PAGE_SHIFT_PREDEF	(16)
+#else
+#  define __DIET_PAGE_SIZE_PREDEF	(4096UL)
+#  define __DIET_PAGE_SHIFT_PREDEF	(12)
+#endif
+
+#ifdef WANT_DYN_PAGESIZE
+#  define __DIET_PAGE_SIZE	(__libc_getpagesize())
+#  define __DIET_PAGE_SHIFT	(ffs(__DIET_PAGE_SIZE)-1)
+#else
+#  define __DIET_PAGE_SIZE	__DIET_PAGE_SIZE_PREDEF
+#  define __DIET_PAGE_SHIFT	__DIET_PAGE_SHIFT_PREDEF
+#endif
+
+#endif	/* H_DIETLIBC_DIETPAGESIZE_H */
diff --git a/dynlinker/ldso_start.S b/dynlinker/ldso_start.S
index ca278d7..da36845 100644
--- a/dynlinker/ldso_start.S
+++ b/dynlinker/ldso_start.S
@@ -86,6 +86,15 @@ __environ:
 	.long 0
 #endif
 
+/* __elfinfo must follow __environ immediately */
+.global __elfinfo
+__elfinfo:
+#if __WORDSIZE == 64
+	.quad 0
+#else
+	.long 0
+#endif
+
 .global fini_entry
 fini_entry:
 	.long 0
diff --git a/i386/dyn_syscalls.S b/i386/dyn_syscalls.S
index e41f3c1..99eb739 100644
--- a/i386/dyn_syscalls.S
+++ b/i386/dyn_syscalls.S
@@ -191,7 +191,6 @@ __unified_syscall:
 #include "../syscalls.s/n_sigpending.S"
 #include "../syscalls.s/n_sigprocmask.S"
 #include "../syscalls.s/n_sigsuspend.S"
-#include "../syscalls.s/nice.S"
 #include "../syscalls.s/pause.S"
 #include "../syscalls.s/personality.S"
 #include "../syscalls.s/query_module.S"
diff --git a/i386/start.S b/i386/start.S
index 361af3d..b681d05 100644
--- a/i386/start.S
+++ b/i386/start.S
@@ -20,12 +20,18 @@ _start:
 	PIC_INIT			/* non-PIC: this is an empty line */
 	PUT_VAR %esi, environ, %ecx	/* non-PIC: movl %esi,environ */
 
-#ifdef WANT_SYSENTER
+#if defined(WANT_ELFINFO) || defined(WANT_SYSENTER)
 /* skip environment, scan for NULL */
 1:
 	lodsl
 	testl	%eax,%eax
 	jnz	1b
+#  ifdef WANT_ELFINFO
+	PUT_VAR %esi, __elfinfo, %ecx
+#  endif
+#endif
+
+#ifdef WANT_SYSENTER
 /* The ELF auxvec follows the environment, consists of key/value pairs.
    We are looking for key 32, which stands for the vsyscall page */
 1:
diff --git a/i386/syscalls.h b/i386/syscalls.h
index c4c9862..94f9be5 100644
--- a/i386/syscalls.h
+++ b/i386/syscalls.h
@@ -368,7 +368,6 @@ sym: \
 .Lend##sym: ; \
 .size sym,.Lend##sym-sym
 
-#ifndef __PIC__
 #define __socketcall(name,NAME) \
 .text; \
 .type name,@function; \
@@ -381,6 +380,3 @@ __libc_##name: ; \
 	jmp socketcall; \
 .Lend##name:; \
 .size name,.Lend##name-name
-#else
-#define __socketcall(name,NAME)
-#endif
diff --git a/ia64/Makefile.add b/ia64/Makefile.add
index ae02eb6..83fcb0f 100644
--- a/ia64/Makefile.add
+++ b/ia64/Makefile.add
@@ -1,2 +1,2 @@
 VPATH:=ia64:syscalls.s:$(VPATH)
-LIBOBJ+=$(OBJDIR)/__time.o $(OBJDIR)/__waitpid.o $(OBJDIR)/__nice.o $(OBJDIR)/__alarm.o $(OBJDIR)/__CAS.o
+LIBOBJ+=$(OBJDIR)/__time.o $(OBJDIR)/__waitpid.o $(OBJDIR)/__alarm.o $(OBJDIR)/__CAS.o $(OBJDIR)/__pause.o
diff --git a/ia64/__pause.c b/ia64/__pause.c
new file mode 100644
index 0000000..bb3a23a
--- /dev/null
+++ b/ia64/__pause.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <signal.h>
+
+int pause(void)
+{
+  sigset_t set;
+  sigemptyset(&set);
+  sigprocmask(SIG_BLOCK, NULL, &set);
+  return sigsuspend(&set);
+}
diff --git a/ia64/clone.S b/ia64/clone.S
index 0f87970..c152483 100644
--- a/ia64/clone.S
+++ b/ia64/clone.S
@@ -43,4 +43,5 @@ __clone:
 	br.call.dptk.few b0=__error_unified_syscall
 	br.ret.sptk.few b0
 .endp __clone
+.endp __clone2
 .size __clone, . - __clone
diff --git a/ia64/start.S b/ia64/start.S
index 50fd015..c917721 100644
--- a/ia64/start.S
+++ b/ia64/start.S
@@ -40,6 +40,16 @@ _start:
 	;;
 	st8  [r14] = out2           /* store envp in environ */
 
+#ifdef WANT_ELFINFO
+#  warning "MAKE ME IE64 CODE!"
+1:	ld8	r9 = [out2], 8	    /* load *envp and increment it */
+	orr	r9 = r9, r9	    /* test for NULL */
+	bne	1b
+
+	adds r14 = 8, r14	    /* __elfinfo = environ + 8 */
+	st8  [r14] = out2           /* store envp in __elfinfo */
+#endif
+
 #ifdef WANT_DYNAMIC
 /* FIXME: dl_init parameter ??? */
 	br.call.sptk.few rp = _dyn_start
diff --git a/ia64/unified.S b/ia64/unified.S
index 548e050..84ca7e8 100644
--- a/ia64/unified.S
+++ b/ia64/unified.S
@@ -16,9 +16,7 @@
 .text
 
 .globl __unified_syscall
-.proc  __unified_syscall
 .globl __error_unified_syscall
-.proc  __error_unified_syscall
 .globl _exit
 .proc  _exit
 
@@ -27,11 +25,18 @@ _exit:
 .endp _exit
 .size _exit, . - _exit
 
+.proc  __unified_syscall
+
 __unified_syscall:
 	break.i 0x100000
 	movl r2=errno
 	cmp.eq p6,p0=-1,r10
 	;;
+.endp __unified_syscall
+.size __unified_syscall, . - __unified_syscall
+
+.proc  __error_unified_syscall
+
 __error_unified_syscall:
 (p6)    st4 [r2]=r8
 (p6)    mov r8=-1
@@ -40,5 +45,5 @@ __error_unified_syscall:
 
 	br.ret.sptk.few rp
 
-.size __unified_syscall, __error_unified_syscall - __unified_syscall
+.endp __error_unified_syscall
 .size __error_unified_syscall, . - __error_unified_syscall
diff --git a/include/fcntl.h b/include/fcntl.h
index e4e668b..d814619 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -614,8 +614,10 @@ struct flock64
 extern int fcntl (int __fd, int __cmd, ...) __THROW;
 #ifndef __NO_STAT64
 extern int fcntl64 (int __fd, int __cmd, ...) __THROW;
+extern int fstatat64(int dirfd, const char *pathname, struct stat *buf, int flags) __THROW;
 #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
 #define fcntl fcntl64
+#define fstatat fstatat64
 #endif
 #endif
 
diff --git a/include/paths.h b/include/paths.h
index 553b4fa..9bf216f 100644
--- a/include/paths.h
+++ b/include/paths.h
@@ -2,7 +2,7 @@
 #define _PATHS_H
 
 #define _PATH_BSHELL "/bin/sh"
-#define _PATH_DEFPATH "/bin:/usr/bin:"
+#define _PATH_DEFPATH "/bin:/usr/bin"
 
 #define _PATH_DEVNULL "/dev/null"
 
diff --git a/include/setjmp.h b/include/setjmp.h
index 10b0a07..7fb0303 100644
--- a/include/setjmp.h
+++ b/include/setjmp.h
@@ -166,7 +166,7 @@ typedef int __jmp_buf[3];
 #ifdef __arm__
 #define __JMP_BUF_SP            8
 #ifndef __ASSEMBLER__
-typedef int __jmp_buf[24];
+typedef int __jmp_buf[10 + 16*2 + 16*2];
 #endif
 #endif
 
diff --git a/include/stdlib.h b/include/stdlib.h
index 4976f86..1dd10ff 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -28,8 +28,12 @@ long double strtold(const char *nptr, char **endptr) __THROW;
 long int strtol(const char *nptr, char **endptr, int base) __THROW;
 unsigned long int strtoul(const char *nptr, char **endptr, int base) __THROW;
 
+/* HACK: used flags in __dtostr
+     0x01 ... 'g'
+     0x02 ... uppercase
+   Define some constants somewhere... */
 extern int __ltostr(char *s, unsigned int size, unsigned long i, unsigned int base, int UpCase) __THROW;
-extern int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int g) __THROW;
+extern int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int flags) __THROW;
 
 #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
 __extension__ long long int strtoll(const char *nptr, char **endptr, int base) __THROW;
@@ -43,7 +47,7 @@ double atof(const char *nptr) __THROW;
 __extension__ long long int atoll(const char *nptr);
 
 void exit(int status) __THROW __attribute__((__noreturn__));
-void abort(void) __THROW;
+void abort(void) __THROW __attribute__((__noreturn__));
 
 extern int rand(void) __THROW;
 extern int rand_r(unsigned int *seed) __THROW;
diff --git a/include/sys/shm.h b/include/sys/shm.h
index 9b2d04d..70bb17e 100644
--- a/include/sys/shm.h
+++ b/include/sys/shm.h
@@ -60,15 +60,6 @@ struct shm_info {
   unsigned long swap_successes;
 };
 
-#if defined(__i386__) || defined(__mips__) || defined(__arm__) || defined(__powerpc__) || defined (__powerpc64__) || defined(__s390__) || defined(__hppa__) || defined(__x86_64__) || defined(__ia64__)
-#define PAGE_SIZE 4096UL
-#define PAGE_SHIFT 12
-#elif defined(__alpha__) || defined(__sparc__)
-/* sun4* has 4k except sun4 architecture, sparc64 has 8k */
-#define PAGE_SIZE 8192UL
-#define PAGE_SHIFT 13
-#endif
-
 extern int shmget(key_t key, int size, int shmflg) __THROW;
 extern void *shmat(int shmid, const void *shmaddr, int shmflg) __THROW;
 extern int shmdt (const void *shmaddr) __THROW;
diff --git a/include/unistd.h b/include/unistd.h
index c482077..09c55e5 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -39,6 +39,8 @@ loff_t lseek64(int fildes, loff_t offset, int whence) __THROW;
 #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
 #define lseek(fildes,offset,whence) lseek64(fildes,offset,whence)
 #endif
+#else
+#define lseek64(fildes,offset,whence) lseek(fildes,offset,whence)
 #endif
 
 int chdir(const char *path) __THROW;
diff --git a/lib/__dtostr.c b/lib/__dtostr.c
index 1d082e3..bc61200 100644
--- a/lib/__dtostr.c
+++ b/lib/__dtostr.c
@@ -5,13 +5,15 @@
 
 static int copystring(char* buf,int maxlen, const char* s) {
   int i;
-  for (i=0; i<3&&i<maxlen; ++i)
+  for (i=0; i<maxlen; ++i) {
     buf[i]=s[i];
-  if (i<maxlen) { buf[i]=0; ++i; }
+    if (!s[i])
+      break;
+  }
   return i;
 }
 
-int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int g) {
+int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int flags) {
 #if 1
   union {
     unsigned long long l;
@@ -35,8 +37,12 @@ int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned i
   double tmp;
   char *oldbuf=buf;
 
-  if ((i=isinf(d))) return copystring(buf,maxlen,i>0?"inf":"-inf");
-  if (isnan(d)) return copystring(buf,maxlen,"nan");
+  if (isinf(d))
+    return copystring(buf,maxlen,
+		      (d<0)?
+		      (flags&0x02?"-INF":"-inf"):
+		      (flags&0x02?"INF":"inf"));
+  if (isnan(d)) return copystring(buf,maxlen,flags&0x02?"NAN":"nan");
   e10=1+(long)(e*0.30102999566398119802); /* log10(2) */
   /* Wir iterieren von Links bis wir bei 0 sind oder maxlen erreicht
    * ist.  Wenn maxlen erreicht ist, machen wir das nochmal in
@@ -126,7 +132,7 @@ int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned i
   if (prec2 || prec>(unsigned int)(buf-oldbuf)+1) {	/* more digits wanted */
     if (!maxlen) return 0; --maxlen;
     *buf='.'; ++buf;
-    if (g) {
+    if ((flags & 0x01)) {
       if (prec2) prec=prec2;
       prec-=buf-oldbuf-1;
     } else {
diff --git a/lib/__get_elf_aux_value.c b/lib/__get_elf_aux_value.c
new file mode 100644
index 0000000..bc140c5
--- /dev/null
+++ b/lib/__get_elf_aux_value.c
@@ -0,0 +1,19 @@
+#include "dietfeatures.h"
+
+#ifdef WANT_ELFINFO
+#include <stdlib.h>
+#include "../dietelfinfo.h"
+
+__diet_elf_addr_t const *__get_elf_aux_value(unsigned int tag)
+{
+  extern __diet_elf_addr_t const * const	__elfinfo;
+  __diet_elf_addr_t const			*aux_ptr;
+
+  for (aux_ptr = __elfinfo; aux_ptr[0]!=AT_NULL; aux_ptr += 2)
+    if (aux_ptr[0]==tag)
+      return aux_ptr+1;
+
+  return NULL;
+}
+
+#endif
diff --git a/lib/__nice.c b/lib/__nice.c
deleted file mode 100644
index d751104..0000000
--- a/lib/__nice.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "syscalls.h"
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#ifndef __NR_nice
-int nice(int i) {
-  return setpriority(PRIO_PROCESS,0,getpriority(PRIO_PROCESS,0)+i);
-}
-#endif
diff --git a/lib/__utime.c b/lib/__utime.c
index e013265..0e4d0df 100644
--- a/lib/__utime.c
+++ b/lib/__utime.c
@@ -1,7 +1,10 @@
-#include <utime.h>
 #include <syscalls.h>
 
 #ifndef __NR_utime
+#define _BSD_SOURCE
+#include <utime.h>
+#include <sys/time.h>
+
 int utime(const char *filename, const struct utimbuf *times)
 {
   if (times == NULL)
diff --git a/lib/__v_printf.c b/lib/__v_printf.c
index 36202f5..964c005 100644
--- a/lib/__v_printf.c
+++ b/lib/__v_printf.c
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <math.h>
 #include "dietstdio.h"
 #include "dietwarning.h"
 
@@ -346,45 +347,49 @@ num_printf:
 #ifdef WANT_FLOATING_POINT_IN_PRINTF
       /* print a floating point value */
       case 'f':
+      case 'F':
       case 'g':
+      case 'G':
 	{
-	  int g=(ch=='g');
+	  int flags=(((ch&0x5f)=='G') ? 0x01 : 0x00) | ((ch&0x20) ? 0x00 : 0x02);
 	  double d=va_arg(arg_ptr,double);
 	  s=buf+1;
 	  if (width==0) width=1;
 	  if (!flag_dot) preci=6;
 	  if (flag_sign || d < +0.0) flag_in_sign=1;
 
-	  sz=__dtostr(d,s,sizeof(buf)-1,width,preci,g);
-
-	  if (flag_dot) {
-	    char *tmp;
-	    if ((tmp=strchr(s,'.'))) {
-	      if (preci || flag_hash) ++tmp;
-	      while (preci>0 && *++tmp) --preci;
-	      *tmp=0;
-	    } else if (flag_hash) {
-	      s[sz]='.';
-	      s[++sz]='\0';
+	  sz=__dtostr(d,s,sizeof(buf)-1,width,preci,flags);
+
+	  if (!isnan(d) && !isinf(d)) {		/* skip NaN + INF values */
+	    if (flag_dot) {
+	      char *tmp;
+	      if ((tmp=strchr(s,'.'))) {
+		if (preci || flag_hash) ++tmp;
+		while (preci>0 && *++tmp) --preci;
+		*tmp=0;
+	      } else if (flag_hash) {
+		s[sz]='.';
+		s[++sz]='\0';
+	      }
 	    }
-	  }
 
-	  if (g) {
-	    char *tmp,*tmp1;	/* boy, is _this_ ugly! */
-	    if ((tmp=strchr(s,'.'))) {
-	      tmp1=strchr(tmp,'e');
-	      while (*tmp) ++tmp;
-	      if (tmp1) tmp=tmp1;
-	      while (*--tmp=='0') ;
-	      if (*tmp!='.') ++tmp;
-	      *tmp=0;
-	      if (tmp1) strcpy(tmp,tmp1);
+	    if ((flags&0x01)) {
+	      char *tmp,*tmp1;	/* boy, is _this_ ugly! */
+	      if ((tmp=strchr(s,'.'))) {
+		tmp1=strchr(tmp,'e');
+		while (*tmp) ++tmp;
+		if (tmp1) tmp=tmp1;
+		while (*--tmp=='0') ;
+		if (*tmp!='.') ++tmp;
+		*tmp=0;
+		if (tmp1) strcpy(tmp,tmp1);
+	      }
 	    }
-	  }
 	  
-	  if ((flag_sign || flag_space) && d>=0) {
-	    *(--s)=(flag_sign)?'+':' ';
-	    ++sz;
+	    if ((flag_sign || flag_space) && d>=0) {
+	      *(--s)=(flag_sign)?'+':' ';
+	      ++sz;
+	    }
 	  }
 	  
 	  sz=strlen(s);
diff --git a/lib/alloc.c b/lib/alloc.c
index 9690565..3f0cedb 100644
--- a/lib/alloc.c
+++ b/lib/alloc.c
@@ -18,8 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <sys/shm.h>	/* for PAGE_SIZE */
-
+#include "../dietpagesize.h"
 
 /* -- HELPER CODE --------------------------------------------------------- */
 
@@ -39,7 +38,7 @@ typedef struct {
 #define BLOCK_START(b)	(((void*)(b))-sizeof(__alloc_t))
 #define BLOCK_RET(b)	(((void*)(b))+sizeof(__alloc_t))
 
-#define MEM_BLOCK_SIZE	PAGE_SIZE
+#define MEM_BLOCK_SIZE	__DIET_PAGE_SIZE
 #define PAGE_ALIGN(s)	(((s)+MEM_BLOCK_SIZE-1)&(unsigned long)(~(MEM_BLOCK_SIZE-1)))
 
 /* a simple mmap :) */
@@ -66,7 +65,9 @@ static __alloc_t* __small_mem[8];
 
 #define FIRST_SMALL(p)		(((unsigned long)(p))&(~(MEM_BLOCK_SIZE-1)))
 
-static inline int __ind_shift() { return (MEM_BLOCK_SIZE==4096)?4:5; }
+static inline int __ind_shift() {
+	return __DIET_PAGE_SHIFT - sizeof(__small_mem)/sizeof(__small_mem[0]);
+}
 
 static size_t REGPARM(1) get_index(size_t _size) {
   register size_t idx=0;
diff --git a/lib/closedir.c b/lib/closedir.c
index 3aade81..21de234 100644
--- a/lib/closedir.c
+++ b/lib/closedir.c
@@ -4,8 +4,10 @@
 #include <dirent.h>
 #include <stdlib.h>
 
+#include "../dietpagesize.h"
+
 int closedir (DIR* d) {
   int res=close(d->fd);
-  munmap (d, PAGE_SIZE);
+  munmap (d, __DIET_PAGE_SIZE);
   return res;
 }
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index 2b76cbd..50ecfa7 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -1,4 +1,5 @@
 #include "dietdirent.h"
+#include "dietpagesize.h"
 #include <sys/mman.h>
 #include <unistd.h>
 #include <dirent.h>
@@ -9,7 +10,7 @@ DIR*  fdopendir ( int fd ) {
   DIR*  t  = NULL;
 
   if ( fd >= 0 ) {
-    t = (DIR *) mmap (NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, 
+    t = (DIR *) mmap (NULL, __DIET_PAGE_SIZE, PROT_READ | PROT_WRITE,
 		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     if (t == MAP_FAILED)
 lose:
diff --git a/lib/mmap64.c b/lib/mmap64.c
index 0ab29a6..5012394 100644
--- a/lib/mmap64.c
+++ b/lib/mmap64.c
@@ -4,16 +4,18 @@
 #include <syscalls.h>
 #include <errno.h>
 
+#include "../dietpagesize.h"
+
 #ifdef __NR_mmap2
 void*__mmap2(void*start,size_t length,int prot,int flags,int fd,off_t pgoffset);
 
 void*__libc_mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset);
 void*__libc_mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset) {
-  if (offset&(PAGE_SIZE-1)) {
+  if (offset&(__DIET_PAGE_SIZE)) {
     errno=-EINVAL;
     return MAP_FAILED;
   }
-  return __mmap2(addr,len,prot,flags,fd,offset>>PAGE_SHIFT);
+  return __mmap2(addr,len,prot,flags,fd,offset>>__DIET_PAGE_SHIFT);
 }
 
 void*mmap64(void*addr,size_t len,int prot,int flags,int fd,off64_t offset)
diff --git a/lib/nice.c b/lib/nice.c
index 3f826af..076bac7 100644
--- a/lib/nice.c
+++ b/lib/nice.c
@@ -1,17 +1,56 @@
-#define _REENTRANT
+/*
+ * nice() for uClibc
+ *
+ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2005 by Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * GNU Library General Public License (LGPL) version 2 or later.
+ */
+
 #include <errno.h>
-#include <unistd.h>
+#include <limits.h>
 #include <sys/resource.h>
 
-int nice(int incr) {
-  int prio;
-  int res;
-  errno=0;
-  prio = getpriority(PRIO_PROCESS,0) + incr;
-  if (prio < PRIO_MIN) prio=PRIO_MIN;
-  if (prio >= PRIO_MAX) prio=PRIO_MAX-1;
-  if (setpriority (PRIO_PROCESS, 0, prio)==-1)
-    return -1;
-  else
-    return getpriority(PRIO_PROCESS, 0);
+static inline int int_add_no_wrap(int a, int b)
+{
+	int	s;
+
+	if ((b > 0) && (a > (INT_MAX - b)))
+		s = INT_MAX;
+	else if ((b < 0) && (a < (INT_MIN - b)))
+		s = INT_MIN;
+	else
+		s = a + b;
+
+	return s;
+}
+
+static inline int __syscall_nice(int incr)
+{
+	int old_priority;
+	int old_errno;
+
+	old_errno = errno;
+	__set_errno(0);
+	old_priority = getpriority(PRIO_PROCESS, 0);
+	if ((old_priority == -1) && errno) {
+		return -1;
+	}
+	__set_errno(old_errno);
+
+	if (setpriority(PRIO_PROCESS, 0, int_add_no_wrap(old_priority, incr))) {
+		__set_errno(EPERM);	/* SUSv3 mandates EPERM for nice failure. */
+		return -1;
+	}
+
+	return 0;
+}
+
+int nice(int incr)
+{
+	if (__syscall_nice(incr)) {
+		return -1;
+	}
+
+	return getpriority(PRIO_PROCESS, 0);
 }
diff --git a/lib/opendir.c b/lib/opendir.c
index 2530d1a..847685e 100644
--- a/lib/opendir.c
+++ b/lib/opendir.c
@@ -5,6 +5,8 @@
 #include <stdlib.h>
 #include <fcntl.h>
 
+#include "../dietpagesize.h"
+
 DIR*  opendir ( const char* name ) {
   int   fd = open (name, O_RDONLY | O_DIRECTORY);
   DIR*  t  = NULL;
@@ -12,7 +14,7 @@ DIR*  opendir ( const char* name ) {
   if ( fd >= 0 ) {
     if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
       goto lose;
-    t = (DIR *) mmap (NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, 
+    t = (DIR *) mmap (NULL, __DIET_PAGE_SIZE, PROT_READ | PROT_WRITE,
 		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     if (t == MAP_FAILED)
 lose:
diff --git a/lib/qsort.c b/lib/qsort.c
index 8c24b77..2523d5d 100644
--- a/lib/qsort.c
+++ b/lib/qsort.c
@@ -30,7 +30,7 @@ static void quicksort(char* base,size_t size,ssize_t l,ssize_t r,
      data is already sorted.  Try to improve by exchanging it with a
      random other pivot.
    */
-  exch(base,size,l+(random()%(r-l)),r);
+  exch(base,size,l+(rand()%(r-l)),r);
 #elif defined MID
   /*
      We chose the rightmost element in the array to be sorted as pivot,
diff --git a/lib/readdir.c b/lib/readdir.c
index ed885a5..d80a406 100644
--- a/lib/readdir.c
+++ b/lib/readdir.c
@@ -5,7 +5,7 @@
 
 struct dirent* readdir(DIR *d) {
   if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) {
-    int res=getdents(d->fd,(struct dirent*)d->buf,sizeof (d->buf)-1);
+    int res=getdents(d->fd,(struct dirent*)d->buf,__DIRSTREAM_BUF_SIZE-1);
     if (res<=0) return 0;
     d->num=res; d->cur=0;
   }
diff --git a/lib/readdir64.c b/lib/readdir64.c
index 924f0a8..06d073b 100644
--- a/lib/readdir64.c
+++ b/lib/readdir64.c
@@ -14,7 +14,7 @@
 #ifndef WANT_LARGEFILE_BACKCOMPAT
 struct dirent64* readdir64(DIR *d) {
   if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
-    int res=getdents64(d->fd,(struct dirent64*)d->buf, sizeof (d->buf)-1);
+    int res=getdents64(d->fd,(struct dirent64*)d->buf, __DIRSTREAM_BUF_SIZE-1);
     if (res<=0) return 0;
     d->num=res; d->cur=0;
   }
@@ -32,7 +32,7 @@ again:
   if (!trygetdents64) {
 #endif
     if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) {
-      int res=getdents(d->fd,(struct dirent*)d->buf, sizeof (d->buf)-1);
+      int res=getdents(d->fd,(struct dirent*)d->buf, __DIRSTREAM_BUF_SIZE-1);
       if (res<=0) return 0;
       d->num=res; d->cur=0;
     }
@@ -46,7 +46,7 @@ again:
 #ifdef __NR_getdents64
   }
   if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
-    int res=getdents64(d->fd,(struct dirent64*)d->buf,sizeof (d->buf));
+    int res=getdents64(d->fd,(struct dirent64*)d->buf,__DIRSTREAM_BUF_SIZE);
     if (res<=0) {
       if (errno==ENOSYS) {
 	trygetdents64=0;
diff --git a/lib/stack_smash_handler2.c b/lib/stack_smash_handler2.c
index 9e85099..179d31b 100644
--- a/lib/stack_smash_handler2.c
+++ b/lib/stack_smash_handler2.c
@@ -8,5 +8,17 @@ void __stack_chk_fail(void);
  * diagnostics.  No more. :-( */
 void __stack_chk_fail(void) {
   __write2("smashed stack detected, program terminated.\n");
-  _exit(127);
+
+  /* trigger a segfault which can be inspected within a debugger (inclusive
+   * stack-trace). 'abort(3)' at this place would be too heavy weighted.
+   *
+   * TODO: limit this to systems which are known to have an MMU (resp. is
+   * dietlibc with stack-protector used on systems without an MMU?)
+   */
+  *(char volatile *)0 = 0;
+  while (1) {
+#if defined(__GNUC__) && ((((__GNUC__) << 8) | (__GNUC_MINOR__)) >= 0x405)
+    __builtin_unreachable();
+#endif
+  }
 }
diff --git a/lib/stackgap.c b/lib/stackgap.c
index 122bc0d..35715ed 100644
--- a/lib/stackgap.c
+++ b/lib/stackgap.c
@@ -16,6 +16,7 @@
 #include <elf.h>
 #include <stdlib.h>
 #include "dietfeatures.h"
+#include "dietelfinfo.h"
 
 #ifdef WANT_GNU_STARTUP_BLOAT
 char* program_invocation_name;
@@ -50,11 +51,12 @@ void* __tdataptr;
 
 static void findtlsdata(long* auxvec) {
 #if (__WORDSIZE == 64)
-  Elf64_Phdr* x=0;
+  Elf64_Phdr const * x=0;
 #else
-  Elf32_Phdr* x=0;
+  Elf32_Phdr const * x=0;
 #endif
   size_t i,n=0;
+#ifndef WANT_ELFINFO
   while (*auxvec) {
     if (auxvec[0]==3) {	/* AT_PHDR */
       x=(void*)auxvec[1];
@@ -65,6 +67,18 @@ static void findtlsdata(long* auxvec) {
     }
     auxvec+=2;
   } /* if we don't find the entry, the kernel let us down */
+#else
+  {
+    __diet_elf_addr_t const	*x_addr = __get_elf_aux_value(AT_PHDR);
+    __diet_elf_addr_t const	*n_addr = __get_elf_aux_value(AT_PHNUM);
+
+    (void)auxvec;
+    if (x_addr)
+      x = (__typeof__(x)) *x_addr;
+    if (n_addr)
+      n = *n_addr;
+  }
+#endif
   if (!x || !n) return;	/* a kernel this old does not support thread local storage anyway */
   for (i=0; i<n; ++i)
     if (x[i].p_type==PT_TLS) {
@@ -125,6 +139,7 @@ void __setup_tls(tcbhead_t* mainthread) {
 }
 #endif
 
+#ifndef WANT_ELFINFO
 static void* find_in_auxvec(long* x,long what) {
   while (*x) {
     if (*x==what)
@@ -133,20 +148,30 @@ static void* find_in_auxvec(long* x,long what) {
   }
   return NULL;
 }
+#endif
 
 int stackgap(int argc,char* argv[],char* envp[]);
 int stackgap(int argc,char* argv[],char* envp[]) {
-  long* auxvec=(long*)envp;
 #if defined(WANT_STACKGAP) || defined(WANT_SSP) || defined(WANT_TLS)
   char* rand;
   char* tlsdata;
+#ifndef WANT_ELFINFO
+  long* auxvec=(long*)envp;
   while (*auxvec) ++auxvec; ++auxvec;	/* skip envp to get to auxvec */
+#endif
 #ifdef WANT_STACKGAP
   unsigned short s;
+  volatile char* gap;
 #endif
 #if defined(WANT_STACKGAP) || defined(WANT_SSP)
-  volatile char* gap;
+#ifndef WANT_ELFINFO
   rand=find_in_auxvec(auxvec,25);
+#else
+  {
+    __diet_elf_addr_t const	*rand_addr = __get_elf_aux_value(25);
+    rand = rand_addr ? (void *)*rand_addr : NULL;
+  }
+#endif
   if (!rand) {
     char myrand[10];
     int fd=open("/dev/urandom",O_RDONLY);
@@ -166,13 +191,25 @@ int stackgap(int argc,char* argv[],char* envp[]) {
 #endif
 #endif
 
+#ifndef WANT_ELFINFO
   __vdso=find_in_auxvec(auxvec,33);	// AT_SYSINFO_EHDR -> vdso start address
+#else
+  {
+    __diet_elf_addr_t const	*vdso_addr = __get_elf_aux_value(33);
+    __vdso = vdso_addr ? (void *)*vdso_addr : NULL;
+  }
+#endif
+
 #ifdef __x86_64__
   if (!__vdso) __vdso=(char*)0xffffffffff600000;
 #endif
 
 #ifdef WANT_TLS
+#ifndef WANT_ELFINFO
   findtlsdata(auxvec);
+#else
+  findtlsdata(NULL);
+#endif
   if (__unlikely(__tmemsize+sizeof(tcbhead_t)<sizeof(tcbhead_t)) ||
       __unlikely(__tmemsize>512*1024*1024) ||
       __unlikely(__tmemsize<__tdatasize))
diff --git a/lib/tcsetattr.c b/lib/tcsetattr.c
index 03fe8ad..15d6966 100644
--- a/lib/tcsetattr.c
+++ b/lib/tcsetattr.c
@@ -3,24 +3,8 @@
 #include <errno.h>
 #include "dietfeatures.h"
 
-#if !defined(__powerpc__) && !defined(__sparc__) && !defined(__alpha__) && !defined(__hppa__)
-#if TCSANOW==0 && TCSADRAIN==1 && TCSAFLUSH==2 && TCSETSW-TCSETS==1 && TCSETSF-TCSETS==2
-#define shortcut
-#endif
-#endif
-
 int  tcsetattr ( int fildes, int optional_actions, struct termios* termios_p )
 {
-#ifdef shortcut
-
-    if ( (unsigned int)optional_actions < 3u )
-        return ioctl ( fildes, TCSETS+optional_actions, termios_p );
-
-    errno = EINVAL;
-    return -1;
-
-#else
-
     switch ( optional_actions ) {
     case TCSANOW:
         return ioctl ( fildes, TCSETS , termios_p );
@@ -32,6 +16,4 @@ int  tcsetattr ( int fildes, int optional_actions, struct termios* termios_p )
         errno = EINVAL;
         return -1;
     }
-    
-#endif    
 }
diff --git a/libcompat/syscall.S b/libcompat/syscall.S
index c9f72bb..5743000 100644
--- a/libcompat/syscall.S
+++ b/libcompat/syscall.S
@@ -130,6 +130,13 @@ syscall:
 	b    __unified_syscall
 
 #else
-		/* arch not implemented yet */
+#include <endian.h>
+	.section	.comment
+#if (__WORDSIZE == 64)
+	.quad		__syscall_2_not_implemented_for_this_arch
+#else
+	.long		__syscall_2_not_implemented_for_this_arch
+#endif
+	.section	.text
 #endif
 .size	syscall, . - syscall
diff --git a/libcruft/getpagesize.c b/libcruft/getpagesize.c
index 5ff8973..ac701cf 100644
--- a/libcruft/getpagesize.c
+++ b/libcruft/getpagesize.c
@@ -1,25 +1,23 @@
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
-/* for environ: */
-#include <stdlib.h>
 
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
+#include "../dietelfinfo.h"
+#include "../dietpagesize.h"
 
-size_t __libc_getpagesize(void);
 size_t __libc_getpagesize(void) {
-  long* x=(long*)environ;
-  int fd;
-  while (*x) ++x; ++x;	/* skip envp to get to auxvec */
-  while (*x) {
-    if (*x==6)
-      return x[1];
-    x+=2;
+#ifdef WANT_DYN_PAGESIZE
+  static size_t	pgsz;
+
+  if (__unlikely(pgsz==0)) {
+    __diet_elf_addr_t const	*v = __get_elf_aux_value(AT_PAGESZ);
+    pgsz = *v;	/* causes segfault when 'v==NULL' */
   }
-  return PAGE_SIZE;
+
+  return pgsz;
+#else
+  return __DIET_PAGE_SIZE_PREDEF;
+#endif
 }
 
 size_t getpagesize(void)       __attribute__((weak,alias("__libc_getpagesize")));
-
diff --git a/libcruft/mkstemp.c b/libcruft/mkstemp.c
index 7dc19d4..226dec4 100644
--- a/libcruft/mkstemp.c
+++ b/libcruft/mkstemp.c
@@ -1,3 +1,4 @@
+#define _FILE_OFFSET_BITS 64
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
diff --git a/libcruft/sysconf.c b/libcruft/sysconf.c
index 6865026..089fbd3 100644
--- a/libcruft/sysconf.c
+++ b/libcruft/sysconf.c
@@ -6,6 +6,9 @@
 #define _GNU_SOURCE
 #include <sched.h>
 
+#include "dietelfinfo.h"
+#include "dietpagesize.h"
+
 extern int __sc_nr_cpus();
 
 static long physpages() {
@@ -42,6 +45,14 @@ long sysconf(int name)
       return limit.rlim_cur;
     }
   case _SC_CLK_TCK:
+#ifdef WANT_ELFINFO
+    {
+      __diet_elf_addr_t const	*v = __get_elf_aux_value(AT_CLKTCK);
+      if (v)
+	return *v;
+    }
+#endif
+
 #ifdef __alpha__
     return 1024;
 #else
@@ -49,11 +60,7 @@ long sysconf(int name)
 #endif
 
   case _SC_PAGESIZE:
-#if ( defined(__alpha__) || defined(__sparc__) )
-    return 8192;
-#else
-    return 4096;
-#endif
+    return __libc_getpagesize();
 
   case _SC_PHYS_PAGES:
     return physpages();
diff --git a/libm/ceil.c b/libm/ceil.c
new file mode 100644
index 0000000..c126b02
--- /dev/null
+++ b/libm/ceil.c
@@ -0,0 +1,92 @@
+/* @(#)s_ceil.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *	Bit twiddling.
+ * Exception:
+ *	Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include <math.h>
+
+typedef union {
+  double value;
+  struct {
+    unsigned int lsw;
+    unsigned int msw;
+  } parts;
+} ieee_double_shape_type;
+
+/* Get two 32 bit ints from a double.  */
+
+#define EXTRACT_WORDS(ix0,ix1,d)                                \
+do {                                                            \
+  ieee_double_shape_type ew_u;                                  \
+  ew_u.value = (d);                                             \
+  (ix0) = ew_u.parts.msw;                                       \
+  (ix1) = ew_u.parts.lsw;                                       \
+} while (0)
+
+#define INSERT_WORDS(d,ix0,ix1)                                 \
+do {                                                            \
+  ieee_double_shape_type iw_u;                                  \
+  iw_u.parts.msw = (ix0);                                       \
+  iw_u.parts.lsw = (ix1);                                       \
+  (d) = iw_u.value;                                             \
+} while (0)
+
+static const double huge = 1.0e300;
+
+double ceil(double x)
+{
+	int i0,i1,j0;
+	unsigned int i,j;
+	EXTRACT_WORDS(i0,i1,x);
+	j0 = ((i0>>20)&0x7ff)-0x3ff;
+	if(j0<20) {
+	    if(j0<0) { 	/* raise inexact if x != 0 */
+		if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+		    if(i0<0) {i0=0x80000000;i1=0;}
+		    else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+		}
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) return x; /* x is integral */
+		if(huge+x>0.0) {	/* raise inexact flag */
+		    if(i0>0) i0 += (0x00100000)>>j0;
+		    i0 &= (~i); i1=0;
+		}
+	    }
+	} else if (j0>51) {
+	    if(j0==0x400) return x+x;	/* inf or NaN */
+	    else return x;		/* x is integral */
+	} else {
+	    i = ((unsigned int)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) return x;	/* x is integral */
+	    if(huge+x>0.0) { 		/* raise inexact flag */
+		if(i0>0) {
+		    if(j0==20) i0+=1;
+		    else {
+			j = i1 + (1<<(52-j0));
+			if(j<i1) i0+=1;	/* got a carry */
+			i1 = j;
+		    }
+		}
+		i1 &= (~i);
+	    }
+	}
+	INSERT_WORDS(x,i0,i1);
+	return x;
+}
diff --git a/libm/gamma.c b/libm/gamma.c
index 9682f35..370bec6 100644
--- a/libm/gamma.c
+++ b/libm/gamma.c
@@ -33,19 +33,19 @@ Return value    gamma returns a value in range (-0.1208, +oo). For a input
 #include <stdlib.h>
 #include <math.h>
 
-#define B0      +            1.0l/   6/ 1/ 2
-#define B1      -            1.0l/  30/ 3/ 4
-#define B2      +            1.0l/  42/ 5/ 6
-#define B3      -            1.0l/  30/ 7/ 8
-#define B4      +            5.0l/  66/ 9/10
-#define B5      -          691.0l/2730/11/12
-#define B6      +            7.0l/   6/13/14
-#define B7      -         3617.0l/ 510/15/16
-#define B8      +        43867.0l/ 798/17/18
-#define B9      -       174611.0l/ 330/19/20
-#define B10     +       854513.0l/ 138/21/22
-#define B11     -    236364091.0l/2730/23/24
-#define B12     +      8553103.0l/   6/25/26
+#define B0      +            1.0/   6/ 1/ 2
+#define B1      -            1.0/  30/ 3/ 4
+#define B2      +            1.0/  42/ 5/ 6
+#define B3      -            1.0/  30/ 7/ 8
+#define B4      +            5.0/  66/ 9/10
+#define B5      -          691.0/2730/11/12
+#define B6      +            7.0/   6/13/14
+#define B7      -         3617.0/ 510/15/16
+#define B8      +        43867.0/ 798/17/18
+#define B9      -       174611.0/ 330/19/20
+#define B10     +       854513.0/ 138/21/22
+#define B11     -    236364091.0/2730/23/24
+#define B12     +      8553103.0/   6/25/26
 
 static const double  coeff[] = { B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10 };
 int                  signgam;
diff --git a/librpc/clnt_raw.c b/librpc/clnt_raw.c
index 042d130..1e89ac0 100644
--- a/librpc/clnt_raw.c
+++ b/librpc/clnt_raw.c
@@ -53,7 +53,10 @@ static struct clntraw_private {
 	CLIENT client_object;
 	XDR xdr_stream;
 	char _raw_buf[UDPMSGSIZE];
-	char mashl_callmsg[MCALL_MSG_SIZE];
+	union {
+		struct rpc_msg	msg;
+		char buf[MCALL_MSG_SIZE];
+	} mashl_call;
 	unsigned int mcnt;
 } *clntraw_private;
 
@@ -101,7 +104,7 @@ unsigned long vers;
 	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
 	call_msg.rm_call.cb_prog = prog;
 	call_msg.rm_call.cb_vers = vers;
-	xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
+	xdrmem_create(xdrs, clp->mashl_call.buf, MCALL_MSG_SIZE, XDR_ENCODE);
 	if (!xdr_callhdr(xdrs, &call_msg)) {
 		perror("clnt_raw.c - Fatal header serialization error.");
 	}
@@ -145,8 +148,8 @@ struct timeval timeout;
 	 */
 	xdrs->x_op = XDR_ENCODE;
 	XDR_SETPOS(xdrs, 0);
-	((struct rpc_msg *) clp->mashl_callmsg)->rm_xid++;
-	if ((!XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+	clp->mashl_call.msg.rm_xid++;
+	if ((!XDR_PUTBYTES(xdrs, clp->mashl_call.buf, clp->mcnt)) ||
 		(!XDR_PUTLONG(xdrs, (long *) &proc)) ||
 		(!AUTH_MARSHALL(h->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp))) {
 		return (RPC_CANTENCODEARGS);
diff --git a/librpc/clnt_udp.c b/librpc/clnt_udp.c
index ae7f3d8..003edf5 100644
--- a/librpc/clnt_udp.c
+++ b/librpc/clnt_udp.c
@@ -335,7 +335,7 @@ struct timeval utimeout;		/* seconds to wait before giving up */
 		if (inlen < 4)
 			continue;
 		/* see if reply transaction id matches sent id */
-		if (*((uint32_t *) (cu->cu_inbuf)) != *((uint32_t *) (cu->cu_outbuf)))
+		if (memcmp(cu->cu_inbuf, cu->cu_outbuf, 4) != 0)
 			continue;
 		/* we now assume we have the proper reply */
 		break;
diff --git a/libstdio/fflush.c b/libstdio/fflush.c
index f197482..df453ec 100644
--- a/libstdio/fflush.c
+++ b/libstdio/fflush.c
@@ -17,7 +17,6 @@ int fflush_unlocked(FILE *stream) {
   if (stream==0) {
     int res;
     FILE *f;
-    __fflush_stdin();
     __fflush_stdout();
     __fflush_stderr();
     for (res=0, f=__stdio_root; f; f=f->next)
diff --git a/libstdio/fwrite.c b/libstdio/fwrite.c
index 464abdd..9f4e8e5 100644
--- a/libstdio/fwrite.c
+++ b/libstdio/fwrite.c
@@ -49,7 +49,7 @@ notlinewise:
     } else
       done=0;
     for (i=done; i<len; ++i)
-      if (fputc_unlocked(((char*)ptr)[i],stream)) {
+      if (fputc_unlocked(((char*)ptr)[i],stream) == EOF) {
 	res=len-i;
 	goto abort;
       }
diff --git a/libugly/asctime_r.c b/libugly/asctime_r.c
index 43c5e2c..9859f5f 100644
--- a/libugly/asctime_r.c
+++ b/libugly/asctime_r.c
@@ -9,7 +9,7 @@ static void num2str(char *c,int i) {
 }
 
 char *asctime_r(const struct tm *t, char *buf) {
-  /* "Wed Jun 30 21:49:08 1993\n" */
+  /* "Wed Jun 30 21:49:08 1993\n\0" */
   *(int*)buf=*(int*)(days+(t->tm_wday<<2));
   *(int*)(buf+4)=*(int*)(months+(t->tm_mon<<2));
   num2str(buf+8,t->tm_mday);
@@ -25,5 +25,6 @@ char *asctime_r(const struct tm *t, char *buf) {
   num2str(buf+20,(t->tm_year+1900)/100);
   num2str(buf+22,(t->tm_year+1900)%100);
   buf[24]='\n';
+  buf[25]='\0';
   return buf;
 }
diff --git a/libugly/strftime.c b/libugly/strftime.c
index b6532aa..a501308 100644
--- a/libugly/strftime.c
+++ b/libugly/strftime.c
@@ -55,6 +55,7 @@ again:
 	    case 'x': src = "%b %a %d";   			 goto _strf;
 	    case 'X': src = "%k:%M:%S";   			 goto _strf;
 	    case 'D': src = "%m/%d/%y";   			 goto _strf;
+	    case 'F': src = "%Y-%m-%d";				 goto _strf;
 	    case 'T': src = "%H:%M:%S";
 	       _strf: p  += strftime (p, (size_t)(dst+max-p), src, tm); 	 break;
 	    case 'a': src = sweekdays [tm->tm_wday]; 		 goto _str;
diff --git a/libugly/strptime.c b/libugly/strptime.c
index 9d7f530..d19f309 100644
--- a/libugly/strptime.c
+++ b/libugly/strptime.c
@@ -119,10 +119,11 @@ char* strptime(const char* s,const char* format, struct tm* tm) {
 	++s;
 	break;
       case 'x':
-	s=strptime(s,"%b %a %d",tm);
+	/* see SUSv2, Ch.7 "LC_TIME Category in the POSIX Locale" */
+	s=strptime(s,"%m/%d/%y",tm);
 	break;
       case 'X':
-	s=strptime(s,"%k:%M:%S",tm);
+	s=strptime(s,"%H:%M:%S",tm);
 	break;
       case 'y':
 	i=getint(&s,2);
diff --git a/mips/start.S b/mips/start.S
index 57144b3..3cf3433 100644
--- a/mips/start.S
+++ b/mips/start.S
@@ -47,6 +47,15 @@ __start:
 #endif
 	add	$a2, $a2, $a1
 	sw	$a2, environ
+#ifdef WANT_ELFINFO
+#  warning "MAKE ME MIPS CODE!"
+1:	addu	$a2, $a2, 4	/* increment envp */
+	lw	$4, -4($a2)     /* load envp[-1]; TODO: is $4 a proper
+				   temporary register? */
+	bnz	1b		/* ... until envp[-1]==NULL
+				   TODO: use proper 'bnz' operation */
+	sw	$a2, __elfinfo
+#endif
 	jalr	$25
 	la	$25, exit
 	move	$4,$2
diff --git a/parisc/semctl.S b/parisc/semctl.S
new file mode 100644
index 0000000..e215ed9
--- /dev/null
+++ b/parisc/semctl.S
@@ -0,0 +1,3 @@
+#include "syscalls.h"
+
+syscall(semctl,semctl)
diff --git a/parisc/semget.S b/parisc/semget.S
new file mode 100644
index 0000000..67f4885
--- /dev/null
+++ b/parisc/semget.S
@@ -0,0 +1,3 @@
+#include "syscalls.h"
+
+syscall(semget,semget)
diff --git a/parisc/semop.S b/parisc/semop.S
new file mode 100644
index 0000000..81b6fc6
--- /dev/null
+++ b/parisc/semop.S
@@ -0,0 +1,3 @@
+#include "syscalls.h"
+
+syscall(semop,semop)
diff --git a/parisc/start.S b/parisc/start.S
index 69d9cce..871296e 100644
--- a/parisc/start.S
+++ b/parisc/start.S
@@ -34,6 +34,16 @@ _start:
 	ldil LP%environ, %r19
 	ldo RP%environ(%r19), %r19
 
+#ifdef WANT_ELFINFO
+#  warning "MAKE ME PARISC CODE!"
+1:	add %r20, %r19, %r19		; envp += 4
+	ldw -4(0,%r19), %r21		; load envp[-4] into %r21
+	comibf =,0, 0,%r21,1b		; compare %r21 with 0 without nullification
+
+	ldil LP%__elfinfo, %r19
+	ldo RP%__elfinfo(%r19), %r19
+#endif
+
 	/* Expand the stack to store the 5th through 7th args */
 	ldo 64(%sp), %sp
 
diff --git a/parisc/strcmp.S b/parisc/strcmp.S
index 9dddd59..b954f48 100644
--- a/parisc/strcmp.S
+++ b/parisc/strcmp.S
@@ -1,6 +1,7 @@
 .text
 .globl strcmp
-
+.weak strcoll
+strcoll:
 strcmp:
 	.PROC
 	.CALLINFO
diff --git a/powerpc/select.S b/powerpc/select.S
new file mode 100644
index 0000000..9e7066e
--- /dev/null
+++ b/powerpc/select.S
@@ -0,0 +1,3 @@
+#include "syscalls.h"
+
+syscall_weak(_newselect,select,__libc_select)
diff --git a/powerpc64/select.S b/powerpc64/select.S
new file mode 100644
index 0000000..9e7066e
--- /dev/null
+++ b/powerpc64/select.S
@@ -0,0 +1,3 @@
+#include "syscalls.h"
+
+syscall_weak(_newselect,select,__libc_select)
diff --git a/ppc/start.S b/ppc/start.S
index 771f1ad..3b5cab1 100644
--- a/ppc/start.S
+++ b/ppc/start.S
@@ -31,6 +31,15 @@ _start:
 	lis	14,environ@ha
 	stw	5,environ@l(14)
 
+#ifdef WANT_ELFINFO
+1:	lwzu	15,0(5)
+	addi	5, 5, 4
+	cmpwi	15,0
+	bne	1b
+
+	stw	5,__elfinfo@l(14)
+#endif
+
 #ifdef WANT_DYNAMIC
 	mr	6,7
 	bl	_dyn_start
diff --git a/ppc64/start.S b/ppc64/start.S
index 3955d48..a9e9d6a 100644
--- a/ppc64/start.S
+++ b/ppc64/start.S
@@ -58,6 +58,15 @@ _start:
 	oris	14,14,environ@ha
 	std	5,environ@l(14)
 
+#ifdef WANT_ELFINFO
+1:	ldu	15,0(5)
+	addi	5, 5, 8
+	cmpdi	15,0
+	bne	1b
+
+	std	5,__elfinfo@l(14)
+#endif
+
 #ifdef WANT_DYNAMIC
 /* #warning dynamic */
 	mr	6,7
diff --git a/s390/setjmp.S b/s390/setjmp.S
index 7522373..762f9e3 100644
--- a/s390/setjmp.S
+++ b/s390/setjmp.S
@@ -14,6 +14,7 @@ __setjmp:
 
 .global _setjmp
 .type	_setjmp,@function
+_setjmp:
 	lhi	%r3,0
 .size	_setjmp,.-_setjmp
 
@@ -26,15 +27,18 @@ __sigsetjmp:
 	std	%f6,48(%r2)
 
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
-	basr	%r1,%r0
+	basr	%r1,0
 #ifdef	PIC
-.L0:	la	%r1,.L1-.L0(0,%r1)
+.L0:	al	%r1,.L1-.L0(0,%r1)
 	l	%r1,__sigjmp_save@GOT12(0,%r1)
+#else
+.L0:	l	%r1,.L1-.L0(0,%r1)
+#endif
 	br	%r1
+	.p2align 3
+#ifdef	PIC
 .L1:	.long	_GLOBAL_OFFSET_TABLE_-.L0
 #else
-	l	%r1,.L1(0,%r1)
-	br	%r1
 .L1:	.long	__sigjmp_save
 #endif
 .size __sigsetjmp,.-__sigsetjmp;
diff --git a/s390/start.S b/s390/start.S
index c0f971f..c1a5a6f 100644
--- a/s390/start.S
+++ b/s390/start.S
@@ -30,6 +30,17 @@ _start:
 	l	%r1,8(%r13)
 	st	%r4,0(%r1)
 
+#ifdef WANT_ELFINFO
+	lhi	%r6, -4
+1:	ahi	%r4, 4		# increment envp
+	l	%r12, 0(%r6,%r4)	# load envp[-1] into %r12
+	or	%r12, %r12	# test %r12 for NULL
+	jne	1b
+
+	ahi	%r1, 4
+	st	%r4,0(%r1)
+#endif
+
 /* call main or _dyn_start */
 	l	%r1,0(%r13)
 	basr	%r14,%r1
diff --git a/s390/syscalls.h b/s390/syscalls.h
index 6ea4a2b..cfd3d82 100644
--- a/s390/syscalls.h
+++ b/s390/syscalls.h
@@ -277,6 +277,7 @@
 #define __NR_mknodat		290
 #define __NR_fchownat		291
 #define __NR_futimesat		292
+#define __NR_fstatat64		293
 #define __NR_unlinkat		294
 #define __NR_renameat		295
 #define __NR_linkat		296
diff --git a/s390x/setjmp.S b/s390x/setjmp.S
index 7522373..762f9e3 100644
--- a/s390x/setjmp.S
+++ b/s390x/setjmp.S
@@ -14,6 +14,7 @@ __setjmp:
 
 .global _setjmp
 .type	_setjmp,@function
+_setjmp:
 	lhi	%r3,0
 .size	_setjmp,.-_setjmp
 
@@ -26,15 +27,18 @@ __sigsetjmp:
 	std	%f6,48(%r2)
 
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
-	basr	%r1,%r0
+	basr	%r1,0
 #ifdef	PIC
-.L0:	la	%r1,.L1-.L0(0,%r1)
+.L0:	al	%r1,.L1-.L0(0,%r1)
 	l	%r1,__sigjmp_save@GOT12(0,%r1)
+#else
+.L0:	l	%r1,.L1-.L0(0,%r1)
+#endif
 	br	%r1
+	.p2align 3
+#ifdef	PIC
 .L1:	.long	_GLOBAL_OFFSET_TABLE_-.L0
 #else
-	l	%r1,.L1(0,%r1)
-	br	%r1
 .L1:	.long	__sigjmp_save
 #endif
 .size __sigsetjmp,.-__sigsetjmp;
diff --git a/s390x/start.S b/s390x/start.S
index 25895a6..f644eb9 100644
--- a/s390x/start.S
+++ b/s390x/start.S
@@ -26,6 +26,16 @@ _start:
 	larl	%r13,environ
 	stg	%r4,0(%r13)
 
+#ifdef WANT_ELFINFO
+1:	aghi	%r4, 8		# increment envp
+	lg	%r12, -8(0,%r4)	# load envp[-1] into %r12
+	ogr	%r12, %r12	# test %r12 for NULL
+	jne	1b
+
+	aghi	%r13, 8
+	stg	%r4,0(%r13)
+#endif
+
 /* call main or _dyn_start */
 #ifdef WANT_DYNAMIC
 	brasl	%r14,_dyn_start
diff --git a/sparc/shmat.c b/sparc/shmat.c
index b7dce2e..ce3bfcb 100644
--- a/sparc/shmat.c
+++ b/sparc/shmat.c
@@ -3,17 +3,15 @@
 #include <sys/shm.h>
 #include <unistd.h>
 
-extern void* __ipc();
+#include "../dietpagesize.h"
 
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
+extern void* __ipc();
 
 void* shmat(int shmid,const void* shmaddr,int shmflg) {
   void* raddr;
   register void* result;
   result=__ipc(SHMAT,shmid,shmflg,&raddr,shmaddr);
-  if ((unsigned long)result <= -(unsigned long)PAGE_SIZE)
+  if ((unsigned long)result <= -(unsigned long)__DIET_PAGE_SIZE)
     result=raddr;
   return result;
 }
diff --git a/sparc/start.S b/sparc/start.S
index a7841e3..bb463c9 100644
--- a/sparc/start.S
+++ b/sparc/start.S
@@ -25,6 +25,17 @@ _start:
 	or	%o3, %lo(environ), %o3
 	st	%o2, [%o3]
 
+#ifdef WANT_ELFINFO
+#  warning "VERIFY ME!"
+1:	add	%o2, %o2, 4
+	ld	[%o2-4], %o4
+	orcc	%o4, %o4, %o4
+	bne	1b
+
+	add	%o3, %o3, 4
+	st	%o2, [%o3]
+#endif
+
 /* When starting a binary via the dynamic linker, %g1 contains the
    address of the shared library termination function, which will be
    registered with atexit(). If we are statically linked, this will
diff --git a/sparc/strchr.S b/sparc/strchr.S
index e27e454..8c2c78c 100644
--- a/sparc/strchr.S
+++ b/sparc/strchr.S
@@ -11,6 +11,8 @@
 
 .text
 .globl strchr
+.weak index
+index:
 strchr:
 	ldub [%o0], %o2
 	cmp %o2, %o1
diff --git a/sparc/strcmp.S b/sparc/strcmp.S
index 50c82b5..81379f2 100644
--- a/sparc/strcmp.S
+++ b/sparc/strcmp.S
@@ -11,6 +11,8 @@
 
 .text
 .globl strcmp
+.weak strcoll
+strcoll:
 strcmp:
 	clr %o4
 .Lloop:
diff --git a/sparc64/start.S b/sparc64/start.S
index a79c4e7..a884658 100644
--- a/sparc64/start.S
+++ b/sparc64/start.S
@@ -25,6 +25,17 @@ _start:
 	or	%o3, %lo(environ), %o3
 	stx	%o2, [%o3]
 
+#ifdef WANT_ELFINFO
+#  warning "VERIFY ME!"
+1:	add	%o2, %o2, 8
+	ldx	[%o2-8], %o4
+	orcc	%o4, %o4, %o4
+	bne	1b
+
+	add	%o3, %o3, 8
+	stx	%o2, [%o3]
+#endif
+
 /* When starting a binary via the dynamic linker, %g1 contains the
    address of the shared library termination function, which will be
    registered with atexit(). If we are statically linked, this will
diff --git a/syscalls.s/environ.S b/syscalls.s/environ.S
index a4dd95e..294f2d4 100644
--- a/syscalls.s/environ.S
+++ b/syscalls.s/environ.S
@@ -1,6 +1,7 @@
 .section ".bss"
 .align 8
 #include <endian.h>
+#include <dietfeatures.h>
 
 .type environ,object
 .weak environ
@@ -15,3 +16,18 @@ environ:
 #endif
 .size environ,.-environ
 .size __environ,.-__environ
+
+/* __elfinfo will be initialized in start.S to point to the
+   terminating NULL of the environment. */
+
+#ifdef WANT_ELFINFO
+.type __elfinfo,object
+.weak __elfinfo
+__elfinfo:
+#if __WORDSIZE == 64
+	.quad 0
+#else
+	.long 0
+#endif
+.size __elfinfo,.-__elfinfo
+#endif
diff --git a/syscalls.s/fadvise64.S b/syscalls.s/fadvise64.S
index 89a6eea..23e01e4 100644
--- a/syscalls.s/fadvise64.S
+++ b/syscalls.s/fadvise64.S
@@ -3,15 +3,14 @@
 
 #include "syscalls.h"
 
+#ifdef __NR_fadvise64
+syscall(fadvise64,fadvise64)
+
 #ifndef __NR_fadvise64_64
+posix_fadvise = fadvise64
 .globl posix_fadvise
-.type posix_fadvise,@function
-posix_fadvise:
 #endif
 
-#ifdef __NR_fadvise64
-syscall(fadvise64,fadvise64)
-
 #endif
 
 #endif
diff --git a/syscalls.s/fstatat.S b/syscalls.s/fstatat.S
new file mode 100644
index 0000000..3d6a4ca
--- /dev/null
+++ b/syscalls.s/fstatat.S
@@ -0,0 +1,5 @@
+#include "syscalls.h"
+
+#ifdef __NR_fstatat
+syscall(fstatat,fstatat)
+#endif
diff --git a/syscalls.s/fstatat64.S b/syscalls.s/fstatat64.S
new file mode 100644
index 0000000..3c6370c
--- /dev/null
+++ b/syscalls.s/fstatat64.S
@@ -0,0 +1,5 @@
+#include "syscalls.h"
+
+#ifdef __NR_fstatat64
+syscall(fstatat64,fstatat64)
+#endif
diff --git a/syscalls.s/newfstatat.S b/syscalls.s/newfstatat.S
index daa2714..4dd0a97 100644
--- a/syscalls.s/newfstatat.S
+++ b/syscalls.s/newfstatat.S
@@ -2,4 +2,11 @@
 
 #ifdef __NR_newfstatat
 syscall(newfstatat,newfstatat)
+
+#ifdef __NR_fstatat64
+#  error __NR_newfstatat and __NR_fstatat64 must not be defined both
+#endif
+
+fstatat = newfstatat
+.globl fstatat
 #endif
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..aecfe9d
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,89 @@
+/adjtime
+/alarm
+/argv
+/asctime
+/asprintf
+/atexit
+/atfile
+/bsearch
+/byteswap
+/calloc
+/confstr
+/cycles
+/empty
+/fadvise
+/ffs
+/flush
+/fnmatch
+/fputc
+/ftruncate
+/ftw
+/fwrite
+/getaddrinfo
+/getdelim
+/getenv
+/getgrnam
+/gethostbyaddr
+/gethostbyname
+/gethostbyname_r
+/getmntent
+/getopt
+/getpass
+/getpwnam
+/getservbyname
+/getservbyport
+/getusershell
+/glob
+/grent
+/hasmntopt
+/hello
+/iconv
+/if_nameindex
+/ltostr
+/malloc-debugger
+/math
+/md5_testharness
+/memccpy
+/memchr
+/memcmp
+/memrchr
+/memusage
+/mktime
+/mmap_test
+/pipe
+/printf
+/printftest
+/protoent
+/prototypes
+/putenv
+/pwent
+/rand48
+/read1
+/readdir
+/regex
+/select
+/sendfile
+/servent
+/setjmp
+/siglist
+/sigsetjmp
+/speed
+/spent
+/sprintf
+/sscanf
+/stdarg
+/strcasecmp
+/strcmp
+/strncat
+/strncpy
+/strptime
+/strrchr
+/strstr
+/strtol
+/sysconf
+/sysenter
+/test
+/testing
+/ungetc
+/utime
+/waitpid
diff --git a/test/Makefile b/test/Makefile
index 701ffe2..39105a9 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,14 +7,14 @@ CFLAGS=-nostdinc -Wall
 
 LCOMPAT=-lcompat
 
-TESTPROGRAMS=adjtime alarm argv asprintf atexit bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
-fputc ftw fwrite getaddrinfo getenv getgrnam gethostbyaddr gethostbyname \
+TESTPROGRAMS=adjtime alarm argv asctime asprintf atexit atfile bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
+fputc ftruncate ftw fwrite getaddrinfo getenv getgrnam gethostbyaddr gethostbyname \
 gethostbyname_r getmntent getopt getpass getpwnam getservbyname getservbyport getusershell \
-glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness \
+glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger math md5_testharness \
 memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest \
-protoent prototypes putenv pwent rand48 read1 readdir regex select sendfile servent siglist \
-speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr \
-strstr strtol sysenter ungetc utime waitpid
+protoent prototypes putenv pwent rand48 read1 readdir regex select sendfile servent setjmp siglist \
+sigsetjmp speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr \
+strstr strtol sysconf sysenter ungetc utime waitpid
 
 test: $(TESTPROGRAMS)
 
diff --git a/test/adjtime.c b/test/adjtime.c
index d42d129..8d7a016 100644
--- a/test/adjtime.c
+++ b/test/adjtime.c
@@ -1,9 +1,25 @@
 #include <stdio.h>
+#include <assert.h>
+#include <errno.h>
 #include <sys/time.h>
 
 int main() {
   struct timeval a,b;
+  int rc;
   a.tv_sec=0; a.tv_usec=0;
-  printf("%d\n",adjtime(&a,&b));
+  rc = adjtime(&a,&b);
+  assert(!rc || errno == EPERM);
+
+  rc = adjtime(&a, NULL);
+  assert(!rc || errno == EPERM);
+
+  rc = adjtime(NULL,&b);
+  assert(!rc);
+  assert(b.tv_sec  < 30);	    /* 30 seconds delta is very unlikely... */
+  assert(b.tv_sec  > -30);	    /* 30 seconds delta is very unlikely... */
+  assert(b.tv_usec > -1000000);
+  assert(b.tv_usec < 1000000);
+
+  printf("%lu/%d\n", (unsigned long)b.tv_sec, (int)b.tv_usec);
   return 0;
 }
diff --git a/test/asctime.c b/test/asctime.c
new file mode 100644
index 0000000..f31f537
--- /dev/null
+++ b/test/asctime.c
@@ -0,0 +1,27 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+
+int main(void)
+{
+	char		*buf;
+	struct tm const	tm = {
+		.tm_sec = 20,
+		.tm_min = 21,
+		.tm_hour = 22,
+		.tm_mday = 10,
+		.tm_mon = 11,
+		.tm_year = 112,
+	};
+	char		*res;
+
+	buf = malloc(4096);
+	assert(buf != NULL);
+	memset(buf, 23, 4096);
+
+	res = asctime_r(&tm, buf);
+	assert(strcmp(res, asctime(&tm)) == 0);
+	assert(strcmp(res, "Sun Dec 10 22:21:20 2012\n") == 0);
+
+	return EXIT_SUCCESS;
+}
diff --git a/test/asprintf.c b/test/asprintf.c
index 996a5aa..0d4f2eb 100644
--- a/test/asprintf.c
+++ b/test/asprintf.c
@@ -13,7 +13,7 @@ int main(int argc, char **argv) {
  assert(strlen(path) == asprintlen);
 	     
  printf("%s\n", path);
- asprintlen=asprintf(&path, "/proc" "/%d/stat", strlen(argv[1]));
+ asprintlen=asprintf(&path, "/proc" "/%zu/stat", strlen(argv[1]));
  assert(strlen(path) == asprintlen);
  printf("%s\n", path);
 
diff --git a/test/atexit.c b/test/atexit.c
index 709a3e4..79ee392 100644
--- a/test/atexit.c
+++ b/test/atexit.c
@@ -2,7 +2,7 @@
 #include <unistd.h>
 
 void blah(void) {
-  write(2,"atexit\n",7);
+  write(1,"atexit\n",7);
 }
 
 int main() {
diff --git a/test/atfile.c b/test/atfile.c
new file mode 100644
index 0000000..cb25379
--- /dev/null
+++ b/test/atfile.c
@@ -0,0 +1,111 @@
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 700
+#define _FILE_OFFSET_BITS 64
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#define TMPDIR	"/tmp"
+
+#define TEST(_op)	do {						\
+		int rc = (_op);						\
+		if (rc < 0) {						\
+			printf("%s:%u: %s: %u/%s\n", __FILE__, __LINE__,	\
+			       # _op, errno, strerror(errno));		\
+			abort();					\
+		}							\
+	} while (0)
+
+#define memeq(_a, _b) \
+	((memcmp(_a, _b, sizeof *(_a)) == 0 ? 0 : -1))
+
+#define memne(_a, _b) \
+	((memcmp(_a, _b, sizeof *(_a)) == 0 ? -1 : 0))
+
+int main(void)
+{
+	char dname_buf[] = "/tmp/test-mmap.XXXXXX";
+	char *dname;
+	int dir_fd;
+	int file_fd;
+	struct stat st[5];
+
+	/* check whether *at(2) syscalls are available */
+	dir_fd = openat(AT_FDCWD, "/", O_DIRECTORY|O_RDONLY);
+	if (dir_fd == -1 && errno == ENOSYS)
+		return EXIT_SUCCESS;	/* kernel too old */
+
+	assert(dir_fd != -1);
+	close(dir_fd);
+
+	/* create a tree like
+	 * /
+	 * +- tmp/
+	 *    +- <tmpname>/
+	 *       |- test/
+	 *       |- some-file
+	 *       +- some-link -> some-file
+	 */
+	dname = mkdtemp(dname_buf);
+	assert(dname != NULL);
+
+	dir_fd = open(dname, O_DIRECTORY|O_RDONLY);
+	assert(dir_fd != -1);
+
+	TEST(mkdirat(dir_fd, "test", 0700));
+	TEST(chdir(dname));
+	TEST(chdir("test"));
+
+	file_fd = openat(dir_fd, "some-file", O_WRONLY|O_CREAT, 0400);
+	assert(file_fd != -1);
+
+	write(file_fd, "some text\n", 10);
+	TEST(close(file_fd));
+
+	TEST(symlinkat("some-file", dir_fd, "some-link"));
+	TEST(symlinkat("dangling", dir_fd, "dangling-link"));
+
+	/* now check, whether attributes of 'some-file' and 'some-link'
+	 * returned by stat(2), lstat(2) and fstatat(2) are consistent */
+	TEST(stat("../some-file", &st[0]));
+	TEST(lstat("../some-link", &st[1]));
+
+	TEST(fstatat(dir_fd, "some-file", &st[2], 0));
+	TEST(fstatat(dir_fd, "some-link", &st[3], AT_SYMLINK_NOFOLLOW));
+	TEST(fstatat(dir_fd, "some-link", &st[4], 0));
+
+	TEST(faccessat(dir_fd, "some-file", R_OK, 0));
+	TEST((faccessat(dir_fd, "some-file", W_OK, 0) == -1 &&
+	      errno == EACCES) ? 0 : -1);;
+
+	if (1)
+		fputs("skipping faccessat(..., AT_SYMLINK_NOFOLLOW) checks for now...\n",
+		      stderr);
+	else {
+		/* this is broken for dietlibc; the 'flags' parameter is not checked
+		 * by the kernel but must be handled by the libc itself */
+		TEST(faccessat(dir_fd, "some-link", W_OK, AT_SYMLINK_NOFOLLOW));
+		TEST(faccessat(dir_fd, "dangling-link", R_OK, AT_SYMLINK_NOFOLLOW));
+	}
+
+	assert(st[0].st_mode == (0400 | S_IFREG));
+	assert(S_ISLNK(st[1].st_mode));
+
+	TEST(memne(&st[0], &st[1]));
+	TEST(memeq(&st[0], &st[2]));
+	TEST(memeq(&st[0], &st[4]));
+	TEST(memeq(&st[1], &st[3]));
+
+	/* and cleanup the mess... */
+	TEST(unlinkat(dir_fd, "some-link", 0));
+	TEST(unlinkat(dir_fd, "some-file", 0));
+	TEST(unlinkat(dir_fd, "dangling-link", 0));
+	TEST(unlinkat(dir_fd, "test", AT_REMOVEDIR));
+	TEST(rmdir(dname));
+
+	return EXIT_SUCCESS;
+}
diff --git a/test/byteswap.c b/test/byteswap.c
index 19239dd..6f43c25 100644
--- a/test/byteswap.c
+++ b/test/byteswap.c
@@ -9,12 +9,12 @@ int main() {
   snprintf(buf,100,"%x %x", bswap_16(0x1234), bswap_16(0x5678));
   assert(strcmp(buf, "3412 7856") == 0);
   
-  printf("%lx\n",bswap_32(0x12345678));
-  snprintf(buf,100,"%lx", bswap_32(0x12345678));
+  printf("%x\n",(unsigned int)bswap_32(0x12345678));
+  snprintf(buf,100,"%x", (unsigned int)bswap_32(0x12345678));
   assert(strcmp(buf, "78563412") == 0);
 
-  printf("%qx\n",bswap_64(0x123456789ABCDEFull));
-  snprintf(buf,100,"%qx", bswap_64(0x123456789ABCDEFull));
+  printf("%llx\n",(unsigned long long)bswap_64(0x123456789ABCDEFull));
+  snprintf(buf,100,"%llx", (unsigned long long)bswap_64(0x123456789ABCDEFull));
   assert(strcmp(buf, "efcdab8967452301") == 0);
   return 0; 
 }
diff --git a/test/cycles.c b/test/cycles.c
index 35547f8..66b3d04 100644
--- a/test/cycles.c
+++ b/test/cycles.c
@@ -12,8 +12,21 @@
   asm volatile ("rdtsc" : "=a" (l), "=d" (h)); \
   dst = (((uint64_t)h) << 32) | l;                             \
 } while (0)
+#elif defined (__powerpc64__)
+#define RDTSC(dst) asm volatile ("mftb %0" : "=r" (dst))
+#elif defined (__powerpc__)
+#define RDTSC(dst) do { \
+  uint32_t chk, tbl, tbu; \
+  /* The code below is as suggested in Motorola reference manual for 32 bits PPCs. */ \
+  __asm__ __volatile__ ("1: mftbu %0; mftb %1; mftbu %2; cmpw %2,%0; bne 1b" \
+    : "=r" (tbu), "=r" (tbl), "=r" (chk) ); \
+  dst = ((uint64_t)tbu << 32) | tbl; \
+} while (0)
+#elif defined (__sparcv9__)
+#define RDTSC(dst) asm volatile ("rd %%tick, %%0":"=r"(dst))
 #else
-#error "Unimplemented rdtsc"
+#warning "Unimplemented rdtsc"
+#define RDTSC(dst) dst = 0
 #endif
 
 extern char **environ;
@@ -24,7 +37,7 @@ int main(int argc,char* argv[]) {
   if (!fork()) { execve(argv[1],argv+1,environ); exit(1); }
   wait(0);
   RDTSC(b);
-  printf("%llu cycles\n",b-a);
+  printf("%llu cycles\n",(unsigned long long)(b-a));
 
   return 0;
 }
diff --git a/test/dirent/.gitignore b/test/dirent/.gitignore
new file mode 100644
index 0000000..eea7a22
--- /dev/null
+++ b/test/dirent/.gitignore
@@ -0,0 +1,2 @@
+/opendir-tst1
+/tst-seekdir
diff --git a/test/ftruncate.c b/test/ftruncate.c
new file mode 100644
index 0000000..e0ebb5d
--- /dev/null
+++ b/test/ftruncate.c
@@ -0,0 +1,54 @@
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 600
+#define _FILE_OFFSET_BITS 64
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#define CHECK(_sz)				\
+  assert(ftruncate(fd, (_sz)) == 0);		\
+  assert(fstat(fd, &st) == 0);			\
+  assert(st.st_size == (_sz));			\
+
+#define CHECK64(_sz)				\
+  assert(ftruncate64(fd, (_sz)) == 0);		\
+  assert(fstat64(fd, &st64) == 0);		\
+  assert(st64.st_size == (_sz));		\
+
+int main(void)
+{
+  char file[] = "/tmp/dietlibc-fadvise-test.XXXXXX";
+  int fd;
+  struct stat st;
+
+  fd = mkstemp(file);
+  unlink(file);
+
+  assert(ftruncate(fd, 500000) == 0);
+  assert(fstat(fd, &st) == 0);
+
+  if (st.st_blocks > 1) {
+    /* spare files not supported by filesystem :( */
+    return EXIT_SUCCESS;
+  }
+
+  CHECK(1);
+  CHECK(0x7fffffff);
+
+#if __WORDSIZE == 32
+  {
+    struct stat64 st64;
+    CHECK64(1);
+    CHECK64(0x7fffffff);
+    CHECK64(0x80000001ul);
+    CHECK64(0x17fffffffull);
+  }
+#else
+  CHECK(0x17fffffffull);
+#endif
+
+  return EXIT_SUCCESS;
+}
diff --git a/test/getmntent.c b/test/getmntent.c
index fc17a83..1039d06 100644
--- a/test/getmntent.c
+++ b/test/getmntent.c
@@ -33,10 +33,6 @@ while ((e = getmntent(fstab))) {
 
  printf("closing /etc/fstab\n");
  assert ( 1 == endmntent(fstab));
- printf("closing /etc/fstab again\n");
- assert ( 1 == endmntent(fstab)); /* endmntent must always return 1 */
- printf("entmntent(0)\n");
- assert ( 1 == endmntent(0)); /* causes a segfault with diet libc */
+
  return 0;
 }
-
diff --git a/test/getservbyname.c b/test/getservbyname.c
index b70ca19..caf1c9f 100644
--- a/test/getservbyname.c
+++ b/test/getservbyname.c
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <netdb.h>
+#include <arpa/inet.h>
 
 int main(int argc,char *argv[]) {
   struct servent* se;
diff --git a/test/if_nameindex.c b/test/if_nameindex.c
index b3c8b22..0c171f8 100644
--- a/test/if_nameindex.c
+++ b/test/if_nameindex.c
@@ -1,8 +1,12 @@
 #include <stdio.h>
+#include <assert.h>
 #include <net/if.h>
 
 int main() {
   struct if_nameindex* t=if_nameindex();
+
+  assert(t != NULL);
+
   if (t) {
     struct if_nameindex* t1=t;
     while (t->if_index) {
diff --git a/test/inet/.gitignore b/test/inet/.gitignore
new file mode 100644
index 0000000..64ef77a
--- /dev/null
+++ b/test/inet/.gitignore
@@ -0,0 +1,3 @@
+/test_ifindex
+/tst-gethnm
+/tst-ntoa
diff --git a/test/malloc-debugger.c b/test/malloc-debugger.c
index 040196e..058807e 100644
--- a/test/malloc-debugger.c
+++ b/test/malloc-debugger.c
@@ -4,7 +4,7 @@
 int main() {
   char* c=malloc(13);
   char* tmp;
-  fprintf(stderr,"got %p\n",c);
+  fprintf(stdout,"got %p\n",c);
   c[0]=14;
 //  c[15]=0;
   tmp=realloc(c,12345);
diff --git a/test/math.c b/test/math.c
new file mode 100644
index 0000000..687103c
--- /dev/null
+++ b/test/math.c
@@ -0,0 +1,29 @@
+#include <math.h>
+#include <float.h>
+#include <assert.h>
+
+int main()
+{
+  extern int __isinf(double d);
+  extern int __isnan(double d);
+
+#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))
+  assert(__isinf(__builtin_inff())  == +1);
+  assert(__isinf(-__builtin_inff()) == -1);
+
+  assert(__isinf(__builtin_inf())   == +1);
+  assert(__isinf(-__builtin_inf())  == -1);
+
+  assert(__isnan(__builtin_nan("")));
+#endif
+
+  assert(__isinf((DBL_MAX * DBL_MAX))  == +1);
+  assert(__isinf(-(DBL_MAX * DBL_MAX)) == -1);
+
+  assert(isinf((DBL_MAX * DBL_MAX)));
+  assert(isinf(-(DBL_MAX * DBL_MAX)));
+
+  //assert(isnan(nan("")));
+
+  return 0;
+}
diff --git a/test/mktime.c b/test/mktime.c
index 5e9e65c..9b4bd5e 100644
--- a/test/mktime.c
+++ b/test/mktime.c
@@ -9,15 +9,15 @@ int main() {
   t.tm_mday=29;
   t.tm_mon=2;
   t.tm_year=100;
-  printf("%d\n",mktime(&t));
+  printf("%ld\n",(long)mktime(&t));
   t.tm_mday=1;
   t.tm_mon=3;
   t.tm_year=102;
-  printf("%d\n",mktime(&t));
+  printf("%ld\n",(long)mktime(&t));
   t.tm_mday=1;
   t.tm_mon=6;
   t.tm_year=102;
-  printf("%d\n",mktime(&t));
+  printf("%ld\n",(long)mktime(&t));
   return 0;
 }
 
diff --git a/test/mmap_test.c b/test/mmap_test.c
index 1fc2616..acd5665 100644
--- a/test/mmap_test.c
+++ b/test/mmap_test.c
@@ -1,12 +1,13 @@
-
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <errno.h>
 
-#define FILENAME   "/tmp/zz_temp_mmap_test"
-#define TESTSTRING "This is a test string"
+#define TESTSTRING0 "This is a test string"
+#define TESTSTRING1 "Another string for testing"
 
 
 int main (int argc, char * argv[])
@@ -14,16 +15,26 @@ int main (int argc, char * argv[])
    int fd;
    void *filememory_1;
    void *filememory_2;
-   
-   fd = open (FILENAME, O_RDWR | O_CREAT);
-   
+   void *filememory_3;
+   unsigned int pg_sz = sysconf(_SC_PAGESIZE);
+   char fname[] = "/tmp/test-mmap.XXXXXX";
+
+   fd = mkstemp(fname);
    if (fd < 0)
    {
-      fprintf (stderr, "Couldn't open %s for writing\n", FILENAME);
+      fprintf (stderr, "Couldn't open %s for writing\n", fname);
       return (1);
    }
 
-   write (fd, TESTSTRING, sizeof(TESTSTRING));
+   unlink(fname);
+
+   write (fd, TESTSTRING0, sizeof TESTSTRING0);
+
+   ftruncate(fd, pg_sz);
+   lseek(fd, pg_sz, SEEK_SET);
+   write(fd, TESTSTRING1, sizeof TESTSTRING1);
+
+   ftruncate(fd, 2*pg_sz);
 
    /*
       Try mmapping the newly created file...
@@ -38,6 +49,18 @@ int main (int argc, char * argv[])
    }
 
    /*
+      Test mapping at a given offset
+    */
+
+   filememory_3 = mmap (NULL, 0x0100, PROT_READ, MAP_PRIVATE, fd, pg_sz);
+
+   if (filememory_3 == (void *) -1)
+   {
+      perror("mmap (pg_sz) returned error");
+      return (1);
+   }
+
+   /*
       Try mmapping with a bogus file descriptor... (should fail)
    */
 
@@ -49,32 +72,33 @@ int main (int argc, char * argv[])
       return (1);
    }
    
-   close (fd);
-
    /*
       Check that we can read back from the file OK
    */
 
-   if ((*(unsigned char *) filememory_1) != TESTSTRING[0])
+   if (memcmp(filememory_1, TESTSTRING0, sizeof TESTSTRING0) != 0)
    {
       fprintf (stderr, "mmap doesn't give expected data...\n");
       return (1);
    }
-   
-   /*
-      fixme: check unmapping as well.... ??
-   */
 
+   if (memcmp(filememory_3, TESTSTRING1, sizeof TESTSTRING1) != 0)
+   {
+      fprintf (stderr, "mmap (pg_sz) doesn't give expected data...\n");
+      return (1);
+   }
+
+   if (munmap(filememory_3, 0x0100) < 0 ||
+       munmap(filememory_1, 0x0100) < 0)
+   {
+      perror("munmap()");
+      return 1;
+   }
 
    /*
       Clean up.
    */
-
-   if (unlink (FILENAME) != 0)
-   {
-      fprintf (stderr, "Unexpected problem deleting the tempfile... ?\n");
-      return (1);
-   }
+   close (fd);
 
    return (0);
 }
diff --git a/test/pipe.c b/test/pipe.c
index fb6ba31..315b4ca 100644
--- a/test/pipe.c
+++ b/test/pipe.c
@@ -5,6 +5,9 @@ int
 main (void)
 {
 	int fd[2];
+	close(3);
+	close(4);
+
 	assert (!pipe (fd));
 	/* if for some reason the parent process has fd3 or fd4
 	   already open, then this will fail although there is
diff --git a/test/printf.c b/test/printf.c
index 719461a..ef6050d 100644
--- a/test/printf.c
+++ b/test/printf.c
@@ -2,11 +2,26 @@
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <math.h>
+#include <float.h>
 #include <sys/param.h>
 #include <locale.h>
 
 #define ALGN		5
 
+#ifndef INFINITY
+#  if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))
+#    define INFINITY	(__builtin_inf())
+#  endif
+#endif
+
+#ifndef NAN
+#  if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))
+#    define NAN		(__builtin_nan(""))
+#  endif
+#endif
+
+
 // https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=112986
 #if 0
 #undef  assert
@@ -60,7 +75,7 @@
   TEST_SNPRINTF(EXP,  0,                __VA_ARGS__);		\
   TEST_SNPRINTF(EXP,  sizeof(EXP)+ALGN, __VA_ARGS__);		\
   TEST_SNPRINTF_NULL(EXP, __VA_ARGS__)
-  
+
 
 int main()
 {
@@ -101,7 +116,7 @@ int main()
   TEST("42.23",   "%5.2f",  42.23);
   TEST("42.23",   "%5.4g",  42.23);
   TEST(" 42.2",   "%5.3g",  42.23);
-  
+
   TEST("   1",     "%*i",   4, 1);
   TEST("   1",     "%4i",   1);
   TEST("1   ",     "%-4i",  1);
@@ -131,13 +146,32 @@ int main()
   TEST("-01234",   "%6.5i", -1234);
   TEST("  1234",   "%6.5s", "1234");
 
+#ifdef INFINITY
+  TEST("inf",	"%f", INFINITY);
+  TEST("-inf",	"%f", -INFINITY);
+  TEST("INF",	"%F", INFINITY);
+  TEST("-INF",	"%F", -INFINITY);
+
+  TEST("inf",	"%g", INFINITY);
+  TEST("-inf",	"%g", -INFINITY);
+  TEST("INF",	"%G", INFINITY);
+  TEST("-INF",	"%G", -INFINITY);
+#endif
+
+#ifdef NAN
+  TEST("nan",	"%f", NAN);
+  TEST("NAN",	"%F", NAN);
+  TEST("nan",	"%g", NAN);
+  TEST("NAN",	"%G", NAN);
+#endif
+
 #ifdef XSI_TESTS
   setlocale(LC_ALL, "de_DE");
-  
+
   TEST("1.234",    "%'u", 1234);
   TEST("2 1",      "%2$u %1$u",  1, 2);
 #endif
-  
-  
+
+
   return EXIT_SUCCESS;
 }
diff --git a/test/printftest.c b/test/printftest.c
index 4743279..47d9580 100644
--- a/test/printftest.c
+++ b/test/printftest.c
@@ -101,8 +101,8 @@ int main()
   printf("#%i#\n",18);
   printf("#%d#\n",18);
   printf("#%u#\n",18);
-  printf("#%lu#\n",18);
-  printf("#%li#\n",18);
+  printf("#%lu#\n",18l);
+  printf("#%li#\n",18l);
   printf("#%-+#06d#\n", -123);
   printf("#%-+#6d#\n", -123);
   printf("#%+#06d#\n", -123);
@@ -142,7 +142,7 @@ int main()
 	    buf);
     memset(buf2,0,sizeof(buf));
     i=snprintf(buf2, 256, "%.9999u", 10);
-    printf("%i %i\n",i,strlen(buf2));
+    printf("%i %li\n",i,strlen(buf2));
     
     printf ("snprintf (\"%%.999999u\", 10) == %d\n",
     	    snprintf(buf2, sizeof(buf2), "%.999999u", 10));
diff --git a/test/rand48.c b/test/rand48.c
index 4f5b08f..1e67632 100644
--- a/test/rand48.c
+++ b/test/rand48.c
@@ -6,16 +6,16 @@ main (void)
 {
   static unsigned short  data[7] = { 1, 2, 3, 4, 5, 6, 7 };
 
-  printf ("one   %X\n", mrand48 ());
-  printf ("two   %X\n", mrand48 ());
-  printf ("three %X\n", mrand48 ());
+  printf ("one   %lX\n", mrand48 ());
+  printf ("two   %lX\n", mrand48 ());
+  printf ("three %lX\n", mrand48 ());
 
   lcong48 (data);
   printf ("after lcong48:\n");
 
-  printf ("one   %X\n", mrand48 ());
-  printf ("two   %X\n", mrand48 ());
-  printf ("three %X\n", mrand48 ());
+  printf ("one   %lX\n", mrand48 ());
+  printf ("two   %lX\n", mrand48 ());
+  printf ("three %lX\n", mrand48 ());
 
   return 0;
 }
diff --git a/test/runtests-X.sh b/test/runtests-X.sh
new file mode 100644
index 0000000..93842e6
--- /dev/null
+++ b/test/runtests-X.sh
@@ -0,0 +1,117 @@
+#! /bin/bash
+
+eval $(grep '^\(SUBDIRS\)=' runtests.sh)
+eval $(make --no-print-directory \
+       --eval 'print-tests:;@echo TESTPROGRAMS=\"$(sort $(TESTPROGRAMS))\"' print-tests)
+
+SKIP=(
+  ":asprintf"			# requires special cmdline
+  ":getpass"			# expects input from TTY
+  ":read1"			# expects input
+  ":stdio:tst-ferror"		# expects input
+  ":stdio:tstscanf"		# expects input
+  ":stdlib:testdiv"		# expects input
+)
+
+FAILURES_BOGUS=(
+  ":gethostbyname"		# network test; net might not be available in test environment
+  ":gethostbyname_r"		# network test; net might not be available in test environment
+
+  ":stdlib:tst-environ"		# test uses environ function in unsupported ways (dup keys)
+  ":stdlib:tst-rand48"		# platform dependent; does not give reliable results
+  ":stdlib:tst-strtod"		# infinite recursion in __dtostr()
+  ":time:tst-mktime"		# dietlibc does not support $TZ env
+  ":time:tst-posixtz"		# dietlibc does not support $TZ env
+  ":time:tst-strftime"		# dietlibc does not support glibc specific format specifications
+)
+
+FAILURES_BOGUS_emulator=(
+  ":adjtime"			# ajdtimex() not implement in qemu
+  ":if_nameindex"		# ioctls not implement in qemu
+  ":mmap_test"			# qemu does not pass back mmap(2) error codes
+  ":fadvise"			# bad translation of 64bit args in qemu
+  ":stdio:tst-fseek"		# !! unclear; must be investigated
+  ":dirent:tst-seekdir"		# 32/64 bit issue when calling lseek()
+)
+
+FAILURES_KNOWN=(
+  ":sendfile"			# stdin/stdout not supported; test must be wrapped
+  ":stdio:tstdiomisc"		# scanf(3) fails on some constructs
+  ":stdio:tst-fphex"		# printf(3) does not support %a specifiers
+  ":stdio:tst-printf"		# printf(3) does not support some floating point ops
+  ":stdio:tst-sscanf"		# scanf(3) fails on double input
+  ":stdlib:test-canon"		# realpath(3) is broken...
+)
+
+function is_in() {
+    local	val=$1
+    local	i
+    shift
+
+    for i; do
+	test x"$i" != x"$val" || return 0
+    done
+    return 1
+}
+
+rc=0
+
+: ${ME:=${BASH_SOURCE[0]}}
+: ${EMULATOR:=}
+: ${RUNTEST_INDENT=0}
+export ME
+export RUNTEST_INDENT
+export RUNTEST_NS
+
+case $ME in
+  /*) ;;
+  *) ME=`pwd`/$ME;;
+esac
+
+test -z "$EMULATOR" || \
+    FAILURES_BOGUS=( "${FAILURES_BOGUS[@]}" "${FAILURES_BOGUS_emulator[@]}" )
+
+for p in $TESTPROGRAMS; do
+    ! tty -s || printf '%*s%-20s' $RUNTEST_INDENT '' "$p"
+
+    is_in "$RUNTEST_NS:$p" "${FAILURES_BOGUS[@]}" && fail_bogus=true || fail_bogus=false
+    is_in "$RUNTEST_NS:$p" "${FAILURES_KNOWN[@]}" && fail_known=true || fail_known=false
+
+    if is_in "$RUNTEST_NS:$p" "${SKIP[@]}"; then
+	res='SKIPPED'
+    else
+	$EMULATOR ./$p >/dev/null && failed=false || failed=true
+
+	case $failed:$fail_known:$fail_bogus in
+	  (false:false:*)	res='OK';;
+	  (false:true:true)	res='OK (bogus)';;
+	  (false:true:false)	res="OK (unexpected)"; let ++rc;;
+	  (true:*:true)		res='FAIL (bogus)';;
+	  (true:true:*)		res="FAIL (known)";;
+	  (true:false:*)	res='FAIL'; let ++rc;;
+	esac
+    fi
+
+    ! tty -s || printf '\r'
+
+    printf '%*s%-20s%s\n' $RUNTEST_INDENT '' "$p" "$res"
+done
+
+test $rc -eq 0 || \
+    printf "%*s--> %u tests failed\n" $RUNTEST_INDENT '' $rc
+
+for d in $SUBDIRS; do
+    echo "--- entering directory $d ---"
+    let RUNTEST_INDENT+=2
+    old_ns=$RUNTEST_NS
+    RUNTEST_NS=$RUNTEST_NS:$d
+
+    cd $d && bash $ME || let ++rc
+
+    RUNTEST_NS=$old_ns
+    let RUNTEST_INDENT-=2
+
+    cd $OLDPWD || exit 1
+done
+
+test $rc -eq 0 && exit 0 || exit 1
diff --git a/test/runtests.sh b/test/runtests.sh
index d6fb19b..444f8c8 100644
--- a/test/runtests.sh
+++ b/test/runtests.sh
@@ -1,6 +1,6 @@
 SUBDIRS="dirent inet stdio string stdlib time"
 
-TESTPROGRAMS="adjtime alarm argv atexit bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent siglist speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysenter ungetc utime waitpid"
+TESTPROGRAMS="adjtime alarm argv asctime atexit atfile bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftruncate ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger math md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent setjmp siglist sigsetjmp speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysconf sysenter ungetc utime waitpid"
 
 STDIN="read1"
 PASS="getpass" 
diff --git a/test/sendfile.c b/test/sendfile.c
index d43cdd2..28b3af5 100644
--- a/test/sendfile.c
+++ b/test/sendfile.c
@@ -11,5 +11,5 @@ int main() {
 
   printf("sendfile returned %d\n",ret);
 
-return 0;    
+  return ret<0 ? 1 : 0;
 }
diff --git a/test/setjmp.c b/test/setjmp.c
new file mode 100644
index 0000000..15951e5
--- /dev/null
+++ b/test/setjmp.c
@@ -0,0 +1,106 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+static int Xmemcmp(void const volatile *a, void const volatile *b, size_t l)
+{
+  return memcmp((void const *)a, (void const *)b, l);
+}
+
+int main(void)
+{
+  char volatile a[8] = "testbufA";
+  jmp_buf env;
+  char volatile b[8] = "testbufB";
+
+  assert(Xmemcmp(a, "testbufA", 8) == 0);
+  assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+
+  /* Test 1: not calling longjmp */
+  if (setjmp(env) == 0) {
+    char volatile somebuf[128];
+
+    memset((void *)somebuf, 0xde, sizeof somebuf);
+
+    assert(Xmemcmp(a, "testbufA", 8) == 0);
+    assert(Xmemcmp(b, "testbufB", 8) == 0);
+  } else
+    assert(0);
+
+  assert(Xmemcmp(a, "testbufA", 8) == 0);
+  assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+
+  /* Test 2: calling longjmp */
+  switch (setjmp(env)) {
+  case 0: {
+    char volatile somebuf[128];
+
+    memset((void *)somebuf, 0xde, sizeof somebuf);
+
+    assert(Xmemcmp(a, "testbufA", 8) == 0);
+    assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+    longjmp(env, 23);
+
+    a[0] = 'X';
+    b[0] = 'X';
+  }
+
+  case 23:
+    break;
+
+  default:
+    assert(0);
+  }
+
+  assert(Xmemcmp(a, "testbufA", 8) == 0);
+  assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+
+  /* Test 3: calling longjmp again with dirty env */
+  switch (setjmp(env)) {
+  case 0: {
+    char volatile somebuf[128];
+
+    memset((void *)somebuf, 0xde, sizeof somebuf);
+
+    assert(Xmemcmp(a, "testbufA", 8) == 0);
+    assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+    longjmp(env, 23);
+
+    a[0] = 'X';
+    b[0] = 'X';
+  }
+
+  case 23:
+    break;
+
+  default:
+    assert(0);
+  }
+
+  assert(Xmemcmp(a, "testbufA", 8) == 0);
+  assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+
+ /* Test 4: not calling longjmp, but dirty env */
+  if (setjmp(env) == 0) {
+    char volatile somebuf[128];
+
+    memset((void *)somebuf, 0xde, sizeof somebuf);
+
+    assert(Xmemcmp(a, "testbufA", 8) == 0);
+    assert(Xmemcmp(b, "testbufB", 8) == 0);
+  } else
+    assert(0);
+
+  assert(Xmemcmp(a, "testbufA", 8) == 0);
+  assert(Xmemcmp(b, "testbufB", 8) == 0);
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/test/sigsetjmp.c b/test/sigsetjmp.c
new file mode 100644
index 0000000..e289922
--- /dev/null
+++ b/test/sigsetjmp.c
@@ -0,0 +1,206 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+
+#define TEST_PATTERN	\
+	"0123456789abcdefghijklmnopqrstuv"	\
+	"ZYXWVUTSRQPONMLKJIHGFEDCBA987654"	\
+	"456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"	\
+	"vutsrqponmlkjihgfedcba9876543210"	\
+	"0123456789ABCDEFGHIJKLMNOPQRSTUV"	\
+	"zyxwvutsrqponmlkjihgfedcba987654"	\
+	"456789abcdefghijklmnopqrstuvwxyz"	\
+	"VUTSRQPONMLKJIHGFEDCBA987654321"	\
+
+static struct {
+	char volatile a[256];
+	sigjmp_buf env;
+	char volatile b[256];
+} sigenv = {
+	.a = TEST_PATTERN "<",
+	.b = TEST_PATTERN ">",
+};
+
+static double const volatile	FP_REF[] = {
+  0.4, 0.8, 1.5, 1.6, 2.3, 4.2
+};
+
+static int volatile sig_seen;
+
+#define VALIDATE_BUFFERS(_sig_exp) do {		\
+    assert(Xmemcmp(sigenv.a, TEST_PATTERN "<", sizeof sigenv.a) == 0);	\
+    assert(Xmemcmp(sigenv.b, TEST_PATTERN ">", sizeof sigenv.b) == 0);	\
+    assert(sig_seen == (_sig_exp));		\
+  } while (0)
+
+static int Xmemcmp(void const volatile *a, void const volatile *b, size_t l)
+{
+  return memcmp((void const *)a, (void const *)b, l);
+}
+
+static void do_test(int sig_num, int do_save, int block_sig)
+{
+  int		rc;
+  sigset_t	block_set;
+  sigset_t	cur_set;
+
+  printf("%s(%d,%d,%d)... ", __func__, sig_num, do_save, block_sig);
+  fflush(stdout);
+
+  VALIDATE_BUFFERS(0);
+
+  sigemptyset(&block_set);
+  assert(sigprocmask(SIG_SETMASK, NULL, &cur_set) == 0);
+
+  /* verify that tested signal is not blocked */
+  if (sig_num != 0)
+    assert(!sigismember(&cur_set, sig_num));
+
+  /* verify that blocked signal is not already blocked and fill signal set */
+  if (block_sig != 0) {
+    assert(!sigismember(&cur_set, block_sig));
+    sigaddset(&block_set, block_sig);
+  }
+
+  sig_seen = 0;
+  rc = sigsetjmp(sigenv.env, do_save);
+  if (rc == 0) {
+    char volatile somebuf[128];
+
+    memset((void *)somebuf, 0x42, sizeof somebuf);
+    VALIDATE_BUFFERS(0);
+
+    /* modify signal mask */
+    if (block_sig != 0)
+      assert(sigprocmask(SIG_BLOCK, &block_set, NULL) == 0);
+
+    /* raise a signal which triggers a siglongjmp */
+    if (sig_num != 0) {
+      raise(sig_num);
+      sigenv.a[0] = 'X';
+      sigenv.b[0] = 'X';
+      assert(0);
+    }
+  } else if (rc != sig_num)
+    /* sigsetjmp() returned with an unexpected value */
+    assert(0);
+
+  VALIDATE_BUFFERS(sig_num);
+  sig_seen = 0;
+
+  /* check whether current signal mask contains the blocked signal; it should
+     be there iff sigsetjmp() was triggered and sigmask was saved. */
+  if (block_sig != 0) {
+    sigset_t	cur_set;
+    assert(sigprocmask(SIG_SETMASK, NULL, &cur_set) == 0);
+
+    if (do_save && rc != 0)
+      assert(!sigismember(&cur_set, block_sig));
+    else {
+      assert( sigismember(&cur_set, block_sig));
+      sigprocmask(SIG_UNBLOCK, &block_set, NULL);
+    }
+  }
+
+  printf(" ok\n");
+};
+
+static void do_test_fp(int sig_num, int do_save)
+{
+  sigset_t	cur_set;
+  int		rc;
+  double	fp0, fp1, fp2, fp3;
+
+  printf("%s(%d,%d)... ", __func__, sig_num, do_save);
+  fflush(stdout);
+
+  VALIDATE_BUFFERS(0);
+
+  assert(sigprocmask(SIG_SETMASK, NULL, &cur_set) == 0);
+
+  /* verify that tested signal is not blocked */
+  if (sig_num != 0)
+    assert(!sigismember(&cur_set, sig_num));
+
+  fp0 = FP_REF[0];
+  fp1 = FP_REF[1];
+  fp2 = FP_REF[2];
+  fp3 = FP_REF[3];
+
+  sig_seen = 0;
+  rc = sigsetjmp(sigenv.env, do_save);
+
+  if (rc == 0) {
+    fp0 = FP_REF[4];
+    fp3 = FP_REF[5];
+
+    if (sig_num != 0) {
+      raise(sig_num);
+      assert(0);
+    }
+  } else if (rc != sig_num)
+    /* sigsetjmp() returned with an unexpected value */
+    assert(0);
+
+  if (sig_num == 0) {
+    /* "exception" was not triggered; we should see the new values */
+    assert(fp0 == FP_REF[4]);
+    assert(fp1 == FP_REF[1]);
+    assert(fp2 == FP_REF[2]);
+    assert(fp3 == FP_REF[5]);
+  } else {
+    /* "exception" was triggered; we should see the old values */
+    assert(fp0 == FP_REF[0]);
+    assert(fp1 == FP_REF[1]);
+    assert(fp2 == FP_REF[2]);
+    assert(fp3 == FP_REF[3]);
+  }
+
+  VALIDATE_BUFFERS(sig_num);
+  sig_seen = 0;
+
+  printf(" ok\n");
+}
+
+static void sig_handler(int num)
+{
+  assert(sig_seen == 0);
+  sig_seen = num;
+  siglongjmp(sigenv.env, num);
+}
+
+int main(void)
+{
+  struct sigaction sigact = {
+    .sa_handler	= sig_handler,
+    .sa_flags	= SA_NODEFER, /* raised signal will be in blocked mask else */
+  };
+
+  /* verify our assumptions about the memory layout */
+  assert(sizeof sigenv.a == 256);
+  assert(sizeof sigenv.b == 256);
+  assert(offsetof(__typeof__(sigenv), env) == sizeof sigenv.a);
+  assert(offsetof(__typeof__(sigenv), b)   == sizeof sigenv.a + sizeof sigenv.env);
+
+  sigaction(SIGBUS,  &sigact, NULL);
+  sigaction(SIGUSR1, &sigact, NULL);
+
+  do_test(0, 0, 0);
+  do_test(0, 0, SIGUSR1);
+  do_test(0, 1, 0);
+  do_test(0, 1, SIGUSR1);
+  do_test(SIGBUS, 0, 0);
+  do_test(SIGBUS, 0, SIGUSR1);
+  do_test(SIGBUS, 1, 0);
+  do_test(SIGBUS, 1, SIGUSR1);
+
+  do_test_fp(0, 0);
+  do_test_fp(0, 1);
+  do_test_fp(SIGBUS, 0);
+  do_test_fp(SIGBUS, 1);
+
+  return EXIT_SUCCESS;
+}
diff --git a/test/speed.c b/test/speed.c
index 674b9a8..22249a7 100644
--- a/test/speed.c
+++ b/test/speed.c
@@ -7,10 +7,10 @@ int main() {
   int i;
   time_t t;
   
-  printf("%d\n", time(0));
+  printf("%ld\n", (long)time(0));
   for (i=0; i<10000000; ++i)
     t=time(0);
 
- printf("%d\n", time(0));
+  printf("%ld\n", (long)time(0));
  return 0;   
 }
diff --git a/test/stdio/.gitignore b/test/stdio/.gitignore
new file mode 100644
index 0000000..8892d20
--- /dev/null
+++ b/test/stdio/.gitignore
@@ -0,0 +1,14 @@
+/tst-fdopen
+/tst-ferror
+/tst-fileno
+/tst-fphex
+/tst-fseek
+/tst-printf
+/tst-sprintf
+/tst-sscanf
+/tst-tmpnam
+/tst-unbputc
+/tst-ungetc
+/tstdiomisc
+/tstgetln
+/tstscanf
diff --git a/test/stdio/tstscanf.c b/test/stdio/tstscanf.c
index 44ddf49..0f55c3c 100644
--- a/test/stdio/tstscanf.c
+++ b/test/stdio/tstscanf.c
@@ -338,14 +338,14 @@ main (int argc, char **argv)
     int res;
 
     res = sscanf ("-InF", "%f", &value);
-    if (res != 1 || isinf (value) != -1)
+    if (res != 1 || !isinf (value) || !(value<0))
       {
 	fputs ("test failed!\n", stdout);
 	result = 1;
       }
 
     res = sscanf ("+InfiNiTY", "%f", &value);
-    if (res != 1 || isinf (value) != 1)
+    if (res != 1 || !isinf (value) || !(value>0))
       {
 	fputs ("test failed!\n", stdout);
 	result = 1;
diff --git a/test/stdlib/.gitignore b/test/stdlib/.gitignore
new file mode 100644
index 0000000..ce37703
--- /dev/null
+++ b/test/stdlib/.gitignore
@@ -0,0 +1,13 @@
+/test-canon
+/testdiv
+/testrand
+/testsort
+/tst-calloc
+/tst-environ
+/tst-limits
+/tst-malloc
+/tst-rand48
+/tst-strtod
+/tst-strtol
+/tst-strtoll
+/tst-system
diff --git a/test/stdlib/testsort.c b/test/stdlib/testsort.c
index aa4332a..5a92bc0 100644
--- a/test/stdlib/testsort.c
+++ b/test/stdlib/testsort.c
@@ -1,3 +1,5 @@
+#define _BSD_SOURCE
+
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
diff --git a/test/stdlib/tst-calloc.c b/test/stdlib/tst-calloc.c
index a9b9e2a..049117b 100644
--- a/test/stdlib/tst-calloc.c
+++ b/test/stdlib/tst-calloc.c
@@ -17,6 +17,8 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#define _BSD_SOURCE
+
 #include <errno.h>
 #include <limits.h>
 #include <malloc.h>
diff --git a/test/stdlib/tst-malloc.c b/test/stdlib/tst-malloc.c
index 09fbb1f..4a491d9 100644
--- a/test/stdlib/tst-malloc.c
+++ b/test/stdlib/tst-malloc.c
@@ -21,13 +21,15 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "../../dietfeatures.h"
+
 static int errors = 0;
 
 static void
 merror (const char *msg)
 {
   ++errors;
-  printf ("Error: %s\n", msg);
+  fprintf (stderr, "Error: %s\n", msg);
 }
 
 int
@@ -56,9 +58,11 @@ main (void)
   if (p != NULL)
     merror ("realloc (p, 0) failed.");
 
+#ifdef WANT_MALLOC_ZERO
   p = malloc (0);
   if (p == NULL)
     merror ("malloc (0) failed.");
+#endif
 
   p = realloc (p, 0);
   if (p != NULL)
diff --git a/test/stdlib/tst-strtod.c b/test/stdlib/tst-strtod.c
index 630a8fc..bacdca7 100644
--- a/test/stdlib/tst-strtod.c
+++ b/test/stdlib/tst-strtod.c
@@ -149,10 +149,10 @@ main (int argc, char ** argv)
     }
 
   const char input2[] = "+1.000000000116415321826934814453125";
-  if (strtold (input2, NULL) != +1.000000000116415321826934814453125)
+  if (strtold (input2, NULL) != +1.000000000116415321826934814453125L)
     {
       printf ("input2: %La != %La\n", strtold (input2, NULL),
-	      +1.000000000116415321826934814453125);
+	      +1.000000000116415321826934814453125L);
       status = 1;
     }
 
diff --git a/test/string/.gitignore b/test/string/.gitignore
new file mode 100644
index 0000000..94b11fc
--- /dev/null
+++ b/test/string/.gitignore
@@ -0,0 +1,16 @@
+/memccpy
+/memchr
+/memcmp
+/memcpy
+/mempcpy
+/memrchr
+/strcasecmp
+/strcmp
+/strcspn
+/strlen
+/strncat
+/strncpy
+/strpbrk
+/strrchr
+/strspn
+/strstr
diff --git a/test/sysconf.c b/test/sysconf.c
new file mode 100644
index 0000000..32263a5
--- /dev/null
+++ b/test/sysconf.c
@@ -0,0 +1,80 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/wait.h>
+
+#include "../dietpagesize.h"
+
+static long exec_getconf(char const *var)
+{
+  char	buf[128];
+  pid_t	pid;
+  int	fd[2];
+  int	status;
+  ssize_t	l;
+
+  if (pipe(fd)<0 || (pid = fork())<0)
+    abort();
+
+  if (pid==0) {
+    close(fd[0]);
+
+    if (fd[1]!=1) {
+      dup2(fd[1], 1);
+      close(fd[1]);
+    }
+
+    execlp("getconf", "getconf", var, NULL);
+    _exit(1);
+  }
+
+  close(fd[1]);
+  l = read(fd[0], buf, sizeof(buf)-1);
+  if (l<0) {
+    perror("read()");
+    goto err;
+  } else if (l==sizeof(buf)-1)
+    goto err;
+  close(fd[0]);
+
+  buf[l] = '\0';
+
+  if (waitpid(pid, &status, 0)<0)
+    goto err;
+
+  if (!WIFEXITED(status) || WEXITSTATUS(status)!=0)
+    goto err;
+
+  return strtol(buf, NULL, 10);
+
+ err:
+  kill(pid, SIGKILL);
+  abort();
+}
+
+static unsigned int do_check(char const *var, long exp)
+{
+  long	cur = exec_getconf(var);
+
+  if (cur!=exp) {
+    fprintf(stderr, "%s mismatch: got %ld, expected %ld\n",
+	    var, cur, exp);
+    return 1;
+  }
+
+  return 0;
+}
+
+int main(int argc, char *argv[])
+{
+  unsigned int	err = 0;
+
+  assert(sysconf(_SC_PAGESIZE) == __DIET_PAGE_SIZE);
+  assert(__DIET_PAGE_SIZE == (1<<__DIET_PAGE_SHIFT));
+
+  err += do_check("PAGE_SIZE", sysconf(_SC_PAGESIZE));
+  err += do_check("CLK_TCK",   sysconf(_SC_CLK_TCK));
+
+  return err;
+}
diff --git a/test/sysenter.c b/test/sysenter.c
index a8fa3a8..3d85916 100644
--- a/test/sysenter.c
+++ b/test/sysenter.c
@@ -11,11 +11,11 @@ int main() {
   int i;
   for (i=0; environ[i]; ++i) ;
   for (x=(struct elf_aux*)(environ+i+1); x->type; ++x) {
-    printf("%d %x\n",x->type,x->value);
+    printf("%ld %lx\n",x->type,x->value);
     if (x->type==AT_PAGESZ)
-      printf("pagesize %d\n",x->value);
+      printf("pagesize %ld\n",x->value);
     else if (x->type==AT_SYSINFO)
-      printf("vsyscall %p\n",x->value);
+      printf("vsyscall %p\n",(void *)x->value);
   }
   return 0;
 }
diff --git a/test/time/.gitignore b/test/time/.gitignore
new file mode 100644
index 0000000..dcd3b38
--- /dev/null
+++ b/test/time/.gitignore
@@ -0,0 +1,4 @@
+/tst-mktime
+/tst-posixtz
+/tst-strftime
+/tst-strptime
diff --git a/test/time/tst-strftime.c b/test/time/tst-strftime.c
index e092e93..27db9a4 100644
--- a/test/time/tst-strftime.c
+++ b/test/time/tst-strftime.c
@@ -49,18 +49,18 @@ int main (void) {
 
       if (res == 0)
 	{
-	  printf ("%Zu: %s: res == 0 despite size == %Zu\n",
+	  printf ("%zu: %s: res == 0 despite size == %zu\n",
 		  cnt, tests[cnt].fmt, size);
 	  result = 1;
 	}
       else if (size < tests[cnt].min)
 	{
-	  printf ("%Zu: %s: size == %Zu was enough\n",
+	  printf ("%zu: %s: size == %zu was enough\n",
 		  cnt, tests[cnt].fmt, size);
 	  result = 1;
 	}
       else
-	printf ("%Zu: %s: size == %Zu: OK\n", cnt, tests[cnt].fmt, size);
+	printf ("%zu: %s: size == %zu: OK\n", cnt, tests[cnt].fmt, size);
 
       free (buf);
     }
diff --git a/test/time/tst-strptime.c b/test/time/tst-strptime.c
index 6277ea6..2773180 100644
--- a/test/time/tst-strptime.c
+++ b/test/time/tst-strptime.c
@@ -41,10 +41,12 @@ static const struct
   { "C", "03/03/00", "%D", 5, 62, 2, 3 },
   { "C", "9/9/99", "%x", 4, 251, 8, 9 },
   { "C", "19990502123412", "%Y%m%d%H%M%S", 0, 121, 4, 2 },
+#if 0		/* dietlibc does not support %U/%W/%j and non-POSIX locales */
   { "C", "2001 20 Mon", "%Y %U %a", 1, 140, 4, 21 },
   { "C", "2001 21 Mon", "%Y %W %a", 1, 140, 4, 21 },
   { "ja_JP.EUC-JP", "2001 20 \xb7\xee", "%Y %U %a", 1, 140, 4, 21 },
   { "ja_JP.EUC-JP", "2001 21 \xb7\xee", "%Y %W %a", 1, 140, 4, 21 },
+#endif
 };
 
 
@@ -72,9 +74,16 @@ test_tm (void)
 
   for (i = 0; i < sizeof (tm_tests) / sizeof (tm_tests[0]); ++i)
     {
+      char *pres;
       memset (&tm, '\0', sizeof (tm));
-      
-      if (strptime (tm_tests[i].input, tm_tests[i].format, &tm) != '\0')
+
+      pres = strptime (tm_tests[i].input, tm_tests[i].format, &tm);
+      if (!pres)
+	{
+	  fprintf(stderr, "failed to parse '%s'\n", day_tests[i].input);
+	  result = 1;
+	}
+      else if (*pres != '\0')
 	{
 	  printf ("not all of `%s' read\n", tm_tests[i].input);
 	  result = 1;
@@ -118,6 +127,7 @@ int main (void) {
 
   for (i = 0; i < sizeof (day_tests) / sizeof (day_tests[0]); ++i)
     {
+      char *pres;
       memset (&tm, '\0', sizeof (tm));
 
       if (setlocale (LC_ALL, day_tests[i].locale) == NULL)
@@ -125,7 +135,14 @@ int main (void) {
 	  printf ("cannot set locale %s: %m\n", day_tests[i].locale);
 	}
 
-      if (*strptime (day_tests[i].input, day_tests[i].format, &tm) != '\0')
+      pres = strptime (day_tests[i].input, day_tests[i].format, &tm);
+      if (!pres)
+	{
+	  fprintf(stderr, "failed to parse '%s' for locale '%s'\n",
+		  day_tests[i].input, day_tests[i].locale);
+	  result = 1;
+	}
+      else if (*pres != '\0')
 	{
 	  printf ("not all of `%s' read\n", day_tests[i].input);
 	  result = 1;
diff --git a/test/waitpid.c b/test/waitpid.c
index fe2cb5b..92c0b0e 100644
--- a/test/waitpid.c
+++ b/test/waitpid.c
@@ -11,7 +11,7 @@ int main() {
     perror("fork");
     _exit(1);
   case 0:
-    fprintf(stderr,"child, my pid is %u\n",getpid());
+    fprintf(stdout,"child, my pid is %u\n",getpid());
     sleep(1);
     _exit(23);
   }
diff --git a/x32/start.S b/x32/start.S
index 86afaaf..3768cba 100644
--- a/x32/start.S
+++ b/x32/start.S
@@ -11,12 +11,29 @@ _start:
 	
 	leaq	4(%rsi,%rdi,4),%rdx	/* %edx = envp = (4*edi)+%esi+4 */
 
+#ifdef WANT_ELFINFO
+	/* untested !! */
+
+#ifdef __DYN_LIB
+	movl	environ@GOTPCREL(%rip), %eax
+#else
+	leal	environ(%rip), %eax
+#endif
+	movl	%edx, (%eax)	/* environ */
+
+1:	add	$4, %edx	/* incorment envp */
+	cmpl	$0, -4(%edx)	/* load envp[-1] */
+	jne	1b		/* ... until envp[-1]==NULL */
+
+	movl	%edx, 4(%eax)	/* __elfinfo */
+#else	/* WANT_ELFINFO */
 #ifdef __DYN_LIB
 	movl	environ@GOTPCREL(%rip), %eax
 	movl	%edx, (%eax)
 #else
 	movl	%edx, environ(%rip)
 #endif
+#endif	/* WANT_ELFINFO */
 
 #ifdef PROFILING
 	pushl	%edi			/* save reg args */
diff --git a/x86_64/__time.S b/x86_64/__time.S
new file mode 100644
index 0000000..774b67f
--- /dev/null
+++ b/x86_64/__time.S
@@ -0,0 +1,11 @@
+/* implement time(2) via gettimeofday(2) on x86-64 because gettimeofday
+   is a vsyscall (i.e. no actual switch to kernel mode) */
+.text
+.global time
+.type time,@function
+time:
+	mov	$0xffffffffff600400,%rax
+	call	*%rax
+	ret
+.Lhere:
+	.size	 time,.Lhere-time
diff --git a/x86_64/dyn_syscalls.S b/x86_64/dyn_syscalls.S
index c1aa035..1aa7da1 100644
--- a/x86_64/dyn_syscalls.S
+++ b/x86_64/dyn_syscalls.S
@@ -141,7 +141,6 @@ __error_unified_syscall:
 #include "../syscalls.s/n_sigprocmask.S"
 #include "../syscalls.s/n_sigsuspend.S"
 #include "../syscalls.s/nanosleep.S"
-#include "../syscalls.s/nice.S"
 #include "../syscalls.s/open.S"
 #include "../syscalls.s/pause.S"
 #include "../syscalls.s/personality.S"
diff --git a/x86_64/start.S b/x86_64/start.S
index adc461a..8b4f3c9 100644
--- a/x86_64/start.S
+++ b/x86_64/start.S
@@ -12,12 +12,28 @@ _start:
 	
 	leaq	8(%rsi,%rdi,8),%rdx	/* %rdx = envp = (8*rdi)+%rsi+8 */
 
+
+#ifdef WANT_ELFINFO
+#ifdef __DYN_LIB
+	movq	environ@GOTPCREL(%rip), %rax
+#else
+	leaq	environ(%rip), %rax
+#endif
+	movq	%rdx, (%rax)	/* environ */
+
+1:	add	$8, %rdx	/* increment envp */
+	cmpq	$0, -8(%rdx)	/* load envp[-1] */
+	jne	1b		/* ... until envp[-1]==NULL */
+
+	movq	%rdx, 8(%rax)	/* __elfinfo */
+#else
 #ifdef __DYN_LIB
 	movq	environ@GOTPCREL(%rip), %rax
 	movq	%rdx, (%rax)
 #else
 	movq	%rdx, environ(%rip)
 #endif
+#endif
 
 #ifdef PROFILING
 	pushq	%rdi			/* save reg args */
diff --git a/x86_64/time.S b/x86_64/time.S
index 774b67f..690ee30 100644
--- a/x86_64/time.S
+++ b/x86_64/time.S
@@ -1,11 +1 @@
-/* implement time(2) via gettimeofday(2) on x86-64 because gettimeofday
-   is a vsyscall (i.e. no actual switch to kernel mode) */
-.text
-.global time
-.type time,@function
-time:
-	mov	$0xffffffffff600400,%rax
-	call	*%rax
-	ret
-.Lhere:
-	.size	 time,.Lhere-time
+/* avoid empty source file */