Merge with master.kernel.org:/pub/scm/linux/kernel/git/herbert/klibc.git
diff --git a/klibc/Makefile b/klibc/Makefile
index dff813f..bf32f7c 100644
--- a/klibc/Makefile
+++ b/klibc/Makefile
@@ -18,7 +18,7 @@
atoi.o atol.o atoll.o \
strtol.o strtoll.o strtoul.o strtoull.o \
strtoimax.o strtoumax.o \
- globals.o exitc.o atexit.o onexit.o \
+ globals.o exit.o atexit.o onexit.o \
execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \
fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \
daemon.o \
diff --git a/klibc/SYSCALLS.def b/klibc/SYSCALLS.def
index b78919b..08e4477 100644
--- a/klibc/SYSCALLS.def
+++ b/klibc/SYSCALLS.def
@@ -16,7 +16,7 @@
;
; Process-related syscalls
;
-<!i386,x86_64> void _exit,exit::_exit(int)
+void _exit,exit::_exit(int)
<?!ia64> pid_t clone::__clone(unsigned long, void *)
<?ia64> pid_t clone::__clone2(unsigned long, void *, void *)
<?!sparc> pid_t fork()
diff --git a/klibc/arch/i386/Makefile.inc b/klibc/arch/i386/Makefile.inc
index 80344bd..aa0aa37 100644
--- a/klibc/arch/i386/Makefile.inc
+++ b/klibc/arch/i386/Makefile.inc
@@ -8,7 +8,6 @@
#
ARCHOBJS = \
- arch/$(ARCH)/exits.o \
arch/$(ARCH)/socketcall.o \
arch/$(ARCH)/setjmp.o \
arch/$(ARCH)/syscall.o \
diff --git a/klibc/arch/i386/exits.S b/klibc/arch/i386/exits.S
deleted file mode 100644
index ed23d98..0000000
--- a/klibc/arch/i386/exits.S
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# exit and _exit get included in *every* program, and gcc generates
-# horrible code for them. Yes, this only saves a few bytes, but
-# it does it in every program.
-#
-
-#include <asm/unistd.h>
-
- .data
- .align 4
- .globl __exit_handler
- .type __exit_handler,@object
-__exit_handler:
- .long _exit
- .size __exit_handler,4
-
- .text
- .align 4
- .globl exit
- .type exit,@function
-exit:
- jmp *(__exit_handler)
- .size exit,.-exit
-
- /* No need to save any registers... we're exiting! */
- .text
- .align 4
- .globl _exit
- .type _exit,@function
-_exit:
-#ifdef _REGPARM
- movl %eax,%ebx
-#else
- popl %ebx
- popl %ebx
-#endif
-#if __NR_exit == 1
- xorl %eax,%eax
- incl %eax
-#else
- movl $__NR_exit,%eax
-#endif
- int $0x80
- hlt
- .size _exit,.-exit
diff --git a/klibc/arch/parisc/Makefile.inc b/klibc/arch/parisc/Makefile.inc
index 980a543..4fddf5f 100644
--- a/klibc/arch/parisc/Makefile.inc
+++ b/klibc/arch/parisc/Makefile.inc
@@ -14,6 +14,3 @@
ARCHOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS))
archclean:
-
-arch/$(ARCH)/syscall.o: arch/$(ARCH)/syscall.c
- $(CC) $(CFLAGS) -ffixed-r20 -c -o $@ $<
diff --git a/klibc/arch/parisc/crt0.S b/klibc/arch/parisc/crt0.S
index fb0bd37..7adc6c4 100644
--- a/klibc/arch/parisc/crt0.S
+++ b/klibc/arch/parisc/crt0.S
@@ -29,6 +29,6 @@
bl __libc_init,%r2
nop
/* break miserably if we ever return */
- iitlbp %r0,(%r0) /* illegal instruction */
+ iitlbp %r0,(%sr0,%r0) /* illegal instruction */
nop
.procend
diff --git a/klibc/arch/parisc/syscall.S b/klibc/arch/parisc/syscall.S
new file mode 100644
index 0000000..a4f26f5
--- /dev/null
+++ b/klibc/arch/parisc/syscall.S
@@ -0,0 +1,36 @@
+/*
+ * arch/parisc/syscall.S
+ *
+ * %r20 contains the system call number, %r2 contains whence we came
+ *
+ */
+
+ .text
+ .align 64 ; cache-width aligned
+ .globl __syscall_common
+ .type __syscall_common,@function
+__syscall_common:
+ ldo 0x40(%sp),%sp
+ stw %rp,-0x54(%sp) ; save return pointer
+
+ ldw -0x74(%sp),%r22 ; %arg4
+ ldw -0x78(%sp),%r21 ; %arg5
+
+ ble 0x100(%sr2, %r0) ; jump to gateway page
+ nop ; can we move a load here?
+
+ ldi -0x1000,%r19 ; %r19 = -4096
+ sub %r0,%ret0,%r22 ; %r22 = -%ret0
+ cmpb,>>=,n %r19,%ret0,1f ; if %ret0 >= -4096UL
+ ldi -1,%ret0 ; nullified on taken forward
+
+ /* store %r22 to errno... */
+ ldil L%errno,%r1
+ ldo R%errno(%r1),%r1
+ stw %r22,0(%r1)
+1:
+ ldw -0x54(%sp),%rp ; restore return pointer
+ bv %r0(%rp) ; jump back
+ ldo -0x40(%sp),%sp
+
+ .size __syscall_common,.-__syscall_common
diff --git a/klibc/arch/parisc/syscall.c b/klibc/arch/parisc/syscall.c
deleted file mode 100644
index 99ef5fe..0000000
--- a/klibc/arch/parisc/syscall.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * arch/parisc/syscall.c
- *
- * This function is called from a stub with %r20 already set up.
- * Compile this function with -ffixed-r20 so that it doesn't clobber
- * this register by mistake.
- */
-
-#include <klibc/compiler.h>
-#include <errno.h>
-
-long __syscall_common(long a0, long a1, long a2, long a3, long a4, long a5)
-{
- register unsigned long rv asm ("r28");
-
- asm volatile("\tble 0x100(%%sr2, %%r0)\n"
- : "=r" (rv)
- : "r" (a0), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5)
- : "%r1", "%r2", "%r29", "%r31");
-
- if ( __unlikely(rv >= -4095UL) ) {
- errno = -rv;
- return -1L;
- } else {
- return (long)rv;
- }
-}
-
-
diff --git a/klibc/arch/x86_64/Makefile.inc b/klibc/arch/x86_64/Makefile.inc
index 26d880d..bfa0885 100644
--- a/klibc/arch/x86_64/Makefile.inc
+++ b/klibc/arch/x86_64/Makefile.inc
@@ -8,7 +8,6 @@
#
ARCHOBJS = \
- arch/$(ARCH)/exits.o \
arch/$(ARCH)/setjmp.o \
arch/$(ARCH)/syscall.o \
arch/$(ARCH)/sigreturn.o
diff --git a/klibc/arch/x86_64/exits.S b/klibc/arch/x86_64/exits.S
deleted file mode 100644
index 618f4fb..0000000
--- a/klibc/arch/x86_64/exits.S
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# exit and _exit get included in *every* program, and gcc generates
-# horrible code for them. Yes, this only saves a few bytes, but
-# it does it in every program.
-#
-
-#include <asm/unistd.h>
-
- .data
- .align 8
- .globl __exit_handler
- .type __exit_handler,@object
-__exit_handler:
- .quad _exit
- .size __exit_handler,8
-
- .text
- .align 8
- .globl exit
- .type exit,@function
-exit:
- jmp *(__exit_handler)
- .size exit,.-exit
-
- /* No need to save any registers... we're exiting! */
- .text
- .align 4
- .globl _exit
- .type _exit,@function
-_exit:
- movl $__NR_exit,%eax
- /* The argument is already in %rdi */
- syscall
- .size _exit,.-exit
-
diff --git a/klibc/atexit.h b/klibc/atexit.h
index 792141d..a60d641 100644
--- a/klibc/atexit.h
+++ b/klibc/atexit.h
@@ -13,5 +13,7 @@
struct atexit *next;
};
+extern struct atexit *__atexit_list;
+
#endif /* ATEXIT_H */
diff --git a/klibc/exit.c b/klibc/exit.c
new file mode 100644
index 0000000..083c736
--- /dev/null
+++ b/klibc/exit.c
@@ -0,0 +1,29 @@
+/*
+ * exit.c
+ *
+ * exit(), including the handling of the atexit chain.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include "atexit.h"
+
+/* Link chain for atexit/on_exit */
+struct atexit *__atexit_list;
+
+__noreturn exit(int rv)
+{
+ struct atexit *ap;
+
+ for ( ap = __atexit_list ; ap ; ap = ap->next ) {
+ /* This assumes extra args are harmless. They should be in all
+ normal C ABIs, but if an architecture has some particularly
+ bizarre ABI this might be worth watching out for. */
+ ap->fctn(rv, ap->arg);
+ }
+
+ /* Handle any library destructors */
+
+ _exit(rv);
+}
diff --git a/klibc/exitc.c b/klibc/exitc.c
deleted file mode 100644
index 8819737..0000000
--- a/klibc/exitc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * exit.c
- *
- * Implement exit()
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-/* We have an assembly version for i386 and x86-64 */
-
-#if !defined(__i386__) && !defined(__x86_64__)
-
-/* This allows atexit/on_exit to install a hook */
-__noreturn (*__exit_handler)(int) = _exit;
-
-__noreturn exit(int rv)
-{
- __exit_handler(rv);
-}
-
-#endif
diff --git a/klibc/libc_init.c b/klibc/libc_init.c
index e91edc4..081eb44 100644
--- a/klibc/libc_init.c
+++ b/klibc/libc_init.c
@@ -17,6 +17,7 @@
#include <stdint.h>
#include <klibc/compiler.h>
#include <elf.h>
+#include "atexit.h"
/* This file is included from __static_init.c or __shared_init.c */
#ifndef SHARED
@@ -31,6 +32,8 @@
uintptr_t v;
};
+static struct atexit at_exit;
+
__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void))
{
int argc;
@@ -45,6 +48,12 @@
#endif
unsigned int page_size = 0, page_shift = 0;
+ if ( onexit ) {
+ at_exit.fctn = (void(*)(int, void *))onexit;
+ /* at_exit.next = NULL already */
+ __atexit_list = &at_exit;
+ }
+
(void)onexit; /* For now, we ignore this... */
argc = (int)*elfdata++;
diff --git a/klibc/onexit.c b/klibc/onexit.c
index 70a9c01..c6e0257 100644
--- a/klibc/onexit.c
+++ b/klibc/onexit.c
@@ -6,20 +6,6 @@
#include <unistd.h>
#include "atexit.h"
-extern __noreturn (*__exit_handler)(int);
-static struct atexit *__atexit_list;
-
-static __noreturn on_exit_exit(int rv)
-{
- struct atexit *ap;
-
- for ( ap = __atexit_list ; ap ; ap = ap->next ) {
- ap->fctn(rv, ap->arg); /* This assumes extra args are harmless */
- }
-
- _exit(rv);
-}
-
int on_exit(void (*fctn)(int, void *), void *arg)
{
struct atexit *as = malloc(sizeof(struct atexit));
@@ -33,7 +19,5 @@
as->next = __atexit_list;
__atexit_list = as;
- __exit_handler = on_exit_exit;
-
return 0;
}