summaryrefslogtreecommitdiff
path: root/klibc/klibc
diff options
context:
space:
mode:
Diffstat (limited to 'klibc/klibc')
-rw-r--r--klibc/klibc/CAVEATS51
-rw-r--r--klibc/klibc/LICENSE73
-rw-r--r--klibc/klibc/MCONFIG49
-rw-r--r--klibc/klibc/Makefile135
-rw-r--r--klibc/klibc/README57
-rw-r--r--klibc/klibc/SOCKETCALLS21
-rw-r--r--klibc/klibc/SYSCALLS146
-rw-r--r--klibc/klibc/__shared_init.c56
-rw-r--r--klibc/klibc/__signal.c22
-rw-r--r--klibc/klibc/__static_init.c40
-rw-r--r--klibc/klibc/abort.c19
-rw-r--r--klibc/klibc/alarm.c29
-rw-r--r--klibc/klibc/arch/README67
-rw-r--r--klibc/klibc/arch/alpha/MCONFIG17
-rw-r--r--klibc/klibc/arch/alpha/Makefile.inc93
-rw-r--r--klibc/klibc/arch/alpha/README-gcc23
-rw-r--r--klibc/klibc/arch/alpha/crt0.S21
-rw-r--r--klibc/klibc/arch/alpha/divide.c57
-rw-r--r--klibc/klibc/arch/alpha/include/klibc/archsetjmp.h33
-rw-r--r--klibc/klibc/arch/alpha/include/klibc/archsys.h53
-rw-r--r--klibc/klibc/arch/alpha/include/machine/asm.h44
-rw-r--r--klibc/klibc/arch/alpha/pipe.c28
-rw-r--r--klibc/klibc/arch/alpha/setjmp.S77
-rw-r--r--klibc/klibc/arch/arm/MCONFIG26
-rw-r--r--klibc/klibc/arch/arm/Makefile.inc31
-rw-r--r--klibc/klibc/arch/arm/crt0.S25
-rw-r--r--klibc/klibc/arch/arm/include/klibc/archsetjmp.h14
-rw-r--r--klibc/klibc/arch/arm/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/arm/setjmp-arm.S40
-rw-r--r--klibc/klibc/arch/arm/setjmp-thumb.S58
-rw-r--r--klibc/klibc/arch/cris/MCONFIG11
-rw-r--r--klibc/klibc/arch/cris/Makefile.inc10
-rw-r--r--klibc/klibc/arch/cris/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/i386/MCONFIG32
-rw-r--r--klibc/klibc/arch/i386/Makefile.inc27
-rw-r--r--klibc/klibc/arch/i386/crt0.S33
-rw-r--r--klibc/klibc/arch/i386/exits.S45
-rw-r--r--klibc/klibc/arch/i386/include/klibc/archsetjmp.h19
-rw-r--r--klibc/klibc/arch/i386/include/klibc/archsys.h96
-rw-r--r--klibc/klibc/arch/i386/include/klibc/diverr.h16
-rw-r--r--klibc/klibc/arch/i386/libgcc/__ashldi3.S29
-rw-r--r--klibc/klibc/arch/i386/libgcc/__ashrdi3.S29
-rw-r--r--klibc/klibc/arch/i386/libgcc/__lshrdi3.S29
-rw-r--r--klibc/klibc/arch/i386/libgcc/__muldi3.S34
-rw-r--r--klibc/klibc/arch/i386/libgcc/__negdi2.S21
-rw-r--r--klibc/klibc/arch/i386/setjmp.S58
-rw-r--r--klibc/klibc/arch/i386/socketcall.S38
-rw-r--r--klibc/klibc/arch/ia64/MCONFIG11
-rw-r--r--klibc/klibc/arch/ia64/Makefile.inc10
-rw-r--r--klibc/klibc/arch/ia64/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/m68k/MCONFIG11
-rw-r--r--klibc/klibc/arch/m68k/Makefile.inc10
-rw-r--r--klibc/klibc/arch/m68k/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/mips/MCONFIG18
-rw-r--r--klibc/klibc/arch/mips/Makefile.inc24
-rw-r--r--klibc/klibc/arch/mips/crt0.S25
-rw-r--r--klibc/klibc/arch/mips/include/klibc/archsetjmp.h39
-rw-r--r--klibc/klibc/arch/mips/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/mips/include/machine/asm.h11
-rw-r--r--klibc/klibc/arch/mips/include/sgidefs.h20
-rw-r--r--klibc/klibc/arch/mips/pipe.S16
-rw-r--r--klibc/klibc/arch/mips/setjmp.S82
-rw-r--r--klibc/klibc/arch/mips/vfork.S19
-rw-r--r--klibc/klibc/arch/mips64/MCONFIG11
-rw-r--r--klibc/klibc/arch/mips64/Makefile.inc10
-rw-r--r--klibc/klibc/arch/mips64/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/parisc/MCONFIG11
-rw-r--r--klibc/klibc/arch/parisc/Makefile.inc10
-rw-r--r--klibc/klibc/arch/parisc/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/ppc/MCONFIG11
-rw-r--r--klibc/klibc/arch/ppc/Makefile.inc15
-rw-r--r--klibc/klibc/arch/ppc/crt0.S29
-rw-r--r--klibc/klibc/arch/ppc/include/klibc/archsetjmp.h36
-rw-r--r--klibc/klibc/arch/ppc/include/klibc/archsys.h55
-rw-r--r--klibc/klibc/arch/ppc/setjmp.S35
-rw-r--r--klibc/klibc/arch/ppc64/MCONFIG11
-rw-r--r--klibc/klibc/arch/ppc64/Makefile.inc10
-rw-r--r--klibc/klibc/arch/ppc64/crt0.S38
-rw-r--r--klibc/klibc/arch/ppc64/include/klibc/archsys.h52
-rw-r--r--klibc/klibc/arch/s390/MCONFIG13
-rw-r--r--klibc/klibc/arch/s390/Makefile.inc16
-rw-r--r--klibc/klibc/arch/s390/crt0.S25
-rw-r--r--klibc/klibc/arch/s390/include/klibc/archsetjmp.h15
-rw-r--r--klibc/klibc/arch/s390/include/klibc/archsys.h41
-rw-r--r--klibc/klibc/arch/s390/setjmp.S32
-rw-r--r--klibc/klibc/arch/s390x/MCONFIG13
-rw-r--r--klibc/klibc/arch/s390x/Makefile.inc16
-rw-r--r--klibc/klibc/arch/s390x/crt0.S21
-rw-r--r--klibc/klibc/arch/s390x/include/klibc/archsetjmp.h15
-rw-r--r--klibc/klibc/arch/s390x/include/klibc/archsys.h41
-rw-r--r--klibc/klibc/arch/s390x/setjmp.S36
-rw-r--r--klibc/klibc/arch/sh/MCONFIG19
-rw-r--r--klibc/klibc/arch/sh/Makefile.inc14
-rw-r--r--klibc/klibc/arch/sh/crt0.S28
-rw-r--r--klibc/klibc/arch/sh/include/klibc/archsetjmp.h22
-rw-r--r--klibc/klibc/arch/sh/include/klibc/archsys.h12
-rw-r--r--klibc/klibc/arch/sh/setjmp.S65
-rw-r--r--klibc/klibc/arch/sparc/MCONFIG18
-rw-r--r--klibc/klibc/arch/sparc/Makefile.inc44
-rw-r--r--klibc/klibc/arch/sparc/crt0.S2
-rw-r--r--klibc/klibc/arch/sparc/crt0i.S100
-rw-r--r--klibc/klibc/arch/sparc/divrem.m4276
-rw-r--r--klibc/klibc/arch/sparc/include/klibc/archsetjmp.h16
-rw-r--r--klibc/klibc/arch/sparc/include/klibc/archsys.h65
-rw-r--r--klibc/klibc/arch/sparc/include/machine/asm.h192
-rw-r--r--klibc/klibc/arch/sparc/include/machine/frame.h138
-rw-r--r--klibc/klibc/arch/sparc/include/machine/trap.h141
-rw-r--r--klibc/klibc/arch/sparc/setjmp.S38
-rw-r--r--klibc/klibc/arch/sparc/smul.S160
-rw-r--r--klibc/klibc/arch/sparc/umul.S193
-rw-r--r--klibc/klibc/arch/sparc64/MCONFIG21
-rw-r--r--klibc/klibc/arch/sparc64/Makefile.inc13
-rw-r--r--klibc/klibc/arch/sparc64/crt0.S2
-rw-r--r--klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h16
-rw-r--r--klibc/klibc/arch/sparc64/include/klibc/archsys.h157
-rw-r--r--klibc/klibc/arch/sparc64/setjmp.S55
-rw-r--r--klibc/klibc/arch/x86_64/MCONFIG16
-rw-r--r--klibc/klibc/arch/x86_64/Makefile.inc16
-rw-r--r--klibc/klibc/arch/x86_64/crt0.S22
-rw-r--r--klibc/klibc/arch/x86_64/exits.S35
-rw-r--r--klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h21
-rw-r--r--klibc/klibc/arch/x86_64/include/klibc/archsys.h32
-rw-r--r--klibc/klibc/arch/x86_64/setjmp.S54
-rw-r--r--klibc/klibc/assert.c13
-rw-r--r--klibc/klibc/atexit.c10
-rw-r--r--klibc/klibc/atexit.h19
-rw-r--r--klibc/klibc/atoi.c3
-rw-r--r--klibc/klibc/atol.c3
-rw-r--r--klibc/klibc/atoll.c3
-rw-r--r--klibc/klibc/atox.c14
-rw-r--r--klibc/klibc/brk.c24
-rw-r--r--klibc/klibc/bsd_signal.c11
-rw-r--r--klibc/klibc/calloc.c21
-rw-r--r--klibc/klibc/closelog.c18
-rw-r--r--klibc/klibc/creat.c12
-rw-r--r--klibc/klibc/ctypes.c281
-rw-r--r--klibc/klibc/exec_l.c57
-rw-r--r--klibc/klibc/execl.c8
-rw-r--r--klibc/klibc/execle.c8
-rw-r--r--klibc/klibc/execlp.c8
-rw-r--r--klibc/klibc/execlpe.c8
-rw-r--r--klibc/klibc/execv.c13
-rw-r--r--klibc/klibc/execvp.c13
-rw-r--r--klibc/klibc/execvpe.c73
-rw-r--r--klibc/klibc/exitc.c36
-rw-r--r--klibc/klibc/fdatasync.c15
-rw-r--r--klibc/klibc/fgetc.c20
-rw-r--r--klibc/klibc/fgets.c33
-rw-r--r--klibc/klibc/fopen.c46
-rw-r--r--klibc/klibc/fork.c29
-rw-r--r--klibc/klibc/fprintf.c19
-rw-r--r--klibc/klibc/fputc.c14
-rw-r--r--klibc/klibc/fputs.c15
-rw-r--r--klibc/klibc/fread.c35
-rw-r--r--klibc/klibc/fread2.c13
-rw-r--r--klibc/klibc/fwrite.c35
-rw-r--r--klibc/klibc/fwrite2.c13
-rw-r--r--klibc/klibc/getcwd.c15
-rw-r--r--klibc/klibc/getdomainname.c25
-rw-r--r--klibc/klibc/getenv.c22
-rw-r--r--klibc/klibc/gethostname.c25
-rw-r--r--klibc/klibc/getopt.c74
-rw-r--r--klibc/klibc/getpriority.c25
-rw-r--r--klibc/klibc/globals.c10
-rw-r--r--klibc/klibc/include/alloca.h13
-rw-r--r--klibc/klibc/include/arpa/inet.h24
-rw-r--r--klibc/klibc/include/assert.h22
-rw-r--r--klibc/klibc/include/bits32/bitsize/limits.h14
-rw-r--r--klibc/klibc/include/bits32/bitsize/stddef.h18
-rw-r--r--klibc/klibc/include/bits32/bitsize/stdint.h34
-rw-r--r--klibc/klibc/include/bits32/bitsize/stdintconst.h18
-rw-r--r--klibc/klibc/include/bits32/bitsize/stdintlimits.h22
-rw-r--r--klibc/klibc/include/bits64/bitsize/limits.h14
-rw-r--r--klibc/klibc/include/bits64/bitsize/stddef.h13
-rw-r--r--klibc/klibc/include/bits64/bitsize/stdint.h36
-rw-r--r--klibc/klibc/include/bits64/bitsize/stdintconst.h18
-rw-r--r--klibc/klibc/include/bits64/bitsize/stdintlimits.h22
-rw-r--r--klibc/klibc/include/ctype.h117
-rw-r--r--klibc/klibc/include/dirent.h20
-rw-r--r--klibc/klibc/include/elf.h12
-rw-r--r--klibc/klibc/include/endian.h41
-rw-r--r--klibc/klibc/include/errno.h8
-rw-r--r--klibc/klibc/include/fcntl.h11
-rw-r--r--klibc/klibc/include/grp.h13
-rw-r--r--klibc/klibc/include/inttypes.h226
-rw-r--r--klibc/klibc/include/klibc/compiler.h61
-rw-r--r--klibc/klibc/include/klibc/diverr.h16
-rw-r--r--klibc/klibc/include/klibc/extern.h14
-rw-r--r--klibc/klibc/include/limits.h40
-rw-r--r--klibc/klibc/include/net/if.h1
-rw-r--r--klibc/klibc/include/net/if_arp.h1
-rw-r--r--klibc/klibc/include/net/if_ether.h1
-rw-r--r--klibc/klibc/include/net/if_packet.h1
-rw-r--r--klibc/klibc/include/netinet/in.h33
-rw-r--r--klibc/klibc/include/netinet/in6.h10
-rw-r--r--klibc/klibc/include/netinet/ip.h13
-rw-r--r--klibc/klibc/include/netinet/tcp.h11
-rw-r--r--klibc/klibc/include/netinet/udp.h19
-rw-r--r--klibc/klibc/include/poll.h16
-rw-r--r--klibc/klibc/include/sched.h23
-rw-r--r--klibc/klibc/include/setjmp.h43
-rw-r--r--klibc/klibc/include/signal.h72
-rw-r--r--klibc/klibc/include/stdarg.h14
-rw-r--r--klibc/klibc/include/stddef.h24
-rw-r--r--klibc/klibc/include/stdint.h113
-rw-r--r--klibc/klibc/include/stdio.h109
-rw-r--r--klibc/klibc/include/stdlib.h94
-rw-r--r--klibc/klibc/include/string.h37
-rw-r--r--klibc/klibc/include/sys/dirent.h13
-rw-r--r--klibc/klibc/include/sys/fsuid.h14
-rw-r--r--klibc/klibc/include/sys/ioctl.h14
-rw-r--r--klibc/klibc/include/sys/klog.h24
-rw-r--r--klibc/klibc/include/sys/mman.h21
-rw-r--r--klibc/klibc/include/sys/module.h158
-rw-r--r--klibc/klibc/include/sys/mount.h55
-rw-r--r--klibc/klibc/include/sys/param.h11
-rw-r--r--klibc/klibc/include/sys/reboot.h25
-rw-r--r--klibc/klibc/include/sys/resource.h15
-rw-r--r--klibc/klibc/include/sys/select.h13
-rw-r--r--klibc/klibc/include/sys/socket.h50
-rw-r--r--klibc/klibc/include/sys/socketcalls.h28
-rw-r--r--klibc/klibc/include/sys/stat.h23
-rw-r--r--klibc/klibc/include/sys/syscall.h15
-rw-r--r--klibc/klibc/include/sys/time.h16
-rw-r--r--klibc/klibc/include/sys/times.h14
-rw-r--r--klibc/klibc/include/sys/types.h127
-rw-r--r--klibc/klibc/include/sys/uio.h15
-rw-r--r--klibc/klibc/include/sys/utime.h10
-rw-r--r--klibc/klibc/include/sys/utsname.h23
-rw-r--r--klibc/klibc/include/sys/vfs.h14
-rw-r--r--klibc/klibc/include/sys/wait.h19
-rw-r--r--klibc/klibc/include/syslog.h53
-rw-r--r--klibc/klibc/include/termios.h86
-rw-r--r--klibc/klibc/include/time.h14
-rw-r--r--klibc/klibc/include/unistd.h111
-rw-r--r--klibc/klibc/include/utime.h15
-rw-r--r--klibc/klibc/inet/bindresvport.c48
-rw-r--r--klibc/klibc/inet/inet_addr.c14
-rw-r--r--klibc/klibc/inet/inet_aton.c23
-rw-r--r--klibc/klibc/inet/inet_ntoa.c19
-rw-r--r--klibc/klibc/inet/inet_ntop.c52
-rw-r--r--klibc/klibc/inet/inet_pton.c74
-rw-r--r--klibc/klibc/interp.S11
-rw-r--r--klibc/klibc/isatty.c21
-rw-r--r--klibc/klibc/libgcc/__divdi3.c29
-rw-r--r--klibc/klibc/libgcc/__divsi3.c29
-rw-r--r--klibc/klibc/libgcc/__moddi3.c29
-rw-r--r--klibc/klibc/libgcc/__modsi3.c29
-rw-r--r--klibc/klibc/libgcc/__udivdi3.c13
-rw-r--r--klibc/klibc/libgcc/__udivmoddi4.c32
-rw-r--r--klibc/klibc/libgcc/__udivmodsi4.c32
-rw-r--r--klibc/klibc/libgcc/__udivsi3.c13
-rw-r--r--klibc/klibc/libgcc/__umoddi3.c16
-rw-r--r--klibc/klibc/libgcc/__umodsi3.c16
-rw-r--r--klibc/klibc/llseek.c34
-rw-r--r--klibc/klibc/lrand48.c42
-rw-r--r--klibc/klibc/makeerrlist.pl80
-rw-r--r--klibc/klibc/malloc.c192
-rw-r--r--klibc/klibc/malloc.h51
-rw-r--r--klibc/klibc/memccpy.c23
-rw-r--r--klibc/klibc/memchr.c18
-rw-r--r--klibc/klibc/memcmp.c19
-rw-r--r--klibc/klibc/memcpy.c29
-rw-r--r--klibc/klibc/memmem.c44
-rw-r--r--klibc/klibc/memmove.c34
-rw-r--r--klibc/klibc/memset.c30
-rw-r--r--klibc/klibc/memswap.c23
-rw-r--r--klibc/klibc/mmap.c51
-rw-r--r--klibc/klibc/nice.c22
-rw-r--r--klibc/klibc/onexit.c39
-rw-r--r--klibc/klibc/pause.c21
-rw-r--r--klibc/klibc/perror.c12
-rw-r--r--klibc/klibc/printf.c19
-rw-r--r--klibc/klibc/pty.c31
-rw-r--r--klibc/klibc/puts.c13
-rw-r--r--klibc/klibc/qsort.c42
-rw-r--r--klibc/klibc/raise.c11
-rw-r--r--klibc/klibc/readdir.c66
-rw-r--r--klibc/klibc/realloc.c49
-rw-r--r--klibc/klibc/reboot.c15
-rw-r--r--klibc/klibc/recv.c11
-rw-r--r--klibc/klibc/sbrk.c23
-rw-r--r--klibc/klibc/seed48.c19
-rw-r--r--klibc/klibc/select.c9
-rw-r--r--klibc/klibc/send.c11
-rw-r--r--klibc/klibc/setegid.c10
-rw-r--r--klibc/klibc/setenv.c124
-rw-r--r--klibc/klibc/seteuid.c10
-rw-r--r--klibc/klibc/setpgrp.c10
-rw-r--r--klibc/klibc/setresgid.c29
-rw-r--r--klibc/klibc/setresuid.c30
-rw-r--r--klibc/klibc/sha1hash.c317
-rw-r--r--klibc/klibc/sigaction.c19
-rw-r--r--klibc/klibc/siglist.c115
-rw-r--r--klibc/klibc/siglongjmp.c16
-rw-r--r--klibc/klibc/signal.c11
-rw-r--r--klibc/klibc/sigpending.c19
-rw-r--r--klibc/klibc/sigprocmask.c19
-rw-r--r--klibc/klibc/sigsuspend.c19
-rw-r--r--klibc/klibc/sleep.c20
-rw-r--r--klibc/klibc/snprintf.c16
-rw-r--r--klibc/klibc/socketcalls.pl71
-rw-r--r--klibc/klibc/socketcommon.h25
-rw-r--r--klibc/klibc/sprintf.c18
-rw-r--r--klibc/klibc/srand48.c16
-rw-r--r--klibc/klibc/sscanf.c17
-rw-r--r--klibc/klibc/strcat.c11
-rw-r--r--klibc/klibc/strchr.c16
-rw-r--r--klibc/klibc/strcmp.c20
-rw-r--r--klibc/klibc/strcpy.c20
-rw-r--r--klibc/klibc/strdup.c17
-rw-r--r--klibc/klibc/strerror.c25
-rw-r--r--klibc/klibc/strlen.c14
-rw-r--r--klibc/klibc/strncat.c11
-rw-r--r--klibc/klibc/strncmp.c20
-rw-r--r--klibc/klibc/strncpy.c22
-rw-r--r--klibc/klibc/strntoimax.c13
-rw-r--r--klibc/klibc/strntoumax.c75
-rw-r--r--klibc/klibc/strrchr.c18
-rw-r--r--klibc/klibc/strsep.c21
-rw-r--r--klibc/klibc/strspn.c67
-rw-r--r--klibc/klibc/strstr.c10
-rw-r--r--klibc/klibc/strtoimax.c3
-rw-r--r--klibc/klibc/strtok.c16
-rw-r--r--klibc/klibc/strtol.c3
-rw-r--r--klibc/klibc/strtoll.c3
-rw-r--r--klibc/klibc/strtoul.c3
-rw-r--r--klibc/klibc/strtoull.c3
-rw-r--r--klibc/klibc/strtoumax.c3
-rw-r--r--klibc/klibc/strtox.c13
-rw-r--r--klibc/klibc/syscalls.pl81
-rw-r--r--klibc/klibc/syscommon.h29
-rw-r--r--klibc/klibc/syslog.c74
-rw-r--r--klibc/klibc/system.c61
-rw-r--r--klibc/klibc/tests/getenvtest.c26
-rw-r--r--klibc/klibc/tests/getopttest.c31
-rw-r--r--klibc/klibc/tests/hello.c7
-rw-r--r--klibc/klibc/tests/idtest.c14
-rw-r--r--klibc/klibc/tests/malloctest.c4145
-rw-r--r--klibc/klibc/tests/memstrtest.c29
-rw-r--r--klibc/klibc/tests/microhello.c9
-rw-r--r--klibc/klibc/tests/minihello.c7
-rw-r--r--klibc/klibc/tests/minips.c452
-rw-r--r--klibc/klibc/tests/nfs_no_rpc.c538
-rw-r--r--klibc/klibc/tests/setjmptest.c36
-rw-r--r--klibc/klibc/tests/testrand48.c19
-rw-r--r--klibc/klibc/tests/testvsnp.c115
-rw-r--r--klibc/klibc/time.c27
-rw-r--r--klibc/klibc/umount.c12
-rw-r--r--klibc/klibc/unsetenv.c40
-rw-r--r--klibc/klibc/usleep.c15
-rw-r--r--klibc/klibc/utime.c30
-rw-r--r--klibc/klibc/vfprintf.c26
-rw-r--r--klibc/klibc/vprintf.c11
-rw-r--r--klibc/klibc/vsnprintf.c433
-rw-r--r--klibc/klibc/vsprintf.c11
-rw-r--r--klibc/klibc/vsscanf.c365
-rw-r--r--klibc/klibc/wait.c12
-rw-r--r--klibc/klibc/wait3.c12
-rw-r--r--klibc/klibc/waitpid.c12
360 files changed, 18170 insertions, 0 deletions
diff --git a/klibc/klibc/CAVEATS b/klibc/klibc/CAVEATS
new file mode 100644
index 0000000000..c7131ac367
--- /dev/null
+++ b/klibc/klibc/CAVEATS
@@ -0,0 +1,51 @@
+ -------------------------------------------------
+ Please note the following caveats to using klibc:
+ -------------------------------------------------
+
+optimization:
+-------------
+
+Compiling with -O0 is not supported. It may or may not work; please
+use -O1 if you want to do maximize debuggability.
+
+Compiling with -O0 is more likely to work on gcc 3.
+
+
+setjmp()/longjmp():
+-------------------
+
+setjmp() and longjmp() *do not* save signal state. sigsetjmp() and
+siglongjmp() *do* save the signal mask -- regardless of the value of
+the extra argument.
+
+The standards actually state that if you pass longjmp() a final value
+of zero the library should change that to a 1! Presumably the reason
+is so people who write broken code can get away with writing
+longjmp(buf); or something equally bad. If you pass longjmp() a final
+value of 0 you get what you deserve -- setjmp() will happily return 0.
+
+
+stdio:
+------
+
+Only a small subset of the stdio functions are implemented. Those
+that are implemented do not buffer, although they *do* trap EINTR or
+short read/writes and iterate.
+
+_fread() and _fwrite(), which take only one size argument (like
+read/write), but do handle EINTR/short return are also available.
+
+
+namespaces:
+-----------
+
+klibc frequently includes headers in other headers in a way that
+exposes more symbols than POSIX says they should. "Live with it."
+
+
+theading:
+---------
+
+klibc is not thread-safe. Consequently, clone() or any of the
+pthreads functions are not included.
+
diff --git a/klibc/klibc/LICENSE b/klibc/klibc/LICENSE
new file mode 100644
index 0000000000..b512ff96bc
--- /dev/null
+++ b/klibc/klibc/LICENSE
@@ -0,0 +1,73 @@
+This license applies to all files in directory and its subdirectories,
+unless otherwise noted in individual files.
+
+
+Some files are derived from files derived from the include/ directory
+of the Linux kernel, and are licensed under the terms of the GNU
+General Public License, version 2, as released by the Free Software
+Foundation, Inc.; incorporated herein by reference.
+
+ -----
+
+Some files are derived from files copyrighted by the Regents of The
+University of California, and are available under the following
+license:
+
+Note: The advertising clause in the license appearing on BSD Unix
+files was officially rescinded by the Director of the Office of
+Technology Licensing of the University of California on July 22
+1999. He states that clause 3 is "hereby deleted in its entirety."
+
+ * Copyright (c)
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+ -----
+
+For all remaining files, the following license applies:
+
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * Any copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG
new file mode 100644
index 0000000000..a46a98a9dd
--- /dev/null
+++ b/klibc/klibc/MCONFIG
@@ -0,0 +1,49 @@
+# -*- makefile -*-
+#
+# Makefile configuration, without explicit rules
+#
+
+SRCROOT = ..
+include ../MCONFIG
+
+WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline
+CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS)
+
+SOFLAGS = -fPIC
+
+.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.c.i:
+ $(CC) $(CFLAGS) -E -o $@ $<
+
+.c.s:
+ $(CC) $(CFLAGS) -S -o $@ $<
+
+.S.o:
+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+
+.S.s:
+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $<
+
+.S.lo:
+ $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+
+.S.ls:
+ $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $<
+
+.s.o:
+ $(CC) $(CFLAGS) -x assembler -c -o $@ $<
+
+.ls.lo:
+ $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $<
+
+.c.lo:
+ $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $<
+
+.c.ls:
+ $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $<
+
+
diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile
new file mode 100644
index 0000000000..470a276ded
--- /dev/null
+++ b/klibc/klibc/Makefile
@@ -0,0 +1,135 @@
+#
+# Makefile
+#
+# Main makefile
+#
+
+# Include configuration rules
+include MCONFIG
+
+TESTS = $(patsubst %.c,%,$(wildcard tests/*.c)) \
+ $(patsubst %.c,%.shared,$(wildcard tests/*.c))
+LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \
+ vsscanf.o sscanf.o ctypes.o \
+ strntoumax.o strntoimax.o \
+ 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 \
+ 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 \
+ printf.o vprintf.o fprintf.o vfprintf.o perror.o \
+ fopen.o fread.o fread2.o fgetc.o fgets.o \
+ fwrite.o fwrite2.o fputc.o fputs.o puts.o \
+ sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \
+ __signal.o signal.o bsd_signal.o siglist.o siglongjmp.o \
+ sigaction.o sigpending.o sigprocmask.o sigsuspend.o \
+ brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \
+ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \
+ memmove.o \
+ strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o \
+ strncat.o strstr.o strncmp.o strncpy.o strrchr.o strspn.o \
+ strsep.o strtok.o \
+ gethostname.o getdomainname.o getcwd.o \
+ seteuid.o setegid.o setresuid.o setresgid.o \
+ getenv.o setenv.o unsetenv.o getopt.o readdir.o \
+ syslog.o closelog.o pty.o isatty.o reboot.o \
+ time.o utime.o fdatasync.o llseek.o select.o nice.o getpriority.o \
+ qsort.o lrand48.o srand48.o seed48.o \
+ inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \
+ inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
+ send.o recv.o
+SOLIB = libc.so
+SOHASH = klibc.so
+
+CRT0 = crt0.o
+LIB = libc.a
+
+#all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so
+all: $(CRT0) $(LIB) $(SOLIB) klibc.so
+
+# Add any architecture-specific rules
+include arch/$(ARCH)/Makefile.inc
+
+tests: $(TESTS)
+
+tests/%.o : tests/%.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+tests/% : tests/%.o $(LIB) $(CRT0)
+ $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC)
+ cp $@ $@.stripped
+ $(STRIP) $@.stripped
+
+tests/%.shared : tests/%.o interp.o $(SOLIB)
+ $(LD) $(LDFLAGS) -o $@ -e main interp.o tests/$*.o -R $(SOLIB) $(LIBGCC)
+ cp $@ $@.stripped
+ $(STRIP) $@.stripped
+
+$(LIB): __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj
+ rm -f $(LIB)
+ $(AR) cq $(LIB) __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/*.o socketcalls/*.o
+ $(RANLIB) $(LIB)
+
+$(SOLIB): $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj
+ $(LD) $(LDFLAGS) $(SHAREDFLAGS) -o $@ \
+ $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) \
+ syscalls/*.o socketcalls/*.o \
+ $(LIBGCC)
+
+sha1hash: sha1hash.c
+ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $<
+
+$(SOLIB).hash: $(SOLIB) sha1hash
+ $(NM) $(SOLIB) | \
+ egrep '^[0-9a-fA-F]+ [ADRTW] ' | sort | ./sha1hash > $@
+
+$(SOHASH): $(SOLIB) $(SOLIB).hash
+ cp -f $(SOLIB) $@
+ $(STRIP) $@
+ rm -f klibc-??????????????????????.so
+ ln -f $@ klibc-`cat $(SOLIB).hash`.so
+
+interp.o: interp.S $(SOLIB).hash
+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -DLIBDIR=\"$(SHLIBDIR)\" \
+ -DSOHASH=\"`cat $(SOLIB).hash`\" \
+ -c -o $@ $<
+
+crt0.o: arch/$(ARCH)/crt0.o
+ cp arch/$(ARCH)/crt0.o .
+
+syscalls.dir: SYSCALLS syscalls.pl syscommon.h
+ rm -rf syscalls
+ mkdir syscalls
+ $(PERL) syscalls.pl $(ARCH) SYSCALLS
+ touch $@
+
+socketcalls.dir: SOCKETCALLS socketcalls.pl socketcommon.h
+ rm -rf socketcalls
+ mkdir socketcalls
+ $(PERL) socketcalls.pl $(ARCH) SOCKETCALLS
+ touch $@
+
+%/static.obj: %.dir
+ $(MAKE) objects-$(basename $(notdir $@)) DIR=$*
+
+STATIC = $(addsuffix .o,$(basename $(wildcard $(DIR)/*.[cS])))
+
+objects-static: $(STATIC)
+ touch $(DIR)/static.obj
+
+clean: archclean
+ find . -type f -a \( -name \*.[isoa] -o -name \*.l[iso] \) -print0 | xargs -0rt rm -f
+ rm -f *.a *.so *.hash *.syms *.stripped
+ rm -f $(TESTS) tests/*.stripped
+ rm -rf syscalls syscalls.dir
+ rm -rf socketcalls socketcalls.dir
+ rm -f sha1hash
+
+spotless: clean
+ find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \
+ xargs -0rt rm -f
+
+ifneq ($(wildcard $(DIR)/.*.d),)
+include $(wildcard $(DIR)/.*.d)
+endif
diff --git a/klibc/klibc/README b/klibc/klibc/README
new file mode 100644
index 0000000000..7d5751804f
--- /dev/null
+++ b/klibc/klibc/README
@@ -0,0 +1,57 @@
+This is klibc, what is intended to be a minimalistic libc subset for
+use with initramfs. It is deliberately written for small size,
+minimal entaglement and portability, not speed. It is definitely a
+work in progress, and a lot of things are still missing.
+
+
+The build procedure is not very polished yet, but it should work like
+this:
+
+a) In the source root directory (the directory above the one in which
+ this file is found) create a symlink called "linux" pointing to a
+ reasonably recent Linux kernel tree (2.4 or 2.5 should be OK.)
+ This tree must have the include/asm symlink set up for the
+ architecture you're compiling for, and include/linux/autoconf.h
+ must exist. The easiest way to make sure of all of these is to do
+ a "make config" or any of its variants on the kernel tree is
+ question, followed by a "make dep".
+
+b) If you're cross-compiling, change ARCH in the main MCONFIG file to
+ the appropriate architecture, and set CROSS to your toolchain
+ prefix.
+
+ IMPORTANT: if you're on a 64-bit machine with a 32-bit userland
+ (ia64, mips64, ppc64 sparc64, s390x or x86_64), and you want to
+ build the 32-bit version: you need to set ARCH to the 32-bit
+ architecture as well as set up the linux/include/asm symlink to
+ point to the 32-bit architecture. Building the 32-bit architecture
+ usually (but not always) produces smaller binaries, and is likely
+ to be better tested.
+
+ If you are on ARM, and want to build a thumb version of the library
+ (this is supported), change OPTFLAGS in arch/arm/MCONFIG to build
+ thumb code.
+
+ The following is the last known status of various architectures:
+
+ Known to work: alpha arm i386 s390 s390x sparc sparc64 x86_64*
+ Works static, not shared: mips* arm-thumb sh*
+ Need crt0.S updates: ppc
+ Missing setjmp: ppc64
+ Need porting work: cris ia64 m68k mips64 parisc
+
+ x86_64: requires a kernel header patch (to be created)
+ mips, sh: linker problem; might work with fixed linker
+
+ Shared library support for sparc/sparc64 requires binutils 2.13.90.0.4.
+
+ Note that even the "known to work" ones likely have bugs. Please
+ report them if you run into them.
+
+c) Type "make" and pray...
+
+d) Try the test programs in the tests/ directory. They should run...
+
+Contact me at <hpa@zytor.com> for more info.
+
+ -hpa
diff --git a/klibc/klibc/SOCKETCALLS b/klibc/klibc/SOCKETCALLS
new file mode 100644
index 0000000000..1ab4e367a2
--- /dev/null
+++ b/klibc/klibc/SOCKETCALLS
@@ -0,0 +1,21 @@
+# -*- fundamental -*-
+#
+# These are calls that are invoked via the socketcall mechanism
+#
+int socket(int, int, int)
+int bind(int, struct sockaddr *, int)
+int connect(int, struct sockaddr *, socklen_t)
+int listen(int, int)
+int accept(int, struct sockaddr *, socklen_t *)
+int getsockname(int, struct sockaddr *, socklen_t *)
+int getpeername(int, struct sockaddr *, socklen_t *)
+int socketpair(int, int, int, int *)
+# int send(int, const void *, size_t, unsigned int)
+int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t)
+# int recv(int, void *, size_t, unsigned int)
+int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *)
+int shutdown(int, int)
+int setsockopt(int, int, int, const void *, socklen_t)
+int getsockopt(int, int, int, void *, socklen_t *)
+int sendmsg(int, const struct msghdr *, unsigned int)
+int recvmsg(int, struct msghdr *, unsigned int)
diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS
new file mode 100644
index 0000000000..1ec94acec6
--- /dev/null
+++ b/klibc/klibc/SYSCALLS
@@ -0,0 +1,146 @@
+# -*- fundamental -*-
+#
+# This is a list of system calls we invoke "directly". These
+# are generated into syscall stubs in their own C files, so the
+# linker can do its job properly.
+#
+# The full description of a line is:
+# [<[!]arch,...>] type sysname[@systype][::funcname](args)
+#
+
+#
+# Process-related syscalls
+#
+<!mips,mips64,sparc> pid_t vfork()
+<sparc> pid_t vfork@forkish()
+<!alpha> pid_t getpid()
+<alpha> pid_t getxpid@dual0::getpid()
+int setpgid(pid_t, pid_t)
+pid_t getpgid(pid_t)
+<!alpha> pid_t getppid()
+<alpha> pid_t getxpid@dual1::getppid()
+<!ia64> pid_t getpgrp()
+pid_t setsid()
+pid_t getsid(pid_t)
+pid_t wait4(pid_t, int *, int, struct rusage *)
+int execve(const char *, char * const *, char * const *)
+int setpriority(int, int, int)
+int sched_setscheduler(pid_t, int, const struct sched_param *)
+int sched_yield()
+
+#
+# User and group IDs
+#
+int setuid(uid_t)
+int setgid(gid_t)
+<!alpha> uid_t getuid()
+<alpha> uid_t getxuid@dual0::getuid()
+<!alpha> gid_t getgid()
+<alpha> gid_t getxgid@dual0::getgid()
+<!alpha> uid_t geteuid()
+<alpha> uid_t getxuid@dual1::geteuid()
+<!alpha> gid_t getegid()
+<alpha> uid_t getxgid@dual1::getegid()
+int getgroups(int, gid_t *)
+int setgroups(size_t, const gid_t *)
+int setreuid(uid_t, uid_t)
+int setregid(gid_t, gid_t)
+int setfsuid(uid_t)
+int setfsgid(gid_t)
+
+#
+# Filesystem-related system calls
+#
+int mount(const char *, const char *, const char *, unsigned long, const void *)
+<!alpha,ia64> int umount2(const char *, int)
+<alpha,ia64> int umount::umount2(const char *, int)
+<!m68k> int pivot_root(const char *, const char *)
+int sync()
+int statfs(const char *, struct statfs *)
+int fstatfs(int, struct statfs *)
+int swapon(const char *, int)
+int swapoff(const char *)
+
+#
+# Inode-related system calls
+#
+int access(const char *, int)
+int link(const char *, const char *)
+int unlink(const char *)
+int chdir(const char *)
+int rename(const char *, const char *)
+int mknod(const char *, mode_t, dev_t)
+int chmod(const char *, mode_t)
+int mkdir(const char *, mode_t)
+int rmdir(const char *)
+<!alpha,mips,mips64> int pipe(int *)
+mode_t umask(mode_t)
+int chroot(const char *)
+int symlink(const char *, const char *)
+int readlink(const char *, char *, size_t)
+int stat(const char *, struct stat *)
+int lstat(const char *, struct stat *)
+int fstat(int, struct stat *)
+int getdents(unsigned int, struct dirent *, unsigned int)
+int chown(const char *, uid_t, gid_t)
+int fchown(int, uid_t, gid_t)
+int lchown(const char *, uid_t, gid_t)
+
+#
+# I/O operations
+#
+ssize_t read(int, void *, size_t)
+ssize_t write(int, const void *, size_t)
+int open(const char *, int, mode_t)
+int close(int)
+off_t lseek(int, off_t, int)
+int dup(int)
+int dup2(int, int)
+int fcntl(int, int, long)
+int ioctl(int, int, void *)
+int flock(int, int)
+int poll(struct pollfd *, nfds_t, long)
+int fsync(int)
+int readv(int, const struct iovec *, int)
+int writev(int, const struct iovec *, int)
+
+#
+# Signal operations
+#
+int kill(pid_t, int)
+int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
+int rt_sigsuspend(const sigset_t *, size_t)
+int rt_sigpending(sigset_t *, size_t)
+int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+int getitimer(int, struct itimerval *)
+int setitimer(int, const struct itimerval *, struct itimerval *)
+
+#
+# Time-related system calls
+#
+clock_t times(struct tms *)
+int gettimeofday(struct timeval *, struct timezone *)
+int settimeofday(const struct timeval *, const struct timezone *)
+int nanosleep(const struct timespec *, struct timespec *)
+
+#
+# Memory
+#
+void * brk::__brk(void *)
+int munmap(void *, size_t)
+void * mremap(void *, size_t, size_t, unsigned long)
+int msync(const void *, size_t, int)
+int mprotect(const void *, size_t, int)
+
+#
+# System stuff
+#
+int uname(struct utsname *)
+int setdomainname(const char *, size_t)
+int sethostname(const char *, size_t)
+int init_module(const char *, struct module *)
+void * create_module(const char *, size_t)
+int delete_module(const char *)
+int query_module(const char *, int, void *, size_t, size_t)
+int reboot::__reboot(int, int, int, void *)
+int syslog::klogctl(int, char *, int)
diff --git a/klibc/klibc/__shared_init.c b/klibc/klibc/__shared_init.c
new file mode 100644
index 0000000000..63e3f4644e
--- /dev/null
+++ b/klibc/klibc/__shared_init.c
@@ -0,0 +1,56 @@
+/*
+ * __shared_init.c
+ *
+ * This function takes the raw data block set up by the ELF loader
+ * in the kernel and parses it. It is invoked by crt0.S which makes
+ * any necessary adjustments and passes calls this function using
+ * the standard C calling convention.
+ *
+ * The arguments are:
+ * uintptr_t *elfdata -- The ELF loader data block; usually from the stack.
+ * Basically a pointer to argc.
+ * void (*onexit)(void) -- Function to install into onexit
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <klibc/compiler.h>
+#include <elf.h>
+
+char **environ;
+
+__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void))
+{
+ int argc;
+ char **argv, **envp, **envend;
+ struct auxentry {
+ uintptr_t type;
+ uintptr_t v;
+ } *auxentry;
+ typedef int (*main_t)(int, char **, char **);
+ main_t main_ptr = NULL;
+
+ (void)onexit; /* For now, we ignore this... */
+
+ argc = (int)*elfdata++;
+ argv = (char **)elfdata;
+ envp = argv+(argc+1);
+
+ /* The auxillary entry vector is after all the environment vars */
+ for ( envend = envp ; *envend ; envend++ );
+ auxentry = (struct auxentry *)(envend+1);
+
+ while ( auxentry->type ) {
+ if ( auxentry->type == AT_ENTRY ) {
+ main_ptr = (main_t)(auxentry->v);
+ break;
+ }
+ auxentry++;
+ }
+
+ environ = envp;
+ exit(main_ptr(argc, argv, envp));
+}
+
+
diff --git a/klibc/klibc/__signal.c b/klibc/klibc/__signal.c
new file mode 100644
index 0000000000..b5081d386b
--- /dev/null
+++ b/klibc/klibc/__signal.c
@@ -0,0 +1,22 @@
+/*
+ * __signal.c
+ */
+
+#include <signal.h>
+
+__sighandler_t __signal(int signum, __sighandler_t handler, int flags)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = handler;
+ sa.sa_flags = flags;
+ sigemptyset(&sa.sa_mask);
+
+ if ( sigaction(signum, &sa, &sa) ) {
+ return (__sighandler_t)SIG_ERR;
+ } else {
+ return (__sighandler_t)sa.sa_handler;
+ }
+}
+
+
diff --git a/klibc/klibc/__static_init.c b/klibc/klibc/__static_init.c
new file mode 100644
index 0000000000..dcb8d01856
--- /dev/null
+++ b/klibc/klibc/__static_init.c
@@ -0,0 +1,40 @@
+/*
+ * __static_init.c
+ *
+ * This function takes the raw data block set up by the ELF loader
+ * in the kernel and parses it. It is invoked by crt0.S which makes
+ * any necessary adjustments and passes calls this function using
+ * the standard C calling convention.
+ *
+ * The arguments are:
+ * uintptr_t *elfdata -- The ELF loader data block; usually from the stack.
+ * Basically a pointer to argc.
+ * void (*onexit)(void) -- Function to install into onexit
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <klibc/compiler.h>
+#include <elf.h>
+
+char **environ;
+
+extern int main(int, char **, char **);
+
+__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void))
+{
+ int argc;
+ char **argv, **envp;
+
+ (void)onexit; /* For now, we ignore this... */
+
+ argc = (int)*elfdata++;
+ argv = (char **)elfdata;
+ envp = argv+(argc+1);
+
+ environ = envp;
+ exit(main(argc, argv, envp));
+}
+
+
diff --git a/klibc/klibc/abort.c b/klibc/klibc/abort.c
new file mode 100644
index 0000000000..9280d9861b
--- /dev/null
+++ b/klibc/klibc/abort.c
@@ -0,0 +1,19 @@
+/*
+ * abort.c
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+void abort(void)
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGABRT);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ raise(SIGABRT);
+ _exit(255); /* raise() should have killed us */
+}
+
diff --git a/klibc/klibc/alarm.c b/klibc/klibc/alarm.c
new file mode 100644
index 0000000000..ca7bb37f92
--- /dev/null
+++ b/klibc/klibc/alarm.c
@@ -0,0 +1,29 @@
+/*
+ * alarm.c
+ */
+
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_alarm
+
+_syscall1(unsigned int,alarm,unsigned int,seconds);
+
+#else
+
+/* Emulate alarm() via setitimer() */
+
+unsigned int alarm(unsigned int seconds)
+{
+ struct itimerval iv;
+
+ iv.it_interval.tv_sec = iv.it_interval.tv_usec = 0;
+ iv.it_value.tv_sec = seconds;
+ iv.it_value.tv_usec = 0;
+
+ setitimer(ITIMER_REAL, &iv, &iv);
+
+ return iv.it_value.tv_sec + (iv.it_value.tv_usec ? 1 : 0);
+}
+
+#endif
diff --git a/klibc/klibc/arch/README b/klibc/klibc/arch/README
new file mode 100644
index 0000000000..eceb23de4b
--- /dev/null
+++ b/klibc/klibc/arch/README
@@ -0,0 +1,67 @@
+To port klibc to a new architecture, you need:
+
+a) A directory structure
+
+Each archtecture has an arch/ directory, which should include an
+MCONFIG and a Makefile.inc file.
+
+b) Startup code (arch/*/crt0.S)
+
+The crt0.S assembly routine typically corresponds to the following
+pseudo-C code. In addition, each architecture needs any support
+routines that gcc-generated code expects to find in the system library
+-- Alpha, for example, needs divide subroutines.
+
+The "getenvtest" test program is a very good test for proper crt0.S
+functionality.
+
+
+extern __noreturn __libc_init(void *, void *);
+
+__noreturn _start(void)
+{
+ void *elf_data = get_elf_data_address(); /* Usually the stack address */
+ void *atexit_ptr = get_atexit_ptr(); /* Usually in a register */
+
+ /* Some architectures need this for debugging to work */
+ setup_null_stack_frame_if_necessary();
+
+ __libc_init(elf_data, atexit_ptr);
+}
+
+
+c) A setenv implementation (arch/*/setjmp.S, arch/*/include/klibc/archsetjmp.h)
+
+On most (but not all!) architectures, this entails creating a setjmp
+buffer big enough to hold all callee-saved registers, plus the stack
+pointer and the return address. In setjmp.S you have:
+
+* A "setjmp" function that writes out the callee-saved registers, the
+ stack pointer and the return address to the buffer pointed to by the
+ first argument, and then returns zero normally.
+
+ On some architectures you need to take some kind of action to make
+ sure the contents of the stack is actually manifest in memory and
+ not cached in the CPU. In some cases (e.g. on SPARC) this will
+ automatically spill the registers onto the stack; then they don't
+ need to be spilled into the jmp_buf.
+
+* A "longjmp" function that read back these same registers from the
+ jmp_buf pointed to by the first argument, and returns the second
+ argument *to the address specified in the jmp_buf*.
+
+ On some architectures you need to take some kind of action to flush
+ any cached stack data or return stack.
+
+
+d) Any support functions needed by gcc, *unless* they are in libgcc
+ *and* libgcc is usable for klibc on your particular platform. If
+ libgcc isn't usable for klibc (on MIPS, for example, libgcc is
+ compiled in a way that is not compatible with klibc) there are
+ reasonably good clones of most of the libgcc functions in the libgcc
+ directory. To use them, add them to ARCHOBJS in
+ arch/*/Makefile.inc.
+
+
+e) A link location for the shared klibc. This should be specified in
+ SHAREDFLAGS in arch/*/MCONFIG.
diff --git a/klibc/klibc/arch/alpha/MCONFIG b/klibc/klibc/arch/alpha/MCONFIG
new file mode 100644
index 0000000000..5987ed5841
--- /dev/null
+++ b/klibc/klibc/arch/alpha/MCONFIG
@@ -0,0 +1,17 @@
+# -*- makefile -*-
+#
+# arch/alpha/MCONFIG
+#
+# Build configuration for this architecture
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 7 GB - normal binaries start at 4.5 GB, and the stack is below
+# the binary.
+SHAREDFLAGS = -Ttext 0x1c0000200
+
diff --git a/klibc/klibc/arch/alpha/Makefile.inc b/klibc/klibc/arch/alpha/Makefile.inc
new file mode 100644
index 0000000000..2a1100f962
--- /dev/null
+++ b/klibc/klibc/arch/alpha/Makefile.inc
@@ -0,0 +1,93 @@
+# -*- makefile -*-
+#
+# arch/alpha/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+# Special CFLAGS for the divide code
+DIVCFLAGS = $(REQFLAGS) \
+ -O3 -fomit-frame-pointer -fcall-saved-1 -fcall-saved-2 \
+ -fcall-saved-3 -fcall-saved-4 -fcall-saved-5 -fcall-saved-6 \
+ -fcall-saved-7 -fcall-saved-8 -fcall-saved-15 -fcall-saved-16 \
+ -fcall-saved-17 -fcall-saved-18 -fcall-saved-19 -fcall-saved-20 \
+ -fcall-saved-21 -fcall-saved-22 -ffixed-23 -fcall-saved-24 \
+ -ffixed-25 -ffixed-27
+
+ARCHOBJS = \
+ arch/$(ARCH)/__divqu.o \
+ arch/$(ARCH)/__remqu.o \
+ arch/$(ARCH)/__divq.o \
+ arch/$(ARCH)/__remq.o \
+ arch/$(ARCH)/__divlu.o \
+ arch/$(ARCH)/__remlu.o \
+ arch/$(ARCH)/__divl.o \
+ arch/$(ARCH)/__reml.o \
+ arch/$(ARCH)/pipe.o \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+arch/$(ARCH)/%.s: arch/$(ARCH)/%.ss
+ sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \
+ -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \
+ -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@
+
+arch/$(ARCH)/%.ls: arch/$(ARCH)/%.lss
+ sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \
+ -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \
+ -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@
+
+arch/$(ARCH)/__divqu.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $<
+
+arch/$(ARCH)/__remqu.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $<
+
+arch/$(ARCH)/__divq.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $<
+
+arch/$(ARCH)/__remq.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $<
+
+arch/$(ARCH)/__divlu.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $<
+
+arch/$(ARCH)/__remlu.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $<
+
+arch/$(ARCH)/__divl.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $<
+
+arch/$(ARCH)/__reml.ss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $<
+
+arch/$(ARCH)/__divqu.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $<
+
+arch/$(ARCH)/__remqu.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $<
+
+arch/$(ARCH)/__divq.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $<
+
+arch/$(ARCH)/__remq.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $<
+
+arch/$(ARCH)/__divlu.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $<
+
+arch/$(ARCH)/__remlu.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $<
+
+arch/$(ARCH)/__divl.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $<
+
+arch/$(ARCH)/__reml.lss: arch/$(ARCH)/divide.c
+ $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $<
+
+archclean:
+ rm -f arch/$(ARCH)/*.ss arch/$(ARCH)/*.lss
+
diff --git a/klibc/klibc/arch/alpha/README-gcc b/klibc/klibc/arch/alpha/README-gcc
new file mode 100644
index 0000000000..9aaba72837
--- /dev/null
+++ b/klibc/klibc/arch/alpha/README-gcc
@@ -0,0 +1,23 @@
+ The current Alpha chips don't provide hardware for integer
+ division. The C compiler expects the functions
+
+ __divqu: 64-bit unsigned long divide
+ __remqu: 64-bit unsigned long remainder
+ __divq/__remq: signed 64-bit
+ __divlu/__remlu: unsigned 32-bit
+ __divl/__reml: signed 32-bit
+
+ These are not normal C functions: instead of the normal calling
+ sequence, these expect their arguments in registers t10 and t11, and
+ return the result in t12 (aka pv). Register AT may be clobbered
+ (assembly temporary), anything else must be saved.
+
+ Furthermore, the return address is in t9 instead of ra.
+
+ Normal function Divide functions
+ --------------- ----------------
+ v0 ($0) t12/pv ($27)
+ a0 ($16) t10 ($24)
+ a1 ($17) t11 ($25)
+ ra ($26) t9 ($23)
+
diff --git a/klibc/klibc/arch/alpha/crt0.S b/klibc/klibc/arch/alpha/crt0.S
new file mode 100644
index 0000000000..6c2958117d
--- /dev/null
+++ b/klibc/klibc/arch/alpha/crt0.S
@@ -0,0 +1,21 @@
+#
+# arch/alpha/crt0.S
+#
+
+ .text
+ .type __start,@function
+ .ent __start, 0
+ .globl __start
+__start:
+ .frame $30, 0, $26, 0
+ mov $31, $15
+ br $29, 1f
+1: ldgp $29, 0($29)
+ .prologue 0
+
+ lda $16, 0($30) # ELF data structure
+ lda $17, 0($0) # atexit pointer
+
+ jsr $26, __libc_init
+
+ .size __start,.-__start
diff --git a/klibc/klibc/arch/alpha/divide.c b/klibc/klibc/arch/alpha/divide.c
new file mode 100644
index 0000000000..49d77cd5dc
--- /dev/null
+++ b/klibc/klibc/arch/alpha/divide.c
@@ -0,0 +1,57 @@
+#include <stdint.h>
+#include <asm/gentrap.h>
+#include <asm/pal.h>
+
+#if BITS == 64
+typedef uint64_t uint;
+typedef int64_t sint;
+#else
+typedef uint32_t uint;
+typedef int32_t sint;
+#endif
+
+#ifdef SIGNED
+typedef sint xint;
+#else
+typedef uint xint;
+#endif
+
+xint NAME (uint num, uint den)
+{
+ uint quot = 0, qbit = 1;
+ int minus = 0;
+ xint v;
+
+ if ( den == 0 ) {
+ /* This is really $16, but $16 and $24 are exchanged by a script */
+ register unsigned long cause asm("$24") = GEN_INTDIV;
+ asm volatile("call_pal %0" :: "i" (PAL_gentrap), "r" (cause));
+ return 0; /* If trap returns... */
+ }
+
+#if SIGNED
+ if ( (sint)(num^den) < 0 )
+ minus = 1;
+ if ( (sint)num < 0 ) num = -num;
+ if ( (sint)den < 0 ) den = -den;
+#endif
+
+ /* Left-justify denominator and count shift */
+ while ( (sint)den >= 0 ) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while ( qbit ) {
+ if ( den <= num ) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ v = (xint)(REM ? num : quot);
+ if ( minus ) v = -v;
+ return v;
+}
diff --git a/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h b/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..9dc570a6f5
--- /dev/null
+++ b/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h
@@ -0,0 +1,33 @@
+/*
+ * arch/alpha/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __s0;
+ unsigned long __s1;
+ unsigned long __s2;
+ unsigned long __s3;
+ unsigned long __s4;
+ unsigned long __s5;
+ unsigned long __fp;
+ unsigned long __ra;
+ unsigned long __gp;
+ unsigned long __sp;
+
+ unsigned long __f2;
+ unsigned long __f3;
+ unsigned long __f4;
+ unsigned long __f5;
+ unsigned long __f6;
+ unsigned long __f7;
+ unsigned long __f8;
+ unsigned long __f9;
+};
+
+/* Must be an array so it will decay to a pointer when a function is called */
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/klibc/klibc/arch/alpha/include/klibc/archsys.h b/klibc/klibc/arch/alpha/include/klibc/archsys.h
new file mode 100644
index 0000000000..16ed658987
--- /dev/null
+++ b/klibc/klibc/arch/alpha/include/klibc/archsys.h
@@ -0,0 +1,53 @@
+/*
+ * arch/alpha/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* Alpha has some bizarre Tru64-derived system calls which return two
+ different values in $0 and $20(!), respectively. The standard
+ macros can't deal with these; even the ones that give the right
+ return value have the wrong clobbers. */
+
+#define _syscall0_dual0(type, name) \
+type name(void) \
+{ \
+ long _sc_ret, _sc_err; \
+ { \
+ register long _sc_0 __asm__("$0"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _sc_20 __asm__("$20"); \
+ \
+ _sc_0 = __NR_##name; \
+ __asm__("callsys" \
+ : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \
+ : "0"(_sc_0) \
+ : _syscall_clobbers); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; (void)(_sc_20); \
+ } \
+ _syscall_return(type); \
+}
+
+#define _syscall0_dual1(type, name) \
+type name(void) \
+{ \
+ long _sc_ret, _sc_err; \
+ { \
+ register long _sc_0 __asm__("$0"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _sc_20 __asm__("$20"); \
+ \
+ _sc_0 = __NR_##name; \
+ __asm__("callsys" \
+ : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \
+ : "0"(_sc_0) \
+ : _syscall_clobbers); \
+ _sc_ret = _sc_20, _sc_err = _sc_19; (void)(_sc_0); \
+ } \
+ _syscall_return(type); \
+}
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/alpha/include/machine/asm.h b/klibc/klibc/arch/alpha/include/machine/asm.h
new file mode 100644
index 0000000000..e22db90412
--- /dev/null
+++ b/klibc/klibc/arch/alpha/include/machine/asm.h
@@ -0,0 +1,44 @@
+/*
+ * machine/asm.h
+ */
+
+#ifndef _MACHINE_ASM_H
+#define _MACHINE_ASM_H
+
+/* Standard aliases for Alpha register names */
+
+#define v0 $0
+#define t0 $1
+#define t1 $2
+#define t2 $3
+#define t3 $4
+#define t4 $5
+#define t5 $6
+#define t6 $7
+#define t7 $8
+#define s0 $9
+#define s1 $10
+#define s2 $11
+#define s3 $12
+#define s4 $13
+#define s5 $14
+#define fp $15
+#define a0 $16
+#define a1 $17
+#define a2 $18
+#define a3 $19
+#define a4 $20
+#define a5 $21
+#define t8 $22
+#define t9 $23
+#define t10 $24
+#define t11 $25
+#define ra $26
+#define t12 $27 /* t12 and pv are both used for $27 */
+#define pv $27 /* t12 and pv are both used for $27 */
+#define at $28
+#define gp $29
+#define sp $30
+#define zero $31
+
+#endif /* _MACHINE_ASM_H */
diff --git a/klibc/klibc/arch/alpha/pipe.c b/klibc/klibc/arch/alpha/pipe.c
new file mode 100644
index 0000000000..5aee9edbab
--- /dev/null
+++ b/klibc/klibc/arch/alpha/pipe.c
@@ -0,0 +1,28 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/* pipe() on alpha returns both file descriptors in registers --
+ $0 and $20 respectively. This is unlike any other system call,
+ as far as I can tell. */
+
+int pipe(int *fds)
+{
+ register long sc_0 __asm__("$0");
+ register long sc_19 __asm__("$19");
+ register long sc_20 __asm__("$20");
+
+ sc_0 = __NR_pipe;
+ asm volatile("callsys" : "=r" (sc_0), "=r" (sc_19), "=r" (sc_20)
+ : "0" (sc_0)
+ : _syscall_clobbers);
+
+ if ( sc_19 ) {
+ errno = sc_19;
+ return -1;
+ }
+
+ fds[0] = sc_0;
+ fds[1] = sc_20;
+
+ return 0;
+}
diff --git a/klibc/klibc/arch/alpha/setjmp.S b/klibc/klibc/arch/alpha/setjmp.S
new file mode 100644
index 0000000000..e1ad642539
--- /dev/null
+++ b/klibc/klibc/arch/alpha/setjmp.S
@@ -0,0 +1,77 @@
+#
+# setjmp.S
+#
+
+#
+# The jmp_buf looks like:
+#
+# s0..5
+# fp
+# ra
+# gp
+# sp
+#
+
+#include <machine/asm.h>
+
+ .text
+ .align 3
+ .type setjmp,@function
+ .ent setjmp, 0
+ .globl setjmp
+setjmp:
+ lda v0, 0(zero)
+ stq s0, 0(a0)
+ stq s1, 8(a0)
+ stq s2, 16(a0)
+ stq s3, 24(a0)
+ stq s4, 32(a0)
+ stq s5, 40(a0)
+ stq fp, 48(a0)
+ stq ra, 56(a0)
+ stq gp, 64(a0)
+ stq sp, 72(a0)
+ stt f2, 80(a0)
+ stt f3, 88(a0)
+ stt f4, 96(a0)
+ stt f5, 104(a0)
+ stt f6, 112(a0)
+ stt f7, 120(a0)
+ stt f8, 128(a0)
+ stt f9, 136(a0)
+ ret zero,(ra),1
+
+ .size setjmp,.-setjmp
+ .end setjmp
+
+ .type longjmp,@function
+ .ent longjmp, 0
+ .globl longjmp
+longjmp:
+ mov a1, v0
+ ldq s0, 0(a0)
+ ldq s1, 8(a0)
+ ldq s2, 16(a0)
+ ldq s3, 24(a0)
+ ldq s4, 32(a0)
+ ldq s5, 40(a0)
+ ldq fp, 48(a0)
+ ldq ra, 56(a0)
+ ldq gp, 64(a0)
+ ldq sp, 72(a0)
+ ldt f2, 80(a0)
+ ldt f3, 88(a0)
+ ldt f4, 96(a0)
+ ldt f5, 104(a0)
+ ldt f6, 112(a0)
+ ldt f7, 120(a0)
+ ldt f8, 128(a0)
+ ldt f9, 136(a0)
+ /* We're bound to get a mispredict here, but at least give us
+ a chance to get the return stack back in sync... */
+ ret zero,(ra),1
+
+ .size longjmp,.-longjmp
+ .end longjmp
+
+
diff --git a/klibc/klibc/arch/arm/MCONFIG b/klibc/klibc/arch/arm/MCONFIG
new file mode 100644
index 0000000000..6fbea32903
--- /dev/null
+++ b/klibc/klibc/arch/arm/MCONFIG
@@ -0,0 +1,26 @@
+# -*- makefile -*-
+#
+# arch/arm/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+THUMB = n
+CPU_ARCH := armv4
+CPU_TUNE := strongarm
+
+OPTFLAGS = -Os -fomit-frame-pointer -march=$(CPU_ARCH) -mtune=$(CPU_TUNE)
+BITSIZE = 32
+
+ifeq ($(THUMB),y)
+CPU_ARCH := $(CPU_ARCH)t
+OPTFLAGS += -mthumb
+LDFLAGS += --thumb-entry _start
+endif
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+SHAREDFLAGS = -Ttext 0x01000200
diff --git a/klibc/klibc/arch/arm/Makefile.inc b/klibc/klibc/arch/arm/Makefile.inc
new file mode 100644
index 0000000000..3ec8c051b2
--- /dev/null
+++ b/klibc/klibc/arch/arm/Makefile.inc
@@ -0,0 +1,31 @@
+# -*- makefile -*-
+#
+# arch/arm/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ libgcc/__divsi3.o \
+ libgcc/__modsi3.o \
+ libgcc/__udivsi3.o \
+ libgcc/__umodsi3.o \
+ libgcc/__udivmodsi4.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
+
+ifeq ($(THUMB),y)
+ARCHOBJS += arch/arm/setjmp-thumb.o
+LIBGCC =
+else
+ARCHOBJS += arch/arm/setjmp-arm.o
+endif
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+archclean:
diff --git a/klibc/klibc/arch/arm/crt0.S b/klibc/klibc/arch/arm/crt0.S
new file mode 100644
index 0000000000..8cd3640c30
--- /dev/null
+++ b/klibc/klibc/arch/arm/crt0.S
@@ -0,0 +1,25 @@
+#
+# arch/arm/crt0.S
+#
+# void _start(void)
+# {
+# /* Divine up argc, argv, and envp */
+# environ = envp;
+# exit(main(argc, argv, envp));
+# }
+#
+
+ .text
+ .align 4
+ .type _start,#function
+ .globl _start
+
+#ifdef __thumb__
+ .thumb_func
+#endif
+
+_start: mov r0, sp
+ mov r1, #0
+ bl __libc_init
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/arm/include/klibc/archsetjmp.h b/klibc/klibc/arch/arm/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..c956b50a90
--- /dev/null
+++ b/klibc/klibc/arch/arm/include/klibc/archsetjmp.h
@@ -0,0 +1,14 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned int regs[10];
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/arm/include/klibc/archsys.h b/klibc/klibc/arch/arm/include/klibc/archsys.h
new file mode 100644
index 0000000000..1a77e53a65
--- /dev/null
+++ b/klibc/klibc/arch/arm/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/arm/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/arm/setjmp-arm.S b/klibc/klibc/arch/arm/setjmp-arm.S
new file mode 100644
index 0000000000..bcb30b4221
--- /dev/null
+++ b/klibc/klibc/arch/arm/setjmp-arm.S
@@ -0,0 +1,40 @@
+#
+# arch/arm/setjmp.S
+#
+# setjmp/longjmp for the ARM architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# r4
+# r5
+# r6
+# r7
+# r8
+# r9
+# r10
+# fp
+# sp
+# lr
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, #function
+setjmp:
+ stmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+ mov r0, #0
+ mov pc, lr
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, #function
+longjmp:
+ ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+ movs r0, r1
+ moveq r0, #1
+ mov pc, lr
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/arm/setjmp-thumb.S b/klibc/klibc/arch/arm/setjmp-thumb.S
new file mode 100644
index 0000000000..b581c5f7ad
--- /dev/null
+++ b/klibc/klibc/arch/arm/setjmp-thumb.S
@@ -0,0 +1,58 @@
+#
+# arch/arm/setjmp-thumb.S
+#
+# setjmp/longjmp for the ARM/thumb architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# lr
+# r4
+# r5
+# r6
+# r7
+# r8
+# r9
+# r10
+# fp
+# sp
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, #function
+ .thumb_func
+setjmp:
+ mov r3, lr
+ stmia r0!, {r3, r4, r5, r6, r7}
+ mov r3, r8
+ mov r4, r9
+ mov r5, r10
+ mov r6, fp
+ mov r7, sp
+ stmia r0!, {r3, r4, r5, r6, r7}
+ mov r0, #0
+ mov pc, lr
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, #function
+ .thumb_func
+longjmp:
+ mov r2, r0
+ add r0, #5*4
+ ldmia r0!, {r3, r4, r5, r6, r7}
+ mov r8, r3
+ mov r9, r4
+ mov r10, r5
+ mov fp, r6
+ mov sp, r7
+ ldmia r2!, {r3, r4, r5, r6, r7}
+ mov r0, r1
+ bne 1f
+ mov r0, #1
+1: mov pc, r3
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/cris/MCONFIG b/klibc/klibc/arch/cris/MCONFIG
new file mode 100644
index 0000000000..27809ebbe7
--- /dev/null
+++ b/klibc/klibc/arch/cris/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/cris/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
diff --git a/klibc/klibc/arch/cris/Makefile.inc b/klibc/klibc/arch/cris/Makefile.inc
new file mode 100644
index 0000000000..41183fd64b
--- /dev/null
+++ b/klibc/klibc/arch/cris/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/cris/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/cris/include/klibc/archsys.h b/klibc/klibc/arch/cris/include/klibc/archsys.h
new file mode 100644
index 0000000000..dfdc70a6de
--- /dev/null
+++ b/klibc/klibc/arch/cris/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/cris/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG
new file mode 100644
index 0000000000..367ee89773
--- /dev/null
+++ b/klibc/klibc/arch/i386/MCONFIG
@@ -0,0 +1,32 @@
+# -*- makefile -*-
+#
+# arch/i386/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+# Comment this out to compile with register parameter passing
+# This doesn't work right now because gcc 3.2 (at least) calls
+# libgcc with the default calling convention instead of forcing
+# them to be cdecl
+# REGPARM = -mregparm=3 -DREGPARM
+
+gcc_major := $(shell $(CC) -v 2>&1 | awk '/gcc version/{print int($$3)}')
+
+OPTFLAGS = $(REGPARM) -march=i386 -Os
+
+ifeq ($(gcc_major),3)
+OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0
+else
+OPTFLAGS += -malign-functions=0 -malign-jumps=0 -malign-loops=0
+endif
+
+BITSIZE = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 96 MB - normal binaries start at 128 MB
+SHAREDFLAGS = -Ttext 0x06000200
diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc
new file mode 100644
index 0000000000..171248a796
--- /dev/null
+++ b/klibc/klibc/arch/i386/Makefile.inc
@@ -0,0 +1,27 @@
+# -*- makefile -*-
+#
+# arch/i386/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/exits.o \
+ arch/$(ARCH)/socketcall.o \
+ arch/$(ARCH)/setjmp.o \
+ arch/$(ARCH)/libgcc/__ashldi3.o \
+ arch/$(ARCH)/libgcc/__ashrdi3.o \
+ arch/$(ARCH)/libgcc/__lshrdi3.o \
+ arch/$(ARCH)/libgcc/__muldi3.o \
+ arch/$(ARCH)/libgcc/__negdi2.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+archclean:
diff --git a/klibc/klibc/arch/i386/crt0.S b/klibc/klibc/arch/i386/crt0.S
new file mode 100644
index 0000000000..1c82eda513
--- /dev/null
+++ b/klibc/klibc/arch/i386/crt0.S
@@ -0,0 +1,33 @@
+#
+# arch/i386/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+ .text
+ .align 4
+ .type _start,@function
+ .globl _start
+_start:
+ # Save the address of the ELF argument array
+ movl %esp,%eax # Address of ELF arguments
+ # Set up a faux stack frame for the benefit of gdb
+ xorl %ebp,%ebp
+ push %ebp # Keep gdb from getting confused
+ push %ebp # Keep gdb from getting confused
+ # Push the arguments and called __libc_init()
+#ifndef REGPARM
+ push %edx # atexit() function
+ push %eax # ELF array
+#endif
+ call __libc_init
+ # If __libc_init returns, problem...
+ ud2
+ hlt
+
+ .size _start, .-_start
+
diff --git a/klibc/klibc/arch/i386/exits.S b/klibc/klibc/arch/i386/exits.S
new file mode 100644
index 0000000000..59ff563ad8
--- /dev/null
+++ b/klibc/klibc/arch/i386/exits.S
@@ -0,0 +1,45 @@
+#
+# 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/klibc/arch/i386/include/klibc/archsetjmp.h b/klibc/klibc/arch/i386/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..db04314b8c
--- /dev/null
+++ b/klibc/klibc/arch/i386/include/klibc/archsetjmp.h
@@ -0,0 +1,19 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned int __ebx;
+ unsigned int __esp;
+ unsigned int __ebp;
+ unsigned int __esi;
+ unsigned int __edi;
+ unsigned int __eip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/i386/include/klibc/archsys.h b/klibc/klibc/arch/i386/include/klibc/archsys.h
new file mode 100644
index 0000000000..e21487b256
--- /dev/null
+++ b/klibc/klibc/arch/i386/include/klibc/archsys.h
@@ -0,0 +1,96 @@
+/*
+ * arch/i386/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/*
+ * If we're compiling i386 in PIC mode, we need to treat %ebx
+ * specially. Most of these are copied from the equivalent file in
+ * newlib and were written by Werner Almesberger.
+ */
+#if defined(__PIC__)
+
+/* _syscall0() is the same as non-PIC */
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"r" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall5
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall6
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+__asm__ __volatile__ ("push %%ebx; pushl %%ebp; movl %2,%%ebx; " \
+ "movl %%eax,%%ebp; movl %1,%%eax; int $0x80; " \
+ "pop %%ebp ; pop %%ebx" \
+ : "=a" (__res) \
+ : "i" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+ "a" ((long)(arg6))); \
+__syscall_return(type,__res); \
+}
+
+#endif /* __PIC__ */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/i386/include/klibc/diverr.h b/klibc/klibc/arch/i386/include/klibc/diverr.h
new file mode 100644
index 0000000000..410aba06d3
--- /dev/null
+++ b/klibc/klibc/arch/i386/include/klibc/diverr.h
@@ -0,0 +1,16 @@
+/*
+ * arch/i386/include/klibc/diverr.h
+ */
+
+#ifndef _KLIBC_DIVERR_H
+#define _KLIBC_DIVERR_H
+
+#include <signal.h>
+
+static __inline__ void
+__divide_error(void)
+{
+ asm volatile("divl %0" :: "rm" (0) : "eax", "edx");
+}
+
+#endif /* _KLIBC_DIVERR_H */
diff --git a/klibc/klibc/arch/i386/libgcc/__ashldi3.S b/klibc/klibc/arch/i386/libgcc/__ashldi3.S
new file mode 100644
index 0000000000..80ed4be3cf
--- /dev/null
+++ b/klibc/klibc/arch/i386/libgcc/__ashldi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashldi3.S
+ *
+ * 64-bit shl
+ */
+ .text
+ .align 4
+ .globl __ashldi3
+ .type __ashldi3,@function
+__ashldi3:
+#ifndef REGPARM
+ movl 4(%esp),%eax
+ movl 8(%esp),%edx
+ movb 12(%esp),%cl
+#endif
+ cmpb $32,%cl
+ jae 1f
+
+ shldl %cl,%eax,%edx
+ shl %cl,%eax
+ ret
+
+1:
+ xorl %edx,%edx
+ shl %cl,%eax
+ xchgl %edx,%eax
+ ret
+
+ .size __ashldi3,.-__ashldi3
diff --git a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S
new file mode 100644
index 0000000000..ba43f9022a
--- /dev/null
+++ b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashrdi3.S
+ *
+ * 64-bit sar
+ */
+ .text
+ .align 4
+ .globl __ashrdi3
+ .type __ashrdi3,@function
+__ashrdi3:
+#ifndef REGPARM
+ movl 4(%esp),%eax
+ movl 8(%esp),%edx
+ movb 12(%esp),%cl
+#endif
+ cmpb $32,%cl
+ jae 1f
+
+ shrdl %cl,%edx,%eax
+ sarl %cl,%edx
+ ret
+
+1:
+ sarl %cl,%edx
+ movl %edx,%eax
+ cdq
+ ret
+
+ .size __ashrdi3,.-__ashrdi3
diff --git a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S
new file mode 100644
index 0000000000..6e521ace2c
--- /dev/null
+++ b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__lshrdi3.S
+ *
+ * 64-bit shr
+ */
+ .text
+ .align 4
+ .globl __lshrdi3
+ .type __lshrdi3,@function
+__lshrdi3:
+#ifndef REGPARM
+ movl 4(%esp),%eax
+ movl 8(%esp),%edx
+ movb 12(%esp),%cl
+#endif
+ cmpb $32,%cl
+ jae 1f
+
+ shrdl %cl,%edx,%eax
+ shrl %cl,%edx
+ ret
+
+1:
+ shrl %cl,%edx
+ xorl %eax,%eax
+ xchgl %edx,%eax
+ ret
+
+ .size __lshrdi3,.-__lshrdi3
diff --git a/klibc/klibc/arch/i386/libgcc/__muldi3.S b/klibc/klibc/arch/i386/libgcc/__muldi3.S
new file mode 100644
index 0000000000..c164588b16
--- /dev/null
+++ b/klibc/klibc/arch/i386/libgcc/__muldi3.S
@@ -0,0 +1,34 @@
+/*
+ * arch/i386/libgcc/__muldi3.S
+ *
+ * 64*64 = 64 bit unsigned multiplication
+ */
+
+ .text
+ .align 4
+ .globl __muldi3
+ .type __muldi3,@function
+__muldi3:
+ push %esi
+#ifndef REGPARM
+ movl 8(%esp),%eax
+ movl %eax,%esi
+ movl 16(%esp),%ecx
+ mull %ecx
+ imull 12(%esp),%ecx
+ imull 20(%esp),%esi
+ addl %ecx,%edx
+ addl %esi,%edx
+#else
+ movl %eax,%esi
+ push %edx
+ mull %ecx
+ imull 8(%esp),%esi
+ addl %esi,%edx
+ pop %esi
+ imull %esi,%ecx
+ addl %ecx,%edx
+#endif
+ pop %esi
+ ret
+ .size __muldi3,.-__muldi3
diff --git a/klibc/klibc/arch/i386/libgcc/__negdi2.S b/klibc/klibc/arch/i386/libgcc/__negdi2.S
new file mode 100644
index 0000000000..6c95cb235c
--- /dev/null
+++ b/klibc/klibc/arch/i386/libgcc/__negdi2.S
@@ -0,0 +1,21 @@
+/*
+ * arch/i386/libgcc/__negdi2.S
+ *
+ * 64-bit negation
+ */
+
+ .text
+ .align 4
+ .globl __negdi2
+ .type __negdi2,@function
+__negdi2:
+#ifndef REGPARM
+ movl 4(%esp),%eax
+ movl 8(%esp),%edx
+#endif
+ negl %edx
+ negl %eax
+ sbbl $0,%edx
+ ret
+
+ .size __negdi2,.-__negdi2
diff --git a/klibc/klibc/arch/i386/setjmp.S b/klibc/klibc/arch/i386/setjmp.S
new file mode 100644
index 0000000000..bea900c519
--- /dev/null
+++ b/klibc/klibc/arch/i386/setjmp.S
@@ -0,0 +1,58 @@
+#
+# arch/i386/setjmp.S
+#
+# setjmp/longjmp for the i386 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# %ebx
+# %esp
+# %ebp
+# %esi
+# %edi
+# <return address>
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+#ifdef REGPARM
+ movl %eax,%edx
+#else
+ movl 4(%esp),%edx
+#endif
+ popl %ecx # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movl %ebx,(%edx)
+ movl %esp,4(%edx) # Post-return %esp!
+ pushl %ecx # Make the call/return stack happy
+ movl %ebp,8(%edx)
+ movl %esi,12(%edx)
+ movl %edi,16(%edx)
+ movl %ecx,20(%edx) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+#ifdef REGPARM
+ xchgl %eax,%edx
+#else
+ movl 4(%esp),%edx # jmp_ptr address
+ movl 8(%esp),%eax # Return value
+#endif
+ movl (%edx),%ebx
+ movl 4(%edx),%esp
+ movl 8(%edx),%ebp
+ movl 12(%edx),%esi
+ movl 16(%edx),%edi
+ jmp *20(%edx)
+
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/i386/socketcall.S b/klibc/klibc/arch/i386/socketcall.S
new file mode 100644
index 0000000000..6bac1e6913
--- /dev/null
+++ b/klibc/klibc/arch/i386/socketcall.S
@@ -0,0 +1,38 @@
+#
+# socketcall.S
+#
+# On i386, the main (only?) user of socketcall(2), the memory array
+# socketcall(2) needs is conveniently already assembled for us on
+# the stack. Capitalize on that to make a common socketcall stub.
+#
+
+#include <asm/unistd.h>
+
+#ifdef __i386__
+
+ .text
+ .align 4
+ .globl __socketcall_common
+ .type __socketcall_common, @function
+
+__socketcall_common:
+ pushl %ebx
+ movzbl %al,%ebx # The socketcall number is passed in in %al
+ leal 8(%esp),%ecx # Argument pointer
+ movl $__NR_socketcall, %eax
+ int $0x80
+ cmpl $-125,%eax # Error return?
+ popl %ebx
+ jb 1f
+ neg %eax
+ movl %eax,errno
+ xorl %eax,%eax
+ decl %eax # Return = -1
+1:
+ ret
+
+ .size __socketcall_common,.-__socketcall_common
+
+#endif
+
+
diff --git a/klibc/klibc/arch/ia64/MCONFIG b/klibc/klibc/arch/ia64/MCONFIG
new file mode 100644
index 0000000000..631a478e4f
--- /dev/null
+++ b/klibc/klibc/arch/ia64/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/ia64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc
new file mode 100644
index 0000000000..1fb364f92e
--- /dev/null
+++ b/klibc/klibc/arch/ia64/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/ia64/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/ia64/include/klibc/archsys.h b/klibc/klibc/arch/ia64/include/klibc/archsys.h
new file mode 100644
index 0000000000..ef5940ac25
--- /dev/null
+++ b/klibc/klibc/arch/ia64/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/ia64/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/m68k/MCONFIG b/klibc/klibc/arch/m68k/MCONFIG
new file mode 100644
index 0000000000..2ba69b3178
--- /dev/null
+++ b/klibc/klibc/arch/m68k/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/m68k/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
diff --git a/klibc/klibc/arch/m68k/Makefile.inc b/klibc/klibc/arch/m68k/Makefile.inc
new file mode 100644
index 0000000000..9abec14db1
--- /dev/null
+++ b/klibc/klibc/arch/m68k/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/m68k/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/m68k/include/klibc/archsys.h b/klibc/klibc/arch/m68k/include/klibc/archsys.h
new file mode 100644
index 0000000000..8f6bed8e94
--- /dev/null
+++ b/klibc/klibc/arch/m68k/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/m68k/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/mips/MCONFIG b/klibc/klibc/arch/mips/MCONFIG
new file mode 100644
index 0000000000..52b518461f
--- /dev/null
+++ b/klibc/klibc/arch/mips/MCONFIG
@@ -0,0 +1,18 @@
+# -*- makefile -*-
+#
+# arch/mips/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHREQFLAGS = -fno-pic -mno-abicalls
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 2 MB -- the normal starting point for text is 4 MB.
+SHAREDFLAGS = -Ttext 0x00200200
diff --git a/klibc/klibc/arch/mips/Makefile.inc b/klibc/klibc/arch/mips/Makefile.inc
new file mode 100644
index 0000000000..09a2d2f736
--- /dev/null
+++ b/klibc/klibc/arch/mips/Makefile.inc
@@ -0,0 +1,24 @@
+# -*- makefile -*-
+#
+# arch/mips/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/pipe.o \
+ arch/$(ARCH)/vfork.o \
+ arch/$(ARCH)/setjmp.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
+
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+
+archclean:
diff --git a/klibc/klibc/arch/mips/crt0.S b/klibc/klibc/arch/mips/crt0.S
new file mode 100644
index 0000000000..42d9dd5e38
--- /dev/null
+++ b/klibc/klibc/arch/mips/crt0.S
@@ -0,0 +1,25 @@
+#
+# arch/mips/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+#include <machine/asm.h>
+
+NESTED(__start, 32, sp)
+ subu sp, 32
+ sw zero, 16(sp)
+
+ lui gp, %hi(_gp) # Initialize gp
+ addiu gp, gp, _gp
+
+ addiu a0, sp, 32 # Pointer to ELF entry structure
+ move a1, v0 # Kernel-provided atexit() pointer
+
+ jal __libc_init
+
+ END(__start)
diff --git a/klibc/klibc/arch/mips/include/klibc/archsetjmp.h b/klibc/klibc/arch/mips/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..40e5be2736
--- /dev/null
+++ b/klibc/klibc/arch/mips/include/klibc/archsetjmp.h
@@ -0,0 +1,39 @@
+/*
+ * arch/mips/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __s0;
+ unsigned long __s1;
+ unsigned long __s2;
+ unsigned long __s3;
+ unsigned long __s4;
+ unsigned long __s5;
+ unsigned long __s6;
+ unsigned long __s7;
+ unsigned long __gp;
+ unsigned long __sp;
+ unsigned long __s8;
+ unsigned long __ra;
+ unsigned long __f20;
+ unsigned long __f21;
+ unsigned long __f22;
+ unsigned long __f23;
+ unsigned long __f24;
+ unsigned long __f25;
+ unsigned long __f26;
+ unsigned long __f27;
+ unsigned long __f28;
+ unsigned long __f29;
+ unsigned long __f30;
+ unsigned long __f31;
+ unsigned long __fcr31;
+ unsigned long __unused;
+} __attribute__((aligned(8)));
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/klibc/klibc/arch/mips/include/klibc/archsys.h b/klibc/klibc/arch/mips/include/klibc/archsys.h
new file mode 100644
index 0000000000..f696cdfaa7
--- /dev/null
+++ b/klibc/klibc/arch/mips/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/mips/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/mips/include/machine/asm.h b/klibc/klibc/arch/mips/include/machine/asm.h
new file mode 100644
index 0000000000..e5239a6cef
--- /dev/null
+++ b/klibc/klibc/arch/mips/include/machine/asm.h
@@ -0,0 +1,11 @@
+/*
+ * arch/mips/include/machine/asm.h
+ */
+
+#ifndef _MACHINE_ASM_H
+#define _MACHINE_ASM_H
+
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+#endif /* _MACHINE_ASM_H */
diff --git a/klibc/klibc/arch/mips/include/sgidefs.h b/klibc/klibc/arch/mips/include/sgidefs.h
new file mode 100644
index 0000000000..eb103ace2c
--- /dev/null
+++ b/klibc/klibc/arch/mips/include/sgidefs.h
@@ -0,0 +1,20 @@
+/*
+ * arch/mips/include/sgidefs.h
+ */
+
+/* Some ABI constants */
+
+#ifndef _SGIDEFS_H
+#define _SGIDEFS_H
+
+#define _MIPS_ISA_MIPS1 1
+#define _MIPS_ISA_MIPS2 2
+#define _MIPS_ISA_MIPS3 3
+#define _MIPS_ISA_MIPS4 4
+#define _MIPS_ISA_MIPS5 5
+
+#define _MIPS_SIM_ABI32 1
+#define _MIPS_SIM_NABI32 2
+#define _MIPS_SIM_ABI64 3
+
+#endif /* _SGIDEFS_H */
diff --git a/klibc/klibc/arch/mips/pipe.S b/klibc/klibc/arch/mips/pipe.S
new file mode 100644
index 0000000000..d79f614025
--- /dev/null
+++ b/klibc/klibc/arch/mips/pipe.S
@@ -0,0 +1,16 @@
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/unistd.h>
+
+LEAF(pipe)
+ li v0, __NR_pipe
+ syscall
+ bnez a3, 1f
+ sw v0, (a0)
+ sw v1, (a1)
+ li v0, 0
+ b 2f
+1: sw v0, errno
+ li v0, -1
+2: jr ra
+ END(pipe)
diff --git a/klibc/klibc/arch/mips/setjmp.S b/klibc/klibc/arch/mips/setjmp.S
new file mode 100644
index 0000000000..4d293757ec
--- /dev/null
+++ b/klibc/klibc/arch/mips/setjmp.S
@@ -0,0 +1,82 @@
+#
+# arch/mips/setjmp.S
+#
+# setjmp/longjmp for the MIPS architecture
+#
+# The jmp_buf is assumed to contain the following, in order:
+# s0..s7
+# gp
+# sp
+# s8
+# ra
+# f20..f31
+# fcr31
+#
+
+#include <machine/asm.h>
+
+LEAF(setjmp)
+ sw s0, 0(a0)
+ sw s1, 4(a0)
+ sw s2, 8(a0)
+ sw s3, 12(a0)
+ sw s4, 16(a0)
+ sw s5, 20(a0)
+ sw s6, 24(a0)
+ sw s7, 28(a0)
+ sw gp, 32(a0)
+ sw sp, 36(a0)
+ sw s8, 40(a0)
+ sw ra, 44(a0)
+ cfc1 t0,$31
+ swc1 $f20,48(a0)
+ swc1 $f21,52(a0)
+ swc1 $f22,56(a0)
+ swc1 $f23,60(a0)
+ swc1 $f24,64(a0)
+ swc1 $f25,68(a0)
+ swc1 $f26,72(a0)
+ swc1 $f27,76(a0)
+ swc1 $f28,80(a0)
+ swc1 $f29,84(a0)
+ swc1 $f30,88(a0)
+ swc1 $f31,92(a0)
+ sw t0,96(a0)
+ move v0,zero
+ jr ra
+
+ END(setjmp)
+
+LEAF(longjmp)
+ lw s0, 0(a0)
+ lw s1, 4(a0)
+ lw s2, 8(a0)
+ lw s3, 12(a0)
+ lw s4, 16(a0)
+ lw s5, 20(a0)
+ lw s6, 24(a0)
+ lw s7, 28(a0)
+ lw gp, 32(a0)
+ lw sp, 36(a0)
+ lw s8, 40(a0)
+ lw ra, 44(a0)
+ lw t0, 96(a0)
+ lwc1 $f20,48(a0)
+ lwc1 $f21,52(a0)
+ lwc1 $f22,56(a0)
+ lwc1 $f23,60(a0)
+ lwc1 $f24,64(a0)
+ lwc1 $f25,68(a0)
+ lwc1 $f26,72(a0)
+ lwc1 $f27,76(a0)
+ lwc1 $f28,80(a0)
+ lwc1 $f29,84(a0)
+ lwc1 $f30,88(a0)
+ lwc1 $f31,92(a0)
+ ctc1 t0,$31
+ move v0,a1
+ jr ra
+
+ END(longjmp)
+
+ \ No newline at end of file
diff --git a/klibc/klibc/arch/mips/vfork.S b/klibc/klibc/arch/mips/vfork.S
new file mode 100644
index 0000000000..aca8083aa4
--- /dev/null
+++ b/klibc/klibc/arch/mips/vfork.S
@@ -0,0 +1,19 @@
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/unistd.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_VFORK 0x00004000
+#define SIGCHLD 18
+
+LEAF(vfork)
+ li a0, CLONE_VFORK | CLONE_VM | SIGCHLD
+ li a1, 0
+ li v0, __NR_clone
+ syscall
+ bnez a3, 1f
+ b 2f
+1: sw v0, errno
+ li v0, -1
+2: jr ra
+ END(vfork)
diff --git a/klibc/klibc/arch/mips64/MCONFIG b/klibc/klibc/arch/mips64/MCONFIG
new file mode 100644
index 0000000000..6a817e54b6
--- /dev/null
+++ b/klibc/klibc/arch/mips64/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/mips64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
diff --git a/klibc/klibc/arch/mips64/Makefile.inc b/klibc/klibc/arch/mips64/Makefile.inc
new file mode 100644
index 0000000000..4a9529adca
--- /dev/null
+++ b/klibc/klibc/arch/mips64/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/mips64/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/mips64/include/klibc/archsys.h b/klibc/klibc/arch/mips64/include/klibc/archsys.h
new file mode 100644
index 0000000000..81e5106e16
--- /dev/null
+++ b/klibc/klibc/arch/mips64/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/mips64/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/parisc/MCONFIG b/klibc/klibc/arch/parisc/MCONFIG
new file mode 100644
index 0000000000..93a31707c6
--- /dev/null
+++ b/klibc/klibc/arch/parisc/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/parisc/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
diff --git a/klibc/klibc/arch/parisc/Makefile.inc b/klibc/klibc/arch/parisc/Makefile.inc
new file mode 100644
index 0000000000..f7a983da7f
--- /dev/null
+++ b/klibc/klibc/arch/parisc/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/parisc/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/parisc/include/klibc/archsys.h b/klibc/klibc/arch/parisc/include/klibc/archsys.h
new file mode 100644
index 0000000000..5013ba8794
--- /dev/null
+++ b/klibc/klibc/arch/parisc/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/parisc/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/ppc/MCONFIG b/klibc/klibc/arch/ppc/MCONFIG
new file mode 100644
index 0000000000..fcb0992150
--- /dev/null
+++ b/klibc/klibc/arch/ppc/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/ppc/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
diff --git a/klibc/klibc/arch/ppc/Makefile.inc b/klibc/klibc/arch/ppc/Makefile.inc
new file mode 100644
index 0000000000..6e87a48d6b
--- /dev/null
+++ b/klibc/klibc/arch/ppc/Makefile.inc
@@ -0,0 +1,15 @@
+# -*- makefile -*-
+#
+# arch/ppc/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+archclean:
diff --git a/klibc/klibc/arch/ppc/crt0.S b/klibc/klibc/arch/ppc/crt0.S
new file mode 100644
index 0000000000..f7274b07dd
--- /dev/null
+++ b/klibc/klibc/arch/ppc/crt0.S
@@ -0,0 +1,29 @@
+#
+# arch/ppc/crt0.S
+#
+# void _start(void)
+# {
+# /* Divine up argc, argv, and envp */
+# environ = envp;
+# exit(main(argc, argv, envp));
+# }
+#
+
+ .text
+ .align 4
+ .type _start,@function
+ .globl _start
+_start:
+ lwz 3,0(1)
+ addi 4,1,4
+ addi 5,1,8
+ slwi 0,3,2
+ add 5,5,0
+ li 0,0
+ stwu 0,-16(1)
+ lis 9,environ@ha
+ stw 5,environ@l(9)
+ bl main
+ bl exit
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h b/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..53e2fccc3b
--- /dev/null
+++ b/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h
@@ -0,0 +1,36 @@
+/*
+ * arch/ppc/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __r2;
+ unsigned long __sp;
+ unsigned long __lr;
+ unsigned long __cr;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+ unsigned long __r16;
+ unsigned long __r17;
+ unsigned long __r18;
+ unsigned long __r19;
+ unsigned long __r20;
+ unsigned long __r21;
+ unsigned long __r22;
+ unsigned long __r23;
+ unsigned long __r24;
+ unsigned long __r25;
+ unsigned long __r26;
+ unsigned long __r27;
+ unsigned long __r28;
+ unsigned long __r29;
+ unsigned long __r30;
+ unsigned long __r31;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/ppc/include/klibc/archsys.h b/klibc/klibc/arch/ppc/include/klibc/archsys.h
new file mode 100644
index 0000000000..33a5ff3236
--- /dev/null
+++ b/klibc/klibc/arch/ppc/include/klibc/archsys.h
@@ -0,0 +1,55 @@
+/*
+ * arch/ppc/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* PowerPC seems to lack _syscall6() in its headers */
+/* This seems to work on both 32- and 64-bit ppc */
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+ unsigned long __sc_ret, __sc_err; \
+ { \
+ register unsigned long __sc_0 __asm__ ("r0"); \
+ register unsigned long __sc_3 __asm__ ("r3"); \
+ register unsigned long __sc_4 __asm__ ("r4"); \
+ register unsigned long __sc_5 __asm__ ("r5"); \
+ register unsigned long __sc_6 __asm__ ("r6"); \
+ register unsigned long __sc_7 __asm__ ("r7"); \
+ register unsigned long __sc_8 __asm__ ("r8"); \
+ \
+ __sc_3 = (unsigned long) (arg1); \
+ __sc_4 = (unsigned long) (arg2); \
+ __sc_5 = (unsigned long) (arg3); \
+ __sc_6 = (unsigned long) (arg4); \
+ __sc_7 = (unsigned long) (arg5); \
+ __sc_8 = (unsigned long) (arg6); \
+ __sc_0 = __NR_##name; \
+ __asm__ __volatile__ \
+ ("sc \n\t" \
+ "mfcr %1 " \
+ : "=&r" (__sc_3), "=&r" (__sc_0) \
+ : "0" (__sc_3), "1" (__sc_0), \
+ "r" (__sc_4), \
+ "r" (__sc_5), \
+ "r" (__sc_6), \
+ "r" (__sc_7), \
+ "r" (__sc_8) \
+ : __syscall_clobbers); \
+ __sc_ret = __sc_3; \
+ __sc_err = __sc_0; \
+ } \
+ __syscall_return (type); \
+}
+
+#endif /* _syscall6() missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/ppc/setjmp.S b/klibc/klibc/arch/ppc/setjmp.S
new file mode 100644
index 0000000000..1c50301707
--- /dev/null
+++ b/klibc/klibc/arch/ppc/setjmp.S
@@ -0,0 +1,35 @@
+#
+# arch/ppc/setjmp.S
+#
+# Basic setjmp/longjmp implementation
+# This file was derived from the equivalent file in NetBSD
+#
+
+ .text
+ .align 4
+ .type setjmp,@function
+ .globl setjmp
+setjmp:
+ mflr %r11 /* save return address */
+ mfcr %r12 /* save condition register */
+ mr %r10,%r1 /* save stack pointer */
+ mr %r9,%r2 /* save GPR2 (not needed) */
+ stmw %r9,0(%r3) /* save r9..r31 */
+ li %r3,0 /* indicate success */
+ blr /* return */
+
+ .size setjmp,.-setjmp
+
+ .type longjmp,@function
+ .globl longjmp
+longjmp:
+ lmw %r9,0(%r3) /* save r9..r31 */
+ mtlr %r11 /* restore LR */
+ mtcr %r12 /* restore CR */
+ mr %r2,%r9 /* restore GPR2 (not needed) */
+ mr %r1,%r10 /* restore stack */
+ mr %r3,%r4 /* get return value */
+ blr /* return */
+
+ .size longjmp,.-longjmp
+ \ No newline at end of file
diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG
new file mode 100644
index 0000000000..6997693e99
--- /dev/null
+++ b/klibc/klibc/arch/ppc64/MCONFIG
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+#
+# arch/ppc64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc
new file mode 100644
index 0000000000..434d0aad96
--- /dev/null
+++ b/klibc/klibc/arch/ppc64/Makefile.inc
@@ -0,0 +1,10 @@
+# -*- makefile -*-
+#
+# arch/ppc64/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+archclean:
diff --git a/klibc/klibc/arch/ppc64/crt0.S b/klibc/klibc/arch/ppc64/crt0.S
new file mode 100644
index 0000000000..2f352e8045
--- /dev/null
+++ b/klibc/klibc/arch/ppc64/crt0.S
@@ -0,0 +1,38 @@
+#
+# arch/ppc64/crt0.S
+#
+# void _start(void)
+# {
+# /* Divine up argc, argv, and envp */
+# environ = envp;
+# exit(main(argc, argv, envp));
+# }
+#
+
+ .section ".toc","aw"
+.LC0: .tc environ[TC],environ
+
+ .section ".opd","aw"
+ .align 3
+ .globl _start
+_start:
+ .quad ._start
+ .quad .TOC.@tocbase, 0
+
+ .text
+ .globl ._start
+ .type ._start,@function
+._start:
+ ld 3,0(1)
+ ld 4,8(1)
+ ld 5,16(1)
+ li 0,0
+ stdu 0,-64(1)
+ ld 9,.LC0@toc(2)
+ std 5,0(9)
+ bl .main
+ nop
+ bl .exit
+ nop
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsys.h b/klibc/klibc/arch/ppc64/include/klibc/archsys.h
new file mode 100644
index 0000000000..4f81fee00d
--- /dev/null
+++ b/klibc/klibc/arch/ppc64/include/klibc/archsys.h
@@ -0,0 +1,52 @@
+/*
+ * arch/ppc64/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+ unsigned long __sc_ret, __sc_err; \
+ { \
+ register unsigned long __sc_0 __asm__ ("r0"); \
+ register unsigned long __sc_3 __asm__ ("r3"); \
+ register unsigned long __sc_4 __asm__ ("r4"); \
+ register unsigned long __sc_5 __asm__ ("r5"); \
+ register unsigned long __sc_6 __asm__ ("r6"); \
+ register unsigned long __sc_7 __asm__ ("r7"); \
+ register unsigned long __sc_8 __asm__ ("r8"); \
+ \
+ __sc_3 = (unsigned long) (arg1); \
+ __sc_4 = (unsigned long) (arg2); \
+ __sc_5 = (unsigned long) (arg3); \
+ __sc_6 = (unsigned long) (arg4); \
+ __sc_7 = (unsigned long) (arg5); \
+ __sc_8 = (unsigned long) (arg6); \
+ __sc_0 = __NR_##name; \
+ __asm__ __volatile__ \
+ ("sc \n\t" \
+ "mfcr %1 " \
+ : "=&r" (__sc_3), "=&r" (__sc_0) \
+ : "0" (__sc_3), "1" (__sc_0), \
+ "r" (__sc_4), \
+ "r" (__sc_5), \
+ "r" (__sc_6), \
+ "r" (__sc_7), \
+ "r" (__sc_8) \
+ : __syscall_clobbers); \
+ __sc_ret = __sc_3; \
+ __sc_err = __sc_0; \
+ } \
+ __syscall_return (type); \
+}
+
+#endif /* _syscall6() missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/s390/MCONFIG b/klibc/klibc/arch/s390/MCONFIG
new file mode 100644
index 0000000000..e32c33faa1
--- /dev/null
+++ b/klibc/klibc/arch/s390/MCONFIG
@@ -0,0 +1,13 @@
+# -*- makefile -*-
+#
+# arch/s390/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
+
+SHAREDFLAGS = -Ttext 0x40000200
diff --git a/klibc/klibc/arch/s390/Makefile.inc b/klibc/klibc/arch/s390/Makefile.inc
new file mode 100644
index 0000000000..45aa551695
--- /dev/null
+++ b/klibc/klibc/arch/s390/Makefile.inc
@@ -0,0 +1,16 @@
+# -*- makefile -*-
+#
+# arch/s390/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+
+archclean:
diff --git a/klibc/klibc/arch/s390/crt0.S b/klibc/klibc/arch/s390/crt0.S
new file mode 100644
index 0000000000..49c3e7ebc7
--- /dev/null
+++ b/klibc/klibc/arch/s390/crt0.S
@@ -0,0 +1,25 @@
+#
+# arch/s390/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+ .text
+ .align 4
+ .type _start,@function
+ .globl _start
+_start:
+ lr %r2,%r15
+ lhi %r3,0
+ ahi %r15,-96
+ bras %r1,.L0
+.L0:
+ l %r1,.L1-.L0(%r1)
+ br %r1
+.L1:
+ .long __libc_init
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/s390/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..11a641ed5a
--- /dev/null
+++ b/klibc/klibc/arch/s390/include/klibc/archsetjmp.h
@@ -0,0 +1,15 @@
+/*
+ * arch/s390/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ uint32_t __gregs[10]; /* general registers r6-r15 */
+ uint64_t __fpregs[2]; /* fp registers f4 and f6 */
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/s390/include/klibc/archsys.h b/klibc/klibc/arch/s390/include/klibc/archsys.h
new file mode 100644
index 0000000000..1cd0948f3c
--- /dev/null
+++ b/klibc/klibc/arch/s390/include/klibc/archsys.h
@@ -0,0 +1,41 @@
+/*
+ * arch/s390/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* S/390 only has five syscall parameters, and uses a structure for
+ 6-argument syscalls. */
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\
+ type4,arg4,type5,arg5,type6,arg6) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ unsigned long __arg[6] = { \
+ (unsigned long) arg1, \
+ (unsigned long) arg2, \
+ (unsigned long) arg3, \
+ (unsigned long) arg4, \
+ (unsigned long) arg5, \
+ (unsigned long) arg6 \
+ }; \
+ register void *__argp asm("2") = &__arg; \
+ long __res; \
+ __asm__ __volatile__ ( \
+ " svc %b1\n" \
+ " lr %0,2" \
+ : "=d" (__res) \
+ : "i" (__NR_##name), \
+ "d" (__argp) \
+ : _svc_clobber); \
+ __syscall_return(type, __res); \
+}
+
+#endif /* _syscall6() missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/s390/setjmp.S b/klibc/klibc/arch/s390/setjmp.S
new file mode 100644
index 0000000000..97132680ae
--- /dev/null
+++ b/klibc/klibc/arch/s390/setjmp.S
@@ -0,0 +1,32 @@
+#
+# arch/s390/setjmp.S
+#
+# setjmp/longjmp for the s390 architecture
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ stm %r6,%r15,0(%r2) # save all general registers
+ std %f4,40(%r2) # save fp registers f4 and f6
+ std %f6,48(%r2)
+ lhi %r2,0 # return 0
+ br %r14
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ lr %r1,%r2 # jmp_buf
+ lr %r2,%r3 # return value
+ ld %f6,48(%r1) # restore all saved registers
+ ld %f4,40(%r1)
+ lm %r6,%r15,0(%r1)
+ br %r14 # return to restored address
+
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/s390x/MCONFIG b/klibc/klibc/arch/s390x/MCONFIG
new file mode 100644
index 0000000000..1c8232bed5
--- /dev/null
+++ b/klibc/klibc/arch/s390x/MCONFIG
@@ -0,0 +1,13 @@
+# -*- makefile -*-
+#
+# arch/s390x/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
+
+SHAREDFLAGS = -Ttext 0x40000200
diff --git a/klibc/klibc/arch/s390x/Makefile.inc b/klibc/klibc/arch/s390x/Makefile.inc
new file mode 100644
index 0000000000..eff8f951ac
--- /dev/null
+++ b/klibc/klibc/arch/s390x/Makefile.inc
@@ -0,0 +1,16 @@
+# -*- makefile -*-
+#
+# arch/s390x/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+
+archclean:
diff --git a/klibc/klibc/arch/s390x/crt0.S b/klibc/klibc/arch/s390x/crt0.S
new file mode 100644
index 0000000000..de35664904
--- /dev/null
+++ b/klibc/klibc/arch/s390x/crt0.S
@@ -0,0 +1,21 @@
+#
+# arch/s390/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+ .text
+ .align 4
+ .type _start,@function
+ .globl _start
+_start:
+ lgr %r2,%r15
+ lghi %r3,0
+ aghi %r15,-160
+ jg __libc_init
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..dd3ed0d47c
--- /dev/null
+++ b/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h
@@ -0,0 +1,15 @@
+/*
+ * arch/s390x/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ uint64_t __gregs[10]; /* general registers r6-r15 */
+ uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/s390x/include/klibc/archsys.h b/klibc/klibc/arch/s390x/include/klibc/archsys.h
new file mode 100644
index 0000000000..15f7113bb4
--- /dev/null
+++ b/klibc/klibc/arch/s390x/include/klibc/archsys.h
@@ -0,0 +1,41 @@
+/*
+ * arch/s390x/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* S/390X only has five syscall parameters, and uses a structure for
+ 6-argument syscalls. */
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\
+ type4,arg4,type5,arg5,type6,arg6) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ unsigned long __arg[6] = { \
+ (unsigned long) arg1, \
+ (unsigned long) arg2, \
+ (unsigned long) arg3, \
+ (unsigned long) arg4, \
+ (unsigned long) arg5, \
+ (unsigned long) arg6 \
+ }; \
+ register void *__argp asm("2") = &__arg; \
+ long __res; \
+ __asm__ __volatile__ ( \
+ " svc %b1\n" \
+ " lgr %0,2" \
+ : "=d" (__res) \
+ : "i" (__NR_##name), \
+ "d" (__argp) \
+ : _svc_clobber); \
+ __syscall_return(type, __res); \
+}
+
+#endif /* _syscall6() missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/s390x/setjmp.S b/klibc/klibc/arch/s390x/setjmp.S
new file mode 100644
index 0000000000..251c57d43a
--- /dev/null
+++ b/klibc/klibc/arch/s390x/setjmp.S
@@ -0,0 +1,36 @@
+#
+# arch/s390x/setjmp.S
+#
+# setjmp/longjmp for the s390x architecture
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ stmg %r6,%r15,0(%r2) # save all general registers
+ std %f1,80(%r2) # save fp registers f4 and f6
+ std %f3,88(%r2)
+ std %f5,96(%r2)
+ std %f7,104(%r2)
+ lghi %r2,0 # return 0
+ br %r14
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ lgr %r1,%r2 # jmp_buf
+ lgr %r2,%r3 # return value
+ ld %f7,104(%r1) # restore all saved registers
+ ld %f5,96(%r1)
+ ld %f3,88(%r1)
+ ld %f1,80(%r1)
+ lmg %r6,%r15,0(%r1)
+ br %r14 # return to restored address
+
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/sh/MCONFIG b/klibc/klibc/arch/sh/MCONFIG
new file mode 100644
index 0000000000..6cd4e5c839
--- /dev/null
+++ b/klibc/klibc/arch/sh/MCONFIG
@@ -0,0 +1,19 @@
+# -*- makefile -*-
+#
+# arch/sh/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHREGFLAGS = -m4 -mno-implicit-fp
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 2 MB -- the normal starting point for text is 4 MB.
+SHAREDFLAGS = -Ttext 0x00200200
+
diff --git a/klibc/klibc/arch/sh/Makefile.inc b/klibc/klibc/arch/sh/Makefile.inc
new file mode 100644
index 0000000000..16d7ea1e18
--- /dev/null
+++ b/klibc/klibc/arch/sh/Makefile.inc
@@ -0,0 +1,14 @@
+# -*- makefile -*-
+#
+# arch/sh/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = arch/sh/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+archclean:
diff --git a/klibc/klibc/arch/sh/crt0.S b/klibc/klibc/arch/sh/crt0.S
new file mode 100644
index 0000000000..c9938a5612
--- /dev/null
+++ b/klibc/klibc/arch/sh/crt0.S
@@ -0,0 +1,28 @@
+#
+# arch/sh/crt0.S
+#
+# void _start(void)
+# {
+# /* Divine up argc, argv, and envp */
+# environ = envp;
+# exit(main(argc, argv, envp));
+# }
+#
+
+ .text
+ .align 2
+ .type _start,#function
+ .globl _start
+
+_start:
+ mov r15, r4
+ mov #0, r5
+ mov.l 1f, r0
+
+ jsr @r0
+ nop
+
+ .align 2
+1: .long __libc_init
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/sh/include/klibc/archsetjmp.h b/klibc/klibc/arch/sh/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..28dd932fbc
--- /dev/null
+++ b/klibc/klibc/arch/sh/include/klibc/archsetjmp.h
@@ -0,0 +1,22 @@
+/*
+ * arch/sh/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long r11;
+ unsigned long r12;
+ unsigned long r13;
+ unsigned long r14;
+ unsigned long r15;
+ unsigned long pr;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/klibc/klibc/arch/sh/include/klibc/archsys.h b/klibc/klibc/arch/sh/include/klibc/archsys.h
new file mode 100644
index 0000000000..5f8050a536
--- /dev/null
+++ b/klibc/klibc/arch/sh/include/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/sh/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/sh/setjmp.S b/klibc/klibc/arch/sh/setjmp.S
new file mode 100644
index 0000000000..63f760283f
--- /dev/null
+++ b/klibc/klibc/arch/sh/setjmp.S
@@ -0,0 +1,65 @@
+#
+# arch/sh/setjmp.S
+#
+# setjmp/longjmp for the SuperH architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+#
+# r8
+# r9
+# r10
+# r11
+# r12
+# r13
+# r14
+# r15
+# pr
+#
+
+ .text
+ .align 2
+
+ .globl setjmp
+ .type setjmp, #function
+
+setjmp:
+ add #(9*4), r4
+ sts.l pr, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+ rts
+ mov #0, r0
+
+ .size setjmp,.-setjmp
+
+ .align 2
+ .globl longjmp
+ .type setjmp, #function
+
+longjmp:
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov.l @r4+, r13
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, pr
+ mov r5, r0
+ tst r0, r0
+ bf 1f
+ mov #1, r0 ! in case val==0
+1: rts
+ nop
+
+ .size longjmp,.-longjmp
+
diff --git a/klibc/klibc/arch/sparc/MCONFIG b/klibc/klibc/arch/sparc/MCONFIG
new file mode 100644
index 0000000000..cb94f46c00
--- /dev/null
+++ b/klibc/klibc/arch/sparc/MCONFIG
@@ -0,0 +1,18 @@
+# -*- makefile -*-
+#
+# arch/sparc/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# Normal binaries start at 64K; the linker wants 64K alignment,
+# and call instructions have a 30-bit signed offset, << 2.
+SHAREDFLAGS = -Ttext 0x40000100
diff --git a/klibc/klibc/arch/sparc/Makefile.inc b/klibc/klibc/arch/sparc/Makefile.inc
new file mode 100644
index 0000000000..0186810aca
--- /dev/null
+++ b/klibc/klibc/arch/sparc/Makefile.inc
@@ -0,0 +1,44 @@
+# -*- makefile -*-
+#
+# arch/sparc/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/sdiv.o \
+ arch/$(ARCH)/udiv.o \
+ arch/$(ARCH)/srem.o \
+ arch/$(ARCH)/urem.o \
+ arch/$(ARCH)/smul.o \
+ arch/$(ARCH)/umul.o \
+ arch/$(ARCH)/setjmp.o
+
+arch/$(ARCH)/sdiv.S: arch/$(ARCH)/divrem.m4
+ @echo 'building $@ from $^'
+ @(echo "define(NAME,\`.div')define(OP,\`div')define(S,\`true')"; \
+ cat $^) | m4 > $@
+ @chmod 444 $@
+
+arch/$(ARCH)/udiv.S: arch/$(ARCH)/divrem.m4
+ @echo 'building $@ from $^'
+ @(echo "define(NAME,\`.udiv')define(OP,\`div')define(S,\`false')"; \
+ cat $^) | m4 > $@
+ @chmod 444 $@
+
+arch/$(ARCH)/srem.S: arch/$(ARCH)/divrem.m4
+ @echo 'building $@ from $^'
+ @(echo "define(NAME,\`.rem')define(OP,\`rem')define(S,\`true')"; \
+ cat $^) | m4 > $@
+ @chmod 444 $@
+
+arch/$(ARCH)/urem.S: arch/$(ARCH)/divrem.m4
+ @echo 'building $@ from $^'
+ @(echo "define(NAME,\`.urem')define(OP,\`rem')define(S,\`false')"; \
+ cat $^) | m4 > $@
+ @chmod 444 $@
+
+archclean:
+ rm -f arch/$(ARCH)/?div.S arch/$(ARCH)/?rem.S
diff --git a/klibc/klibc/arch/sparc/crt0.S b/klibc/klibc/arch/sparc/crt0.S
new file mode 100644
index 0000000000..148cb4b4e9
--- /dev/null
+++ b/klibc/klibc/arch/sparc/crt0.S
@@ -0,0 +1,2 @@
+#define TARGET_PTR_SIZE 32
+#include "arch/sparc/crt0i.S"
diff --git a/klibc/klibc/arch/sparc/crt0i.S b/klibc/klibc/arch/sparc/crt0i.S
new file mode 100644
index 0000000000..97652a3090
--- /dev/null
+++ b/klibc/klibc/arch/sparc/crt0i.S
@@ -0,0 +1,100 @@
+! This file derived from the equivalent in newlib
+!
+! C run time start off
+
+! This file supports:
+!
+! - both 32bit pointer and 64bit pointer environments (at compile time)
+! - an imposed stack bias (of 2047) (at run time)
+! - medium/low and medium/anywhere code models (at run time)
+
+! Initial stack setup:
+!
+! bottom of stack (higher memory address)
+! ...
+! text of environment strings
+! text of argument strings
+! envp[envc] = 0 (4/8 bytes)
+! ...
+! env[0] (4/8 bytes)
+! argv[argc] = 0 (4/8 bytes)
+! ...
+! argv[0] (4/8 bytes)
+! argc (4/8 bytes)
+! register save area (64 bits by 16 registers = 128 bytes)
+! top of stack (%sp)
+
+! Stack Bias:
+!
+! It is the responsibility of the o/s to set this up.
+! We handle both a 0 and 2047 value for the stack bias.
+
+! Medium/Anywhere code model support:
+!
+! In this model %g4 points to the start of the data segment.
+! The text segment can go anywhere, but %g4 points to the *data* segment.
+! It is up to the compiler/linker to get this right.
+!
+! Since this model is statically linked the start of the data segment
+! is known at link time. Eg:
+!
+! sethi %hh(data_start), %g1
+! sethi %lm(data_start), %g4
+! or %g1, %hm(data_start), %g1
+! or %g4, %lo(data_start), %g4
+! sllx %g1, 32, %g1
+! or %g4, %g1, %g4
+!
+! FIXME: For now we just assume 0.
+
+! FIXME: if %g1 contains a non-zero value, atexit() should be invoked
+! with this value.
+
+
+ .text
+ .align 4
+ .globl _start
+ .type _start, @function
+_start:
+ clr %fp
+
+! We use %g4 even if the code model is Medium/Low (simplifies the code).
+
+ clr %g4 ! Medium/Anywhere base reg
+
+! If there is a stack bias in effect, account for it in %g5. Then always
+! add %g5 to stack references below. This way the code can be used with
+! or without an imposed bias.
+
+ andcc %sp, 1, %g5
+ bz,a .LNoBias
+ nop
+ mov 2047, %g5
+.LNoBias:
+ add %sp, %g5, %g5
+
+! On entry, the kernel leaves room for one register frame, but
+! the C API wants more free space. Thus, we need to drop the stack
+! pointer additionally.
+
+#if TARGET_PTR_SIZE == 32
+ sub %sp, 32, %sp ! make room for incoming arguments
+#else /* TARGET_PTR_SIZE == 64 */
+ sub %sp, 64, %sp ! make room for incoming arguments
+#endif
+
+! Set up pointers to the ELF data structure (argc, argv, ...)
+! Pass as the first argument to __libc_init
+#if TARGET_PTR_SIZE == 32
+ add %g5, 0x40, %o0
+#else /* TARGET_PTR_SIZE == 64 */
+ add %g5, 0x80, %o0
+#endif
+
+ call __libc_init
+ mov %g1, %o1 ! This is the "atexit" pointer;
+ ! pass as the second argument to __libc_init
+
+! If __libc_init returns, something is hosed. Try an illegal insn.
+! If that does not work, the o/s is hosed more than we are.
+ .long 0
diff --git a/klibc/klibc/arch/sparc/divrem.m4 b/klibc/klibc/arch/sparc/divrem.m4
new file mode 100644
index 0000000000..aa4171dd88
--- /dev/null
+++ b/klibc/klibc/arch/sparc/divrem.m4
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: divrem.m4,v 1.4 92/06/25 13:23:57 torek Exp
+ * $NetBSD: divrem.m4,v 1.4 1997/10/09 10:07:54 lukem Exp $
+ */
+
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+ .asciz "@(#)divrem.m4 8.1 (Berkeley) 6/4/93"
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * NAME name of function to generate
+ * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1
+ * S S=true => signed; S=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TWOSUPN 2^N, for label generation (m4 exponentiation currently broken)
+ * TOPBITS number of bits in the top `decade' of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+define(N, `4')
+define(TWOSUPN, `16')
+define(WORDSIZE, `32')
+define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N)))
+
+define(dividend, `%o0')
+define(divisor, `%o1')
+define(Q, `%o2')
+define(R, `%o3')
+define(ITER, `%o4')
+define(V, `%o5')
+
+/* m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d */
+define(T, `%g1')
+define(SC, `%g7')
+ifelse(S, `true', `define(SIGN, `%g6')')
+
+/*
+ * This is the recursive definition for developing quotient digits.
+ *
+ * Parameters:
+ * $1 the current depth, 1 <= $1 <= N
+ * $2 the current accumulation of quotient bits
+ * N max depth
+ *
+ * We add a new bit to $2 and either recurse or insert the bits in
+ * the quotient. R, Q, and V are inputs and outputs as defined above;
+ * the condition codes are expected to reflect the input R, and are
+ * modified to reflect the output R.
+ */
+define(DEVELOP_QUOTIENT_BITS,
+` ! depth $1, accumulated bits $2
+ bl L.$1.eval(TWOSUPN+$2)
+ srl V,1,V
+ ! remainder is positive
+ subcc R,V,R
+ ifelse($1, N,
+ ` b 9f
+ add Q, ($2*2+1), Q
+ ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
+L.$1.eval(TWOSUPN+$2):
+ ! remainder is negative
+ addcc R,V,R
+ ifelse($1, N,
+ ` b 9f
+ add Q, ($2*2-1), Q
+ ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
+ ifelse($1, 1, `9:')')
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+
+FUNC(NAME)
+ifelse(S, `true',
+` ! compute sign of result; if neither is negative, no problem
+ orcc divisor, dividend, %g0 ! either negative?
+ bge 2f ! no, go do the divide
+ ifelse(OP, `div',
+ `xor divisor, dividend, SIGN',
+ `mov dividend, SIGN') ! compute sign in any case
+ tst divisor
+ bge 1f
+ tst dividend
+ ! divisor is definitely negative; dividend might also be negative
+ bge 2f ! if dividend not negative...
+ neg divisor ! in any case, make divisor nonneg
+1: ! dividend is negative, divisor is nonnegative
+ neg dividend ! make dividend nonnegative
+2:
+')
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc divisor, %g0, V
+ bnz 1f
+ mov dividend, R
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ t ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp R, V ! if divisor exceeds dividend, done
+ blu Lgot_result ! (and algorithm fails otherwise)
+ clr Q
+ sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
+ cmp R, T
+ blu Lnot_really_big
+ clr ITER
+
+ ! `Here the dividend is >= 2^(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.'
+ 1:
+ cmp V, T
+ bgeu 3f
+ mov 1, SC
+ sll V, N, V
+ b 1b
+ inc ITER
+
+ ! Now compute SC.
+ 2: addcc V, V, V
+ bcc Lnot_too_big
+ inc SC
+
+ ! We get here if the divisor overflowed while shifting.
+ ! This means that R has the high-order bit set.
+ ! Restore V and subtract from R.
+ sll T, TOPBITS, T ! high order bit
+ srl V, 1, V ! rest of V
+ add V, T, V
+ b Ldo_single_div
+ dec SC
+
+ Lnot_too_big:
+ 3: cmp V, R
+ blu 2b
+ nop
+ be Ldo_single_div
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! V > R: went too far: back up 1 step
+ ! srl V, 1, V
+ ! dec SC
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that R >= V, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if R >= 0. Because both R and V may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ Ldo_single_div:
+ deccc SC
+ bl Lend_regular_divide
+ nop
+ sub R, V, R
+ mov 1, Q
+ b Lend_single_divloop
+ nop
+ Lsingle_divloop:
+ sll Q, 1, Q
+ bl 1f
+ srl V, 1, V
+ ! R >= 0
+ sub R, V, R
+ b 2f
+ inc Q
+ 1: ! R < 0
+ add R, V, R
+ dec Q
+ 2:
+ Lend_single_divloop:
+ deccc SC
+ bge Lsingle_divloop
+ tst R
+ b,a Lend_regular_divide
+
+Lnot_really_big:
+1:
+ sll V, N, V
+ cmp V, R
+ bleu 1b
+ inccc ITER
+ be Lgot_result
+ dec ITER
+
+ tst R ! set up for initial iteration
+Ldivloop:
+ sll Q, N, Q
+ DEVELOP_QUOTIENT_BITS(1, 0)
+Lend_regular_divide:
+ deccc ITER
+ bge Ldivloop
+ tst R
+ bl,a Lgot_result
+ ! non-restoring fixup here (one instruction only!)
+ifelse(OP, `div',
+` dec Q
+', ` add R, divisor, R
+')
+
+Lgot_result:
+ifelse(S, `true',
+` ! check to see if answer should be < 0
+ tst SIGN
+ bl,a 1f
+ ifelse(OP, `div', `neg Q', `neg R')
+1:')
+ retl
+ ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
diff --git a/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..92c1c74c9d
--- /dev/null
+++ b/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h
@@ -0,0 +1,16 @@
+/*
+ * arch/sparc/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __sp;
+ unsigned long __fp;
+ unsigned long __pc;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/sparc/include/klibc/archsys.h b/klibc/klibc/arch/sparc/include/klibc/archsys.h
new file mode 100644
index 0000000000..fe6e68df8a
--- /dev/null
+++ b/klibc/klibc/arch/sparc/include/klibc/archsys.h
@@ -0,0 +1,65 @@
+/*
+ * arch/sparc/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* fork and vfork return the "other process" pid in %o0 and an
+ "is child" flag in %o1... */
+
+#define _syscall0_forkish(type,name) \
+type name(void) \
+{ \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register unsigned long __o0 __asm__ ("o0"); \
+register unsigned long __o1 __asm__ ("o1"); \
+__asm__ __volatile__ ("t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "mov %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__o0), "=r" (__o1)\
+ : "r" (__g1) \
+ : "cc"); \
+if ((unsigned long)__o0 < (unsigned long)-255) \
+ return (type)(__o0 & (__o1-1)); \
+errno = (int)-__o0; \
+return -1; \
+}
+
+/* SPARC seems to lack _syscall6() in its headers */
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+register long __o3 __asm__ ("o3") = (long)(arg4); \
+register long __o4 __asm__ ("o4") = (long)(arg5); \
+register long __o5 __asm__ ("o5") = (long)(arg6); \
+__asm__ __volatile__ ("t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "mov %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res), "=&r" (__o0) \
+ : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \
+ : "cc"); \
+if (__res < -255 || __res>=0) \
+return (type) __res; \
+errno = -__res; \
+return (type)-1; \
+}
+
+#endif /* _syscall6 missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/sparc/include/machine/asm.h b/klibc/klibc/arch/sparc/include/machine/asm.h
new file mode 100644
index 0000000000..b622bd8cf1
--- /dev/null
+++ b/klibc/klibc/arch/sparc/include/machine/asm.h
@@ -0,0 +1,192 @@
+/* $NetBSD: asm.h,v 1.14 2002/07/20 08:37:30 mrg Exp $ */
+
+/*
+ * Copyright (c) 1994 Allen Briggs
+ * All rights reserved.
+ *
+ * Gleaned from locore.s and sun3 asm.h which had the following copyrights:
+ * locore.s:
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * sun3/include/asm.h:
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1990 The Regents of the University of California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ASM_H_
+#define _ASM_H_
+
+/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */
+#ifndef _LOCORE
+#define _LOCORE
+#endif
+#include <machine/frame.h>
+
+#ifdef __ELF__
+#define _C_LABEL(name) name
+#else
+#ifdef __STDC__
+#define _C_LABEL(name) _ ## name
+#else
+#define _C_LABEL(name) _/**/name
+#endif
+#endif
+#define _ASM_LABEL(name) name
+
+#ifdef PIC
+/*
+ * PIC_PROLOGUE() is akin to the compiler generated function prologue for
+ * PIC code. It leaves the address of the Global Offset Table in DEST,
+ * clobbering register TMP in the process.
+ *
+ * We can use two code sequences. We can read the %pc or use the call
+ * instruction that saves the pc in %o7. Call requires the branch unit and
+ * IEU1, and clobbers %o7 which needs to be restored. This instruction
+ * sequence takes about 4 cycles due to instruction interdependence. Reading
+ * the pc takes 4 cycles to dispatch and is always dispatched alone. That
+ * sequence takes 7 cycles.
+ */
+#ifdef __arch64__
+#define PIC_PROLOGUE(dest,tmp) \
+ mov %o7, tmp; \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \
+ call 0f; \
+ or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \
+0: \
+ add dest,%o7,dest; \
+ mov tmp, %o7
+#else
+#define PIC_PROLOGUE(dest,tmp) \
+ mov %o7,tmp; 3: call 4f; nop; 4: \
+ sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
+ or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \
+ add dest,%o7,dest; mov tmp,%o7
+#endif
+
+/*
+ * PICCY_SET() does the equivalent of a `set var, %dest' instruction in
+ * a PIC-like way, but without involving the Global Offset Table. This
+ * only works for VARs defined in the same file *and* in the text segment.
+ */
+#ifdef __arch64__
+#define PICCY_SET(var,dest,tmp) \
+ 3: rd %pc, tmp; add tmp,(var-3b),dest
+#else
+#define PICCY_SET(var,dest,tmp) \
+ mov %o7,tmp; 3: call 4f; nop; 4: \
+ add %o7,(var-3b),dest; mov tmp,%o7
+#endif
+#else
+#define PIC_PROLOGUE(dest,tmp)
+#define PICCY_OFFSET(var,dest,tmp)
+#endif
+
+#define FTYPE(x) .type x,@function
+#define OTYPE(x) .type x,@object
+
+#define _ENTRY(name) \
+ .align 4; .globl name; .proc 1; FTYPE(name); name:
+
+#ifdef GPROF
+/* see _MCOUNT_ENTRY in profile.h */
+#ifdef __ELF__
+#ifdef __arch64__
+#define _PROF_PROLOGUE \
+ .data; .align 8; 1: .uaword 0; .uaword 0; \
+ .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \
+ or %o0,%lo(1b),%o0; restore
+#else
+#define _PROF_PROLOGUE \
+ .data; .align 4; 1: .long 0; \
+ .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \
+ or %o0,%lo(1b),%o0; restore
+#endif
+#else
+#ifdef __arch64__
+#define _PROF_PROLOGUE \
+ .data; .align 8; 1: .uaword 0; .uaword 0; \
+ .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \
+ or %o0,%lo(1b),%o0; restore
+#else
+#define _PROF_PROLOGUE \
+ .data; .align 4; 1: .long 0; \
+ .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \
+ or %o0,%lo(1b),%o0; restore
+#endif
+#endif
+#else
+#define _PROF_PROLOGUE
+#endif
+
+#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE
+#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name))
+#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE
+#define FUNC(name) ASENTRY(name)
+#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \
+ OTYPE(_C_LABEL(name)); _C_LABEL(name):
+
+
+#define ASMSTR .asciz
+
+#define RCSID(name) .asciz name
+
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
+
+/*
+ * WARN_REFERENCES: create a warning if the specified symbol is referenced.
+ */
+#ifdef __ELF__
+#ifdef __STDC__
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning. ## _sym ; .ascii _msg ; .text
+#else
+#define WARN_REFERENCES(_sym,_msg) \
+ .section .gnu.warning./**/_sym ; .ascii _msg ; .text
+#endif /* __STDC__ */
+#else
+#ifdef __STDC__
+#define __STRING(x) #x
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg ## ,30,0,0,0 ; \
+ .stabs __STRING(_ ## sym) ## ,1,0,0,0
+#else
+#define __STRING(x) "x"
+#define WARN_REFERENCES(sym,msg) \
+ .stabs msg,30,0,0,0 ; \
+ .stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+#endif /* __ELF__ */
+
+#endif /* _ASM_H_ */
diff --git a/klibc/klibc/arch/sparc/include/machine/frame.h b/klibc/klibc/arch/sparc/include/machine/frame.h
new file mode 100644
index 0000000000..b09175c7f4
--- /dev/null
+++ b/klibc/klibc/arch/sparc/include/machine/frame.h
@@ -0,0 +1,138 @@
+/* $NetBSD: frame.h,v 1.4 2001/12/04 00:05:05 darrenr Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)frame.h 8.1 (Berkeley) 6/11/93
+ */
+
+#if defined(_KERNEL_OPT)
+#include "opt_sparc_arch.h"
+#endif
+
+/*
+ * Sparc stack frame format.
+ *
+ * Note that the contents of each stack frame may be held only in
+ * machine register windows. In order to get an accurate picture
+ * of the frame, you must first force the kernel to write any such
+ * windows to the stack.
+ */
+#ifndef _LOCORE
+#ifndef SUN4U
+struct frame {
+ int32_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ struct frame *fr_fp; /* space to save frame pointer (%i6) */
+ int32_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SunOS reserves another 8 words here; this is pointless
+ * but we do it for compatibility.
+ */
+ int32_t fr_xxx; /* `structure return pointer' (unused) */
+ int32_t fr_argd[6]; /* `arg dump area' (lunacy) */
+ int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */
+};
+#else
+struct frame32 {
+ int32_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ u_int32_t fr_fp; /* space to save frame pointer (%i6) */
+ u_int32_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SunOS reserves another 8 words here; this is pointless
+ * but we do it for compatibility.
+ */
+ int32_t fr_xxx; /* `structure return pointer' (unused) */
+ int32_t fr_argd[6]; /* `arg dump area' (lunacy) */
+ int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */
+};
+#endif
+#endif
+
+/*
+ * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if
+ * a function is to call C code. It should be just 64, but Sun defined
+ * their frame with space to hold arguments 0 through 5 (plus some junk),
+ * and varargs routines (such as kprintf) demand this, and gcc uses this
+ * area at times anyway.
+ */
+#define CCFSZ 96
+
+/*
+ * Sparc v9 stack frame format.
+ *
+ * Note that the contents of each stack frame may be held only in
+ * machine register windows. In order to get an accurate picture
+ * of the frame, you must first force the kernel to write any such
+ * windows to the stack.
+ *
+ * V9 frames have an odd bias, so you can tall a v9 frame from
+ * a v8 frame by testing the stack pointer's lsb.
+ */
+#if !defined(_LOCORE) && !defined(_LIBC)
+struct frame64 {
+ int64_t fr_local[8]; /* space to save locals (%l0..%l7) */
+ int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */
+ u_int64_t fr_fp; /* space to save frame pointer (%i6) */
+ u_int64_t fr_pc; /* space to save return pc (%i7) */
+ /*
+ * SVR4 reserves a bunch of extra stuff.
+ */
+ int64_t fr_argd[6]; /* `register save area' (lunacy) */
+ int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */
+};
+
+#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS))
+#endif
+
+/*
+ * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used
+ * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs.
+ */
+#define CC64FSZ 176
+
+/*
+ * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily
+ * detect it by testing the register for an odd value. Why 2K-1 I don't know.
+ */
+#define BIAS (2048-1)
+
diff --git a/klibc/klibc/arch/sparc/include/machine/trap.h b/klibc/klibc/arch/sparc/include/machine/trap.h
new file mode 100644
index 0000000000..42c3ef6ae2
--- /dev/null
+++ b/klibc/klibc/arch/sparc/include/machine/trap.h
@@ -0,0 +1,141 @@
+/* $NetBSD: trap.h,v 1.11 1999/01/20 00:15:08 pk Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)trap.h 8.1 (Berkeley) 6/11/93
+ */
+/*
+ * Sun4m support by Aaron Brown, Harvard University.
+ * Changes Copyright (c) 1995 The President and Fellows of Harvard College.
+ * All rights reserved.
+ */
+
+#ifndef _MACHINE_TRAP_H
+#define _MACHINE_TRAP_H
+
+/* trap vec (pri) description */
+#define T_RESET 0x00 /* (1) not actually vectored; jumps to 0 */
+#define T_TEXTFAULT 0x01 /* (2) address fault during instr fetch */
+#define T_ILLINST 0x02 /* (3) illegal instruction */
+#define T_PRIVINST 0x03 /* (4) privileged instruction */
+#define T_FPDISABLED 0x04 /* (5) fp instr while fp disabled */
+#define T_WINOF 0x05 /* (6) register window overflow */
+#define T_WINUF 0x06 /* (7) register window underflow */
+#define T_ALIGN 0x07 /* (8) address not properly aligned */
+#define T_FPE 0x08 /* (9) floating point exception */
+#define T_DATAFAULT 0x09 /* (10) address fault during data fetch */
+#define T_TAGOF 0x0a /* (11) tag overflow */
+/* 0x0b unused */
+/* 0x0c unused */
+/* 0x0d unused */
+/* 0x0e unused */
+/* 0x0f unused */
+/* 0x10 unused */
+#define T_L1INT 0x11 /* (27) level 1 interrupt */
+#define T_L2INT 0x12 /* (26) level 2 interrupt */
+#define T_L3INT 0x13 /* (25) level 3 interrupt */
+#define T_L4INT 0x14 /* (24) level 4 interrupt */
+#define T_L5INT 0x15 /* (23) level 5 interrupt */
+#define T_L6INT 0x16 /* (22) level 6 interrupt */
+#define T_L7INT 0x17 /* (21) level 7 interrupt */
+#define T_L8INT 0x18 /* (20) level 8 interrupt */
+#define T_L9INT 0x19 /* (19) level 9 interrupt */
+#define T_L10INT 0x1a /* (18) level 10 interrupt */
+#define T_L11INT 0x1b /* (17) level 11 interrupt */
+#define T_L12INT 0x1c /* (16) level 12 interrupt */
+#define T_L13INT 0x1d /* (15) level 13 interrupt */
+#define T_L14INT 0x1e /* (14) level 14 interrupt */
+#define T_L15INT 0x1f /* (13) level 15 interrupt */
+/* 0x20 unused */
+/* through 0x23 unused */
+#define T_CPDISABLED 0x24 /* (5) coprocessor instr while disabled */
+#define T_UNIMPLFLUSH 0x25 /* Unimplemented FLUSH */
+/* through 0x27 unused */
+#define T_CPEXCEPTION 0x28 /* (9) coprocessor exception */
+/* 0x29 unused */
+#define T_IDIV0 0x2a /* divide by zero (from hw [su]div instr) */
+#define T_STOREBUFFAULT 0x2b /* SuperSPARC: Store buffer copy-back fault */
+/* 0x2c unused */
+/* through 0x7f unused */
+
+/* beginning of `user' vectors (from trap instructions) - all priority 12 */
+#define T_SUN_SYSCALL 0x80 /* system call */
+#define T_BREAKPOINT 0x81 /* breakpoint `instruction' */
+#define T_DIV0 0x82 /* division routine was handed 0 */
+#define T_FLUSHWIN 0x83 /* flush windows */
+#define T_CLEANWIN 0x84 /* provide clean windows */
+#define T_RANGECHECK 0x85 /* ? */
+#define T_FIXALIGN 0x86 /* fix up unaligned accesses */
+#define T_INTOF 0x87 /* integer overflow ? */
+#define T_SVR4_SYSCALL 0x88 /* SVR4 system call */
+#define T_BSD_SYSCALL 0x89 /* BSD system call */
+#define T_KGDB_EXEC 0x8a /* for kernel gdb */
+
+/* 0x8b..0xff are currently unallocated, except the following */
+#define T_SVR4_GETCC 0xa0
+#define T_SVR4_SETCC 0xa1
+#define T_SVR4_GETPSR 0xa2
+#define T_SVR4_SETPSR 0xa3
+#define T_SVR4_GETHRTIME 0xa4
+#define T_SVR4_GETHRVTIME 0xa5
+#define T_SVR4_GETHRESTIME 0xa7
+
+
+#ifdef _KERNEL /* pseudo traps for locore.s */
+#define T_RWRET -1 /* need first user window for trap return */
+#define T_AST -2 /* no-op, just needed reschedule or profile */
+#endif
+
+/* flags to system call (flags in %g1 along with syscall number) */
+#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */
+#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */
+
+/*
+ * `software trap' macros to keep people happy (sparc v8 manual says not
+ * to set the upper bits).
+ */
+#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f)
+#define ST_DIV0 (T_DIV0 & 0x7f)
+#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f)
+#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f)
+
+#endif /* _MACHINE_TRAP_H_ */
diff --git a/klibc/klibc/arch/sparc/setjmp.S b/klibc/klibc/arch/sparc/setjmp.S
new file mode 100644
index 0000000000..f41ee2bf12
--- /dev/null
+++ b/klibc/klibc/arch/sparc/setjmp.S
@@ -0,0 +1,38 @@
+!
+! setjmp.S
+!
+! Basic setjmp/longjmp
+!
+! This code was based on the equivalent code in NetBSD
+!
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+
+!
+! The jmp_buf contains the following entries:
+! sp
+! fp
+! pc
+!
+ENTRY(setjmp)
+ st %sp,[%o0+0] ! Callers stack pointer
+ st %o7,[%o0+4] ! Return pc
+ st %fp,[%o0+8] ! Frame pointer
+ retl ! Return
+ clr %o0 ! ...0
+
+ENTRY(longjmp)
+ sub %sp, 64, %sp ! set up a local stack frame
+0:
+ t ST_FLUSHWIN ! flush register windows out to memory
+ !
+ ! We restore the saved stack pointer to %fp, then issue
+ ! a restore instruction which will reload the register
+ ! window from the stack.
+ !
+ ld [%o0+4], %o7 /* restore return pc */
+ ld [%o0+0], %fp /* and stack pointer */
+
+ retl ! success, return %g6
+ restore %o1, 0, %o0
diff --git a/klibc/klibc/arch/sparc/smul.S b/klibc/klibc/arch/sparc/smul.S
new file mode 100644
index 0000000000..0eb218bbe8
--- /dev/null
+++ b/klibc/klibc/arch/sparc/smul.S
@@ -0,0 +1,160 @@
+/* $NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: mul.s,v 1.5 92/06/25 13:24:03 torek Exp
+ */
+
+#include <machine/asm.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+ .asciz "@(#)mul.s 8.1 (Berkeley) 6/4/93"
+#else
+ RCSID("$NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $")
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Signed multiply, from Appendix E of the Sparc Version 8
+ * Architecture Manual.
+ *
+ * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of
+ * the 64-bit product).
+ *
+ * This code optimizes short (less than 13-bit) multiplies.
+ */
+
+FUNC(.mul)
+ mov %o0, %y ! multiplier -> Y
+ andncc %o0, 0xfff, %g0 ! test bits 12..31
+ be Lmul_shortway ! if zero, can do it the short way
+ andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
+
+ /*
+ * Long multiply. 32 steps, followed by a final shift step.
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %o1, %o4 ! 13
+ mulscc %o4, %o1, %o4 ! 14
+ mulscc %o4, %o1, %o4 ! 15
+ mulscc %o4, %o1, %o4 ! 16
+ mulscc %o4, %o1, %o4 ! 17
+ mulscc %o4, %o1, %o4 ! 18
+ mulscc %o4, %o1, %o4 ! 19
+ mulscc %o4, %o1, %o4 ! 20
+ mulscc %o4, %o1, %o4 ! 21
+ mulscc %o4, %o1, %o4 ! 22
+ mulscc %o4, %o1, %o4 ! 23
+ mulscc %o4, %o1, %o4 ! 24
+ mulscc %o4, %o1, %o4 ! 25
+ mulscc %o4, %o1, %o4 ! 26
+ mulscc %o4, %o1, %o4 ! 27
+ mulscc %o4, %o1, %o4 ! 28
+ mulscc %o4, %o1, %o4 ! 29
+ mulscc %o4, %o1, %o4 ! 30
+ mulscc %o4, %o1, %o4 ! 31
+ mulscc %o4, %o1, %o4 ! 32
+ mulscc %o4, %g0, %o4 ! final shift
+
+ ! If %o0 was negative, the result is
+ ! (%o0 * %o1) + (%o1 << 32))
+ ! We fix that here.
+
+ tst %o0
+ bge 1f
+ rd %y, %o0
+
+ ! %o0 was indeed negative; fix upper 32 bits of result by subtracting
+ ! %o1 (i.e., return %o4 - %o1 in %o1).
+ retl
+ sub %o4, %o1, %o1
+
+1:
+ retl
+ mov %o4, %o1
+
+Lmul_shortway:
+ /*
+ * Short multiply. 12 steps, followed by a final shift step.
+ * The resulting bits are off by 12 and (32-12) = 20 bit positions,
+ * but there is no problem with %o0 being negative (unlike above).
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %g0, %o4 ! final shift
+
+ /*
+ * %o4 has 20 of the bits that should be in the low part of the
+ * result; %y has the bottom 12 (as %y's top 12). That is:
+ *
+ * %o4 %y
+ * +----------------+----------------+
+ * | -12- | -20- | -12- | -20- |
+ * +------(---------+------)---------+
+ * --hi-- ----low-part----
+ *
+ * The upper 12 bits of %o4 should be sign-extended to form the
+ * high part of the product (i.e., highpart = %o4 >> 20).
+ */
+
+ rd %y, %o5
+ sll %o4, 12, %o0 ! shift middle bits left 12
+ srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left
+ or %o5, %o0, %o0 ! construct low part of result
+ retl
+ sra %o4, 20, %o1 ! ... and extract high part of result
diff --git a/klibc/klibc/arch/sparc/umul.S b/klibc/klibc/arch/sparc/umul.S
new file mode 100644
index 0000000000..6a7193d217
--- /dev/null
+++ b/klibc/klibc/arch/sparc/umul.S
@@ -0,0 +1,193 @@
+/* $NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Header: umul.s,v 1.4 92/06/25 13:24:05 torek Exp
+ */
+
+#include <machine/asm.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+ .asciz "@(#)umul.s 8.1 (Berkeley) 6/4/93"
+#else
+ RCSID("$NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $")
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the
+ * upper 32 bits of the 64-bit product).
+ *
+ * This code optimizes short (less than 13-bit) multiplies. Short
+ * multiplies require 25 instruction cycles, and long ones require
+ * 45 instruction cycles.
+ *
+ * On return, overflow has occurred (%o1 is not zero) if and only if
+ * the Z condition code is clear, allowing, e.g., the following:
+ *
+ * call .umul
+ * nop
+ * bnz overflow (or tnz)
+ */
+
+FUNC(.umul)
+ or %o0, %o1, %o4
+ mov %o0, %y ! multiplier -> Y
+ andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
+ be Lmul_shortway ! if zero, can do it the short way
+ andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
+
+ /*
+ * Long multiply. 32 steps, followed by a final shift step.
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %o1, %o4 ! 13
+ mulscc %o4, %o1, %o4 ! 14
+ mulscc %o4, %o1, %o4 ! 15
+ mulscc %o4, %o1, %o4 ! 16
+ mulscc %o4, %o1, %o4 ! 17
+ mulscc %o4, %o1, %o4 ! 18
+ mulscc %o4, %o1, %o4 ! 19
+ mulscc %o4, %o1, %o4 ! 20
+ mulscc %o4, %o1, %o4 ! 21
+ mulscc %o4, %o1, %o4 ! 22
+ mulscc %o4, %o1, %o4 ! 23
+ mulscc %o4, %o1, %o4 ! 24
+ mulscc %o4, %o1, %o4 ! 25
+ mulscc %o4, %o1, %o4 ! 26
+ mulscc %o4, %o1, %o4 ! 27
+ mulscc %o4, %o1, %o4 ! 28
+ mulscc %o4, %o1, %o4 ! 29
+ mulscc %o4, %o1, %o4 ! 30
+ mulscc %o4, %o1, %o4 ! 31
+ mulscc %o4, %o1, %o4 ! 32
+ mulscc %o4, %g0, %o4 ! final shift
+
+
+ /*
+ * Normally, with the shift-and-add approach, if both numbers are
+ * positive you get the correct result. WIth 32-bit two's-complement
+ * numbers, -x is represented as
+ *
+ * x 32
+ * ( 2 - ------ ) mod 2 * 2
+ * 32
+ * 2
+ *
+ * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s,
+ * we can treat this as if the radix point were just to the left
+ * of the sign bit (multiply by 2^32), and get
+ *
+ * -x = (2 - x) mod 2
+ *
+ * Then, ignoring the `mod 2's for convenience:
+ *
+ * x * y = xy
+ * -x * y = 2y - xy
+ * x * -y = 2x - xy
+ * -x * -y = 4 - 2x - 2y + xy
+ *
+ * For signed multiplies, we subtract (x << 32) from the partial
+ * product to fix this problem for negative multipliers (see mul.s).
+ * Because of the way the shift into the partial product is calculated
+ * (N xor V), this term is automatically removed for the multiplicand,
+ * so we don't have to adjust.
+ *
+ * But for unsigned multiplies, the high order bit wasn't a sign bit,
+ * and the correction is wrong. So for unsigned multiplies where the
+ * high order bit is one, we end up with xy - (y << 32). To fix it
+ * we add y << 32.
+ */
+ tst %o1
+ bl,a 1f ! if %o1 < 0 (high order bit = 1),
+ add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
+1: rd %y, %o0 ! get lower half of product
+ retl
+ addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
+
+Lmul_shortway:
+ /*
+ * Short multiply. 12 steps, followed by a final shift step.
+ * The resulting bits are off by 12 and (32-12) = 20 bit positions,
+ * but there is no problem with %o0 being negative (unlike above),
+ * and overflow is impossible (the answer is at most 24 bits long).
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %g0, %o4 ! final shift
+
+ /*
+ * %o4 has 20 of the bits that should be in the result; %y has
+ * the bottom 12 (as %y's top 12). That is:
+ *
+ * %o4 %y
+ * +----------------+----------------+
+ * | -12- | -20- | -12- | -20- |
+ * +------(---------+------)---------+
+ * -----result-----
+ *
+ * The 12 bits of %o4 left of the `result' area are all zero;
+ * in fact, all top 20 bits of %o4 are zero.
+ */
+
+ rd %y, %o5
+ sll %o4, 12, %o0 ! shift middle bits left 12
+ srl %o5, 20, %o5 ! shift low bits right 20
+ or %o5, %o0, %o0
+ retl
+ addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
diff --git a/klibc/klibc/arch/sparc64/MCONFIG b/klibc/klibc/arch/sparc64/MCONFIG
new file mode 100644
index 0000000000..d490c63643
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/MCONFIG
@@ -0,0 +1,21 @@
+# -*- makefile -*-
+#
+# arch/sparc64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHREQFLAGS = -m64 -mptr64
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
+
+LDFLAGS = -m elf64_sparc
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# Normal binaries start at 1 MB; the linker wants 1 MB alignment,
+# and call instructions have a 30-bit signed offset, << 2.
+SHAREDFLAGS = -Ttext 0x80000200
diff --git a/klibc/klibc/arch/sparc64/Makefile.inc b/klibc/klibc/arch/sparc64/Makefile.inc
new file mode 100644
index 0000000000..d59f9878e9
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/Makefile.inc
@@ -0,0 +1,13 @@
+# -*- makefile -*-
+#
+# arch/sparc64/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o
+
+archclean:
diff --git a/klibc/klibc/arch/sparc64/crt0.S b/klibc/klibc/arch/sparc64/crt0.S
new file mode 100644
index 0000000000..23af82ecc4
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/crt0.S
@@ -0,0 +1,2 @@
+#define TARGET_PTR_SIZE 64
+#include "arch/sparc/crt0i.S"
diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..022a31e542
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h
@@ -0,0 +1,16 @@
+/*
+ * arch/sparc64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __sp;
+ unsigned long __fp;
+ unsigned long __pc;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsys.h b/klibc/klibc/arch/sparc64/include/klibc/archsys.h
new file mode 100644
index 0000000000..651e4f7f09
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/include/klibc/archsys.h
@@ -0,0 +1,157 @@
+/*
+ * arch/sparc64/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* The Linux 2.5.31 SPARC64 syscall macros are just plain broken */
+
+#undef _syscall0
+#undef _syscall1
+#undef _syscall2
+#undef _syscall3
+#undef _syscall4
+#undef _syscall5
+#undef _syscall6
+
+#define _syscall0(type,name) \
+type name (void) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name (type1 arg1) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name (type1 arg1,type2 arg2) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ register type2 __o1 __asm__ ("o1") = (arg2); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__o1), "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name (type1 arg1,type2 arg2,type3 arg3) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ register type2 __o1 __asm__ ("o1") = (arg2); \
+ register type3 __o2 __asm__ ("o2") = (arg3); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ register type2 __o1 __asm__ ("o1") = (arg2); \
+ register type3 __o2 __asm__ ("o2") = (arg3); \
+ register type4 __o3 __asm__ ("o3") = (arg4); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
+ type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ register type2 __o1 __asm__ ("o1") = (arg2); \
+ register type3 __o2 __asm__ ("o2") = (arg3); \
+ register type4 __o3 __asm__ ("o3") = (arg4); \
+ register type5 __o4 __asm__ ("o4") = (arg5); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \
+ "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+ register unsigned long __g1 __asm__ ("g1") = __NR_##name; \
+ register unsigned long __ret __asm__("o0"); \
+ type1 __o0 = (arg1); \
+ register type2 __o1 __asm__ ("o1") = (arg2); \
+ register type3 __o2 __asm__ ("o2") = (arg3); \
+ register type4 __o3 __asm__ ("o3") = (arg4); \
+ register type5 __o4 __asm__ ("o4") = (arg5); \
+ register type6 __o5 __asm__ ("o5") = (arg6); \
+ __asm__ __volatile__ ("t 0x6d\n\t" \
+ "bcs,a %%xcc, 1f\n\t" \
+ " st %0,%1\n\t" \
+ "1:" \
+ "movcs %%xcc,-1,%0\n" \
+ : "=&r" (__ret), "+m" (errno) \
+ : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \
+ "r" (__o5), "r" (__g1) \
+ : "cc"); \
+ return (type) __ret; \
+}
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/sparc64/setjmp.S b/klibc/klibc/arch/sparc64/setjmp.S
new file mode 100644
index 0000000000..b04d47faab
--- /dev/null
+++ b/klibc/klibc/arch/sparc64/setjmp.S
@@ -0,0 +1,55 @@
+!
+! setjmp.S
+!
+! Basic setjmp/longjmp
+!
+! This code was based on the equivalent code in NetBSD
+!
+
+!
+! The jmp_buf contains the following entries:
+! sp
+! fp
+! pc
+!
+ .text
+ .align 4
+ .global setjmp
+ .type setjmp, @function
+setjmp:
+ stx %sp,[%o0+0] ! Callers stack pointer
+ stx %o7,[%o0+8] ! Return pc
+ stx %fp,[%o0+16] ! Frame pointer
+ retl ! Return
+ clr %o0 ! ...0
+
+ .size setjmp,.-setjmp
+
+
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ mov %o1, %g4 ! save return value
+ mov %o0, %g1 ! save target
+ ldx [%g1+16],%g5 ! get callers frame
+1:
+ cmp %fp, %g5 ! compare against desired frame
+ bl,a 1b ! if below...
+ restore ! pop frame and loop
+ be,a 2f ! if there...
+ ldx [%g1+0],%o2 ! fetch return %sp
+
+.Lbotch:
+ unimp 0 ! ... error ...
+
+2:
+ cmp %o2, %sp ! %sp must not decrease
+ bl .Lbotch
+ nop
+ mov %o2, %sp ! it is OK, put it in place
+
+ ldx [%g1+8],%o3 ! fetch %pc
+ jmp %o3 + 8 ! if sucess...
+ mov %g4,%o0 ! return %g4
+
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG
new file mode 100644
index 0000000000..ecb14ccb70
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/MCONFIG
@@ -0,0 +1,16 @@
+# -*- makefile -*-
+#
+# arch/x86-64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+# Blatantly copied and modified from i386 version by Mats Petersson, AMD.
+#
+
+ARCHREQFLAGS = -m64
+OPTFLAGS = -Os -fomit-frame-pointer -falign-functions=0 -falign-jumps=0 -falign-loops=0
+BITSIZE = 64
+LDFLAGS = -m elf_x86_64
+
diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc
new file mode 100644
index 0000000000..c84443f4e1
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/Makefile.inc
@@ -0,0 +1,16 @@
+# -*- makefile -*-
+#
+# arch/x86_64/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/exits.o \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
+archclean:
diff --git a/klibc/klibc/arch/x86_64/crt0.S b/klibc/klibc/arch/x86_64/crt0.S
new file mode 100644
index 0000000000..c562708d0f
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/crt0.S
@@ -0,0 +1,22 @@
+#
+# arch/x86_64/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+ .text
+ .align 4
+ .type _start,@function
+ .globl _start
+_start:
+ movq %rsp,%rdi # Offset of the ELF data structure
+ movq %rdx,%rsi # The atexit() pointer (if any)
+ call __libc_init
+ # We should never get here...
+ hlt
+
+ .size _start,.-_start
diff --git a/klibc/klibc/arch/x86_64/exits.S b/klibc/klibc/arch/x86_64/exits.S
new file mode 100644
index 0000000000..618f4fb585
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/exits.S
@@ -0,0 +1,35 @@
+#
+# 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/klibc/arch/x86_64/include/klibc/archsetjmp.h b/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h
new file mode 100644
index 0000000000..90d0a0d263
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h
@@ -0,0 +1,21 @@
+/*
+ * arch/x86_64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __rbx;
+ unsigned long __rsp;
+ unsigned long __rbp;
+ unsigned long __r12;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+ unsigned long __rip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsys.h b/klibc/klibc/arch/x86_64/include/klibc/archsys.h
new file mode 100644
index 0000000000..3bd8b0a5d9
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/include/klibc/archsys.h
@@ -0,0 +1,32 @@
+/*
+ * arch/x86_64/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* x86-64 seems to miss _syscall6() from its headers */
+
+#ifndef _syscall6
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+register type4 __r10 asm("%r10") = arg4; \
+register type5 __r8 asm("%r8") = arg5; \
+register type6 __r9 asm("%r9") = arg6; \
+__asm__ volatile (__syscall \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"D" (arg1),"S" (arg2), \
+ "d" (arg3),"r" (__r10),"r" (__r8), "r" (__r9) \
+ : __syscall_clobber); \
+__syscall_return(type,__res); \
+}
+
+#endif /* _syscall6 missing */
+
+#endif /* _KLIBC_ARCHSYS_H */
diff --git a/klibc/klibc/arch/x86_64/setjmp.S b/klibc/klibc/arch/x86_64/setjmp.S
new file mode 100644
index 0000000000..45f547b404
--- /dev/null
+++ b/klibc/klibc/arch/x86_64/setjmp.S
@@ -0,0 +1,54 @@
+#
+# arch/x86_64/setjmp.S
+#
+# setjmp/longjmp for the x86-64 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# %rbx
+# %rsp (post-return)
+# %rbp
+# %r12
+# %r13
+# %r14
+# %r15
+# <return address>
+#
+
+ .text
+ .align 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ pop %rsi # Return address, and adjust the stack
+ xorl %eax,%eax # Return value
+ movq %rbx,(%rdi)
+ movq %rsp,8(%rdi) # Post-return %rsp!
+ push %rsi # Make the call/return stack happy
+ movq %rbp,16(%rdi)
+ movq %r12,24(%rdi)
+ movq %r13,32(%rdi)
+ movq %r14,40(%rdi)
+ movq %r15,48(%rdi)
+ movq %rsi,56(%rdi) # Return address
+ ret
+
+ .size setjmp,.-setjmp
+
+ .text
+ .align 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ movl %esi,%eax # Return value (int)
+ movq (%rdi),%rbx
+ movq 8(%rdi),%rsp
+ movq 16(%rdi),%rbp
+ movq 24(%rdi),%r12
+ movq 32(%rdi),%r13
+ movq 40(%rdi),%r14
+ movq 48(%rdi),%r15
+ jmp *56(%rdi)
+
+ .size longjmp,.-longjmp
diff --git a/klibc/klibc/assert.c b/klibc/klibc/assert.c
new file mode 100644
index 0000000000..6d3ff238c9
--- /dev/null
+++ b/klibc/klibc/assert.c
@@ -0,0 +1,13 @@
+/*
+ * assert.c
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+void __assert_fail(const char *expr, const char *file, unsigned int line)
+{
+ printf("Assertion %s failed, file %s, line %u\n", expr, file, line);
+ abort();
+}
diff --git a/klibc/klibc/atexit.c b/klibc/klibc/atexit.c
new file mode 100644
index 0000000000..078dd8b211
--- /dev/null
+++ b/klibc/klibc/atexit.c
@@ -0,0 +1,10 @@
+/*
+ * atexit.c
+ */
+
+#include <stdlib.h>
+
+int atexit(void (*fctn)(void))
+{
+ return on_exit((void (*)(int, void *))fctn, NULL);
+}
diff --git a/klibc/klibc/atexit.h b/klibc/klibc/atexit.h
new file mode 100644
index 0000000000..a60d641e23
--- /dev/null
+++ b/klibc/klibc/atexit.h
@@ -0,0 +1,19 @@
+/*
+ * atexit.h
+ *
+ * atexit()/on_exit() internal definitions
+ */
+
+#ifndef ATEXIT_H
+#define ATEXIT_H
+
+struct atexit {
+ void (*fctn)(int, void *);
+ void *arg; /* on_exit() parameter */
+ struct atexit *next;
+};
+
+extern struct atexit *__atexit_list;
+
+#endif /* ATEXIT_H */
+
diff --git a/klibc/klibc/atoi.c b/klibc/klibc/atoi.c
new file mode 100644
index 0000000000..a6ec0bf778
--- /dev/null
+++ b/klibc/klibc/atoi.c
@@ -0,0 +1,3 @@
+#define TYPE int
+#define NAME atoi
+#include "atox.c"
diff --git a/klibc/klibc/atol.c b/klibc/klibc/atol.c
new file mode 100644
index 0000000000..e65484e7f1
--- /dev/null
+++ b/klibc/klibc/atol.c
@@ -0,0 +1,3 @@
+#define TYPE long
+#define NAME atol
+#include "atox.c"
diff --git a/klibc/klibc/atoll.c b/klibc/klibc/atoll.c
new file mode 100644
index 0000000000..25df79e1bf
--- /dev/null
+++ b/klibc/klibc/atoll.c
@@ -0,0 +1,3 @@
+#define TYPE long long
+#define NAME atoll
+#include "atox.c"
diff --git a/klibc/klibc/atox.c b/klibc/klibc/atox.c
new file mode 100644
index 0000000000..56f8d93b40
--- /dev/null
+++ b/klibc/klibc/atox.c
@@ -0,0 +1,14 @@
+/*
+ * atox.c
+ *
+ * atoi(), atol(), atoll()
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+TYPE NAME (const char *nptr)
+{
+ return (TYPE) strntoumax(nptr, (char **)NULL, 10, ~(size_t)0);
+}
diff --git a/klibc/klibc/brk.c b/klibc/klibc/brk.c
new file mode 100644
index 0000000000..0a08c4e1c5
--- /dev/null
+++ b/klibc/klibc/brk.c
@@ -0,0 +1,24 @@
+/* brk.c - Change data segment size */
+
+/* Written 2000 by Werner Almesberger */
+
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+char *__current_brk; /* Common with sbrk.c */
+
+/*
+ * The Linux brk() isn't what most people expect, so we call the
+ * system call __brk() and provide a wrapper.
+ */
+int brk(void *end_data_segment)
+{
+ char *new_brk;
+
+ new_brk = __brk(end_data_segment);
+ if (new_brk != end_data_segment) return -1;
+ __current_brk = new_brk;
+ return 0;
+}
diff --git a/klibc/klibc/bsd_signal.c b/klibc/klibc/bsd_signal.c
new file mode 100644
index 0000000000..9acc867a36
--- /dev/null
+++ b/klibc/klibc/bsd_signal.c
@@ -0,0 +1,11 @@
+/*
+ * bsd_signal.c
+ */
+
+#include <signal.h>
+
+__sighandler_t bsd_signal(int signum, __sighandler_t handler)
+{
+ /* BSD signal() semantics */
+ return __signal(signum, handler, SA_RESTART);
+}
diff --git a/klibc/klibc/calloc.c b/klibc/klibc/calloc.c
new file mode 100644
index 0000000000..228a1b70e4
--- /dev/null
+++ b/klibc/klibc/calloc.c
@@ -0,0 +1,21 @@
+/*
+ * calloc.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+/* FIXME: This should look for multiplication overflow */
+
+void *calloc(size_t nmemb, size_t size)
+{
+ void *ptr;
+
+ size *= nmemb;
+ ptr = malloc(size);
+ if ( ptr )
+ memset(ptr, 0, size);
+
+ return ptr;
+}
+
diff --git a/klibc/klibc/closelog.c b/klibc/klibc/closelog.c
new file mode 100644
index 0000000000..2359d4f92b
--- /dev/null
+++ b/klibc/klibc/closelog.c
@@ -0,0 +1,18 @@
+/*
+ * closelog.c
+ */
+
+#include <syslog.h>
+#include <unistd.h>
+
+extern int __syslog_fd;
+
+void closelog(void)
+{
+ int logfd = __syslog_fd;
+
+ if ( logfd != -1 ) {
+ close(logfd);
+ __syslog_fd = -1;
+ }
+}
diff --git a/klibc/klibc/creat.c b/klibc/klibc/creat.c
new file mode 100644
index 0000000000..9bd22172d4
--- /dev/null
+++ b/klibc/klibc/creat.c
@@ -0,0 +1,12 @@
+/*
+ * creat.c
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int creat(const char *pathname, mode_t mode)
+{
+ return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
diff --git a/klibc/klibc/ctypes.c b/klibc/klibc/ctypes.c
new file mode 100644
index 0000000000..a9398b8071
--- /dev/null
+++ b/klibc/klibc/ctypes.c
@@ -0,0 +1,281 @@
+/*
+ * ctypes.c
+ *
+ * This is the array that defines <ctype.h> classes.
+ * This assumes ISO 8859-1.
+ */
+
+#include <ctype.h>
+
+const unsigned char __ctypes[257] = {
+ 0, /* EOF */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ __ctype_space, /* BS */
+ __ctype_space, /* TAB */
+ __ctype_space, /* LF */
+ __ctype_space, /* VT */
+ __ctype_space, /* FF */
+ __ctype_space, /* CR */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+
+ __ctype_space|__ctype_print, /* space */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_upper|__ctype_print, /* G-Z */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_lower|__ctype_print, /* g-z */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ 0, /* control character */
+
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+ 0, /* control character */
+
+ __ctype_space|__ctype_print, /* NBSP */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_print|__ctype_punct, /* punctuation */
+
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_upper|__ctype_print, /* upper accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_print|__ctype_punct, /* punctuation */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+ __ctype_lower|__ctype_print, /* lower accented */
+};
diff --git a/klibc/klibc/exec_l.c b/klibc/klibc/exec_l.c
new file mode 100644
index 0000000000..cdae11e981
--- /dev/null
+++ b/klibc/klibc/exec_l.c
@@ -0,0 +1,57 @@
+/*
+ * exec_l.c
+ *
+ * Common implementation of execl() execle() execlp()
+ */
+
+#include <stdarg.h>
+#include <alloca.h>
+#include <unistd.h>
+
+int NAME (const char *path, const char *arg0, ...)
+{
+ va_list ap, cap;
+ int argc = 1, rv;
+ const char **argv, **argp;
+ const char *arg;
+#if EXEC_E
+ char * const * envp;
+#else
+#define envp environ
+#endif
+
+ va_start(ap, arg0);
+ va_copy(cap, ap);
+
+ /* Count the number of arguments */
+ do {
+ arg = va_arg(cap, const char *);
+ argc++;
+ } while ( arg );
+
+ va_end(cap);
+
+ /* Allocate memory for the pointer array */
+ argp = argv = alloca(argc*sizeof(const char *));
+ if ( !argv ) {
+ va_end(ap);
+ return -1;
+ }
+
+ /* Copy the list into an array */
+ *argp++ = arg0;
+ do {
+ *argp++ = arg = va_arg(ap, const char *);
+ } while ( arg );
+
+#if EXEC_E
+ /* execle() takes one more argument for the environment pointer */
+ envp = va_arg(ap, char * const *);
+#endif
+
+ rv = (EXEC_P ? execvpe : execve)(path, (char * const *)argv, envp);
+
+ va_end(ap);
+
+ return rv;
+}
diff --git a/klibc/klibc/execl.c b/klibc/klibc/execl.c
new file mode 100644
index 0000000000..4581113ba5
--- /dev/null
+++ b/klibc/klibc/execl.c
@@ -0,0 +1,8 @@
+/*
+ * execl.c
+ */
+
+#define NAME execl
+#define EXEC_P 0
+#define EXEC_E 0
+#include "exec_l.c"
diff --git a/klibc/klibc/execle.c b/klibc/klibc/execle.c
new file mode 100644
index 0000000000..b073988835
--- /dev/null
+++ b/klibc/klibc/execle.c
@@ -0,0 +1,8 @@
+/*
+ * execle.c
+ */
+
+#define NAME execle
+#define EXEC_P 0
+#define EXEC_E 1
+#include "exec_l.c"
diff --git a/klibc/klibc/execlp.c b/klibc/klibc/execlp.c
new file mode 100644
index 0000000000..65c9aa4a7a
--- /dev/null
+++ b/klibc/klibc/execlp.c
@@ -0,0 +1,8 @@
+/*
+ * execlp.c
+ */
+
+#define NAME execlp
+#define EXEC_P 1
+#define EXEC_E 0
+#include "exec_l.c"
diff --git a/klibc/klibc/execlpe.c b/klibc/klibc/execlpe.c
new file mode 100644
index 0000000000..fef972fcb3
--- /dev/null
+++ b/klibc/klibc/execlpe.c
@@ -0,0 +1,8 @@
+/*
+ * execlpe.c
+ */
+
+#define NAME execlpe
+#define EXEC_P 1
+#define EXEC_E 1
+#include "exec_l.c"
diff --git a/klibc/klibc/execv.c b/klibc/klibc/execv.c
new file mode 100644
index 0000000000..9856b76d87
--- /dev/null
+++ b/klibc/klibc/execv.c
@@ -0,0 +1,13 @@
+/*
+ * execv.c
+ */
+
+#include <stdarg.h>
+#include <unistd.h>
+
+int execv(const char *path, char * const * argv)
+{
+ return execve(path, argv, environ);
+}
+
+
diff --git a/klibc/klibc/execvp.c b/klibc/klibc/execvp.c
new file mode 100644
index 0000000000..b1065ee47e
--- /dev/null
+++ b/klibc/klibc/execvp.c
@@ -0,0 +1,13 @@
+/*
+ * execvp.c
+ */
+
+#include <stdarg.h>
+#include <unistd.h>
+
+int execvp(const char *path, char * const * argv)
+{
+ return execvpe(path, argv, environ);
+}
+
+
diff --git a/klibc/klibc/execvpe.c b/klibc/klibc/execvpe.c
new file mode 100644
index 0000000000..afd791ab43
--- /dev/null
+++ b/klibc/klibc/execvpe.c
@@ -0,0 +1,73 @@
+/*
+ * execvpe.c
+ *
+ * execvpe() function (from which we build execlp, execlpe, execvp).
+ *
+ * This version of execvpe() will *not* spawn /bin/sh if the command
+ * return ENOEXEC. That's what #! is for, folks!
+ *
+ * Since execlpe() and execvpe() aren't in POSIX, nor in glibc,
+ * I have followed QNX precedent in the implementation of the PATH:
+ * the PATH that is used is the one in the current environment, not
+ * in the new environment.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#define DEFAULT_PATH "/bin:/usr/bin:."
+
+int execvpe(const char *file, char * const *argv, char * const *envp)
+{
+ char path[PATH_MAX];
+ const char *searchpath, *esp;
+ size_t prefixlen, filelen, totallen;
+
+ if ( strchr(file, '/') ) /* Specific path */
+ return execve(file, argv, envp);
+
+ filelen = strlen(file);
+
+ searchpath = getenv("PATH");
+ if ( !searchpath )
+ searchpath = DEFAULT_PATH;
+
+ errno = ENOENT; /* Default errno, if execve() doesn't change it */
+
+ do {
+ esp = strchr(searchpath, ':');
+ if ( esp )
+ prefixlen = esp-searchpath;
+ else
+ prefixlen = strlen(searchpath);
+
+ if ( prefixlen == 0 || searchpath[prefixlen-1] == '/' ) {
+ totallen = prefixlen+filelen;
+ if ( totallen >= PATH_MAX )
+ continue;
+ memcpy(path, searchpath, prefixlen);
+ memcpy(path+prefixlen, file, filelen);
+ } else {
+ totallen = prefixlen+filelen+1;
+ if ( totallen >= PATH_MAX )
+ continue;
+ memcpy(path, searchpath, prefixlen);
+ path[prefixlen] = '/';
+ memcpy(path+prefixlen+1, file, filelen);
+ }
+ path[totallen] = '\0';
+
+ execve(path, argv, envp);
+ if ( errno == E2BIG || errno == ENOEXEC ||
+ errno == ENOMEM || errno == ETXTBSY )
+ break; /* Report this as an error, no more search */
+
+ searchpath = esp+1;
+ } while ( esp );
+
+ return -1;
+}
+
diff --git a/klibc/klibc/exitc.c b/klibc/klibc/exitc.c
new file mode 100644
index 0000000000..6e5d78979d
--- /dev/null
+++ b/klibc/klibc/exitc.c
@@ -0,0 +1,36 @@
+/*
+ * exit.c
+ *
+ * Note: all programs need exit(), since it's invoked from
+ * crt0.o. Therefore there is no point in breaking apart
+ * exit() and _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__)
+
+#define __NR___exit __NR_exit
+
+/* Syscalls can't return void... */
+static inline _syscall1(int,__exit,int,rv);
+
+/* This allows atexit/on_exit to install a hook */
+__noreturn (*__exit_handler)(int) = _exit;
+
+__noreturn exit(int rv)
+{
+ __exit_handler(rv);
+}
+
+__noreturn _exit(int rv)
+{
+ __exit(rv);
+ for(;;);
+}
+
+#endif
diff --git a/klibc/klibc/fdatasync.c b/klibc/klibc/fdatasync.c
new file mode 100644
index 0000000000..53079b09d6
--- /dev/null
+++ b/klibc/klibc/fdatasync.c
@@ -0,0 +1,15 @@
+/*
+ * fdatasync.c
+ *
+ * Some systems don't have this (alpha?) ... this is really a bug,
+ * but mimic using fsync()
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_fdatasync
+#define __NR_fdatasync __NR_fsync
+#endif
+
+_syscall1(int,fdatasync,int,fd);
diff --git a/klibc/klibc/fgetc.c b/klibc/klibc/fgetc.c
new file mode 100644
index 0000000000..83eee16f61
--- /dev/null
+++ b/klibc/klibc/fgetc.c
@@ -0,0 +1,20 @@
+/*
+ * fgetc.c
+ *
+ * Extremely slow fgetc implementation, using _fread(). If people
+ * actually need character-oriented input to be fast, we may actually
+ * have to implement buffering. Sigh.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int fgetc(FILE *f)
+{
+ unsigned char ch;
+
+ return (_fread(&ch, 1, f) == 1) ? (int)ch : EOF;
+}
+
diff --git a/klibc/klibc/fgets.c b/klibc/klibc/fgets.c
new file mode 100644
index 0000000000..88a145a63f
--- /dev/null
+++ b/klibc/klibc/fgets.c
@@ -0,0 +1,33 @@
+/*
+ * fgets.c
+ *
+ * This will be very slow due to the implementation of getc(),
+ * but we can't afford to drain characters we don't need from
+ * the input.
+ */
+
+#include <stdio.h>
+
+char *fgets(char *s, int n, FILE *f)
+{
+ int ch;
+ char *p = s;
+
+ while ( n > 1 ) {
+ ch = getc(f);
+ if ( ch == EOF ) {
+ *p = '\0';
+ return NULL;
+ }
+ *p++ = ch;
+ if ( ch == '\n' )
+ break;
+ }
+ if ( n )
+ *p = '\0';
+
+ return s;
+}
+
+
+
diff --git a/klibc/klibc/fopen.c b/klibc/klibc/fopen.c
new file mode 100644
index 0000000000..5c84184809
--- /dev/null
+++ b/klibc/klibc/fopen.c
@@ -0,0 +1,46 @@
+/*
+ * fopen.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* This depends on O_RDONLY == 0, O_WRONLY == 1, O_RDWR == 2 */
+
+
+FILE *fopen(const char *file, const char *mode)
+{
+ int flags = O_RDONLY;
+ int plus = 0;
+ int fd;
+
+ while ( *mode ) {
+ switch ( *mode ) {
+ case 'r':
+ flags = O_RDONLY;
+ break;
+ case 'w':
+ flags = O_WRONLY|O_CREAT|O_TRUNC;
+ break;
+ case 'a':
+ flags = O_WRONLY|O_CREAT|O_APPEND;
+ break;
+ case '+':
+ plus = 1;
+ break;
+ }
+ mode++;
+ }
+
+ if ( plus ) {
+ flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR;
+ }
+
+ fd = open(file, flags, 0666);
+
+ if ( fd < 0 )
+ return NULL;
+ else
+ return fdopen(fd, mode);
+}
diff --git a/klibc/klibc/fork.c b/klibc/klibc/fork.c
new file mode 100644
index 0000000000..d7e4db89a1
--- /dev/null
+++ b/klibc/klibc/fork.c
@@ -0,0 +1,29 @@
+/*
+ * fork.c
+ *
+ * This is normally just a syscall stub, but at least one system
+ * doesn't have sys_fork, only sys_clone...
+ */
+
+#include <sys/syscall.h>
+#include <signal.h>
+#include <unistd.h>
+
+#ifdef __NR_fork
+
+#ifdef _syscall0_forkish
+_syscall0_forkish(pid_t,fork);
+#else
+_syscall0(pid_t,fork);
+#endif
+
+#else /* __NR_fork */
+
+static inline _syscall2(pid_t,clone,unsigned long,flags,void *,newsp);
+
+pid_t fork(void)
+{
+ return clone(SIGCHLD, 0);
+}
+
+#endif /* __NR_fork */
diff --git a/klibc/klibc/fprintf.c b/klibc/klibc/fprintf.c
new file mode 100644
index 0000000000..df3823eac3
--- /dev/null
+++ b/klibc/klibc/fprintf.c
@@ -0,0 +1,19 @@
+/*
+ * fprintf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define BUFFER_SIZE 16384
+
+int fprintf(FILE *file, const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vfprintf(file, format, ap);
+ va_end(ap);
+ return rv;
+}
diff --git a/klibc/klibc/fputc.c b/klibc/klibc/fputc.c
new file mode 100644
index 0000000000..61aff1644b
--- /dev/null
+++ b/klibc/klibc/fputc.c
@@ -0,0 +1,14 @@
+/*
+ * fputc.c
+ *
+ * gcc "printf decompilation" expects this to exist...
+ */
+
+#include <stdio.h>
+
+int fputc(int c, FILE *f)
+{
+ unsigned char ch = c;
+
+ return _fwrite(&ch, 1, f) == 1 ? ch : EOF;
+}
diff --git a/klibc/klibc/fputs.c b/klibc/klibc/fputs.c
new file mode 100644
index 0000000000..4b68f96886
--- /dev/null
+++ b/klibc/klibc/fputs.c
@@ -0,0 +1,15 @@
+/*
+ * fputs.c
+ *
+ * This isn't quite fputs() in the stdio sense, since we don't
+ * have stdio, but it takes a file descriptor argument instead
+ * of the FILE *.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+int fputs(const char *s, FILE *file)
+{
+ return _fwrite(s, strlen(s), file);
+}
diff --git a/klibc/klibc/fread.c b/klibc/klibc/fread.c
new file mode 100644
index 0000000000..8f7dba9c19
--- /dev/null
+++ b/klibc/klibc/fread.c
@@ -0,0 +1,35 @@
+/*
+ * fread.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+
+size_t _fread(void *buf, size_t count, FILE *f)
+{
+ size_t bytes = 0;
+ ssize_t rv;
+ char *p = buf;
+
+ while ( count ) {
+ rv = read(fileno(f), p, count);
+ if ( rv == -1 ) {
+ if ( errno == EINTR )
+ continue;
+ else
+ break;
+ } else if ( rv == 0 ) {
+ break;
+ }
+
+ p += rv;
+ bytes += rv;
+ count -= rv;
+ }
+
+ return bytes;
+}
+
+
+
diff --git a/klibc/klibc/fread2.c b/klibc/klibc/fread2.c
new file mode 100644
index 0000000000..9e5ac81fc2
--- /dev/null
+++ b/klibc/klibc/fread2.c
@@ -0,0 +1,13 @@
+/*
+ * fread2.c
+ *
+ * The actual fread() function as a non-inline
+ */
+
+#define __NO_FREAD_FWRITE_INLINES
+#include <stdio.h>
+
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *f)
+{
+ return _fread(ptr, size*nmemb, f)/size;
+}
diff --git a/klibc/klibc/fwrite.c b/klibc/klibc/fwrite.c
new file mode 100644
index 0000000000..0a73188c67
--- /dev/null
+++ b/klibc/klibc/fwrite.c
@@ -0,0 +1,35 @@
+/*
+ * fwrite.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+
+size_t _fwrite(const void *buf, size_t count, FILE *f)
+{
+ size_t bytes = 0;
+ ssize_t rv;
+ const char *p = buf;
+
+ while ( count ) {
+ rv = write(fileno(f), p, count);
+ if ( rv == -1 ) {
+ if ( errno == EINTR )
+ continue;
+ else
+ break;
+ } else if ( rv == 0 ) {
+ break;
+ }
+
+ p += rv;
+ bytes += rv;
+ count -= rv;
+ }
+
+ return bytes;
+}
+
+
+
diff --git a/klibc/klibc/fwrite2.c b/klibc/klibc/fwrite2.c
new file mode 100644
index 0000000000..82ec832be4
--- /dev/null
+++ b/klibc/klibc/fwrite2.c
@@ -0,0 +1,13 @@
+/*
+ * fwrite2.c
+ *
+ * The actual fwrite() function as a non-inline
+ */
+
+#define __NO_FREAD_FWRITE_INLINES
+#include <stdio.h>
+
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *f)
+{
+ return _fwrite(ptr, size*nmemb, f)/size;
+}
diff --git a/klibc/klibc/getcwd.c b/klibc/klibc/getcwd.c
new file mode 100644
index 0000000000..350ec69a63
--- /dev/null
+++ b/klibc/klibc/getcwd.c
@@ -0,0 +1,15 @@
+/*
+ * getcwd.c
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#define __NR___getcwd __NR_getcwd
+static inline _syscall2(int,__getcwd,char *,buf,size_t,size);
+
+char *getcwd(char *buf, size_t size)
+{
+ return ( __getcwd(buf, size) < 0 ) ? NULL : buf;
+}
+
diff --git a/klibc/klibc/getdomainname.c b/klibc/klibc/getdomainname.c
new file mode 100644
index 0000000000..4cd68a3cb5
--- /dev/null
+++ b/klibc/klibc/getdomainname.c
@@ -0,0 +1,25 @@
+/*
+ * getdomainname.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+int getdomainname(char *name, size_t len)
+{
+ struct utsname un;
+
+ if ( !uname(&un) )
+ return -1;
+
+ if ( len < strlen(un.domainname)+1 ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ strcpy(name, un.domainname);
+
+ return 0;
+}
diff --git a/klibc/klibc/getenv.c b/klibc/klibc/getenv.c
new file mode 100644
index 0000000000..84fc94c00e
--- /dev/null
+++ b/klibc/klibc/getenv.c
@@ -0,0 +1,22 @@
+/*
+ * getenv.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+char *getenv(const char *name)
+{
+ char **p, *q;
+ int len = strlen(name);
+
+ for ( p = environ ; (q = *p) ; p++ ) {
+ if ( !strncmp(name, q, len) && q[len] == '=' ) {
+ return q+(len+1);
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/klibc/klibc/gethostname.c b/klibc/klibc/gethostname.c
new file mode 100644
index 0000000000..6c5062e816
--- /dev/null
+++ b/klibc/klibc/gethostname.c
@@ -0,0 +1,25 @@
+/*
+ * gethostname.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+int gethostname(char *name, size_t len)
+{
+ struct utsname un;
+
+ if ( !uname(&un) )
+ return -1;
+
+ if ( len < strlen(un.nodename)+1 ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ strcpy(name, un.nodename);
+
+ return 0;
+}
diff --git a/klibc/klibc/getopt.c b/klibc/klibc/getopt.c
new file mode 100644
index 0000000000..5a992dcdd7
--- /dev/null
+++ b/klibc/klibc/getopt.c
@@ -0,0 +1,74 @@
+/*
+ * getopt.c
+ *
+ * Simple POSIX getopt(), no GNU extensions...
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+
+char *optarg;
+int optind = 1;
+int opterr, optopt;
+static const char *__optptr;
+
+int getopt(int argc, char * const *argv, const char *optstring)
+{
+ const char *carg = argv[optind];
+ const char *osptr;
+ int opt;
+
+ /* We don't actually need argc */
+ (void)argc;
+
+ /* First, eliminate all non-option cases */
+
+ if ( !carg || carg[0] != '-' || !carg[1] ) {
+ return -1;
+ }
+
+ if ( carg[1] == '-' && !carg[2] ) {
+ optind++;
+ return -1;
+ }
+
+ if ( (uintptr_t)(__optptr-carg) > (uintptr_t)strlen(carg) )
+ __optptr = carg+1; /* Someone frobbed optind, change to new opt. */
+
+ opt = *__optptr++;
+
+ if ( opt != ':' && (osptr = strchr(optstring, opt)) ) {
+ if ( osptr[1] == ':' ) {
+ if ( *__optptr ) {
+ /* Argument-taking option with attached argument */
+ optarg = (char *)__optptr;
+ optind++;
+ } else {
+ /* Argument-taking option with non-attached argument */
+ if ( argv[optind+1] ) {
+ optarg = (char *)argv[optind+1];
+ optind += 2;
+ } else {
+ /* Missing argument */
+ return (optstring[0] == ':') ? ':' : '?';
+ }
+ }
+ return opt;
+ } else {
+ /* Non-argument-taking option */
+ /* __optptr will remember the exact position to resume at */
+ if ( ! *__optptr )
+ optind++;
+ return opt;
+ }
+ } else {
+ /* Unknown option */
+ optopt = opt;
+ if ( ! *__optptr )
+ optind++;
+ return '?';
+ }
+}
+
+
diff --git a/klibc/klibc/getpriority.c b/klibc/klibc/getpriority.c
new file mode 100644
index 0000000000..d6db2cc6b9
--- /dev/null
+++ b/klibc/klibc/getpriority.c
@@ -0,0 +1,25 @@
+/*
+ * getpriority.c
+ *
+ * Needs to do some post-syscall mangling to distinguish error returns...
+ * but only on some platforms. Sigh.
+ */
+
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+
+#define __NR__getpriority __NR_getpriority
+
+static inline _syscall2(int,_getpriority,int,which,int,who);
+
+int getpriority(int which, int who)
+{
+#if defined(__alpha__) || defined(__ia64__)
+ return _getpriority(which, who);
+#else
+ int rv = _getpriority(which, who);
+ return ( rv < 0 ) ? rv : 20-rv;
+#endif
+}
diff --git a/klibc/klibc/globals.c b/klibc/klibc/globals.c
new file mode 100644
index 0000000000..72ae91fbad
--- /dev/null
+++ b/klibc/klibc/globals.c
@@ -0,0 +1,10 @@
+/*
+ * globals.c
+ *
+ * These have to be defined somewhere...
+ */
+#include <errno.h>
+#include <unistd.h>
+
+int errno;
+char **environ;
diff --git a/klibc/klibc/include/alloca.h b/klibc/klibc/include/alloca.h
new file mode 100644
index 0000000000..41a4d94d44
--- /dev/null
+++ b/klibc/klibc/include/alloca.h
@@ -0,0 +1,13 @@
+/*
+ * alloca.h
+ *
+ * Just call the builtin alloca() function
+ */
+
+#ifndef _ALLOCA_H
+#define _ALLOCA_H
+
+#define alloca(size) __builtin_alloca(size)
+
+#endif /* _ALLOCA_H */
+
diff --git a/klibc/klibc/include/arpa/inet.h b/klibc/klibc/include/arpa/inet.h
new file mode 100644
index 0000000000..043b148e17
--- /dev/null
+++ b/klibc/klibc/include/arpa/inet.h
@@ -0,0 +1,24 @@
+/*
+ * arpa/inet.h
+ */
+
+#ifndef _ARPA_INET_H
+#define _ARPA_INET_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in6.h>
+
+__extern uint32_t inet_addr(const char *);
+__extern int inet_aton(const char *, struct in_addr *);
+__extern char *inet_ntoa(struct in_addr);
+__extern int inet_pton(int, const char *, void *);
+__extern const char *inet_ntop(int, const void *, char *, size_t);
+__extern unsigned int inet_nsap_addr(const char *, unsigned char *, int);
+__extern char *inet_nsap_ntoa(int, const unsigned char *, char *);
+
+#endif /* _ARPA_INET_H */
+
+
diff --git a/klibc/klibc/include/assert.h b/klibc/klibc/include/assert.h
new file mode 100644
index 0000000000..58cc37c487
--- /dev/null
+++ b/klibc/klibc/include/assert.h
@@ -0,0 +1,22 @@
+/*
+ * assert.h
+ */
+
+#ifndef _ASSERT_H
+#define _ASSERT_H
+
+#ifdef NDEBUG
+
+#define assert(x) ((void)(x))
+
+#else
+
+extern void __assert_fail(const char *, const char *,
+ unsigned int);
+
+#define assert(x) ((x) ? (void)0 : __assert_fail(#x, __FILE__, __LINE__))
+
+#endif
+
+#endif /* _ASSERT_H */
+
diff --git a/klibc/klibc/include/bits32/bitsize/limits.h b/klibc/klibc/include/bits32/bitsize/limits.h
new file mode 100644
index 0000000000..f90e524b2b
--- /dev/null
+++ b/klibc/klibc/include/bits32/bitsize/limits.h
@@ -0,0 +1,14 @@
+/*
+ * bits32/limits.h
+ */
+
+#ifndef _BITSIZE_LIMITS_H
+#define _BITSIZE_LIMITS_H
+
+#define LONG_BIT 32
+
+#define LONG_MIN (-2147483647L-1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 4294967295UL
+
+#endif /* _BITSIZE_LIMITS_H */
diff --git a/klibc/klibc/include/bits32/bitsize/stddef.h b/klibc/klibc/include/bits32/bitsize/stddef.h
new file mode 100644
index 0000000000..bf6e695ed3
--- /dev/null
+++ b/klibc/klibc/include/bits32/bitsize/stddef.h
@@ -0,0 +1,18 @@
+/*
+ * bits32/stddef.h
+ */
+
+#ifndef _BITSIZE_STDDEF_H
+#define _BITSIZE_STDDEF_H
+
+#define _SIZE_T
+#if (defined(__s390__) || defined(__hppa__) || defined(__cris__))
+typedef unsigned long size_t;
+#else
+typedef unsigned int size_t;
+#endif
+
+#define _PTRDIFF_T
+typedef signed int ptrdiff_t;
+
+#endif /* _BITSIZE_STDDEF_H */
diff --git a/klibc/klibc/include/bits32/bitsize/stdint.h b/klibc/klibc/include/bits32/bitsize/stdint.h
new file mode 100644
index 0000000000..40b464961c
--- /dev/null
+++ b/klibc/klibc/include/bits32/bitsize/stdint.h
@@ -0,0 +1,34 @@
+/*
+ * bits32/stdint.h
+ */
+
+#ifndef _BITSIZE_STDINT_H
+#define _BITSIZE_STDINT_H
+
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+
+typedef int int_fast16_t;
+typedef int int_fast32_t;
+
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
+
+#define __PRI64_RANK "ll"
+#define __PRIFAST_RANK ""
+#define __PRIPTR_RANK ""
+
+#endif /* _BITSIZE_STDINT_H */
diff --git a/klibc/klibc/include/bits32/bitsize/stdintconst.h b/klibc/klibc/include/bits32/bitsize/stdintconst.h
new file mode 100644
index 0000000000..8157dd06e0
--- /dev/null
+++ b/klibc/klibc/include/bits32/bitsize/stdintconst.h
@@ -0,0 +1,18 @@
+/*
+ * bits32/stdintconst.h
+ */
+
+#ifndef _BITSIZE_STDINTCONST_H
+#define _BITSIZE_STDINTCONST_H
+
+#define INT_FAST16_C(c) INT32_C(c)
+#define INT_FAST32_C(c) INT32_C(c)
+
+#define UINT_FAST16_C(c) UINT32_C(c)
+#define UINT_FAST32_C(c) UINT32_C(c)
+
+#define INTPTR_C(c) INT32_C(c)
+#define UINTPTR_C(c) UINT32_C(c)
+#define PTRDIFF_C(c) INT32_C(c)
+
+#endif /* _BITSIZE_STDINTCONST_H */
diff --git a/klibc/klibc/include/bits32/bitsize/stdintlimits.h b/klibc/klibc/include/bits32/bitsize/stdintlimits.h
new file mode 100644
index 0000000000..b44fe01186
--- /dev/null
+++ b/klibc/klibc/include/bits32/bitsize/stdintlimits.h
@@ -0,0 +1,22 @@
+/*
+ * bits32/stdintlimits.h
+ */
+
+#ifndef _BITSIZE_STDINTLIMITS_H
+#define _BITSIZE_STDINTLIMITS_H
+
+#define INT_FAST16_MIN INT32_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST16_MAX INT32_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+
+#endif /* _BITSIZE_STDINTLIMITS_H */
diff --git a/klibc/klibc/include/bits64/bitsize/limits.h b/klibc/klibc/include/bits64/bitsize/limits.h
new file mode 100644
index 0000000000..7b20da085b
--- /dev/null
+++ b/klibc/klibc/include/bits64/bitsize/limits.h
@@ -0,0 +1,14 @@
+/*
+ * bits64/limits.h
+ */
+
+#ifndef _BITSIZE_LIMITS_H
+#define _BITSIZE_LIMITS_H
+
+#define LONG_BIT 64
+
+#define LONG_MIN (-9223372036854775807L-1)
+#define LONG_MAX 9223372036854775807L
+#define ULONG_MAX 18446744073709551615UL
+
+#endif /* _BITSIZE_LIMITS_H */
diff --git a/klibc/klibc/include/bits64/bitsize/stddef.h b/klibc/klibc/include/bits64/bitsize/stddef.h
new file mode 100644
index 0000000000..3e72621862
--- /dev/null
+++ b/klibc/klibc/include/bits64/bitsize/stddef.h
@@ -0,0 +1,13 @@
+/*
+ * bits64/stddef.h
+ */
+
+#ifndef _BITSIZE_STDDEF_H
+#define _BITSIZE_STDDEF_H
+
+#define _SIZE_T
+typedef unsigned long size_t;
+#define _PTRDIFF_T
+typedef signed long ptrdiff_t;
+
+#endif /* _BITSIZE_STDDEF_H */
diff --git a/klibc/klibc/include/bits64/bitsize/stdint.h b/klibc/klibc/include/bits64/bitsize/stdint.h
new file mode 100644
index 0000000000..f569f526b6
--- /dev/null
+++ b/klibc/klibc/include/bits64/bitsize/stdint.h
@@ -0,0 +1,36 @@
+/*
+ * bits64/stdint.h
+ */
+
+#ifndef _BITSIZE_STDINT_H
+#define _BITSIZE_STDINT_H
+
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long int uint64_t;
+
+typedef long int int_fast16_t;
+typedef long int int_fast32_t;
+
+typedef unsigned long int uint_fast16_t;
+typedef unsigned long int uint_fast32_t;
+
+typedef long int intptr_t;
+typedef unsigned long int uintptr_t;
+
+#define __INT64_C(c) c ## L
+#define __UINT64_C(c) c ## UL
+
+#define __PRI64_RANK "l"
+#define __PRIFAST_RANK "l"
+#define __PRIPTR_RANK "l"
+
+#endif /* _BITSIZE_STDINT_H */
+
+
diff --git a/klibc/klibc/include/bits64/bitsize/stdintconst.h b/klibc/klibc/include/bits64/bitsize/stdintconst.h
new file mode 100644
index 0000000000..65f2db0501
--- /dev/null
+++ b/klibc/klibc/include/bits64/bitsize/stdintconst.h
@@ -0,0 +1,18 @@
+/*
+ * bits64/stdintconst.h
+ */
+
+#ifndef _BITSIZE_STDINTCONST_H
+#define _BITSIZE_STDINTCONST_H
+
+#define INT_FAST16_C(c) INT64_C(c)
+#define INT_FAST32_C(c) INT64_C(c)
+
+#define UINT_FAST16_C(c) UINT64_C(c)
+#define UINT_FAST32_C(c) UINT64_C(c)
+
+#define INTPTR_C(c) INT64_C(c)
+#define UINTPTR_C(c) UINT64_C(c)
+#define PTRDIFF_C(c) INT64_C(c)
+
+#endif /* _BITSIZE_STDINTCONST_H */
diff --git a/klibc/klibc/include/bits64/bitsize/stdintlimits.h b/klibc/klibc/include/bits64/bitsize/stdintlimits.h
new file mode 100644
index 0000000000..d110d17d2d
--- /dev/null
+++ b/klibc/klibc/include/bits64/bitsize/stdintlimits.h
@@ -0,0 +1,22 @@
+/*
+ * bits64/stdintlimits.h
+ */
+
+#ifndef _BITSIZE_STDINTLIMITS_H
+#define _BITSIZE_STDINTLIMITS_H
+
+#define INT_FAST16_MIN INT64_MIN
+#define INT_FAST32_MIN INT64_MIN
+#define INT_FAST16_MAX INT64_MAX
+#define INT_FAST32_MAX INT64_MAX
+#define UINT_FAST16_MAX UINT64_MAX
+#define UINT_FAST32_MAX UINT64_MAX
+
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+
+#endif /* _BITSIZE_STDINTLIMITS_H */
diff --git a/klibc/klibc/include/ctype.h b/klibc/klibc/include/ctype.h
new file mode 100644
index 0000000000..2cb90a45d3
--- /dev/null
+++ b/klibc/klibc/include/ctype.h
@@ -0,0 +1,117 @@
+/*
+ * ctype.h
+ *
+ * This assumes ISO 8859-1, being a reasonable superset of ASCII.
+ */
+
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+#ifndef __CTYPE_NO_INLINE
+# define __ctype_inline extern __inline__
+#else
+# define __ctype_inline
+#endif
+
+/*
+ * This relies on the following definitions:
+ *
+ * cntrl = !print
+ * alpha = upper|lower
+ * graph = punct|alpha|digit
+ * blank = '\t' || ' ' (per POSIX requirement)
+ */
+enum {
+ __ctype_upper = (1 << 0),
+ __ctype_lower = (1 << 1),
+ __ctype_digit = (1 << 2),
+ __ctype_xdigit = (1 << 3),
+ __ctype_space = (1 << 4),
+ __ctype_print = (1 << 5),
+ __ctype_punct = (1 << 6)
+};
+
+extern const unsigned char __ctypes[];
+
+__ctype_inline int isalnum(int __c)
+{
+ return __ctypes[__c+1] &
+ (__ctype_upper|__ctype_lower|__ctype_digit);
+}
+
+__ctype_inline int isalpha(int __c)
+{
+ return __ctypes[__c+1] &
+ (__ctype_upper|__ctype_lower);
+}
+
+__ctype_inline int isascii(int __c)
+{
+ return !(__c & ~0x7f);
+}
+
+__ctype_inline int isblank(int __c)
+{
+ return (__c == '\t') || (__c == ' ');
+}
+
+__ctype_inline int iscntrl(int __c)
+{
+ return (__c >= 0) && !(__ctypes[__c+1] & __ctype_print);
+}
+
+__ctype_inline int isdigit(int __c)
+{
+ return __ctypes[__c+1] & __ctype_digit;
+}
+
+__ctype_inline int isgraph(int __c)
+{
+ return __ctypes[__c+1] &
+ (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct);
+}
+
+__ctype_inline int islower(int __c)
+{
+ return __ctypes[__c+1] & __ctype_lower;
+}
+
+__ctype_inline int isprint(int __c)
+{
+ return __ctypes[__c+1] & __ctype_print;
+}
+
+__ctype_inline int ispunct(int __c)
+{
+ return __ctypes[__c+1] & __ctype_punct;
+}
+
+__ctype_inline int isspace(int __c)
+{
+ return __ctypes[__c+1] & __ctype_space;
+}
+
+__ctype_inline int isupper(int __c)
+{
+ return __ctypes[__c+1] & __ctype_upper;
+}
+
+__ctype_inline int isxdigit(int __c)
+{
+ return __ctypes[__c+1] & __ctype_xdigit;
+}
+
+#define _toupper(__c) ((__c) & ~0x20)
+#define _tolower(__c) ((__c) | 0x20)
+
+__ctype_inline int toupper(int __c)
+{
+ return islower(__c) ? _toupper(__c) : __c;
+}
+
+__ctype_inline int tolower(int __c)
+{
+ return isupper(__c) ? _tolower(__c) : __c;
+}
+
+#endif /* _CTYPE_H */
diff --git a/klibc/klibc/include/dirent.h b/klibc/klibc/include/dirent.h
new file mode 100644
index 0000000000..10dd138ee5
--- /dev/null
+++ b/klibc/klibc/include/dirent.h
@@ -0,0 +1,20 @@
+/*
+ * dirent.h
+ */
+
+#ifndef _DIRENT_H
+#define _DIRENT_H
+
+#include <klibc/extern.h>
+#include <sys/dirent.h>
+
+#ifndef __IO_DIR_DEFINED
+struct _IO_dir;
+#endif
+typedef struct _IO_dir DIR;
+
+__extern DIR *opendir(const char *);
+__extern struct dirent *readdir(DIR *);
+__extern int closedir(DIR *);
+
+#endif /* _DIRENT_H */
diff --git a/klibc/klibc/include/elf.h b/klibc/klibc/include/elf.h
new file mode 100644
index 0000000000..bd0f3e7f9b
--- /dev/null
+++ b/klibc/klibc/include/elf.h
@@ -0,0 +1,12 @@
+/*
+ * elf.h
+ */
+
+#ifndef _ELF_H
+#define _ELF_H
+
+#include <sys/types.h>
+#include <linux/elf.h>
+
+#endif /* _ELF_H */
+
diff --git a/klibc/klibc/include/endian.h b/klibc/klibc/include/endian.h
new file mode 100644
index 0000000000..10dbbd8a89
--- /dev/null
+++ b/klibc/klibc/include/endian.h
@@ -0,0 +1,41 @@
+/*
+ * endian.h
+ */
+
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <asm/byteorder.h>
+
+/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or
+ __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be
+ defined with __BYTE_ORDER defining which is actually used... */
+
+#if defined(__LITTLE_ENDIAN)
+# undef __LITTLE_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN 4321
+# define __PDP_ENDIAN 3412
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN)
+# undef __BIG_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN 4321
+# define __PDP_ENDIAN 3412
+# define __BYTE_ORDER __BIG_ENDIAN
+#elif defined(__PDP_ENDIAN)
+# undef __PDP_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN 4321
+# define __PDP_ENDIAN 3412
+# define __BYTE_ORDER __PDP_ENDIAN
+#else
+# error "Unknown byte order!"
+#endif
+
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define BIG_ENDIAN __BIG_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#endif /* _ENDIAN_H */
diff --git a/klibc/klibc/include/errno.h b/klibc/klibc/include/errno.h
new file mode 100644
index 0000000000..b2e666504d
--- /dev/null
+++ b/klibc/klibc/include/errno.h
@@ -0,0 +1,8 @@
+/*
+ * errno.h
+ */
+
+#include <klibc/extern.h>
+#include <asm/errno.h>
+
+__extern int errno;
diff --git a/klibc/klibc/include/fcntl.h b/klibc/klibc/include/fcntl.h
new file mode 100644
index 0000000000..e90959c7e9
--- /dev/null
+++ b/klibc/klibc/include/fcntl.h
@@ -0,0 +1,11 @@
+/*
+ * fcntl.h
+ */
+
+#ifndef _FCNTL_H
+#define _FCNTL_H
+
+#include <sys/types.h>
+#include <linux/fcntl.h>
+
+#endif /* _FCNTL_H */
diff --git a/klibc/klibc/include/grp.h b/klibc/klibc/include/grp.h
new file mode 100644
index 0000000000..03ceb31560
--- /dev/null
+++ b/klibc/klibc/include/grp.h
@@ -0,0 +1,13 @@
+/*
+ * grp.h
+ */
+
+#ifndef _GRP_H
+#define _GRP_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+
+__extern int setgroups(size_t, const gid_t *);
+
+#endif /* _GRP_H */
diff --git a/klibc/klibc/include/inttypes.h b/klibc/klibc/include/inttypes.h
new file mode 100644
index 0000000000..e00fa63160
--- /dev/null
+++ b/klibc/klibc/include/inttypes.h
@@ -0,0 +1,226 @@
+/*
+ * inttypes.h
+ */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <stddef.h>
+
+static __inline__ intmax_t imaxabs(intmax_t __n)
+{
+ return (__n < (intmax_t)0) ? -__n : __n;
+}
+
+__extern intmax_t strtoimax(const char *, char **, int);
+__extern uintmax_t strtoumax(const char *, char **, int);
+
+/* extensions */
+__extern intmax_t strntoimax(const char *, char **, int, size_t);
+__extern uintmax_t strntoumax(const char *, char **, int, size_t);
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 __PRI64_RANK "d"
+
+#define PRIdLEAST8 "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 __PRI64_RANK "d"
+
+#define PRIdFAST8 "d"
+#define PRIdFAST16 __PRIFAST_RANK "d"
+#define PRIdFAST32 __PRIFAST_RANK "d"
+#define PRIdFAST64 __PRI64_RANK "d"
+
+#define PRIdMAX __PRI64_RANK "d"
+#define PRIdPTR __PRIPTR_RANK "d"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 __PRI64_RANK "i"
+
+#define PRIiLEAST8 "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 __PRI64_RANK "i"
+
+#define PRIiFAST8 "i"
+#define PRIiFAST16 __PRIFAST_RANK "i"
+#define PRIiFAST32 __PRIFAST_RANK "i"
+#define PRIiFAST64 __PRI64_RANK "i"
+
+#define PRIiMAX __PRI64_RANK "i"
+#define PRIiPTR __PRIPTR_RANK "i"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 __PRI64_RANK "o"
+
+#define PRIoLEAST8 "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 __PRI64_RANK "o"
+
+#define PRIoFAST8 "o"
+#define PRIoFAST16 __PRIFAST_RANK "o"
+#define PRIoFAST32 __PRIFAST_RANK "o"
+#define PRIoFAST64 __PRI64_RANK "o"
+
+#define PRIoMAX __PRI64_RANK "o"
+#define PRIoPTR __PRIPTR_RANK "o"
+
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 __PRI64_RANK "u"
+
+#define PRIuLEAST8 "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 __PRI64_RANK "u"
+
+#define PRIuFAST8 "u"
+#define PRIuFAST16 __PRIFAST_RANK "u"
+#define PRIuFAST32 __PRIFAST_RANK "u"
+#define PRIuFAST64 __PRI64_RANK "u"
+
+#define PRIuMAX __PRI64_RANK "u"
+#define PRIuPTR __PRIPTR_RANK "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 __PRI64_RANK "x"
+
+#define PRIxLEAST8 "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 __PRI64_RANK "x"
+
+#define PRIxFAST8 "x"
+#define PRIxFAST16 __PRIFAST_RANK "x"
+#define PRIxFAST32 __PRIFAST_RANK "x"
+#define PRIxFAST64 __PRI64_RANK "x"
+
+#define PRIxMAX __PRI64_RANK "x"
+#define PRIxPTR __PRIPTR_RANK "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 __PRI64_RANK "X"
+
+#define PRIXLEAST8 "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 __PRI64_RANK "X"
+
+#define PRIXFAST8 "X"
+#define PRIXFAST16 __PRIFAST_RANK "X"
+#define PRIXFAST32 __PRIFAST_RANK "X"
+#define PRIXFAST64 __PRI64_RANK "X"
+
+#define PRIXMAX __PRI64_RANK "X"
+#define PRIXPTR __PRIPTR_RANK "X"
+
+#define SCNd8 "hhd"
+#define SCNd16 "hd"
+#define SCNd32 "d"
+#define SCNd64 __PRI64_RANK "d"
+
+#define SCNdLEAST8 "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 __PRI64_RANK "d"
+
+#define SCNdFAST8 "hhd"
+#define SCNdFAST16 __PRIFAST_RANK "d"
+#define SCNdFAST32 __PRIFAST_RANK "d"
+#define SCNdFAST64 __PRI64_RANK "d"
+
+#define SCNdMAX __PRI64_RANK "d"
+#define SCNdPTR __PRIPTR_RANK "d"
+
+#define SCNi8 "hhi"
+#define SCNi16 "hi"
+#define SCNi32 "i"
+#define SCNi64 __PRI64_RANK "i"
+
+#define SCNiLEAST8 "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 __PRI64_RANK "i"
+
+#define SCNiFAST8 "hhi"
+#define SCNiFAST16 __PRIFAST_RANK "i"
+#define SCNiFAST32 __PRIFAST_RANK "i"
+#define SCNiFAST64 __PRI64_RANK "i"
+
+#define SCNiMAX __PRI64_RANK "i"
+#define SCNiPTR __PRIPTR_RANK "i"
+
+#define SCNo8 "hho"
+#define SCNo16 "ho"
+#define SCNo32 "o"
+#define SCNo64 __PRI64_RANK "o"
+
+#define SCNoLEAST8 "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 __PRI64_RANK "o"
+
+#define SCNoFAST8 "hho"
+#define SCNoFAST16 __PRIFAST_RANK "o"
+#define SCNoFAST32 __PRIFAST_RANK "o"
+#define SCNoFAST64 __PRI64_RANK "o"
+
+#define SCNoMAX __PRI64_RANK "o"
+#define SCNoPTR __PRIPTR_RANK "o"
+
+#define SCNu8 "hhu"
+#define SCNu16 "hu"
+#define SCNu32 "u"
+#define SCNu64 __PRI64_RANK "u"
+
+#define SCNuLEAST8 "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 __PRI64_RANK "u"
+
+#define SCNuFAST8 "hhu"
+#define SCNuFAST16 __PRIFAST_RANK "u"
+#define SCNuFAST32 __PRIFAST_RANK "u"
+#define SCNuFAST64 __PRI64_RANK "u"
+
+#define SCNuMAX __PRI64_RANK "u"
+#define SCNuPTR __PRIPTR_RANK "u"
+
+#define SCNx8 "hhx"
+#define SCNx16 "hx"
+#define SCNx32 "x"
+#define SCNx64 __PRI64_RANK "x"
+
+#define SCNxLEAST8 "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 __PRI64_RANK "x"
+
+#define SCNxFAST8 "hhx"
+#define SCNxFAST16 __PRIFAST_RANK "x"
+#define SCNxFAST32 __PRIFAST_RANK "x"
+#define SCNxFAST64 __PRI64_RANK "x"
+
+#define SCNxMAX __PRI64_RANK "x"
+#define SCNxPTR __PRIPTR_RANK "x"
+
+#endif
+
+#endif /* _INTTYPES_H */
diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h
new file mode 100644
index 0000000000..5c284b206c
--- /dev/null
+++ b/klibc/klibc/include/klibc/compiler.h
@@ -0,0 +1,61 @@
+/*
+ * klibc/compiler.h
+ *
+ * Various compiler features
+ */
+
+#ifndef _KLIBC_COMPILER_H
+#define _KLIBC_COMPILER_H
+
+/* Specific calling conventions */
+#ifdef __i386__
+# ifdef __GNUC__
+# define __cdecl __attribute__((cdecl,regparm(0)))
+# else
+ /* Most other C compilers have __cdecl as a keyword */
+# endif
+#endif
+
+/* How to declare a function that *must* be inlined */
+#ifdef __GNUC__
+# if __GNUC_MAJOR__ >= 3
+# define __must_inline static __inline__ __attribute__((always_inline))
+# else
+# define __must_inline extern __inline__
+# endif
+#else
+# define __must_inline inline /* Just hope this works... */
+#endif
+
+/* How to declare a function that does not return */
+#ifdef __GNUC__
+# define __noreturn void __attribute__((noreturn))
+#else
+# define __noreturn void
+#endif
+
+/* How to declare a "constant" function (a function in the
+ mathematical sense) */
+#ifdef __GNUC__
+# define __constfunc __attribute__((const))
+#else
+# define __constfunc
+#endif
+
+/* Format attribute */
+#ifdef __GNUC__
+# define __formatfunc(t,f,a) __attribute__((format(t,f,a)))
+#else
+# define __formatfunc(t,f,a)
+#endif
+
+/* likely/unlikely */
+#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95))
+# define __likely(x) __builtin_expect((x), 1)
+# define __unlikely(x) __builtin_expect((x), 0)
+#else
+# define __likely(x) (x)
+# define __unlikely(x) (x)
+#endif
+
+#endif
diff --git a/klibc/klibc/include/klibc/diverr.h b/klibc/klibc/include/klibc/diverr.h
new file mode 100644
index 0000000000..4d8c8d36c2
--- /dev/null
+++ b/klibc/klibc/include/klibc/diverr.h
@@ -0,0 +1,16 @@
+/*
+ * klibc/diverr.h
+ */
+
+#ifndef _KLIBC_DIVERR_H
+#define _KLIBC_DIVERR_H
+
+#include <signal.h>
+
+static __inline__ void
+__divide_error(void)
+{
+ raise(SIGFPE);
+}
+
+#endif /* _KLIBC_DIVERR_H */
diff --git a/klibc/klibc/include/klibc/extern.h b/klibc/klibc/include/klibc/extern.h
new file mode 100644
index 0000000000..f9c3467211
--- /dev/null
+++ b/klibc/klibc/include/klibc/extern.h
@@ -0,0 +1,14 @@
+/*
+ * klibc/extern.h
+ */
+
+#ifndef _KLIBC_EXTERN_H
+#define _KLIBC_EXTERN_H
+
+#ifdef __cplusplus
+#define __extern extern "C"
+#else
+#define __extern extern
+#endif
+
+#endif /* _KLIBC_EXTERN_H */
diff --git a/klibc/klibc/include/limits.h b/klibc/klibc/include/limits.h
new file mode 100644
index 0000000000..f1532e5323
--- /dev/null
+++ b/klibc/klibc/include/limits.h
@@ -0,0 +1,40 @@
+/*
+ * limits.h
+ */
+
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#define CHAR_BIT 8
+#define SHRT_BIT 16
+#define INT_BIT 32
+#define LONGLONG_BIT 64
+
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+
+#ifdef __CHAR_UNSIGNED__
+# define CHAR_MIN 0
+# define CHAR_MAX UCHAR_MAX
+#else
+# define CHAR_MIN SCHAR_MIN
+# define CHAR_MAX SCHAR_MAX
+#endif
+
+#define SHRT_MIN (-32768)
+#define SHRT_MAX 32767
+#define USHRT_MAX 65535
+
+#define INT_MIN (-2147483647-1)
+#define INT_MAX 2147483647
+#define UINT_MAX 4294967295U
+
+#define LONGLONG_MIN (-9223372036854775807LL-1)
+#define LONGLONG_MAX 9223372036854775807LL
+#define ULONGLONG_MAX 18446744073709551615ULL
+
+#include <bitsize/limits.h>
+#include <linux/limits.h>
+
+#endif /* _LIMITS_H */
diff --git a/klibc/klibc/include/net/if.h b/klibc/klibc/include/net/if.h
new file mode 100644
index 0000000000..1aa8e7b90c
--- /dev/null
+++ b/klibc/klibc/include/net/if.h
@@ -0,0 +1 @@
+#include <linux/if.h>
diff --git a/klibc/klibc/include/net/if_arp.h b/klibc/klibc/include/net/if_arp.h
new file mode 100644
index 0000000000..a25f1b4759
--- /dev/null
+++ b/klibc/klibc/include/net/if_arp.h
@@ -0,0 +1 @@
+#include <linux/if_arp.h>
diff --git a/klibc/klibc/include/net/if_ether.h b/klibc/klibc/include/net/if_ether.h
new file mode 100644
index 0000000000..060ef22070
--- /dev/null
+++ b/klibc/klibc/include/net/if_ether.h
@@ -0,0 +1 @@
+#include <linux/if_ether.h>
diff --git a/klibc/klibc/include/net/if_packet.h b/klibc/klibc/include/net/if_packet.h
new file mode 100644
index 0000000000..b5e8e0e11f
--- /dev/null
+++ b/klibc/klibc/include/net/if_packet.h
@@ -0,0 +1 @@
+#include <linux/if_packet.h>
diff --git a/klibc/klibc/include/netinet/in.h b/klibc/klibc/include/netinet/in.h
new file mode 100644
index 0000000000..92dc843bb1
--- /dev/null
+++ b/klibc/klibc/include/netinet/in.h
@@ -0,0 +1,33 @@
+/*
+ * netinet/in.h
+ */
+
+#ifndef _NETINET_IN_H
+#define _NETINET_IN_H
+
+/* added this include by Mats Petersson */
+#include <linux/socket.h>
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <endian.h> /* Must be included *before* <linux/in.h> */
+#include <linux/in.h>
+
+#ifndef htons
+# define htons(x) __cpu_to_be16(x)
+#endif
+#ifndef ntohs
+# define ntohs(x) __be16_to_cpu(x)
+#endif
+#ifndef htonl
+# define htonl(x) __cpu_to_be32(x)
+#endif
+#ifndef ntohl
+# define ntohl(x) __be32_to_cpu(x)
+#endif
+
+#define IPPORT_RESERVED 1024
+
+__extern int bindresvport (int sd, struct sockaddr_in *sin);
+
+#endif /* _NETINET_IN_H */
diff --git a/klibc/klibc/include/netinet/in6.h b/klibc/klibc/include/netinet/in6.h
new file mode 100644
index 0000000000..46584ca627
--- /dev/null
+++ b/klibc/klibc/include/netinet/in6.h
@@ -0,0 +1,10 @@
+/*
+ * netinet/in6.h
+ */
+
+#ifndef _NETINET_IN6_H
+#define _NETINET_IN6_H
+
+#include <linux/in6.h>
+
+#endif /* _NETINET_IN6_H */
diff --git a/klibc/klibc/include/netinet/ip.h b/klibc/klibc/include/netinet/ip.h
new file mode 100644
index 0000000000..8aecbe66a3
--- /dev/null
+++ b/klibc/klibc/include/netinet/ip.h
@@ -0,0 +1,13 @@
+/*
+ * netinet/ip.h
+ */
+
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
+
+#include <endian.h>
+#include <linux/ip.h>
+
+#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
+
+#endif /* _NETINET_IP_H */
diff --git a/klibc/klibc/include/netinet/tcp.h b/klibc/klibc/include/netinet/tcp.h
new file mode 100644
index 0000000000..bb5d307e98
--- /dev/null
+++ b/klibc/klibc/include/netinet/tcp.h
@@ -0,0 +1,11 @@
+/*
+ * netinet/tcp.h
+ */
+
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
+
+#include <endian.h> /* Include *before* linux/tcp.h */
+#include <linux/tcp.h>
+
+#endif /* _NETINET_TCP_H */
diff --git a/klibc/klibc/include/netinet/udp.h b/klibc/klibc/include/netinet/udp.h
new file mode 100644
index 0000000000..b809b4ee6e
--- /dev/null
+++ b/klibc/klibc/include/netinet/udp.h
@@ -0,0 +1,19 @@
+/*
+ * netinet/udp.h
+ */
+
+#ifndef _NETINET_UDP_H
+#define _NETINET_UDP_H
+
+/*
+ * We would include linux/udp.h, but it brings in too much other stuff
+ */
+
+struct udphdr {
+ __u16 source;
+ __u16 dest;
+ __u16 len;
+ __u16 check;
+};
+
+#endif /* _NETINET_UDP_H */
diff --git a/klibc/klibc/include/poll.h b/klibc/klibc/include/poll.h
new file mode 100644
index 0000000000..8710d92ebd
--- /dev/null
+++ b/klibc/klibc/include/poll.h
@@ -0,0 +1,16 @@
+/*
+ * poll.h
+ */
+
+#ifndef _POLL_H
+#define _POLL_H
+
+#include <klibc/extern.h>
+#include <linux/poll.h>
+
+/* POSIX specifies "int" for the timeout, Linux seems to use long... */
+
+typedef unsigned int nfds_t;
+__extern int poll(struct pollfd *, nfds_t, long);
+
+#endif /* _POLL_H */
diff --git a/klibc/klibc/include/sched.h b/klibc/klibc/include/sched.h
new file mode 100644
index 0000000000..5e6103965f
--- /dev/null
+++ b/klibc/klibc/include/sched.h
@@ -0,0 +1,23 @@
+/*
+ * sched.h
+ */
+
+#ifndef _SCHED_H
+#define _SCHED_H
+
+#include <klibc/extern.h>
+
+/* linux/sched.h is unusable; put the declarations we need here... */
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+
+struct sched_param {
+ int sched_priority;
+};
+
+__extern int sched_setschedule(pid_t, int, const struct sched_param *);
+__extern int sched_yield(void);
+
+#endif /* _SCHED_H */
diff --git a/klibc/klibc/include/setjmp.h b/klibc/klibc/include/setjmp.h
new file mode 100644
index 0000000000..b504eb6d08
--- /dev/null
+++ b/klibc/klibc/include/setjmp.h
@@ -0,0 +1,43 @@
+/*
+ * setjmp.h
+ */
+
+#ifndef _SETJMP_H
+#define _SETJMP_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <signal.h>
+
+#include <klibc/archsetjmp.h>
+
+__extern int setjmp(jmp_buf);
+__extern __noreturn longjmp(jmp_buf, int);
+
+/*
+ Whose bright idea was it to add unrelated functionality to just about
+ the only function in the standard C library (setjmp) which cannot be
+ wrapped by an ordinary function wrapper? Anyway, the damage is done,
+ and therefore, this wrapper *must* be inline. However, gcc will
+ complain if this is an inline function for unknown reason, and
+ therefore sigsetjmp() needs to be a macro.
+*/
+
+struct __sigjmp_buf {
+ jmp_buf __jmpbuf;
+ sigset_t __sigs;
+};
+
+typedef struct __sigjmp_buf sigjmp_buf[1];
+
+#define sigsetjmp(__env, __save) \
+({ \
+ struct __sigjmp_buf *__e = (__env); \
+ sigprocmask(0, NULL, &__e->__sigs); \
+ setjmp(__e->__jmpbuf); \
+})
+
+__extern __noreturn siglongjmp(sigjmp_buf, int);
+
+#endif /* _SETJMP_H */
diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h
new file mode 100644
index 0000000000..ffd2beba43
--- /dev/null
+++ b/klibc/klibc/include/signal.h
@@ -0,0 +1,72 @@
+/*
+ * signal.h
+ */
+
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#include <klibc/extern.h>
+#include <string.h> /* For memset() */
+#include <limits.h> /* For LONG_BIT */
+#include <sys/types.h>
+#include <asm/signal.h>
+
+/* Some architectures don't define these */
+#ifndef SA_RESETHAND
+# define SA_RESETHAND SA_ONESHOT
+#endif
+#ifndef SA_NODEFER
+# define SA_NODEFER SA_NOMASK
+#endif
+#ifndef NSIG
+# define NSIG _NSIG
+#endif
+
+__extern const char * const sys_siglist[];
+
+/* This assumes sigset_t is either an unsigned long or an array of such,
+ and that _NSIG_BPW in the kernel is always LONG_BIT */
+
+static __inline__ int sigemptyset(sigset_t *__set)
+{
+ memset(__set, 0, sizeof *__set);
+ return 0;
+}
+static __inline__ int sigfillset(sigset_t *__set)
+{
+ memset(__set, ~0, sizeof *__set);
+ return 0;
+}
+static __inline__ int sigaddset(sigset_t *__set, int __signum)
+{
+ unsigned long *__lset = (unsigned long *)__set;
+ __lset[__signum/LONG_BIT] |= 1UL << (__signum%LONG_BIT);
+ return 0;
+}
+static __inline__ int sigdelset(sigset_t *__set, int __signum)
+{
+ unsigned long *__lset = (unsigned long *)__set;
+ __lset[__signum/LONG_BIT] &= ~(1UL << (__signum%LONG_BIT));
+ return 0;
+}
+static __inline__ int sigismember(sigset_t *__set, int __signum)
+{
+ unsigned long *__lset = (unsigned long *)__set;
+ return (int)((__lset[__signum/LONG_BIT] >> (__signum%LONG_BIT)) & 1);
+}
+
+__extern __sighandler_t __signal(int, __sighandler_t, int);
+__extern __sighandler_t signal(int, __sighandler_t);
+__extern __sighandler_t bsd_signal(int, __sighandler_t);
+__extern int sigaction(int, const struct sigaction *, struct sigaction *);
+__extern int sigprocmask(int, const sigset_t *, sigset_t *);
+__extern int sigpending(sigset_t *);
+__extern int sigsuspend(const sigset_t *);
+__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
+__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
+__extern int rt_sigpending(sigset_t *, size_t);
+__extern int rt_sigsuspend(const sigset_t *, size_t);
+__extern int raise(int);
+__extern int kill(pid_t, int);
+
+#endif /* _SIGNAL_H */
diff --git a/klibc/klibc/include/stdarg.h b/klibc/klibc/include/stdarg.h
new file mode 100644
index 0000000000..cc324b825d
--- /dev/null
+++ b/klibc/klibc/include/stdarg.h
@@ -0,0 +1,14 @@
+/*
+ * stdarg.h
+ *
+ * This is just a wrapper for the gcc one, but defines va_copy()
+ * even if gcc doesn't.
+ */
+
+/* Note: the _STDARG_H macro belongs to the gcc header... */
+#include_next <stdarg.h>
+
+/* Older gcc considers this an extension, so it's double underbar only */
+#ifndef va_copy
+#define va_copy(d,s) __va_copy(d,s)
+#endif
diff --git a/klibc/klibc/include/stddef.h b/klibc/klibc/include/stddef.h
new file mode 100644
index 0000000000..900c147cd8
--- /dev/null
+++ b/klibc/klibc/include/stddef.h
@@ -0,0 +1,24 @@
+/*
+ * stddef.h
+ */
+
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#ifndef __KLIBC__
+# define __KLIBC__ 1
+#endif
+
+#include <bitsize/stddef.h>
+
+#undef NULL
+#ifdef __cplusplus
+# define NULL 0
+#else
+# define NULL ((void *)0)
+#endif
+
+#undef offsetof
+#define offsetof(t,m) ((size_t)&((t *)0->m))
+
+#endif /* _STDDEF_H */
diff --git a/klibc/klibc/include/stdint.h b/klibc/klibc/include/stdint.h
new file mode 100644
index 0000000000..2022a30fd7
--- /dev/null
+++ b/klibc/klibc/include/stdint.h
@@ -0,0 +1,113 @@
+/*
+ * stdint.h
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#include <bitsize/stdint.h>
+
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+typedef int8_t int_fast8_t;
+typedef int64_t int_fast64_t;
+
+typedef uint8_t uint_fast8_t;
+typedef uint64_t uint_fast64_t;
+
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+#define INT8_MIN (-128)
+#define INT16_MIN (-32768)
+#define INT32_MIN (-2147483647-1)
+#define INT64_MIN (__INT64_C(-9223372036854775807)-1)
+
+#define INT8_MAX (127)
+#define INT16_MAX (32767)
+#define INT32_MAX (2147483647)
+#define INT64_MAX (__INT64_C(9223372036854775807))
+
+#define UINT8_MAX (255U)
+#define UINT16_MAX (65535U)
+#define UINT32_MAX (4294967295U)
+#define UINT64_MAX (__UINT64_C(18446744073709551615))
+
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST64_MIN INT64_MIN
+
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST64_MAX INT64_MAX
+
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#include <bitsize/stdintlimits.h>
+
+#endif
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define INT8_C(c) c
+#define INT16_C(c) c
+#define INT32_C(c) c
+#define INT64_C(c) __INT64_C(c)
+
+#define UINT8_C(c) c ## U
+#define UINT16_C(c) c ## U
+#define UINT32_C(c) c ## U
+#define UINT64_C(c) __UINT64_C(c)
+
+#define INT_LEAST8_C(c) INT8_C(c)
+#define INT_LEAST16_C(c) INT16_C(c)
+#define INT_LEAST32_C(c) INT32_C(c)
+#define INT_LEAST64_C(c) INT64_C(c)
+
+#define UINT_LEAST8_C(c) UINT8_C(c)
+#define UINT_LEAST16_C(c) UINT16_C(c)
+#define UINT_LEAST32_C(c) UINT32_C(c)
+#define UINT_LEAST64_C(c) UINT64_C(c)
+
+#define INT_FAST8_C(c) INT8_C(c)
+#define INT_FAST64_C(c) INT64_C(c)
+
+#define UINT_FAST8_C(c) UINT8_C(c)
+#define UINT_FAST64_C(c) UINT64_C(c)
+
+#define INTMAX_C(c) INT64_C(c)
+#define UINTMAX_C(c) UINT64_C(c)
+
+#include <bitsize/stdintconst.h>
+
+#endif
+
+#endif /* _STDINT_H */
diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h
new file mode 100644
index 0000000000..5e621af5f1
--- /dev/null
+++ b/klibc/klibc/include/stdio.h
@@ -0,0 +1,109 @@
+/*
+ * stdio.h
+ */
+
+#ifndef _STDIO_H
+#define _STDIO_H
+
+#include <klibc/extern.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* This structure doesn't really exist, but it gives us something
+ to define FILE * with */
+struct _IO_file;
+typedef struct _IO_file FILE;
+
+#define stdin ((FILE *)0)
+#define stdout ((FILE *)1)
+#define stderr ((FILE *)2)
+
+#ifndef EOF
+# define EOF (-1)
+#endif
+
+#ifndef BUFSIZ
+# define BUFSIZ 4096
+#endif
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+static __inline__ int fileno(FILE *__f)
+{
+ /* This should really be intptr_t, but size_t should be the same size */
+ return (int)(size_t)__f;
+}
+
+static __inline__ FILE * __create_file(int __fd)
+{
+ return (FILE *)(size_t)__fd;
+}
+
+__extern FILE *fopen(const char *, const char *);
+
+static __inline__ FILE *fdopen(int __fd, const char *__m)
+{
+ (void)__m; return __create_file(__fd);
+}
+static __inline__ int fclose(FILE *__f)
+{
+ extern int close(int);
+ return close(fileno(__f));
+}
+static __inline__ int fseek(FILE *__f, off_t __o, int __w)
+{
+ extern off_t lseek(int, off_t, int);
+ return (lseek(fileno(__f), __o, __w) == (off_t)-1) ? -1 : 0;
+}
+static __inline__ off_t ftell(FILE *__f)
+{
+ extern off_t lseek(int, off_t, int);
+ return lseek(fileno(__f), 0, SEEK_CUR);
+}
+
+__extern int fputs(const char *, FILE *);
+__extern int puts(const char *);
+__extern int fputc(int, FILE *);
+#define putc(c,f) fputc((c),(f))
+#define putchar(c) fputc((c),stdout)
+
+__extern int fgetc(FILE *);
+__extern char * fgets(char *, int, FILE *);
+#define getc(f) fgetc(f)
+
+__extern size_t _fread(void *, size_t, FILE *);
+__extern size_t _fwrite(const void *, size_t, FILE *);
+
+#ifndef __NO_FREAD_FWRITE_INLINES
+static __inline__ size_t
+fread(void *__p, size_t __s, size_t __n, FILE *__f)
+{
+ return _fread(__p, __s*__n, __f)/__s;
+}
+static __inline__ size_t
+fwrite(void *__p, size_t __s, size_t __n, FILE *__f)
+{
+ return _fwrite(__p, __s*__n, __f)/__s;
+}
+#endif
+
+__extern int printf(const char *, ...);
+__extern int vprintf(const char *, va_list);
+__extern int fprintf(FILE *, const char *, ...);
+__extern int vfprintf(FILE *, const char *, va_list);
+__extern int sprintf(char *, const char *, ...);
+__extern int vsprintf(char *, const char *, va_list);
+__extern int snprintf(char *, size_t n, const char *, ...);
+__extern int vsnprintf(char *, size_t n, const char *, va_list);
+
+__extern int sscanf(const char *, const char *, ...);
+__extern int vsscanf(const char *, const char *, va_list);
+
+__extern void perror(const char *);
+
+__extern int rename(const char *, const char *);
+
+#endif /* _STDIO_H */
diff --git a/klibc/klibc/include/stdlib.h b/klibc/klibc/include/stdlib.h
new file mode 100644
index 0000000000..38dd1624a5
--- /dev/null
+++ b/klibc/klibc/include/stdlib.h
@@ -0,0 +1,94 @@
+/*
+ * stdlib.h
+ */
+
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+static __inline__ __noreturn _Exit(int __n) {
+ __extern __noreturn _exit(int);
+ _exit(__n);
+ for(;;); /* Some gcc versions are stupid */
+}
+__extern __noreturn abort(void);
+static __inline__ int abs(int __n) {
+ return (__n < 0) ? -__n : __n;
+}
+__extern int atexit(void (*)(void));
+__extern int on_exit(void (*)(int, void *), void *);
+__extern int atoi(const char *);
+__extern long atol(const char *);
+__extern long long atoll(const char *);
+__extern __noreturn exit(int);
+__extern void free(void *);
+static __inline__ long labs(long __n) {
+ return (__n < 0L) ? -__n : __n;
+}
+
+static __inline__ long long llabs(long long __n) {
+ return (__n < 0LL) ? -__n : __n;
+}
+
+#if defined(__GNUC__) && __GNUC_MAJOR__ >= 3
+# define __attribute_malloc __attribute__((malloc))
+#else
+# define __attribute_malloc
+#endif
+
+__extern __attribute_malloc void *malloc(size_t);
+__extern __attribute_malloc void *calloc(size_t, size_t);
+__extern void *realloc(void *, size_t);
+__extern long strtol(const char *, char **, int);
+__extern long long strtoll(const char *, char **, int);
+__extern unsigned long strtoul(const char *, char **, int);
+__extern unsigned long long strtoull(const char *, char **, int);
+
+__extern char *getenv(const char *);
+__extern int putenv(const char *);
+__extern int setenv(const char *, const char *, int);
+__extern int unsetenv(const char *);
+
+__extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+
+
+__extern long jrand48(unsigned short *);
+__extern long mrand48(void);
+__extern long nrand48(unsigned short *);
+__extern long lrand48(void);
+__extern unsigned short *seed48(const unsigned short *);
+__extern void srand48(long);
+
+#define RAND_MAX 0x7fffffff
+static __inline__ int rand(void) {
+ return (int)lrand48();
+}
+static __inline__ void srand(unsigned int __s) {
+ srand48(__s);
+}
+static __inline__ long random(void)
+{
+ return lrand48();
+}
+static __inline__ void srandom(unsigned int __s)
+{
+ srand48(__s);
+}
+
+/* Basic PTY functions. These only work if devpts is mounted! */
+
+static __inline__ int grantpt(int __fd)
+{
+ (void)__fd;
+ return 0; /* devpts does this all for us! */
+}
+__extern int unlockpt(int);
+__extern char *ptsname(int);
+
+#endif /* _STDLIB_H */
diff --git a/klibc/klibc/include/string.h b/klibc/klibc/include/string.h
new file mode 100644
index 0000000000..bce69284ec
--- /dev/null
+++ b/klibc/klibc/include/string.h
@@ -0,0 +1,37 @@
+/*
+ * string.h
+ */
+
+#ifndef _STRING_H
+#define _STRING_H
+
+#include <klibc/extern.h>
+#include <stddef.h>
+
+__extern void *memccpy(void *, const void *, int, size_t);
+__extern void *memchr(const void *, int, size_t);
+__extern int memcmp(const void *, const void *, size_t);
+__extern void *memcpy(void *, const void *, size_t);
+__extern void *memmove(void *, const void *, size_t);
+__extern void *memset(void *, int, size_t);
+__extern void *memmem(const void *, size_t, const void *, size_t);
+__extern void memswap(void *, void *, size_t);
+__extern char *strcat(char *, const char *);
+__extern char *strchr(const char *, int);
+__extern int strcmp(const char *, const char *);
+__extern char *strcpy(char *, const char *);
+__extern size_t strcspn(const char *, const char *);
+__extern char *strdup(const char *);
+__extern char *strerror(int);
+__extern size_t strlen(const char *);
+__extern char *strncat(char *, const char *, size_t);
+__extern int strncmp(const char *, const char *, size_t);
+__extern char *strncpy(char *, const char *, size_t);
+__extern char *strpbrk(const char *, const char *);
+__extern char *strrchr(const char *, int);
+__extern char *strsep(char **, const char *);
+__extern size_t strspn(const char *, const char *);
+__extern char *strstr(const char *, const char *);
+__extern char *strtok(char *, const char *);
+
+#endif /* _STRING_H */
diff --git a/klibc/klibc/include/sys/dirent.h b/klibc/klibc/include/sys/dirent.h
new file mode 100644
index 0000000000..0700f4b561
--- /dev/null
+++ b/klibc/klibc/include/sys/dirent.h
@@ -0,0 +1,13 @@
+/*
+ * sys/dirent.h
+ */
+
+#ifndef _SYS_DIRENT_H
+#define _SYS_DIRENT_H
+
+#include <sys/types.h>
+#include <linux/dirent.h>
+
+__extern int getdents(unsigned int, struct dirent *, unsigned int);
+
+#endif /* _SYS_DIRENT_H */
diff --git a/klibc/klibc/include/sys/fsuid.h b/klibc/klibc/include/sys/fsuid.h
new file mode 100644
index 0000000000..823486b776
--- /dev/null
+++ b/klibc/klibc/include/sys/fsuid.h
@@ -0,0 +1,14 @@
+/*
+ * sys/fsuid.h
+ */
+
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+
+__extern int setfsuid(uid_t);
+__extern int setfsgid(gid_t);
+
+#endif /* _SYS_FSUID_H */
diff --git a/klibc/klibc/include/sys/ioctl.h b/klibc/klibc/include/sys/ioctl.h
new file mode 100644
index 0000000000..b0cee4c02c
--- /dev/null
+++ b/klibc/klibc/include/sys/ioctl.h
@@ -0,0 +1,14 @@
+/*
+ * sys/ioctl.h
+ */
+
+#ifndef _SYS_IOCTL_H
+#define _SYS_IOCTL_H
+
+#include <klibc/extern.h>
+#include <linux/ioctl.h>
+#include <asm/ioctls.h>
+
+__extern int ioctl(int, int, void *);
+
+#endif /* _SYS_IOCTL_H */
diff --git a/klibc/klibc/include/sys/klog.h b/klibc/klibc/include/sys/klog.h
new file mode 100644
index 0000000000..0fc5f5d945
--- /dev/null
+++ b/klibc/klibc/include/sys/klog.h
@@ -0,0 +1,24 @@
+/*
+ * sys/klog.h
+ */
+
+#ifndef _SYS_KLOG_H
+#define _SYS_KLOG_H
+
+#include <klibc/extern.h>
+
+#define KLOG_CLOSE 0
+#define KLOG_OPEN 1
+#define KLOG_READ 2
+#define KLOG_READ_ALL 3
+#define KLOG_READ_CLEAR 4
+#define KLOG_CLEAR 5
+#define KLOG_DISABLE 6
+#define KLOG_ENABLE 7
+#define KLOG_SETLEVEL 8
+#define KLOG_UNREADSIZE 9
+#define KLOG_WRITE 10
+
+__extern int klogctl(int, char *, int);
+
+#endif /* _SYS_KLOG_H */
diff --git a/klibc/klibc/include/sys/mman.h b/klibc/klibc/include/sys/mman.h
new file mode 100644
index 0000000000..3d8a2f63c2
--- /dev/null
+++ b/klibc/klibc/include/sys/mman.h
@@ -0,0 +1,21 @@
+/*
+ * sys/mman.h
+ */
+
+#ifndef _SYS_MMAN_H
+#define _SYS_MMAN_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+#include <asm/mman.h>
+#include <asm/page.h> /* For PAGE_SIZE */
+
+#define MAP_FAILED ((void *)-1)
+
+__extern void *mmap(void *, size_t, int, int, int, off_t);
+__extern int munmap(void *, size_t);
+__extern void *mremap(void *, size_t, size_t, unsigned long);
+__extern int msync(const void *, size_t, int);
+__extern int mprotect(const void *, size_t, int);
+
+#endif /* _SYS_MMAN_H */
diff --git a/klibc/klibc/include/sys/module.h b/klibc/klibc/include/sys/module.h
new file mode 100644
index 0000000000..96b3b59945
--- /dev/null
+++ b/klibc/klibc/include/sys/module.h
@@ -0,0 +1,158 @@
+/*
+ * sys/module.h
+ *
+ * This is a bastardized version of linux/module.h, since the latter
+ * doesn't have __KERNEL__ guards where it needs them...
+ */
+
+#ifndef _SYS_MODULE_H
+#define _SYS_MODULE_H
+
+/*
+ * Dynamic loading of modules into the kernel.
+ *
+ * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
+ */
+
+#include <asm/atomic.h>
+
+/* Don't need to bring in all of uaccess.h just for this decl. */
+struct exception_table_entry;
+
+/* Used by get_kernel_syms, which is obsolete. */
+struct kernel_sym
+{
+ unsigned long value;
+ char name[60]; /* should have been 64-sizeof(long); oh well */
+};
+
+struct module_symbol
+{
+ unsigned long value;
+ const char *name;
+};
+
+struct module_ref
+{
+ struct module *dep; /* "parent" pointer */
+ struct module *ref; /* "child" pointer */
+ struct module_ref *next_ref;
+};
+
+/* TBD */
+struct module_persist;
+
+struct module
+{
+ unsigned long size_of_struct; /* == sizeof(module) */
+ struct module *next;
+ const char *name;
+ unsigned long size;
+
+ union
+ {
+ atomic_t usecount;
+ long pad;
+ } uc; /* Needs to keep its size - so says rth */
+
+ unsigned long flags; /* AUTOCLEAN et al */
+
+ unsigned nsyms;
+ unsigned ndeps;
+
+ struct module_symbol *syms;
+ struct module_ref *deps;
+ struct module_ref *refs;
+ int (*init)(void);
+ void (*cleanup)(void);
+ const struct exception_table_entry *ex_table_start;
+ const struct exception_table_entry *ex_table_end;
+#ifdef __alpha__
+ unsigned long gp;
+#endif
+ /* Members past this point are extensions to the basic
+ module support and are optional. Use mod_member_present()
+ to examine them. */
+ const struct module_persist *persist_start;
+ const struct module_persist *persist_end;
+ int (*can_unload)(void);
+ int runsize; /* In modutils, not currently used */
+ const char *kallsyms_start; /* All symbols for kernel debugging */
+ const char *kallsyms_end;
+ const char *archdata_start; /* arch specific data for module */
+ const char *archdata_end;
+ const char *kernel_data; /* Reserved for kernel internal use */
+};
+
+struct module_info
+{
+ unsigned long addr;
+ unsigned long size;
+ unsigned long flags;
+ long usecount;
+};
+
+/* Bits of module.flags. */
+
+#define MOD_UNINITIALIZED 0
+#define MOD_RUNNING 1
+#define MOD_DELETED 2
+#define MOD_AUTOCLEAN 4
+#define MOD_VISITED 8
+#define MOD_USED_ONCE 16
+#define MOD_JUST_FREED 32
+#define MOD_INITIALIZING 64
+
+/* Values for query_module's which. */
+
+#define QM_MODULES 1
+#define QM_DEPS 2
+#define QM_REFS 3
+#define QM_SYMBOLS 4
+#define QM_INFO 5
+
+/* Can the module be queried? */
+#define MOD_CAN_QUERY(mod) (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED))
+
+/* When struct module is extended, we must test whether the new member
+ is present in the header received from insmod before we can use it.
+ This function returns true if the member is present. */
+
+#define mod_member_present(mod,member) \
+ ((unsigned long)(&((struct module *)0L)->member + 1) \
+ <= (mod)->size_of_struct)
+
+/*
+ * Ditto for archdata. Assumes mod->archdata_start and mod->archdata_end
+ * are validated elsewhere.
+ */
+#define mod_archdata_member_present(mod, type, member) \
+ (((unsigned long)(&((type *)0L)->member) + \
+ sizeof(((type *)0L)->member)) <= \
+ ((mod)->archdata_end - (mod)->archdata_start))
+
+
+/* Check if an address p with number of entries n is within the body of module m */
+#define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \
+ (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
+
+/* Backwards compatibility definition. */
+
+#define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount))
+
+/* Poke the use count of a module. */
+
+#define __MOD_INC_USE_COUNT(mod) \
+ (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
+#define __MOD_DEC_USE_COUNT(mod) \
+ (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
+#define __MOD_IN_USE(mod) \
+ (mod_member_present((mod), can_unload) && (mod)->can_unload \
+ ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount))
+
+/* Indirect stringification. */
+
+#define __MODULE_STRING_1(x) #x
+#define __MODULE_STRING(x) __MODULE_STRING_1(x)
+
+#endif /* _SYS_MODULE_H */
diff --git a/klibc/klibc/include/sys/mount.h b/klibc/klibc/include/sys/mount.h
new file mode 100644
index 0000000000..313c90ec0e
--- /dev/null
+++ b/klibc/klibc/include/sys/mount.h
@@ -0,0 +1,55 @@
+/*
+ * sys/mount.h
+ */
+
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#include <klibc/extern.h>
+
+/*
+ * These are the fs-independent mount-flags: up to 32 flags are supported
+ */
+#define MS_RDONLY 1 /* Mount read-only */
+#define MS_NOSUID 2 /* Ignore suid and sgid bits */
+#define MS_NODEV 4 /* Disallow access to device special files */
+#define MS_NOEXEC 8 /* Disallow program execution */
+#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
+#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
+#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
+#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#define MS_NOATIME 1024 /* Do not update access times. */
+#define MS_NODIRATIME 2048 /* Do not update directory access times */
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_VERBOSE 32768
+#define MS_NOUSER (1<<31)
+
+/*
+ * Superblock flags that can be altered by MS_REMOUNT
+ */
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME)
+
+/*
+ * Old magic mount flag and mask
+ */
+#define MS_MGC_VAL 0xC0ED0000
+#define MS_MGC_MSK 0xffff0000
+
+/*
+ * umount2() flags
+ */
+#define MNT_FORCE 1
+
+/*
+ * Prototypes
+ */
+__extern int mount(const char *, const char *,
+ const char *, unsigned long,
+ const void *);
+__extern int umount(const char *);
+__extern int umount2(const char *, int);
+__extern int pivot_root(const char *, const char *);
+
+#endif /* _SYS_MOUNT_H */
diff --git a/klibc/klibc/include/sys/param.h b/klibc/klibc/include/sys/param.h
new file mode 100644
index 0000000000..63a0661f43
--- /dev/null
+++ b/klibc/klibc/include/sys/param.h
@@ -0,0 +1,11 @@
+/*
+ * sys/param.h
+ */
+
+#ifndef _SYS_PARAM_H
+#define _SYS_PARAM_H
+
+#include <limits.h>
+#include <linux/param.h>
+
+#endif /* _SYS_PARAM_H */
diff --git a/klibc/klibc/include/sys/reboot.h b/klibc/klibc/include/sys/reboot.h
new file mode 100644
index 0000000000..eaf56610d7
--- /dev/null
+++ b/klibc/klibc/include/sys/reboot.h
@@ -0,0 +1,25 @@
+/*
+ * sys/reboot.h
+ */
+
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H
+
+#include <klibc/extern.h>
+#include <linux/reboot.h>
+
+/* glibc names these constants differently; allow both versions */
+
+#define RB_AUTOBOOT LINUX_REBOOT_CMD_RESTART
+#define RB_HALT_SYSTEM LINUX_REBOOT_CMD_HALT
+#define RB_ENABLE_CAD LINUX_REBOOT_CMD_CAD_ON
+#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF
+#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
+
+/* glibc-ish one-argument version */
+__extern int reboot(int);
+
+/* Native four-argument system call */
+__extern int __reboot(int, int, int, void *);
+
+#endif /* _SYS_REBOOT_H */
diff --git a/klibc/klibc/include/sys/resource.h b/klibc/klibc/include/sys/resource.h
new file mode 100644
index 0000000000..ef14bde9f6
--- /dev/null
+++ b/klibc/klibc/include/sys/resource.h
@@ -0,0 +1,15 @@
+/*
+ * sys/resource.h
+ */
+
+#ifndef _SYS_RESOURCE_H
+#define _SYS_RESOURCE_H
+
+#include <klibc/extern.h>
+#include <sys/types.h> /* MUST be included before linux/resource.h */
+#include <linux/resource.h>
+
+__extern int getpriority(int, int);
+__extern int setpriority(int, int, int);
+
+#endif /* _SYS_RESOURCE_H */
diff --git a/klibc/klibc/include/sys/select.h b/klibc/klibc/include/sys/select.h
new file mode 100644
index 0000000000..7caf8c931b
--- /dev/null
+++ b/klibc/klibc/include/sys/select.h
@@ -0,0 +1,13 @@
+/*
+ * sys/select.h
+ */
+
+#ifndef _SYS_SELECT_H
+#define _SYS_SELECT_H
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+__extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+#endif /* _SYS_SELECT_H */
diff --git a/klibc/klibc/include/sys/socket.h b/klibc/klibc/include/sys/socket.h
new file mode 100644
index 0000000000..cbc2b89591
--- /dev/null
+++ b/klibc/klibc/include/sys/socket.h
@@ -0,0 +1,50 @@
+/*
+ * sys/socket.h
+ */
+
+#ifndef _SYS_SOCKET_H
+#define _SYS_SOCKET_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <linux/socket.h>
+
+/* For some reason these may be protected by __KERNEL__ in asm/socket.h */
+#ifndef SOCK_STREAM
+# define SOCK_STREAM 1
+# define SOCK_DGRAM 2
+# define SOCK_RAW 3
+# define SOCK_RDM 4
+# define SOCK_SEQPACKET 5
+# define SOCK_PACKET 10
+#endif
+
+#ifdef __i386__
+# define __socketcall __extern __cdecl
+#else
+# define __socketcall __extern
+#endif
+
+typedef int socklen_t;
+
+__socketcall int socket(int, int, int);
+__socketcall int bind(int, struct sockaddr *, int);
+__socketcall int connect(int, struct sockaddr *, socklen_t);
+__socketcall int listen(int, int);
+__socketcall int accept(int, struct sockaddr *, socklen_t *);
+__socketcall int getsockname(int, struct sockaddr *, socklen_t *);
+__socketcall int getpeername(int, struct sockaddr *, socklen_t *);
+__socketcall int socketpair(int, int, int, int *);
+__extern int send(int, const void *, size_t, unsigned int);
+__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+__extern int recv(int, void *, size_t, unsigned int);
+__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *);
+__socketcall int shutdown(int, int);
+__socketcall int setsockopt(int, int, int, const void *, socklen_t);
+__socketcall int getsockopt(int, int, int, void *, socklen_t *);
+__socketcall int sendmsg(int, const struct msghdr *, unsigned int);
+__socketcall int recvmsg(int, struct msghdr *, unsigned int);
+
+#undef __socketcall
+
+#endif /* _SYS_SOCKET_H */
diff --git a/klibc/klibc/include/sys/socketcalls.h b/klibc/klibc/include/sys/socketcalls.h
new file mode 100644
index 0000000000..dac9f9aab6
--- /dev/null
+++ b/klibc/klibc/include/sys/socketcalls.h
@@ -0,0 +1,28 @@
+/*
+ * sys/socketcalls.h
+ */
+
+#ifndef _SYS_SOCKETCALLS_H
+#define _SYS_SOCKETCALLS_H
+
+/* socketcalls by number, since <linux/net.h> isn't usable for assembly */
+
+#define SYS_SOCKET 1 /* sys_socket(2) */
+#define SYS_BIND 2 /* sys_bind(2) */
+#define SYS_CONNECT 3 /* sys_connect(2) */
+#define SYS_LISTEN 4 /* sys_listen(2) */
+#define SYS_ACCEPT 5 /* sys_accept(2) */
+#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
+#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
+#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
+#define SYS_SEND 9 /* sys_send(2) */
+#define SYS_RECV 10 /* sys_recv(2) */
+#define SYS_SENDTO 11 /* sys_sendto(2) */
+#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
+#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
+#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
+#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
+#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
+#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
+
+#endif /* _SYS_SOCKETCALLS_H */
diff --git a/klibc/klibc/include/sys/stat.h b/klibc/klibc/include/sys/stat.h
new file mode 100644
index 0000000000..f7bb5aacc5
--- /dev/null
+++ b/klibc/klibc/include/sys/stat.h
@@ -0,0 +1,23 @@
+/*
+ * sys/stat.h
+ */
+
+#ifndef _SYS_STAT_H
+#define _SYS_STAT_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+#include <asm/stat.h>
+#include <linux/stat.h>
+
+__extern int stat(const char *, struct stat *);
+__extern int fstat(int, struct stat *);
+__extern int lstat(const char *, struct stat *);
+__extern mode_t umask(mode_t);
+__extern int mknod(const char *, mode_t, dev_t);
+static __inline__ int mkfifo(const char *__p, mode_t __m)
+{
+ return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0);
+}
+
+#endif /* _SYS_STAT_H */
diff --git a/klibc/klibc/include/sys/syscall.h b/klibc/klibc/include/sys/syscall.h
new file mode 100644
index 0000000000..907c7f9b9a
--- /dev/null
+++ b/klibc/klibc/include/sys/syscall.h
@@ -0,0 +1,15 @@
+/*
+ * sys/syscall.h
+ *
+ * Generic system call interface macros
+ */
+#ifndef _SYS_SYSCALL_H
+#define _SYS_SYSCALL_H
+
+#include <errno.h>
+#include <asm/unistd.h>
+
+/* Many architectures have incomplete or defective syscall macros */
+#include <klibc/archsys.h>
+
+#endif /* _SYS_SYSCALL_H */
diff --git a/klibc/klibc/include/sys/time.h b/klibc/klibc/include/sys/time.h
new file mode 100644
index 0000000000..4eccf824a4
--- /dev/null
+++ b/klibc/klibc/include/sys/time.h
@@ -0,0 +1,16 @@
+/*
+ * sys/time.h
+ */
+
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+
+#include <klibc/extern.h>
+#include <linux/time.h>
+
+__extern int gettimeofday(struct timeval *, struct timezone *);
+__extern int settimeofday(const struct timeval *, const struct timezone *);
+__extern int getitimer(int, struct itimerval *);
+__extern int setitimer(int, const struct itimerval *, struct itimerval *);
+
+#endif /* _SYS_TIME_H */
diff --git a/klibc/klibc/include/sys/times.h b/klibc/klibc/include/sys/times.h
new file mode 100644
index 0000000000..657f9c4b1c
--- /dev/null
+++ b/klibc/klibc/include/sys/times.h
@@ -0,0 +1,14 @@
+/*
+ * sys/times.h
+ */
+
+#ifndef _SYS_TIMES_H
+#define _SYS_TIMES_H
+
+#include <linux/times.h>
+
+__extern clock_t times(struct tms *);
+__extern int gettimeofday(struct timeval *, struct timezone *);
+__extern int settimeofday(const struct timeval *, const struct timezone *);
+
+#endif /* _SYS_TIMES_H */
diff --git a/klibc/klibc/include/sys/types.h b/klibc/klibc/include/sys/types.h
new file mode 100644
index 0000000000..a25873cc4b
--- /dev/null
+++ b/klibc/klibc/include/sys/types.h
@@ -0,0 +1,127 @@
+/*
+ * sys/types.h
+ *
+ * This is a bastardized version of linux/types.h, since that file
+ * is broken w.r.t. <stdint.h> definitions.
+ */
+
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define _SSIZE_T
+typedef ptrdiff_t ssize_t;
+
+#include <linux/posix_types.h>
+#include <asm/types.h>
+
+/* Keeps linux/types.h from getting included elsewhere */
+#define _LINUX_TYPES_H
+
+typedef __kernel_fd_set fd_set;
+typedef uint32_t dev_t;
+typedef __kernel_ino_t ino_t;
+typedef __kernel_mode_t mode_t;
+typedef __kernel_nlink_t nlink_t;
+typedef __kernel_off_t off_t;
+typedef __kernel_pid_t pid_t;
+typedef __kernel_daddr_t daddr_t;
+typedef __kernel_key_t key_t;
+typedef __kernel_suseconds_t suseconds_t;
+typedef __kernel_timer_t timer_t;
+
+typedef __kernel_uid32_t uid_t;
+typedef __kernel_gid32_t gid_t;
+
+typedef __kernel_loff_t loff_t;
+
+/*
+ * The following typedefs are also protected by individual ifdefs for
+ * historical reasons:
+ */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __kernel_size_t size_t;
+#endif
+
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef __kernel_ssize_t ssize_t;
+#endif
+
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef __kernel_ptrdiff_t ptrdiff_t;
+#endif
+
+#ifndef _TIME_T
+#define _TIME_T
+typedef __kernel_time_t time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef __kernel_clock_t clock_t;
+#endif
+
+#ifndef _CADDR_T
+#define _CADDR_T
+typedef __kernel_caddr_t caddr_t;
+#endif
+
+/* bsd */
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+/* sysv */
+typedef unsigned char unchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+
+typedef __u8 u_int8_t;
+typedef __u16 u_int16_t;
+typedef __u32 u_int32_t;
+typedef __u64 u_int64_t;
+
+#endif /* !(__BIT_TYPES_DEFINED__) */
+
+/*
+ * transition to 64-bit sector_t, possibly making it an option...
+ */
+#undef BLK_64BIT_SECTOR
+
+#ifdef BLK_64BIT_SECTOR
+typedef u64 sector_t;
+#else
+typedef unsigned long sector_t;
+#endif
+
+/*
+ * The type of an index into the pagecache. Use a #define so asm/types.h
+ * can override it.
+ */
+#ifndef pgoff_t
+#define pgoff_t unsigned long
+#endif
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+struct ustat {
+ __kernel_daddr_t f_tfree;
+ __kernel_ino_t f_tinode;
+ char f_fname[6];
+ char f_fpack[6];
+};
+
+#endif
diff --git a/klibc/klibc/include/sys/uio.h b/klibc/klibc/include/sys/uio.h
new file mode 100644
index 0000000000..fc2525d11a
--- /dev/null
+++ b/klibc/klibc/include/sys/uio.h
@@ -0,0 +1,15 @@
+/*
+ * sys/uio.h
+ */
+
+#ifndef _SYS_UIO_H
+#define _SYS_UIO_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+#include <linux/uio.h>
+
+__extern int readv(int, const struct iovec *, int);
+__extern int writev(int, const struct iovec *, int);
+
+#endif /* _SYS_UIO_H */
diff --git a/klibc/klibc/include/sys/utime.h b/klibc/klibc/include/sys/utime.h
new file mode 100644
index 0000000000..d1d635d242
--- /dev/null
+++ b/klibc/klibc/include/sys/utime.h
@@ -0,0 +1,10 @@
+/*
+ * sys/utime.h
+ */
+
+#ifndef _SYS_UTIME_H
+#define _SYS_UTIME_H
+
+#include <linux/utime.h>
+
+#endif /* _SYS_UTIME_H */
diff --git a/klibc/klibc/include/sys/utsname.h b/klibc/klibc/include/sys/utsname.h
new file mode 100644
index 0000000000..f2990f5711
--- /dev/null
+++ b/klibc/klibc/include/sys/utsname.h
@@ -0,0 +1,23 @@
+/*
+ * sys/utsname.h
+ */
+
+#ifndef _SYS_UTSNAME_H
+#define _SYS_UTSNAME_H
+
+#include <klibc/extern.h>
+
+#define SYS_NMLN 65
+
+struct utsname {
+ char sysname[SYS_NMLN];
+ char nodename[SYS_NMLN];
+ char release[SYS_NMLN];
+ char version[SYS_NMLN];
+ char machine[SYS_NMLN];
+ char domainname[SYS_NMLN];
+};
+
+__extern int uname(struct utsname *);
+
+#endif /* _SYS_UTSNAME_H */
diff --git a/klibc/klibc/include/sys/vfs.h b/klibc/klibc/include/sys/vfs.h
new file mode 100644
index 0000000000..8c1577c4bf
--- /dev/null
+++ b/klibc/klibc/include/sys/vfs.h
@@ -0,0 +1,14 @@
+/*
+ * sys/vfs.h
+ */
+
+#ifndef _SYS_VFS_H
+#define _SYS_VFS_H
+
+#include <klibc/extern.h>
+#include <linux/vfs.h>
+
+__extern int statfs(const char *, struct statfs *);
+__extern int fstatfs(int, struct statfs *);
+
+#endif /* _SYS_VFS_H */
diff --git a/klibc/klibc/include/sys/wait.h b/klibc/klibc/include/sys/wait.h
new file mode 100644
index 0000000000..cad6989bf7
--- /dev/null
+++ b/klibc/klibc/include/sys/wait.h
@@ -0,0 +1,19 @@
+/*
+ * sys/wait.h
+ */
+
+#ifndef _SYS_WAIT_H
+#define _SYS_WAIT_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <linux/wait.h>
+
+__extern pid_t wait(int *);
+__extern pid_t waitpid(pid_t, int *, int);
+__extern pid_t wait3(int *, int, struct rusage *);
+__extern pid_t wait4(pid_t, int *, int, struct rusage *);
+
+#endif /* _SYS_WAIT_H */
diff --git a/klibc/klibc/include/syslog.h b/klibc/klibc/include/syslog.h
new file mode 100644
index 0000000000..b6c0acfea1
--- /dev/null
+++ b/klibc/klibc/include/syslog.h
@@ -0,0 +1,53 @@
+/*
+ * syslog.h
+ */
+
+#ifndef _SYSLOG_H
+#define _SYSLOG_H
+
+#include <klibc/extern.h>
+
+/* Alert levels */
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARNING 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DEBUG 7
+
+#define LOG_PRIMASK 7
+#define LOG_PRI(x) ((x) & LOG_PRIMASK)
+
+
+/* Facilities; not actually used */
+#define LOG_KERN 0000
+#define LOG_USER 0010
+#define LOG_MAIL 0020
+#define LOG_DAEMON 0030
+#define LOG_AUTH 0040
+#define LOG_SYSLOG 0050
+#define LOG_LPR 0060
+#define LOG_NEWS 0070
+#define LOG_UUCP 0100
+#define LOG_CRON 0110
+#define LOG_AUTHPRIV 0120
+#define LOG_FTP 0130
+#define LOG_LOCAL0 0200
+#define LOG_LOCAL1 0210
+#define LOG_LOCAL2 0220
+#define LOG_LOCAL3 0230
+#define LOG_LOCAL4 0240
+#define LOG_LOCAL5 0250
+#define LOG_LOCAL6 0260
+#define LOG_LOCAL7 0270
+
+#define LOG_FACMASK 01770
+#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3))
+
+__extern void openlog(const char *, int, int);
+__extern void syslog(int, const char *, ...);
+__extern void closelog(void);
+
+#endif /* _SYSLOG_H */
diff --git a/klibc/klibc/include/termios.h b/klibc/klibc/include/termios.h
new file mode 100644
index 0000000000..08a5e56855
--- /dev/null
+++ b/klibc/klibc/include/termios.h
@@ -0,0 +1,86 @@
+/*
+ * termios.h
+ */
+
+#ifndef _TERMIOS_H
+#define _TERMIOS_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/termios.h>
+
+/* Redefine these so the magic constants == the ioctl number to use. */
+#undef TCSANOW
+#undef TCSADRAIN
+#undef TCSAFLUSH
+#define TCSANOW TCSETS
+#define TCSADRAIN TCSETSW
+#define TCSAFLUSH TCSETSF
+
+static __inline__ int tcgetattr(int __fd, struct termios *__s)
+{
+ return ioctl(__fd, TCGETS, __s);
+}
+
+static __inline__ int tcsetattr(int __fd, int __opt, const struct termios *__s)
+{
+ return ioctl(__fd, __opt, (void *)__s);
+}
+
+static __inline__ int tcflow(int __fd, int __action)
+{
+ return ioctl(__fd, TCXONC, (void *)(intptr_t)__action);
+}
+
+static __inline__ int tcflush(int __fd, int __queue)
+{
+ return ioctl(__fd, TCFLSH, (void *)(intptr_t)__queue);
+}
+
+static __inline__ pid_t tcgetpgrp(int __fd)
+{
+ pid_t __p;
+ return ioctl(__fd, TIOCGPGRP, &__p) ? (pid_t)-1 : __p;
+}
+
+static __inline__ pid_t tcgetsid(int __fd)
+{
+ pid_t __p;
+ return ioctl(__fd, TIOCGSID, &__p) ? (pid_t)-1 : __p;
+}
+
+static __inline__ int tcsendbreak(int __fd, int __duration)
+{
+ return ioctl(__fd, TCSBRKP, (void *)(uintptr_t)__duration);
+}
+
+static __inline__ int tcsetpgrp(int __fd, pid_t __p)
+{
+ return ioctl(__fd, TIOCSPGRP, &__p);
+}
+
+static __inline__ speed_t cfgetospeed(const struct termios *__s)
+{
+ return (speed_t)(__s->c_cflag & CBAUD);
+}
+
+static __inline__ speed_t cfgetispeed(const struct termios *__s)
+{
+ return (speed_t)(__s->c_cflag & CBAUD);
+}
+
+static __inline__ int cfsetospeed(struct termios *__s, speed_t __v)
+{
+ __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD);
+ return 0;
+}
+
+static __inline__ int cfsetispeed(struct termios *__s, speed_t __v)
+{
+ __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD);
+ return 0;
+}
+
+#endif /* _TERMIOS_H */
diff --git a/klibc/klibc/include/time.h b/klibc/klibc/include/time.h
new file mode 100644
index 0000000000..c69c231ec8
--- /dev/null
+++ b/klibc/klibc/include/time.h
@@ -0,0 +1,14 @@
+/*
+ * time.h
+ */
+
+#ifndef _TIME_H
+#define _TIME_H
+
+#include <klibc/extern.h>
+#include <sys/time.h>
+
+__extern time_t time(time_t *);
+__extern int nanosleep(const struct timespec *, struct timespec *);
+
+#endif /* _TIME_H */
diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h
new file mode 100644
index 0000000000..a9b434c16b
--- /dev/null
+++ b/klibc/klibc/include/unistd.h
@@ -0,0 +1,111 @@
+/*
+ * unistd.h
+ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/select.h>
+
+__extern char **environ;
+__extern __noreturn _exit(int);
+
+__extern pid_t fork(void);
+__extern pid_t vfork(void);
+__extern pid_t getpid(void);
+__extern int setpgid(pid_t, pid_t);
+__extern pid_t getppid(void);
+__extern pid_t getpgrp(void);
+__extern int setpgrp(void);
+__extern pid_t setsid(void);
+__extern pid_t getsid(pid_t);
+__extern int execv(const char *, char * const *);
+__extern int execvp(const char *, char * const *);
+__extern int execve(const char *, char * const *, char * const *);
+__extern int execvpe(const char *, char * const *, char * const *);
+__extern int execl(const char *, const char *, ...);
+__extern int execlp(const char *, const char *, ...);
+__extern int execle(const char *, const char *, ...);
+__extern int execlpe(const char *, const char *, ...);
+
+__extern int setuid(uid_t);
+__extern uid_t getuid(void);
+__extern int seteuid(uid_t);
+__extern uid_t geteuid(void);
+__extern int setgid(gid_t);
+__extern gid_t getgid(void);
+__extern int setegid(gid_t);
+__extern gid_t getegid(void);
+__extern int getgroups(int, gid_t *);
+__extern int setgroups(size_t, const gid_t *);
+__extern int setreuid(uid_t, uid_t);
+__extern int setregid(gid_t, gid_t);
+__extern int setresuid(uid_t, uid_t, uid_t);
+__extern int setresgid(gid_t, gid_t, gid_t);
+__extern int getfsuid(uid_t);
+__extern int setfsuid(uid_t);
+
+__extern int access(const char *, int);
+__extern int link(const char *, const char *);
+__extern int unlink(const char *);
+__extern int chdir(const char *);
+__extern int chmod(const char *, mode_t);
+__extern int mkdir(const char *, mode_t);
+__extern int rmdir(const char *);
+__extern int pipe(int *);
+__extern int chroot(const char *);
+__extern int symlink(const char *, const char *);
+__extern int readlink(const char *, char *, size_t);
+__extern int chown(const char *, uid_t, gid_t);
+__extern int fchown(int, uid_t, gid_t);
+__extern int lchown(const char *, uid_t, gid_t);
+__extern char *getcwd(char *, size_t);
+
+__extern int sync(void);
+
+__extern ssize_t read(int, void *, size_t);
+__extern ssize_t write(int, const void *, size_t);
+#ifndef __IN_SYS_COMMON
+__extern int open(const char *, int, ...);
+#endif
+__extern int close(int);
+__extern off_t lseek(int, off_t, int);
+__extern loff_t llseek(int, loff_t, int);
+__extern int dup(int);
+__extern int dup2(int, int);
+__extern int fcntl(int, int, long);
+__extern int ioctl(int, int, void *);
+__extern int flock(int, int);
+__extern int fsync(int);
+__extern int fdatasync(int);
+
+__extern int pause(void);
+__extern unsigned int alarm(unsigned int);
+__extern unsigned int sleep(unsigned int);
+__extern void usleep(unsigned long);
+
+__extern int gethostname(char *, size_t);
+__extern int sethostname(const char *, size_t);
+__extern int getdomainname(char *, size_t);
+__extern int setdomainname(const char *, size_t);
+
+__extern void *__brk(void *);
+__extern int brk(void *);
+__extern void *sbrk(ptrdiff_t);
+
+__extern int getopt(int, char * const *, const char *);
+__extern char *optarg;
+__extern int optind, opterr, optopt;
+
+__extern int isatty(int);
+
+/* Standard file descriptor numbers. */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#endif /* _UNISTD_H */
diff --git a/klibc/klibc/include/utime.h b/klibc/klibc/include/utime.h
new file mode 100644
index 0000000000..3dfa03a14a
--- /dev/null
+++ b/klibc/klibc/include/utime.h
@@ -0,0 +1,15 @@
+/*
+ * utime.h
+ */
+
+#ifndef _UTIME_H
+#define _UTIME_H
+
+#include <klibc/extern.h>
+#include <sys/types.h>
+#include <linux/utime.h>
+
+__extern int utime(const char *, const struct utimbuf *);
+
+#endif /* _UTIME_H */
+
diff --git a/klibc/klibc/inet/bindresvport.c b/klibc/klibc/inet/bindresvport.c
new file mode 100644
index 0000000000..b5f327bb33
--- /dev/null
+++ b/klibc/klibc/inet/bindresvport.c
@@ -0,0 +1,48 @@
+/*
+ * inet/bindresvport.c
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <unistd.h>
+
+#define START_PORT 600
+#define END_PORT (IPPORT_RESERVED - 1)
+#define NUM_PORTS (END_PORT - START_PORT)
+
+int bindresvport(int sd, struct sockaddr_in *sin)
+{
+ struct sockaddr_in me;
+ static short port;
+ int ret = 0;
+ int i;
+
+ if (sin == NULL) {
+ sin = &me;
+ memset(sin, 0, sizeof(me));
+ sin->sin_port = AF_INET;
+ }
+ else if (sin->sin_family != AF_INET) {
+ errno = EPFNOSUPPORT;
+ ret = -1;
+ goto bail;
+ }
+
+ if (port == 0) {
+ port = START_PORT + (getpid() % NUM_PORTS);
+ }
+
+ for (i = 0; i < NUM_PORTS; i++, port++) {
+ sin->sin_port = htons(port);
+ if ((ret = bind(sd, sin, sizeof(*sin))) != -1)
+ break;
+ if (port == END_PORT)
+ port = START_PORT;
+ }
+
+ bail:
+ return ret;
+}
diff --git a/klibc/klibc/inet/inet_addr.c b/klibc/klibc/inet/inet_addr.c
new file mode 100644
index 0000000000..e04a4d0214
--- /dev/null
+++ b/klibc/klibc/inet/inet_addr.c
@@ -0,0 +1,14 @@
+/*
+ * inet/inet_addr.c
+ */
+
+#include <arpa/inet.h>
+#include <stdio.h>
+
+uint32_t inet_addr(const char *str)
+{
+ struct in_addr a;
+ int rv = inet_aton(str, &a);
+
+ return rv ? INADDR_NONE : a.s_addr;
+}
diff --git a/klibc/klibc/inet/inet_aton.c b/klibc/klibc/inet/inet_aton.c
new file mode 100644
index 0000000000..e581b492ad
--- /dev/null
+++ b/klibc/klibc/inet/inet_aton.c
@@ -0,0 +1,23 @@
+/*
+ * inet/inet_aton.c
+ */
+
+#include <arpa/inet.h>
+#include <stdio.h>
+
+int inet_aton(const char *str, struct in_addr *addr)
+{
+ union {
+ uint8_t b[4];
+ uint32_t l;
+ } a;
+
+ if ( sscanf(str, "%hhu.%hhu.%hhu.%hhu", &a.b[0], &a.b[1], &a.b[2], &a.b[3]) == 4 ) {
+ addr->s_addr = a.l; /* Always in network byte order */
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
diff --git a/klibc/klibc/inet/inet_ntoa.c b/klibc/klibc/inet/inet_ntoa.c
new file mode 100644
index 0000000000..5340aa622a
--- /dev/null
+++ b/klibc/klibc/inet/inet_ntoa.c
@@ -0,0 +1,19 @@
+/*
+ * inet/inet_ntoa.c
+ */
+
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *inet_ntoa(struct in_addr addr)
+{
+ static char name[16];
+ union {
+ uint8_t b[4];
+ uint32_t l;
+ } a;
+ a.l = addr.s_addr;
+
+ sprintf(name, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]);
+ return name;
+}
diff --git a/klibc/klibc/inet/inet_ntop.c b/klibc/klibc/inet/inet_ntop.c
new file mode 100644
index 0000000000..377bab7bf2
--- /dev/null
+++ b/klibc/klibc/inet/inet_ntop.c
@@ -0,0 +1,52 @@
+/*
+ * inet/inet_ntop.c
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <netinet/in6.h>
+
+const char *inet_ntop(int af, const void *cp, char *buf, size_t len)
+{
+ size_t xlen;
+
+ switch ( af ) {
+ case AF_INET:
+ {
+ union {
+ uint8_t b[4];
+ uint32_t l;
+ } a;
+ a.l = ((const struct in_addr *)cp)->s_addr;
+
+ xlen = snprintf(buf, len, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]);
+ }
+ break;
+
+ case AF_INET6:
+ {
+ const struct in6_addr *s = (const struct in6_addr *)cp;
+
+ xlen = snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x",
+ ntohs(s->s6_addr16[0]), ntohs(s->s6_addr16[1]),
+ ntohs(s->s6_addr16[2]), ntohs(s->s6_addr16[3]),
+ ntohs(s->s6_addr16[4]), ntohs(s->s6_addr16[5]),
+ ntohs(s->s6_addr16[6]), ntohs(s->s6_addr16[7]));
+ }
+ break;
+
+ default:
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if ( xlen > len ) {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ return buf;
+}
+
diff --git a/klibc/klibc/inet/inet_pton.c b/klibc/klibc/inet/inet_pton.c
new file mode 100644
index 0000000000..6c14b3cfb6
--- /dev/null
+++ b/klibc/klibc/inet/inet_pton.c
@@ -0,0 +1,74 @@
+/*
+ * inet/inet_pton.c
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/in6.h>
+
+static inline int hexval(int ch)
+{
+ if ( ch >= '0' && ch <= '9' ) {
+ return ch-'0';
+ } else if ( ch >= 'A' && ch <= 'F' ) {
+ return ch-'A'+10;
+ } else if ( ch >= 'a' && ch <= 'f' ) {
+ return ch-'a'+10;
+ } else {
+ return -1;
+ }
+}
+
+int inet_pton(int af, const char *src, void *dst)
+{
+ switch ( af ) {
+ case AF_INET:
+ return inet_aton(src, (struct in_addr *)dst);
+
+ case AF_INET6:
+ {
+ struct in6_addr *d = (struct in6_addr *)dst;
+ int colons = 0, dcolons = 0;
+ int i;
+ const char *p;
+
+ /* A double colon will increment colons by 2, dcolons by 1 */
+ for ( p = dst ; *p ; p++ ) {
+ if ( p[0] == ':' ) {
+ colons++;
+ if ( p[1] == ':' )
+ dcolons++;
+ } else if ( !isxdigit(*p) )
+ return 0; /* Not a valid address */
+ }
+
+ if ( colons > 7 || dcolons > 1 || (!dcolons && colons != 7) )
+ return 0; /* Not a valid address */
+
+ memset(d, 0, sizeof(struct in6_addr));
+
+ i = 0;
+ for ( p = dst ; *p ; p++ ) {
+ if ( *p == ':' ) {
+ if ( p[1] == ':' ) {
+ i += (8-colons);
+ } else {
+ i++;
+ }
+ } else {
+ d->s6_addr16[i] = htons((ntohs(d->s6_addr16[i]) << 4) + hexval(*p));
+ }
+ }
+
+ return 1;
+ }
+
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+}
diff --git a/klibc/klibc/interp.S b/klibc/klibc/interp.S
new file mode 100644
index 0000000000..303943697b
--- /dev/null
+++ b/klibc/klibc/interp.S
@@ -0,0 +1,11 @@
+#
+# This is a hack to generate the .intrp section, which then
+# ld turns into an PT_INTERP header.
+#
+
+ .section ".interp","a"
+ .ascii LIBDIR
+ .ascii "/klibc-"
+ .ascii SOHASH
+ .ascii ".so"
+ .byte 0
diff --git a/klibc/klibc/isatty.c b/klibc/klibc/isatty.c
new file mode 100644
index 0000000000..ff5e1ff748
--- /dev/null
+++ b/klibc/klibc/isatty.c
@@ -0,0 +1,21 @@
+/*
+ * isatty.c
+ */
+
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+
+int isatty(int fd)
+{
+ int old_errno = errno;
+ int istty;
+ pid_t dummy;
+
+ /* All ttys support TIOCGPGRP */
+ istty = !ioctl(fd, TIOCGPGRP, &dummy);
+ errno = old_errno;
+
+ return istty;
+}
+
diff --git a/klibc/klibc/libgcc/__divdi3.c b/klibc/klibc/libgcc/__divdi3.c
new file mode 100644
index 0000000000..be13caed7e
--- /dev/null
+++ b/klibc/klibc/libgcc/__divdi3.c
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+int64_t __divdi3(int64_t num, int64_t den)
+{
+ int minus = 0;
+ int64_t v;
+
+ if ( num < 0 ) {
+ num = -num;
+ minus = 1;
+ }
+ if ( den < 0 ) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ v = __udivmoddi4(num, den, NULL);
+ if ( minus )
+ v = -v;
+
+ return v;
+}
diff --git a/klibc/klibc/libgcc/__divsi3.c b/klibc/klibc/libgcc/__divsi3.c
new file mode 100644
index 0000000000..24a7e044c8
--- /dev/null
+++ b/klibc/klibc/libgcc/__divsi3.c
@@ -0,0 +1,29 @@
+/*
+ * libgcc/__divsi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem);
+
+int32_t __divsi3(int32_t num, int32_t den)
+{
+ int minus = 0;
+ int32_t v;
+
+ if ( num < 0 ) {
+ num = -num;
+ minus = 1;
+ }
+ if ( den < 0 ) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ v = __udivmodsi4(num, den, NULL);
+ if ( minus )
+ v = -v;
+
+ return v;
+}
diff --git a/klibc/klibc/libgcc/__moddi3.c b/klibc/klibc/libgcc/__moddi3.c
new file mode 100644
index 0000000000..3e613654e4
--- /dev/null
+++ b/klibc/klibc/libgcc/__moddi3.c
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__moddi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+int64_t __moddi3(int64_t num, int64_t den)
+{
+ int minus = 0;
+ int64_t v;
+
+ if ( num < 0 ) {
+ num = -num;
+ minus = 1;
+ }
+ if ( den < 0 ) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ (void) __udivmoddi4(num, den, &v);
+ if ( minus )
+ v = -v;
+
+ return v;
+}
diff --git a/klibc/klibc/libgcc/__modsi3.c b/klibc/klibc/libgcc/__modsi3.c
new file mode 100644
index 0000000000..cf62b8b556
--- /dev/null
+++ b/klibc/klibc/libgcc/__modsi3.c
@@ -0,0 +1,29 @@
+/*
+ * libgcc/__modsi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem);
+
+int32_t __modsi3(int32_t num, int32_t den)
+{
+ int minus = 0;
+ int32_t v;
+
+ if ( num < 0 ) {
+ num = -num;
+ minus = 1;
+ }
+ if ( den < 0 ) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ (void) __udivmodsi4(num, den, &v);
+ if ( minus )
+ v = -v;
+
+ return v;
+}
diff --git a/klibc/klibc/libgcc/__udivdi3.c b/klibc/klibc/libgcc/__udivdi3.c
new file mode 100644
index 0000000000..901ce2aea6
--- /dev/null
+++ b/klibc/klibc/libgcc/__udivdi3.c
@@ -0,0 +1,13 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+uint64_t __udivdi3(uint64_t num, uint64_t den)
+{
+ return __udivmoddi4(num, den, NULL);
+}
diff --git a/klibc/klibc/libgcc/__udivmoddi4.c b/klibc/klibc/libgcc/__udivmoddi4.c
new file mode 100644
index 0000000000..1c456543be
--- /dev/null
+++ b/klibc/klibc/libgcc/__udivmoddi4.c
@@ -0,0 +1,32 @@
+#include <klibc/diverr.h>
+#include <stdint.h>
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p)
+{
+ uint64_t quot = 0, qbit = 1;
+
+ if ( den == 0 ) {
+ __divide_error();
+ return 0; /* If trap returns... */
+ }
+
+ /* Left-justify denominator and count shift */
+ while ( (int64_t)den >= 0 ) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while ( qbit ) {
+ if ( den <= num ) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if ( rem_p )
+ *rem_p = num;
+
+ return quot;
+}
diff --git a/klibc/klibc/libgcc/__udivmodsi4.c b/klibc/klibc/libgcc/__udivmodsi4.c
new file mode 100644
index 0000000000..61f6bef0a4
--- /dev/null
+++ b/klibc/klibc/libgcc/__udivmodsi4.c
@@ -0,0 +1,32 @@
+#include <klibc/diverr.h>
+#include <stdint.h>
+
+uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem_p)
+{
+ uint32_t quot = 0, qbit = 1;
+
+ if ( den == 0 ) {
+ __divide_error();
+ return 0; /* If trap returns... */
+ }
+
+ /* Left-justify denominator and count shift */
+ while ( (int32_t)den >= 0 ) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while ( qbit ) {
+ if ( den <= num ) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if ( rem_p )
+ *rem_p = num;
+
+ return quot;
+}
diff --git a/klibc/klibc/libgcc/__udivsi3.c b/klibc/klibc/libgcc/__udivsi3.c
new file mode 100644
index 0000000000..cba6f8f03d
--- /dev/null
+++ b/klibc/klibc/libgcc/__udivsi3.c
@@ -0,0 +1,13 @@
+/*
+ * libgcc/__divsi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem);
+
+uint32_t __udivsi3(uint32_t num, uint32_t den)
+{
+ return __udivmodsi4(num, den, NULL);
+}
diff --git a/klibc/klibc/libgcc/__umoddi3.c b/klibc/klibc/libgcc/__umoddi3.c
new file mode 100644
index 0000000000..c007d4859f
--- /dev/null
+++ b/klibc/klibc/libgcc/__umoddi3.c
@@ -0,0 +1,16 @@
+/*
+ * arch/i386/libgcc/__umoddi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+uint64_t __umoddi3(uint64_t num, uint64_t den)
+{
+ uint64_t v;
+
+ (void) __udivmoddi4(num, den, &v);
+ return v;
+}
diff --git a/klibc/klibc/libgcc/__umodsi3.c b/klibc/klibc/libgcc/__umodsi3.c
new file mode 100644
index 0000000000..e3db972c4e
--- /dev/null
+++ b/klibc/klibc/libgcc/__umodsi3.c
@@ -0,0 +1,16 @@
+/*
+ * libgcc/__umodsi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem);
+
+uint32_t __umodsi3(uint32_t num, uint32_t den)
+{
+ uint32_t v;
+
+ (void) __udivmodsi4(num, den, &v);
+ return v;
+}
diff --git a/klibc/klibc/llseek.c b/klibc/klibc/llseek.c
new file mode 100644
index 0000000000..fdffc16e2c
--- /dev/null
+++ b/klibc/klibc/llseek.c
@@ -0,0 +1,34 @@
+/*
+ * llseek.c
+ *
+ * On 32-bit platforms, we need llseek() as well as lseek() to be
+ * able to handle large disks
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#if BITSIZE == 32
+
+static inline _syscall5(int, _llseek, int, fd, unsigned long, hi, unsigned long, lo, loff_t *,res, int, whence);
+
+loff_t llseek(int fd, loff_t offset, int whence)
+{
+ loff_t result;
+ int rv;
+
+ rv = _llseek(fd, (unsigned long)(offset >> 32),
+ (unsigned long)offset, &result, whence);
+
+ return rv ? (loff_t)-1 : result;
+}
+
+#else
+
+loff_t llseek(int fd, loff_t offset, int whence)
+{
+ return lseek(fd, offset, whence);
+}
+
+#endif
+
diff --git a/klibc/klibc/lrand48.c b/klibc/klibc/lrand48.c
new file mode 100644
index 0000000000..4d05de2e89
--- /dev/null
+++ b/klibc/klibc/lrand48.c
@@ -0,0 +1,42 @@
+/*
+ * lrand48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+unsigned short __rand48_seed[3];
+
+long jrand48(unsigned short xsubi[3])
+{
+ uint64_t x;
+
+ /* The xsubi[] array is littleendian by spec */
+ x = (uint64_t)xsubi[0] +
+ ((uint64_t)xsubi[1] << 16) +
+ ((uint64_t)xsubi[2] << 32);
+
+ x = (0x5deece66dULL * x) + 0xb;
+
+ xsubi[0] = (unsigned short)x;
+ xsubi[1] = (unsigned short)(x >> 16);
+ xsubi[2] = (unsigned short)(x >> 32);
+
+ return (long)(int32_t)(x >> 16);
+}
+
+long mrand48(void)
+{
+ return jrand48(__rand48_seed);
+}
+
+long nrand48(unsigned short xsubi[3])
+{
+ return (long)((uint32_t)jrand48(xsubi) >> 1);
+}
+
+long lrand48(void)
+{
+ return (long)((uint32_t)(mrand48() >> 1));
+}
+
diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl
new file mode 100644
index 0000000000..121ed1f46b
--- /dev/null
+++ b/klibc/klibc/makeerrlist.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# This creates sys_errlist from <asm/errno.h> through somewhat
+# heuristic matching. It presumes the relevant entries are of the form
+# #define Exxxx <integer> /* comment */
+#
+
+use FileHandle;
+
+%errors = ();
+%errmsg = ();
+$maxerr = -1;
+$rootdir = 'linux/include/'; # Must have trailing /
+
+sub parse_file($) {
+ my($file) = @_;
+ my($fh) = new FileHandle;
+ my($line, $error, $msg);
+ my($kernelonly) = 0;
+
+ $file = $rootdir.$file;
+
+ print STDERR "opening $file\n";
+
+ if ( !($fh->open("< ".$file)) ) {
+ die "$0: cannot open $file\n";
+ }
+
+ while ( defined($line = <$fh>) ) {
+ if ( $kernelonly ) {
+ if ( $line =~ /^\#\s*endif/ ) {
+ $kernelonly--;
+ } elsif ( $line =~ /^\#\sif/ ) {
+ $kernelonly++;
+ }
+ } else {
+ if ( $line =~ /^\#\s*define\s+([A-Z0-9_]+)\s+([0-9]+)\s*\/\*\s*(.*\S)\s*\*\// ) {
+ $error = $1;
+ $errno = $2+0;
+ $msg = $3;
+ print STDERR "$error ($errno) => \"$msg\"\n";
+ $errors{$errno} = $error;
+ $errmsg{$errno} = $msg;
+ $maxerr = $errno if ( $errno > $maxerr );
+ } elsif ( $line =~ /^\#\s*include\s+[\<\"](.*)[\>\"]/ ) {
+ parse_file($1);
+ } elsif ( $line =~ /^\#\s*ifdef\s+__KERNEL__/ ) {
+ $kernelonly++;
+ }
+ }
+ }
+ close($fh);
+ print STDERR "closing $file\n";
+}
+
+parse_file('linux/errno.h');
+
+($type) = @ARGV;
+
+if ( $type eq '-errlist' ) {
+ print "#include <errno.h>\n";
+ printf "const int sys_nerr = %d;\n", $maxerr+1;
+ printf "const char * const sys_errlist[%d] = {\n", $maxerr+1;
+ foreach $e ( sort(keys(%errors)) ) {
+ printf " [%s] = \"%s\",\n", $errors{$e}, $errmsg{$e};
+ }
+ print "};\n";
+} elsif ( $type eq '-errnos' ) {
+ print "#include <errno.h>\n";
+ printf "const int sys_nerr = %d;\n", $maxerr+1;
+ printf "const char * const sys_errlist[%d] = {\n", $maxerr+1;
+ foreach $e ( sort(keys(%errors)) ) {
+ printf " [%s] = \"%s\",\n", $errors{$e}, $errors{$e};
+ }
+ print "};\n";
+} elsif ( $type eq '-maxerr' ) {
+ print $maxerr, "\n";
+}
+
+
diff --git a/klibc/klibc/malloc.c b/klibc/klibc/malloc.c
new file mode 100644
index 0000000000..20a2350d71
--- /dev/null
+++ b/klibc/klibc/malloc.c
@@ -0,0 +1,192 @@
+/*
+ * malloc.c
+ *
+ * Very simple linked-list based malloc()/free().
+ */
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include "malloc.h"
+
+struct free_arena_header __malloc_head =
+{
+ {
+ ARENA_TYPE_HEAD,
+ 0,
+ &__malloc_head,
+ &__malloc_head,
+ },
+ &__malloc_head,
+ &__malloc_head
+};
+
+static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
+{
+ size_t fsize;
+ struct free_arena_header *nfp, *na;
+
+ fsize = fp->a.size;
+
+ /* We need the 2* to account for the larger requirements of a free block */
+ if ( fsize >= size+2*sizeof(struct arena_header) ) {
+ /* Bigger block than required -- split block */
+ nfp = (struct free_arena_header *)((char *)fp + size);
+ na = fp->a.next;
+
+ nfp->a.type = ARENA_TYPE_FREE;
+ nfp->a.size = fsize-size;
+ fp->a.type = ARENA_TYPE_USED;
+ fp->a.size = size;
+
+ /* Insert into all-block chain */
+ nfp->a.prev = fp;
+ nfp->a.next = na;
+ na->a.prev = nfp;
+ fp->a.next = nfp;
+
+ /* Replace current block on free chain */
+ nfp->next_free = fp->next_free;
+ nfp->prev_free = fp->prev_free;
+ fp->next_free->prev_free = nfp;
+ fp->prev_free->next_free = nfp;
+ } else {
+ /* Allocate the whole block */
+ fp->a.type = ARENA_TYPE_USED;
+
+ /* Remove from free chain */
+ fp->next_free->prev_free = fp->prev_free;
+ fp->prev_free->next_free = fp->next_free;
+ }
+
+ return (void *)(&fp->a + 1);
+}
+
+static struct free_arena_header *
+__free_block(struct free_arena_header *ah)
+{
+ struct free_arena_header *pah, *nah;
+
+ pah = ah->a.prev;
+ nah = ah->a.next;
+ if ( pah->a.type == ARENA_TYPE_FREE &&
+ (char *)pah+pah->a.size == (char *)ah ) {
+ /* Coalesce into the previous block */
+ pah->a.size += ah->a.size;
+ pah->a.next = nah;
+ nah->a.prev = pah;
+
+#ifdef DEBUG_MALLOC
+ ah->a.type = ARENA_TYPE_DEAD;
+#endif
+
+ ah = pah;
+ pah = ah->a.prev;
+ } else {
+ /* Need to add this block to the free chain */
+ ah->a.type = ARENA_TYPE_FREE;
+
+ ah->next_free = __malloc_head.next_free;
+ ah->prev_free = &__malloc_head;
+ __malloc_head.next_free = ah;
+ ah->next_free->prev_free = ah;
+ }
+
+ /* In either of the previous cases, we might be able to merge
+ with the subsequent block... */
+ if ( nah->a.type == ARENA_TYPE_FREE &&
+ (char *)ah+ah->a.size == (char *)nah ) {
+ ah->a.size += nah->a.size;
+
+ /* Remove the old block from the chains */
+ nah->next_free->prev_free = nah->prev_free;
+ nah->prev_free->next_free = nah->next_free;
+ ah->a.next = nah->a.next;
+ nah->a.next->a.prev = ah;
+
+#ifdef DEBUG_MALLOC
+ nah->a.type = ARENA_TYPE_DEAD;
+#endif
+ }
+
+ /* Return the block that contains the called block */
+ return ah;
+}
+
+void *malloc(size_t size)
+{
+ struct free_arena_header *fp;
+ struct free_arena_header *pah;
+ size_t fsize;
+
+ if ( size == 0 )
+ return NULL;
+
+ /* Add the obligatory arena header, and round up */
+ size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK;
+
+ for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ;
+ fp = fp->next_free ) {
+ if ( fp->a.size >= size ) {
+ /* Found fit -- allocate out of this block */
+ return __malloc_from_block(fp, size);
+ }
+ }
+
+ /* Nothing found... need to request a block from the kernel */
+ fsize = (size+MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK;
+ fp = (struct free_arena_header *)
+ mmap(NULL, fsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+
+ if ( fp == (struct free_arena_header *)MAP_FAILED ) {
+ return NULL; /* Failed to get a block */
+ }
+
+ /* Insert the block into the management chains. We need to set
+ up the size and the main block list pointer, the rest of
+ the work is logically identical to free(). */
+ fp->a.type = ARENA_TYPE_FREE;
+ fp->a.size = fsize;
+
+ /* We need to insert this into the main block list in the proper
+ place -- this list is required to be sorted. Since we most likely
+ get memory assignments in ascending order, search backwards for
+ the proper place. */
+ for ( pah = __malloc_head.a.prev ; pah->a.type != ARENA_TYPE_HEAD ;
+ pah = pah->a.prev ) {
+ if ( pah < fp )
+ break;
+ }
+
+ /* Now pah points to the node that should be the predecessor of
+ the new node */
+ fp->a.next = pah->a.next;
+ fp->a.prev = pah;
+ pah->a.next = fp;
+ fp->a.next->a.prev = fp;
+
+
+ /* Insert into the free chain and coalesce with adjacent blocks */
+ fp = __free_block(fp);
+
+ /* Now we can allocate from this block */
+ return __malloc_from_block(fp, size);
+}
+
+void free(void *ptr)
+{
+ struct free_arena_header *ah;
+
+ if ( !ptr )
+ return;
+
+ ah = (struct free_arena_header *)
+ ((struct arena_header *)ptr - 1);
+
+#ifdef DEBUG_MALLOC
+ assert( ah->a.type == ARENA_TYPE_USED );
+#endif
+
+ __free_block(ah);
+
+ /* Here we could insert code to return memory to the system. */
+}
diff --git a/klibc/klibc/malloc.h b/klibc/klibc/malloc.h
new file mode 100644
index 0000000000..e053f71401
--- /dev/null
+++ b/klibc/klibc/malloc.h
@@ -0,0 +1,51 @@
+/*
+ * malloc.h
+ *
+ * Internals for the memory allocator
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/*
+ * This is the minimum chunk size we will ask the kernel for; this should
+ * be a multiple of the page size on all architectures.
+ */
+#define MALLOC_CHUNK_SIZE 65536
+#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1)
+
+/*
+ * This structure should be a power of two. This becomes the
+ * alignment unit.
+ */
+struct free_arena_header;
+
+struct arena_header {
+ size_t type;
+ size_t size; /* Also gives the location of the next entry */
+ struct free_arena_header *next, *prev;
+};
+
+#ifdef DEBUG_MALLOC
+#define ARENA_TYPE_USED 0x64e69c70
+#define ARENA_TYPE_FREE 0x012d610a
+#define ARENA_TYPE_HEAD 0x971676b5
+#define ARENA_TYPE_DEAD 0xeeeeeeee
+#else
+#define ARENA_TYPE_USED 0
+#define ARENA_TYPE_FREE 1
+#define ARENA_TYPE_HEAD 2
+#endif
+
+#define ARENA_SIZE_MASK (~(sizeof(struct arena_header)-1))
+
+/*
+ * This structure should be no more than twice the size of the
+ * previous structure.
+ */
+struct free_arena_header {
+ struct arena_header a;
+ struct free_arena_header *next_free, *prev_free;
+};
+
+extern struct free_arena_header __malloc_head;
diff --git a/klibc/klibc/memccpy.c b/klibc/klibc/memccpy.c
new file mode 100644
index 0000000000..22f68deaad
--- /dev/null
+++ b/klibc/klibc/memccpy.c
@@ -0,0 +1,23 @@
+/*
+ * memccpy.c
+ *
+ * memccpy()
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memccpy(void *dst, const void *src, int c, size_t n)
+{
+ char *q = dst;
+ const char *p = src;
+ char ch;
+
+ while ( n-- ) {
+ *q++ = ch = *p++;
+ if ( ch == (char)c )
+ return q;
+ }
+
+ return NULL; /* No instance of "c" found */
+}
diff --git a/klibc/klibc/memchr.c b/klibc/klibc/memchr.c
new file mode 100644
index 0000000000..c5c5fa2963
--- /dev/null
+++ b/klibc/klibc/memchr.c
@@ -0,0 +1,18 @@
+/*
+ * memchr.c
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memchr(const void *s, int c, size_t n)
+{
+ const unsigned char *sp = s;
+
+ while ( n-- ) {
+ if ( *sp == (unsigned char)c )
+ return (void *)sp;
+ }
+
+ return NULL;
+}
diff --git a/klibc/klibc/memcmp.c b/klibc/klibc/memcmp.c
new file mode 100644
index 0000000000..f6bc17286f
--- /dev/null
+++ b/klibc/klibc/memcmp.c
@@ -0,0 +1,19 @@
+/*
+ * memcmp.c
+ */
+
+#include <string.h>
+
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+ const unsigned char *c1 = s1, *c2 = s2;
+ int d = 0;
+
+ while ( n-- ) {
+ d = (int)*c1++ - (int)*c2++;
+ if ( d )
+ break;
+ }
+
+ return d;
+}
diff --git a/klibc/klibc/memcpy.c b/klibc/klibc/memcpy.c
new file mode 100644
index 0000000000..b9171c300d
--- /dev/null
+++ b/klibc/klibc/memcpy.c
@@ -0,0 +1,29 @@
+/*
+ * memcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memcpy(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb"
+ : "+c" (nl), "+S" (p), "+D" (q)
+ : "r" (n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb"
+ : "+c" (nq), "+S" (p), "+D" (q)
+ : "r" ((uint32_t)(n & 7)));
+#else
+ while ( n-- ) {
+ *q++ = *p++;
+ }
+#endif
+
+ return dst;
+}
diff --git a/klibc/klibc/memmem.c b/klibc/klibc/memmem.c
new file mode 100644
index 0000000000..0f59938ffb
--- /dev/null
+++ b/klibc/klibc/memmem.c
@@ -0,0 +1,44 @@
+/*
+ * memmem.c
+ *
+ * Find a byte string inside a longer byte string
+ *
+ * This uses the "Not So Naive" algorithm, a very simple but
+ * usually effective algorithm, see:
+ *
+ * http://www-igm.univ-mlv.fr/~lecroq/string/
+ */
+
+#include <string.h>
+
+void *memmem(const void *haystack, size_t n, const void *needle, size_t m)
+{
+ const unsigned char *y = (const unsigned char *)haystack;
+ const unsigned char *x = (const unsigned char *)needle;
+
+ size_t j, k, l;
+
+ if ( m > n )
+ return NULL;
+
+ if ( x[0] == x[1] ) {
+ k = 2;
+ l = 1;
+ } else {
+ k = 1;
+ l = 2;
+ }
+
+ j = 0;
+ while ( j <= n-m ) {
+ if (x[1] != y[j+1]) {
+ j += k;
+ } else {
+ if ( !memcmp(x+2, y+j+2, m-2) && x[0] == y[j] )
+ return (void *)&y[j];
+ j += l;
+ }
+ }
+
+ return NULL;
+}
diff --git a/klibc/klibc/memmove.c b/klibc/klibc/memmove.c
new file mode 100644
index 0000000000..c1f042af39
--- /dev/null
+++ b/klibc/klibc/memmove.c
@@ -0,0 +1,34 @@
+/*
+ * memmove.c
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t n)
+{
+ const char *p = src;
+ char *q = dst;
+#if defined(__i386__) || defined(__x86_64__)
+ if ( q < p ) {
+ asm volatile("cld ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q));
+ } else {
+ p += (n-1);
+ q += (n-1);
+ asm volatile("std ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q));
+ }
+#else
+ if ( q < p ) {
+ while ( n-- ) {
+ *q++ = *p++;
+ }
+ } else {
+ p += n;
+ q += n;
+ while ( n-- ) {
+ *--q = *--p;
+ }
+ }
+#endif
+
+ return dst;
+}
diff --git a/klibc/klibc/memset.c b/klibc/klibc/memset.c
new file mode 100644
index 0000000000..522cc59a1e
--- /dev/null
+++ b/klibc/klibc/memset.c
@@ -0,0 +1,30 @@
+/*
+ * memset.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dst, int c, size_t n)
+{
+ char *q = dst;
+
+#if defined(__i386__)
+ size_t nl = n >> 2;
+ asm volatile("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb"
+ : "+c" (nl), "+D" (q)
+ : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3));
+#elif defined(__x86_64__)
+ size_t nq = n >> 3;
+ asm volatile("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb"
+ : "+c" (nq), "+D" (q)
+ : "a" ((unsigned char)c * 0x0101010101010101U),
+ "r" ((uint32_t)n & 7));
+#else
+ while ( n-- ) {
+ *q++ = c;
+ }
+#endif
+
+ return dst;
+}
diff --git a/klibc/klibc/memswap.c b/klibc/klibc/memswap.c
new file mode 100644
index 0000000000..10440e3499
--- /dev/null
+++ b/klibc/klibc/memswap.c
@@ -0,0 +1,23 @@
+/*
+ * memswap()
+ *
+ * Swaps the contents of two nonoverlapping memory areas.
+ * This really could be done faster...
+ */
+
+#include <string.h>
+
+void memswap(void *m1, void *m2, size_t n)
+{
+ char *p = m1;
+ char *q = m2;
+ char tmp;
+
+ while ( n-- ) {
+ tmp = *p;
+ *p = *q;
+ *q = tmp;
+
+ p++; q++;
+ }
+}
diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c
new file mode 100644
index 0000000000..3d28cba601
--- /dev/null
+++ b/klibc/klibc/mmap.c
@@ -0,0 +1,51 @@
+/*
+ * mmap.c
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <asm/page.h> /* For PAGE_SHIFT */
+
+#if defined(__sparc__)
+# define MMAP2_SHIFT 12 /* Fixed by syscall definition */
+#else
+# define MMAP2_SHIFT PAGE_SHIFT
+#endif
+#define MMAP2_MASK ((1UL << MMAP2_SHIFT)-1)
+
+/*
+ * Prefer mmap2() over mmap(), except on the architectures listed
+ */
+
+#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__)
+
+/* This architecture uses mmap2() */
+
+static inline _syscall6(void *,mmap2,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset);
+
+/* The Linux mmap2() system call takes a page offset as the offset argument.
+ We need to make sure we have the proper conversion in place. */
+
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ if ( offset & MMAP2_MASK ) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ return mmap2(start, length, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT);
+}
+
+#else
+
+/* This architecture uses a plain mmap() system call */
+/* Only use this for architectures where mmap() is a real 6-argument system call! */
+
+_syscall6(void *,mmap,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset)
+
+#endif
+
+
+
diff --git a/klibc/klibc/nice.c b/klibc/klibc/nice.c
new file mode 100644
index 0000000000..f0d97a3cd0
--- /dev/null
+++ b/klibc/klibc/nice.c
@@ -0,0 +1,22 @@
+/*
+ * nice.c
+ */
+
+#include <unistd.h>
+#include <sched.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_nice
+
+_syscall1(int,nice,int,inc);
+
+#else
+
+int nice(int inc)
+{
+ pid_t me = getpid();
+ return setpriority(me, PRIO_PROCESS, getpriority(me, PRIO_PROCESS)+inc);
+}
+
+#endif
diff --git a/klibc/klibc/onexit.c b/klibc/klibc/onexit.c
new file mode 100644
index 0000000000..70a9c01f61
--- /dev/null
+++ b/klibc/klibc/onexit.c
@@ -0,0 +1,39 @@
+/*
+ * onexit.c
+ */
+
+#include <stdlib.h>
+#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));
+
+ if ( !as )
+ return -1;
+
+ as->fctn = fctn;
+ as->arg = arg;
+
+ as->next = __atexit_list;
+ __atexit_list = as;
+
+ __exit_handler = on_exit_exit;
+
+ return 0;
+}
diff --git a/klibc/klibc/pause.c b/klibc/klibc/pause.c
new file mode 100644
index 0000000000..5748728472
--- /dev/null
+++ b/klibc/klibc/pause.c
@@ -0,0 +1,21 @@
+/*
+ * pause.c
+ */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_pause
+
+_syscall0(int,pause);
+
+#else
+
+int pause(void)
+{
+ return select(0,NULL,NULL,NULL,NULL);
+}
+
+#endif
diff --git a/klibc/klibc/perror.c b/klibc/klibc/perror.c
new file mode 100644
index 0000000000..45585cd577
--- /dev/null
+++ b/klibc/klibc/perror.c
@@ -0,0 +1,12 @@
+/*
+ * perror.c
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+void perror(const char *s)
+{
+ fprintf(stderr, "%s: error %d\n", s, errno);
+}
diff --git a/klibc/klibc/printf.c b/klibc/klibc/printf.c
new file mode 100644
index 0000000000..34237592d6
--- /dev/null
+++ b/klibc/klibc/printf.c
@@ -0,0 +1,19 @@
+/*
+ * printf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define BUFFER_SIZE 16384
+
+int printf(const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vfprintf(stdout, format, ap);
+ va_end(ap);
+ return rv;
+}
diff --git a/klibc/klibc/pty.c b/klibc/klibc/pty.c
new file mode 100644
index 0000000000..5907ca2ff5
--- /dev/null
+++ b/klibc/klibc/pty.c
@@ -0,0 +1,31 @@
+/*
+ * pty.c
+ *
+ * Basic Unix98 PTY functionality; assumes devpts
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+char *ptsname(int fd)
+{
+ static char buffer[32]; /* Big enough to hold even a 64-bit pts no */
+ unsigned int ptyno;
+
+ if ( ioctl(fd, TIOCGPTN, &ptyno) )
+ return NULL;
+
+ snprintf(buffer, sizeof buffer, "/dev/pts/%u", ptyno);
+
+ return buffer;
+}
+
+int unlockpt(int fd)
+{
+ int unlock = 0;
+
+ return ioctl(fd, TIOCSPTLCK, &unlock);
+}
diff --git a/klibc/klibc/puts.c b/klibc/klibc/puts.c
new file mode 100644
index 0000000000..ecebf275da
--- /dev/null
+++ b/klibc/klibc/puts.c
@@ -0,0 +1,13 @@
+/*
+ * puts.c
+ */
+
+#include <stdio.h>
+
+int puts(const char *s)
+{
+ if ( fputs(s, stdout) < 0 )
+ return -1;
+
+ return _fwrite("\n", 1, stdout);
+}
diff --git a/klibc/klibc/qsort.c b/klibc/klibc/qsort.c
new file mode 100644
index 0000000000..e2197ea2ae
--- /dev/null
+++ b/klibc/klibc/qsort.c
@@ -0,0 +1,42 @@
+/*
+ * qsort.c
+ *
+ * This is actually combsort. It's an O(n log n) algorithm with
+ * simplicity/small code size being its main virtue.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+static inline size_t newgap(size_t gap)
+{
+ gap = (gap*10)/13;
+ if ( gap == 9 || gap == 10 )
+ gap = 11;
+
+ if ( gap < 1 )
+ gap = 1;
+ return gap;
+}
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
+{
+ size_t gap = nmemb;
+ size_t i, j;
+ void *p1, *p2;
+ int swapped;
+
+ do {
+ gap = newgap(gap);
+ swapped = 0;
+
+ for ( i = 0, p1 = base ; i < nmemb-gap ; i++, (char *)p1 += size ) {
+ j = i+gap;
+ if ( compar(p1, p2 = (char *)base+j*size) > 0 ) {
+ memswap(p1, p2, size);
+ swapped = 1;
+ }
+ }
+ } while ( gap > 1 || swapped );
+}
+
diff --git a/klibc/klibc/raise.c b/klibc/klibc/raise.c
new file mode 100644
index 0000000000..dcbb9c9c6c
--- /dev/null
+++ b/klibc/klibc/raise.c
@@ -0,0 +1,11 @@
+/*
+ * raise.c
+ */
+
+#include <unistd.h>
+#include <signal.h>
+
+int raise(int signal)
+{
+ return kill(getpid(), signal);
+}
diff --git a/klibc/klibc/readdir.c b/klibc/klibc/readdir.c
new file mode 100644
index 0000000000..bb216a1951
--- /dev/null
+++ b/klibc/klibc/readdir.c
@@ -0,0 +1,66 @@
+/*
+ * opendir/readdir/closedir
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/dirent.h>
+#include <stdio.h>
+
+#define __IO_DIR_DEFINED
+struct _IO_dir {
+ int fd;
+ size_t bytes_left;
+ struct dirent *next;
+ struct dirent buffer[15]; /* 15 times max dirent size =~ 4K */
+};
+
+#include <dirent.h>
+
+DIR *opendir(const char *name)
+{
+ DIR *dp = malloc(sizeof(DIR));
+
+ if ( !dp )
+ return NULL;
+
+ dp->fd = open(name, O_DIRECTORY|O_RDONLY);
+
+ if ( dp->fd < 0 ) {
+ free(dp);
+ return NULL;
+ }
+
+ dp->bytes_left = 0;
+
+ return dp;
+}
+
+struct dirent *readdir(DIR *dir)
+{
+ struct dirent *dent;
+ int rv;
+
+ if ( !dir->bytes_left ) {
+ rv = getdents(dir->fd, dir->buffer, sizeof(dir->buffer));
+ if ( rv <= 0 )
+ return NULL;
+ dir->bytes_left = rv;
+ dir->next = dir->buffer;
+ }
+
+ dent = dir->next;
+ ((char *)dir->next) += dent->d_reclen;
+ dir->bytes_left -= dent->d_reclen;
+
+ return dent;
+}
+
+int closedir(DIR *dir)
+{
+ int rv;
+ rv = close(dir->fd);
+ free(dir);
+ return rv;
+}
diff --git a/klibc/klibc/realloc.c b/klibc/klibc/realloc.c
new file mode 100644
index 0000000000..577c2001a5
--- /dev/null
+++ b/klibc/klibc/realloc.c
@@ -0,0 +1,49 @@
+/*
+ * realloc.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "malloc.h"
+
+/* FIXME: This is cheesy, it should be fixed later */
+
+void *realloc(void *ptr, size_t size)
+{
+ struct free_arena_header *ah;
+ void *newptr;
+ size_t oldsize;
+
+ if ( !ptr )
+ return malloc(size);
+
+ if ( size == 0 ) {
+ free(ptr);
+ return NULL;
+ }
+
+ /* Add the obligatory arena header, and round up */
+ size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK;
+
+ ah = (struct free_arena_header *)
+ ((struct arena_header *)ptr - 1);
+
+ if ( ah->a.size >= size && size >= (ah->a.size >> 2) ) {
+ /* This field is a good size already. */
+ return ptr;
+ } else {
+ /* Make me a new block. This is kind of bogus; we should
+ be checking the adjacent blocks to see if we can do an
+ in-place adjustment... fix that later. */
+
+ oldsize = ah->a.size - sizeof(struct arena_header);
+
+ newptr = malloc(size);
+ memcpy(newptr, ptr, (size < oldsize) ? size : oldsize);
+ free(ptr);
+
+ return newptr;
+ }
+}
+
diff --git a/klibc/klibc/reboot.c b/klibc/klibc/reboot.c
new file mode 100644
index 0000000000..772c85910e
--- /dev/null
+++ b/klibc/klibc/reboot.c
@@ -0,0 +1,15 @@
+/*
+ * reboot.c
+ */
+
+#include <unistd.h>
+#include <sys/reboot.h>
+#include <sys/syscall.h>
+
+/* This provides the one-argument glibc-ish version of reboot.
+ The full four-argument system call is available as __reboot(). */
+
+int reboot(int flag)
+{
+ return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, NULL);
+}
diff --git a/klibc/klibc/recv.c b/klibc/klibc/recv.c
new file mode 100644
index 0000000000..4d30610cee
--- /dev/null
+++ b/klibc/klibc/recv.c
@@ -0,0 +1,11 @@
+/*
+ * recv.c
+ */
+
+#include <stddef.h>
+#include <sys/socket.h>
+
+int recv(int s, void *buf, size_t len, unsigned int flags)
+{
+ return recvfrom(s, buf, len, flags, NULL, 0);
+}
diff --git a/klibc/klibc/sbrk.c b/klibc/klibc/sbrk.c
new file mode 100644
index 0000000000..03ab3c14bb
--- /dev/null
+++ b/klibc/klibc/sbrk.c
@@ -0,0 +1,23 @@
+/* sbrk.c - Change data segment size */
+
+/* Written 2000 by Werner Almesberger */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+char *__current_brk; /* Common with brk.c */
+
+void *sbrk(ptrdiff_t increment)
+{
+ char *old_brk, *new_brk;
+
+ if (!__current_brk)
+ __current_brk = __brk(NULL);
+ new_brk = __brk(__current_brk+increment);
+ if (new_brk != __current_brk+increment)
+ return (void *) -1;
+ old_brk = __current_brk;
+ __current_brk = new_brk;
+ return old_brk;
+}
diff --git a/klibc/klibc/seed48.c b/klibc/klibc/seed48.c
new file mode 100644
index 0000000000..f8353c8715
--- /dev/null
+++ b/klibc/klibc/seed48.c
@@ -0,0 +1,19 @@
+/*
+ * seed48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+extern unsigned short __rand48_seed[3];
+
+unsigned short *seed48(const unsigned short xsubi[3])
+{
+ static unsigned short oldseed[3];
+ memcpy(oldseed, __rand48_seed, sizeof __rand48_seed);
+ memcpy(__rand48_seed, xsubi, sizeof __rand48_seed);
+
+ return oldseed;
+}
+
diff --git a/klibc/klibc/select.c b/klibc/klibc/select.c
new file mode 100644
index 0000000000..2404bb1e64
--- /dev/null
+++ b/klibc/klibc/select.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifdef __NR__newselect
+#undef __NR_select
+#define __NR_select __NR__newselect
+#endif
+
+_syscall5(int,select,int,a0,fd_set *,a1,fd_set *,a2,fd_set *,a3,struct timeval *,a4);
diff --git a/klibc/klibc/send.c b/klibc/klibc/send.c
new file mode 100644
index 0000000000..8c53d0f764
--- /dev/null
+++ b/klibc/klibc/send.c
@@ -0,0 +1,11 @@
+/*
+ * send.c
+ */
+
+#include <stddef.h>
+#include <sys/socket.h>
+
+int send(int s, const void *buf, size_t len, unsigned int flags)
+{
+ return sendto(s, buf, len, flags, NULL, 0);
+}
diff --git a/klibc/klibc/setegid.c b/klibc/klibc/setegid.c
new file mode 100644
index 0000000000..09f2416e43
--- /dev/null
+++ b/klibc/klibc/setegid.c
@@ -0,0 +1,10 @@
+/*
+ * setegid.c
+ */
+
+#include <unistd.h>
+
+int setegid(gid_t egid)
+{
+ return setregid(-1, egid);
+}
diff --git a/klibc/klibc/setenv.c b/klibc/klibc/setenv.c
new file mode 100644
index 0000000000..d1118ff3ed
--- /dev/null
+++ b/klibc/klibc/setenv.c
@@ -0,0 +1,124 @@
+/*
+ * setenv.c
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Initialized to zero, meaning "not malloc'd" */
+static size_t __environ_size;
+
+/* str should be a duplicated version of the input string;
+ len is the length of the key including the = sign */
+static int _putenv(char *str, size_t len, int overwrite)
+{
+ char **p, *q;
+ char **newenv;
+ size_t n;
+
+ n = 1; /* Include space for final NULL */
+ for ( p = environ ; (q = *p) ; p++ ) {
+ n++;
+ if ( !strncmp(q,str,len) ) {
+ if ( overwrite )
+ free(str);
+ else
+ *p = str; /* Memory leak... */
+ return 0;
+ }
+ }
+
+ /* Need to extend the environment */
+ if ( n < __environ_size ) {
+ p[1] = NULL;
+ *p = str;
+ return 0;
+ } else {
+ if ( __environ_size ) {
+ newenv = realloc(environ, (__environ_size << 1)*sizeof(char *));
+ if ( !newenv )
+ return -1;
+
+ __environ_size <<= 1;
+ } else {
+ /* Make a reasonable guess how much more space we need */
+ size_t newsize = n+32;
+ newenv = malloc(newsize*sizeof(char *));
+ if ( !newenv )
+ return -1;
+
+ memcpy(newenv, environ, n*sizeof(char *));
+ __environ_size = newsize;
+ }
+ newenv[n+1] = NULL;
+ newenv[n] = str;
+ environ = newenv;
+ }
+ return 0;
+}
+
+int putenv(const char *str)
+{
+ char *s;
+ const char *e, *z;
+ size_t len;
+
+ if ( !str ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ len = 0; e = NULL;
+ for ( z = str ; *z ; z++ ) {
+ len++;
+ if ( *z == '=' )
+ e = z;
+ }
+
+ if ( !e ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ s = strdup(str);
+ if ( !s )
+ return -1;
+
+ return _putenv(s, len, 1);
+}
+
+int setenv(const char *name, const char *val, int overwrite)
+{
+ const char *z;
+ char *s;
+ size_t l1, l2;
+
+ if ( !name || !name[0] ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ l1 = 0;
+ for ( z = name ; *z ; z++ ) {
+ l1++;
+ if ( *z == '=' ) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ l2 = strlen(val);
+
+ s = malloc(l1+l2+2);
+ if ( !s )
+ return -1;
+
+ memcpy(s, name, l1);
+ s[l1] = '=';
+ memcpy(s+l1+1, val, l2);
+ s[l1+l2+1] = '\0';
+
+ return _putenv(s, l1+1, overwrite);
+}
diff --git a/klibc/klibc/seteuid.c b/klibc/klibc/seteuid.c
new file mode 100644
index 0000000000..6d1ac3922a
--- /dev/null
+++ b/klibc/klibc/seteuid.c
@@ -0,0 +1,10 @@
+/*
+ * seteuid.c
+ */
+
+#include <unistd.h>
+
+int seteuid(uid_t euid)
+{
+ return setreuid(-1, euid);
+}
diff --git a/klibc/klibc/setpgrp.c b/klibc/klibc/setpgrp.c
new file mode 100644
index 0000000000..001dd0435d
--- /dev/null
+++ b/klibc/klibc/setpgrp.c
@@ -0,0 +1,10 @@
+/*
+ * setpgrp.c
+ */
+
+#include <unistd.h>
+
+int setpgrp(void)
+{
+ return setpgid(0,0);
+}
diff --git a/klibc/klibc/setresgid.c b/klibc/klibc/setresgid.c
new file mode 100644
index 0000000000..f1a8c6b45c
--- /dev/null
+++ b/klibc/klibc/setresgid.c
@@ -0,0 +1,29 @@
+/*
+ * setresgid.c
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_setresgid
+
+_syscall3(int,setresgid,gid_t,a0,gid_t,a1,gid_t,a2);
+
+#elif defined(__NR_setresgid32)
+
+static inline _syscall3(int,setresgid32,gid_t,a0,gid_t,a1,gid_t,a2);
+
+int setresgid(gid_t a0, gid_t a1, gid_t a2)
+{
+ if ( sizeof(gid_t) == sizeof(uint32_t) ) {
+ return setresgid32(a0,a1,a2);
+ } else {
+ uint32_t x0 = (a0 == (gid_t)-1) ? (uint32_t)-1 : a0;
+ uint32_t x1 = (a1 == (gid_t)-1) ? (uint32_t)-1 : a1;
+ uint32_t x2 = (a2 == (gid_t)-1) ? (uint32_t)-1 : a2;
+
+ return setresgid32(x0,x1,x2);
+ }
+}
+
+#endif
diff --git a/klibc/klibc/setresuid.c b/klibc/klibc/setresuid.c
new file mode 100644
index 0000000000..a587acbae3
--- /dev/null
+++ b/klibc/klibc/setresuid.c
@@ -0,0 +1,30 @@
+/*
+ * setresuid.c
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_setresuid
+
+_syscall3(int,setresuid,uid_t,a0,uid_t,a1,uid_t,a2);
+
+#elif defined(__NR_setresuid32)
+
+static inline _syscall3(int,setresuid32,uid_t,a0,uid_t,a1,uid_t,a2);
+
+int setresuid(uid_t a0, uid_t a1, uid_t a2)
+{
+ if ( sizeof(uid_t) == sizeof(uint32_t) ) {
+ return setresuid32(a0,a1,a2);
+ } else {
+ uint32_t x0 = (a0 == (uid_t)-1) ? (uint32_t)-1 : a0;
+ uint32_t x1 = (a1 == (uid_t)-1) ? (uint32_t)-1 : a1;
+ uint32_t x2 = (a2 == (uid_t)-1) ? (uint32_t)-1 : a2;
+
+ return setresuid32(x0,x1,x2);
+ }
+}
+
+#endif
+
diff --git a/klibc/klibc/sha1hash.c b/klibc/klibc/sha1hash.c
new file mode 100644
index 0000000000..600d51248c
--- /dev/null
+++ b/klibc/klibc/sha1hash.c
@@ -0,0 +1,317 @@
+/*
+SHA-1 in C
+By Steve Reid <sreid@sea-to-sky.net>
+100% Public Domain
+
+-----------------
+Modified 7/98
+By James H. Brown <jbrown@burgoyne.com>
+Still 100% Public Domain
+
+Corrected a problem which generated improper hash values on 16 bit machines
+Routine SHA1Update changed from
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
+len)
+to
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
+long len)
+
+The 'len' parameter was declared an int which works fine on 32 bit machines.
+However, on 16 bit machines an int is too small for the shifts being done
+against
+it. This caused the hash function to generate incorrect values if len was
+greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
+
+Since the file IO in main() reads 16K at a time, any file 8K or larger would
+be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
+"a"s).
+
+I also changed the declaration of variables i & j in SHA1Update to
+unsigned long from unsigned int for the same reason.
+
+These changes should make no difference to any 32 bit implementations since
+an
+int and a long are the same size in those environments.
+
+--
+I also corrected a few compiler warnings generated by Borland C.
+1. Added #include <process.h> for exit() prototype
+2. Removed unused variable 'j' in SHA1Final
+3. Changed exit(0) to return(0) at end of main.
+
+ALL changes I made can be located by searching for comments containing 'JHB'
+-----------------
+Modified 8/98
+By Steve Reid <sreid@sea-to-sky.net>
+Still 100% public domain
+
+1- Removed #include <process.h> and used return() instead of exit()
+2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
+3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
+
+-----------------
+Modified 4/01
+By Saul Kravitz <Saul.Kravitz@celera.com>
+Still 100% PD
+Modified to run on Compaq Alpha hardware.
+
+-----------------
+Modified 2/03
+By H. Peter Anvin <hpa@zytor.com>
+Still 100% PD
+Modified to run on any hardware with <inttypes.h> and <netinet/in.h>
+Changed the driver program
+
+*/
+
+/*
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define SHA1HANDSOFF */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <netinet/in.h> /* For htonl/ntohl/htons/ntohs */
+
+/* #include <process.h> */ /* prototype for exit() - JHB */
+/* Using return() instead of exit() - SWR */
+
+typedef struct {
+ uint32_t state[5];
+ uint32_t count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(uint32_t state[5], unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len); /*
+JHB */
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#define blk0(i) (block->l[i] = ntohl(block->l[i]))
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+#ifdef VERBOSE /* SAK */
+void SHAPrintContext(SHA1_CTX *context, char *msg){
+ printf("%s (%d,%d) %x %x %x %x %x\n",
+ msg,
+ context->count[0], context->count[1],
+ context->state[0],
+ context->state[1],
+ context->state[2],
+ context->state[3],
+ context->state[4]);
+}
+#endif
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(uint32_t state[5], unsigned char buffer[64])
+{
+uint32_t a, b, c, d, e;
+typedef union {
+ unsigned char c[64];
+ uint32_t l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+ block = (CHAR64LONG16*)workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16*)buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len) /*
+JHB */
+{
+uint32_t i, j; /* JHB */
+
+#ifdef VERBOSE
+ SHAPrintContext(context, "before");
+#endif
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+#ifdef VERBOSE
+ SHAPrintContext(context, "after ");
+#endif
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+uint32_t i; /* JHB */
+unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (unsigned char *)"\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (unsigned char *)"\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform()
+*/
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+ /* Wipe variables */
+ i = 0; /* JHB */
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(finalcount, 0, 8); /* SWR */
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
+ SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+/*************************************************************/
+
+/* This is not quite the MIME base64 algorithm: it uses _ instead of /,
+ and instead of padding the output with = characters we just make the
+ output shorter. */
+char *mybase64(uint8_t digest[20])
+{
+ static const char charz[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
+ uint8_t input[21];
+ static char output[28];
+ int i, j;
+ uint8_t *p;
+ char *q;
+ uint32_t bv;
+
+ memcpy(input, digest, 20);
+ input[20] = 0; /* Pad to multiple of 3 bytes */
+
+ p = input; q = output;
+ for ( i = 0 ; i < 7 ; i++ ) {
+ bv = (p[0] << 16) | (p[1] << 8) | p[2];
+ p += 3;
+ for ( j = 0 ; j < 4 ; j++ ) {
+ *q++ = charz[(bv >> 18) & 0x3f];
+ bv <<= 6;
+ }
+ }
+ *--q = '\0'; /* The last character is not significant */
+ return output;
+}
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ SHA1_CTX context;
+ uint8_t digest[20], buffer[16384];
+ FILE* file;
+
+ if (argc < 2) {
+ file = stdin;
+ }
+ else {
+ if (!(file = fopen(argv[1], "rb"))) {
+ fputs("Unable to open file.", stderr);
+ return(-1);
+ }
+ }
+ SHA1Init(&context);
+ while (!feof(file)) { /* note: what if ferror(file) */
+ i = fread(buffer, 1, 16384, file);
+ SHA1Update(&context, buffer, i);
+ }
+ SHA1Final(digest, &context);
+ fclose(file);
+
+ puts(mybase64(digest));
+
+ return 0;
+}
diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c
new file mode 100644
index 0000000000..ebd34710f1
--- /dev/null
+++ b/klibc/klibc/sigaction.c
@@ -0,0 +1,19 @@
+/*
+ * sigaction.c
+ */
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_sigaction
+
+_syscall3(int,sigaction,int,sig,const struct sigaction *,act,struct sigaction *,oact);
+
+#else
+
+int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
+{
+ return rt_sigaction(sig, act, oact, sizeof(sigset_t));
+}
+
+#endif
diff --git a/klibc/klibc/siglist.c b/klibc/klibc/siglist.c
new file mode 100644
index 0000000000..dce7355079
--- /dev/null
+++ b/klibc/klibc/siglist.c
@@ -0,0 +1,115 @@
+/*
+ * siglist.h
+ *
+ * Construct the signal list
+ */
+
+#include <signal.h>
+#include <unistd.h>
+
+const char * const sys_siglist[NSIG] = {
+#ifdef SIGABRT
+ [SIGABRT] = "Aborted",
+#endif
+#ifdef SIGALRM
+ [SIGALRM] = "Alarm clock",
+#endif
+#ifdef SIGBUS
+ [SIGBUS] = "Bus error",
+#endif
+#ifdef SIGCHLD
+ [SIGCHLD] = "Child exited",
+#endif
+#if defined(SIGCLD) && (SIGCHLD != SIGCLD)
+ [SIGCLD] = "Child exited",
+#endif
+#ifdef SIGEMT
+ [SIGEMT] = "Emulation trap",
+#endif
+#ifdef SIGFPE
+ [SIGFPE] = "Floating point exception",
+#endif
+#ifdef SIGHUP
+ [SIGHUP] = "Hangup",
+#endif
+#ifdef SIGILL
+ [SIGILL] = "Illegal instruction",
+#endif
+ /* SIGINFO == SIGPWR */
+#ifdef SIGINT
+ [SIGINT] = "Interrupt",
+#endif
+#ifdef SIGIO
+ [SIGIO] = "I/O possible",
+#endif
+#if defined(SIGIOT) && (SIGIOT != SIGABRT)
+ [SIGIOT] = "I/O trap",
+#endif
+#ifdef SIGKILL
+ [SIGKILL] = "Killed",
+#endif
+#if defined(SIGLOST) && (SIGLOST != SIGIO) && (SIGLOST != SIGPWR)
+ [SIGLOST] = "Lock lost",
+#endif
+#ifdef SIGPIPE
+ [SIGPIPE] = "Broken pipe",
+#endif
+#if defined(SIGPOLL) && (SIGPOLL != SIGIO)
+ [SIGPOLL] = "Pollable event",
+#endif
+#ifdef SIGPROF
+ [SIGPROF] = "Profiling timer expired",
+#endif
+#ifdef SIGPWR
+ [SIGPWR] = "Power failure",
+#endif
+#ifdef SIGQUIT
+ [SIGQUIT] = "Quit",
+#endif
+ /* SIGRESERVE == SIGUNUSED */
+#ifdef SIGSEGV
+ [SIGSEGV] = "Segment violation",
+#endif
+#ifdef SIGSTKFLT
+ [SIGSTKFLT] = "Stack fault",
+#endif
+#ifdef SIGSTOP
+ [SIGSTOP] = "Stopped (signal)",
+#endif
+#ifdef SIGSYS
+ [SIGSYS] = "Bad system call",
+#endif
+#ifdef SIGTERM
+ [SIGTERM] = "Terminated",
+#endif
+#ifdef SIGTSTP
+ [SIGTSTP] = "Stopped",
+#endif
+#ifdef SIGTTIN
+ [SIGTTIN] = "Stopped (tty input)",
+#endif
+#ifdef SIGTTOU
+ [SIGTTOU] = "Stopped (tty output)",
+#endif
+#ifdef SIGURG
+ [SIGURG] = "Urgent I/O condition",
+#endif
+#ifdef SIGUSR1
+ [SIGUSR1] = "User signal 1",
+#endif
+#ifdef SIGUSR2
+ [SIGUSR2] = "User signal 2",
+#endif
+#ifdef SIGVTALRM
+ [SIGVTALRM] = "Virtual timer expired",
+#endif
+#ifdef SIGWINCH
+ [SIGWINCH] = "Window size changed",
+#endif
+#ifdef SIGXCPU
+ [SIGXCPU] = "CPU time limit exceeded",
+#endif
+#ifdef SIGXFSZ
+ [SIGXFSZ] = "File size limit exceeded",
+#endif
+};
diff --git a/klibc/klibc/siglongjmp.c b/klibc/klibc/siglongjmp.c
new file mode 100644
index 0000000000..2ba1239b6b
--- /dev/null
+++ b/klibc/klibc/siglongjmp.c
@@ -0,0 +1,16 @@
+/*
+ * siglongjmp.c
+ *
+ * sigsetjmp() is a macro, by necessity (it's either that or write
+ * it in assembly), but siglongjmp() is a normal function.
+ */
+
+#include <setjmp.h>
+#include <signal.h>
+
+__noreturn siglongjmp(sigjmp_buf buf, int retval)
+{
+ sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
+ longjmp(buf->__jmpbuf, retval);
+}
+
diff --git a/klibc/klibc/signal.c b/klibc/klibc/signal.c
new file mode 100644
index 0000000000..982d0c659d
--- /dev/null
+++ b/klibc/klibc/signal.c
@@ -0,0 +1,11 @@
+/*
+ * signal.c
+ */
+
+#include <signal.h>
+
+__sighandler_t signal(int signum, __sighandler_t handler)
+{
+ /* Linux/SysV signal() semantics */
+ return __signal(signum, handler, SA_RESETHAND);
+}
diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c
new file mode 100644
index 0000000000..afbcf3cf34
--- /dev/null
+++ b/klibc/klibc/sigpending.c
@@ -0,0 +1,19 @@
+/*
+ * sigpending.c
+ */
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_sigpending
+
+_syscall1(int,sigpending,sigset_t *,set);
+
+#else
+
+int sigpending(sigset_t *set)
+{
+ return rt_sigpending(set, sizeof(sigset_t));
+}
+
+#endif
diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c
new file mode 100644
index 0000000000..3a90f67732
--- /dev/null
+++ b/klibc/klibc/sigprocmask.c
@@ -0,0 +1,19 @@
+/*
+ * sigprocmask.c
+ */
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_sigprocmask
+
+_syscall3(int,sigprocmask,int,how,const sigset_t *,set,sigset_t *,oset);
+
+#else
+
+int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
+{
+ return rt_sigprocmask(how, set, oset, sizeof(sigset_t));
+}
+
+#endif
diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c
new file mode 100644
index 0000000000..85cdea20ca
--- /dev/null
+++ b/klibc/klibc/sigsuspend.c
@@ -0,0 +1,19 @@
+/*
+ * sigsuspend.c
+ */
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_sigsuspend
+
+_syscall1(int,sigsuspend,const sigset_t *,mask);
+
+#else
+
+int sigsuspend(const sigset_t *mask)
+{
+ return rt_sigsuspend(mask, sizeof *mask);
+}
+
+#endif
diff --git a/klibc/klibc/sleep.c b/klibc/klibc/sleep.c
new file mode 100644
index 0000000000..eb3777e8a6
--- /dev/null
+++ b/klibc/klibc/sleep.c
@@ -0,0 +1,20 @@
+/*
+ * sleep.c
+ */
+
+#include <errno.h>
+#include <time.h>
+
+unsigned int sleep(unsigned int seconds)
+{
+ struct timespec ts;
+
+ ts.tv_sec = seconds;
+ ts.tv_nsec = 0;
+ if ( !nanosleep(&ts,&ts) )
+ return 0;
+ else if ( errno == EINTR )
+ return ts.tv_sec;
+ else
+ return -1;
+}
diff --git a/klibc/klibc/snprintf.c b/klibc/klibc/snprintf.c
new file mode 100644
index 0000000000..c642851b2f
--- /dev/null
+++ b/klibc/klibc/snprintf.c
@@ -0,0 +1,16 @@
+/*
+ * snprintf.c
+ */
+
+#include <stdio.h>
+
+int snprintf(char *buffer, size_t n, const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vsnprintf(buffer, n, format, ap);
+ va_end(ap);
+ return rv;
+}
diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl
new file mode 100644
index 0000000000..cf4daf6036
--- /dev/null
+++ b/klibc/klibc/socketcalls.pl
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+($arch, $file) = @ARGV;
+
+if (!open(FILE, "< $file")) {
+ print STDERR "$file: $!\n";
+ exit(1);
+}
+
+while ( defined($line = <FILE>) ) {
+ chomp $line;
+ $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks
+ next unless $line;
+
+ if ( $line =~ /^\s*(.*)\s+([_a-zA-Z][_a-zA-Z0-9]+)\s*\((.*)\)$/ ) {
+ $type = $1;
+ $name = $2;
+ $argv = $3;
+
+ @args = split(/\s*\,\s*/, $argv);
+ @cargs = ();
+
+ $i = 0;
+ for $arg ( @args ) {
+ push(@cargs, "$arg a".$i++);
+ }
+ $nargs = $i;
+
+ if ( $arch eq 'i386' ) {
+ open(OUT, "> socketcalls/${name}.S")
+ or die "$0: Cannot open socketcalls/${name}.S\n";
+
+ print OUT "#include <sys/socketcalls.h>\n";
+ print OUT "\n";
+ print OUT "\t.text\n";
+ print OUT "\t.align 4\n";
+ print OUT "\t.globl ${name}\n";
+ print OUT "\t.type ${name},\@function\n";
+ print OUT "${name}:\n";
+ print OUT "\tmovb \$SYS_\U${name}\E,%al\n";
+ print OUT "\tjmp __socketcall_common\n";
+ print OUT "\t.size ${name},.-${name}\n";
+ } else {
+ open(OUT, "> socketcalls/${name}.c")
+ or die "$0: Cannot open socketcalls/${name}.c\n";
+ print OUT "#include \"socketcommon.h\"\n\n";
+
+ print OUT "#ifdef __NR_$name\n\n";
+ print OUT "_syscall", scalar(@args), "(", $type, ',', $name;
+ $i = 0;
+ foreach $arg ( @args ) {
+ print OUT ",", $arg, ",a",$i++;
+ }
+ print OUT ");\n";
+ print OUT "\n#else\n\n";
+
+ print OUT "$type $name (", join(', ', @cargs), ")\n";
+ print OUT "{\n";
+ print OUT " unsigned long args[$nargs];\n";
+ for ( $i = 0 ; $i < $nargs ; $i++ ) {
+ print OUT " args[$i] = (unsigned long)a$i;\n";
+ }
+ print OUT " return ($type) socketcall(SYS_\U${name}\E, args);\n";
+ print OUT "}\n";
+ print OUT "\n#endif\n";
+ }
+ close(OUT);
+ } else {
+ print STDERR "$file:$.: Could not parse input\n";
+ exit(1);
+ }
+}
diff --git a/klibc/klibc/socketcommon.h b/klibc/klibc/socketcommon.h
new file mode 100644
index 0000000000..7a5acaadaf
--- /dev/null
+++ b/klibc/klibc/socketcommon.h
@@ -0,0 +1,25 @@
+/*
+ * socketcommon.h
+ *
+ * Common header file for socketcall stubs
+ */
+
+#define __IN_SYS_COMMON
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <linux/net.h>
+
+/*
+ * Some architectures have socketcall(), some have real syscalls,
+ * and some have both, but the syscall version is always preferred.
+ * Look for __NR_<call> to probe for the existence of a syscall.
+ */
+
+#ifdef __NR_socketcall
+static inline _syscall2(int,socketcall,int,call,unsigned long *,args);
+#endif
diff --git a/klibc/klibc/sprintf.c b/klibc/klibc/sprintf.c
new file mode 100644
index 0000000000..31f28af005
--- /dev/null
+++ b/klibc/klibc/sprintf.c
@@ -0,0 +1,18 @@
+/*
+ * sprintf.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int sprintf(char *buffer, const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vsnprintf(buffer, ~(size_t)0, format, ap);
+ va_end(ap);
+
+ return rv;
+}
diff --git a/klibc/klibc/srand48.c b/klibc/klibc/srand48.c
new file mode 100644
index 0000000000..a3df16d95c
--- /dev/null
+++ b/klibc/klibc/srand48.c
@@ -0,0 +1,16 @@
+/*
+ * srand48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+extern unsigned short __rand48_seed[3];
+
+
+void srand48(long seedval)
+{
+ __rand48_seed[0] = 0x330e;
+ __rand48_seed[1] = (unsigned short)seedval;
+ __rand48_seed[2] = (unsigned short)((uint32_t)seedval >> 16);
+}
diff --git a/klibc/klibc/sscanf.c b/klibc/klibc/sscanf.c
new file mode 100644
index 0000000000..81aab9e05b
--- /dev/null
+++ b/klibc/klibc/sscanf.c
@@ -0,0 +1,17 @@
+/*
+ * sscanf()
+ */
+
+#include <stdio.h>
+
+int sscanf(const char *str, const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vsscanf(str, format, ap);
+ va_end(ap);
+
+ return rv;
+}
diff --git a/klibc/klibc/strcat.c b/klibc/klibc/strcat.c
new file mode 100644
index 0000000000..a5f9477866
--- /dev/null
+++ b/klibc/klibc/strcat.c
@@ -0,0 +1,11 @@
+/*
+ * strcat.c
+ */
+
+#include <string.h>
+
+char *strcat(char *dst, const char *src)
+{
+ strcpy(strchr(dst, '\0'), src);
+ return dst;
+}
diff --git a/klibc/klibc/strchr.c b/klibc/klibc/strchr.c
new file mode 100644
index 0000000000..192f83600c
--- /dev/null
+++ b/klibc/klibc/strchr.c
@@ -0,0 +1,16 @@
+/*
+ * strchr.c
+ */
+
+#include <string.h>
+
+char *strchr(const char *s, int c)
+{
+ while ( *s != (char)c ) {
+ if ( ! *s )
+ return NULL;
+ s++;
+ }
+
+ return (char *)s;
+}
diff --git a/klibc/klibc/strcmp.c b/klibc/klibc/strcmp.c
new file mode 100644
index 0000000000..f44774f443
--- /dev/null
+++ b/klibc/klibc/strcmp.c
@@ -0,0 +1,20 @@
+/*
+ * strcmp.c
+ */
+
+#include <string.h>
+
+int strcmp(const char *s1, const char *s2)
+{
+ const unsigned char *c1 = s1, *c2 = s2;
+ unsigned char ch;
+ int d = 0;
+
+ while ( 1 ) {
+ d = (int)(ch = *c1++) - (int)*c2++;
+ if ( d || !ch )
+ break;
+ }
+
+ return d;
+}
diff --git a/klibc/klibc/strcpy.c b/klibc/klibc/strcpy.c
new file mode 100644
index 0000000000..8372eba50b
--- /dev/null
+++ b/klibc/klibc/strcpy.c
@@ -0,0 +1,20 @@
+/*
+ * strcpy.c
+ *
+ * strcpy()
+ */
+
+#include <string.h>
+
+char *strcpy(char *dst, const char *src)
+{
+ char *q = dst;
+ const char *p = src;
+ char ch;
+
+ do {
+ *q++ = ch = *p++;
+ } while ( ch );
+
+ return dst;
+}
diff --git a/klibc/klibc/strdup.c b/klibc/klibc/strdup.c
new file mode 100644
index 0000000000..eb170c2645
--- /dev/null
+++ b/klibc/klibc/strdup.c
@@ -0,0 +1,17 @@
+/*
+ * strdup.c
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+char *strdup(const char *s)
+{
+ int l = strlen(s)+1;
+ char *d = malloc(l);
+
+ if ( d )
+ memcpy(d, s, l);
+
+ return d;
+}
diff --git a/klibc/klibc/strerror.c b/klibc/klibc/strerror.c
new file mode 100644
index 0000000000..754a30693c
--- /dev/null
+++ b/klibc/klibc/strerror.c
@@ -0,0 +1,25 @@
+/*
+ * strerror.c
+ */
+
+#include <string.h>
+
+char *strerror(int errnum)
+{
+ static char message[32] = "error "; /* enough for error 2^63-1 */
+
+ char numbuf[32];
+ char *p;
+ int len;
+
+ p = numbuf+sizeof numbuf;
+ *--p = '\0';
+
+ do {
+ *--p = (errnum % 10) + '0';
+ errnum /= 10;
+ } while ( errnum );
+
+ return (char *)memcpy(message+6, p, (numbuf+sizeof numbuf)-p);
+}
+
diff --git a/klibc/klibc/strlen.c b/klibc/klibc/strlen.c
new file mode 100644
index 0000000000..4d773f9a05
--- /dev/null
+++ b/klibc/klibc/strlen.c
@@ -0,0 +1,14 @@
+/*
+ * strlen()
+ */
+
+#include <string.h>
+
+size_t strlen(const char *s)
+{
+ const char *ss = s;
+ while ( *ss )
+ ss++;
+ return ss-s;
+}
+
diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c
new file mode 100644
index 0000000000..99d957594c
--- /dev/null
+++ b/klibc/klibc/strncat.c
@@ -0,0 +1,11 @@
+/*
+ * strncat.c
+ */
+
+#include <string.h>
+
+char *strncat(char *dst, const char *src, size_t n)
+{
+ strncpy(strchr(dst, '\0'), src, n);
+ return dst;
+}
diff --git a/klibc/klibc/strncmp.c b/klibc/klibc/strncmp.c
new file mode 100644
index 0000000000..98a41c3773
--- /dev/null
+++ b/klibc/klibc/strncmp.c
@@ -0,0 +1,20 @@
+/*
+ * strncmp.c
+ */
+
+#include <string.h>
+
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+ const unsigned char *c1 = s1, *c2 = s2;
+ unsigned char ch;
+ int d = 0;
+
+ while ( n-- ) {
+ d = (int)*c2++ - (int)(ch = *c1++);
+ if ( d || !ch )
+ break;
+ }
+
+ return d;
+}
diff --git a/klibc/klibc/strncpy.c b/klibc/klibc/strncpy.c
new file mode 100644
index 0000000000..a8fe45fcbb
--- /dev/null
+++ b/klibc/klibc/strncpy.c
@@ -0,0 +1,22 @@
+/*
+ * strncpy.c
+ *
+ * strncpy()
+ */
+
+#include <string.h>
+
+char *strncpy(char *dst, const char *src, size_t n)
+{
+ char *q = dst;
+ const char *p = src;
+ char ch;
+
+ while ( n-- ) {
+ *q++ = ch = *p++;
+ if ( !ch )
+ break;
+ }
+
+ return dst;
+}
diff --git a/klibc/klibc/strntoimax.c b/klibc/klibc/strntoimax.c
new file mode 100644
index 0000000000..f53a266dba
--- /dev/null
+++ b/klibc/klibc/strntoimax.c
@@ -0,0 +1,13 @@
+/*
+ * strntoimax.c
+ *
+ * strntoimax()
+ */
+
+#include <stddef.h>
+#include <inttypes.h>
+
+intmax_t strntoimax(const char *nptr, char **endptr, int base, size_t n)
+{
+ return (intmax_t) strntoumax(nptr, endptr, base, n);
+}
diff --git a/klibc/klibc/strntoumax.c b/klibc/klibc/strntoumax.c
new file mode 100644
index 0000000000..4e30637d2c
--- /dev/null
+++ b/klibc/klibc/strntoumax.c
@@ -0,0 +1,75 @@
+/*
+ * strntoumax.c
+ *
+ * The strntoumax() function and associated
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <ctype.h>
+
+static inline int digitval(int ch)
+{
+ if ( ch >= '0' && ch <= '9' ) {
+ return ch-'0';
+ } else if ( ch >= 'A' && ch <= 'Z' ) {
+ return ch-'A'+10;
+ } else if ( ch >= 'a' && ch <= 'z' ) {
+ return ch-'a'+10;
+ } else {
+ return -1;
+ }
+}
+
+uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n)
+{
+ int minus = 0;
+ uintmax_t v = 0;
+ int d;
+
+ while ( n && isspace((unsigned char)*nptr) ) {
+ nptr++;
+ n--;
+ }
+
+ /* Single optional + or - */
+ if ( n && *nptr == '-' ) {
+ minus = 1;
+ nptr++;
+ n--;
+ } else if ( n && *nptr == '+' ) {
+ nptr++;
+ }
+
+ if ( base == 0 ) {
+ if ( n >= 2 && nptr[0] == '0' &&
+ (nptr[1] == 'x' || nptr[1] == 'X') ) {
+ n -= 2;
+ nptr += 2;
+ base = 16;
+ } else if ( n >= 1 && nptr[0] == '0' ) {
+ n--;
+ nptr++;
+ base = 8;
+ } else {
+ base = 10;
+ }
+ } else if ( base == 16 ) {
+ if ( n >= 2 && nptr[0] == '0' &&
+ (nptr[1] == 'x' || nptr[1] == 'X') ) {
+ n -= 2;
+ nptr += 2;
+ }
+ }
+
+ while ( n && (d = digitval(*nptr)) >= 0 && d < base ) {
+ v = v*base + d;
+ n--;
+ nptr++;
+ }
+
+ if ( endptr )
+ *endptr = (char *)nptr;
+
+ return minus ? -v : v;
+}
diff --git a/klibc/klibc/strrchr.c b/klibc/klibc/strrchr.c
new file mode 100644
index 0000000000..3b42464059
--- /dev/null
+++ b/klibc/klibc/strrchr.c
@@ -0,0 +1,18 @@
+/*
+ * strrchr.c
+ */
+
+#include <string.h>
+
+char *strrchr(const char *s, int c)
+{
+ const char *found = NULL;
+
+ while ( *s ) {
+ if ( *s == (char) c )
+ found = s;
+ s++;
+ }
+
+ return (char *)found;
+}
diff --git a/klibc/klibc/strsep.c b/klibc/klibc/strsep.c
new file mode 100644
index 0000000000..58a7a07773
--- /dev/null
+++ b/klibc/klibc/strsep.c
@@ -0,0 +1,21 @@
+/*
+ * strsep.c
+ */
+
+#include <string.h>
+
+char *strsep(char **stringp, const char *delim)
+{
+ char *s = *stringp;
+ char *e;
+
+ if ( !s )
+ return NULL;
+
+ e = strpbrk(s, delim);
+ if (e)
+ *e++ = '\0';
+
+ *stringp = e;
+ return s;
+}
diff --git a/klibc/klibc/strspn.c b/klibc/klibc/strspn.c
new file mode 100644
index 0000000000..856a964197
--- /dev/null
+++ b/klibc/klibc/strspn.c
@@ -0,0 +1,67 @@
+/*
+ * strspn, strcspn
+ */
+
+#include <string.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <limits.h>
+
+#ifndef LONG_BIT
+#define LONG_BIT (CHAR_BIT*sizeof(long))
+#endif
+
+static inline void
+set_bit(unsigned long *bitmap, unsigned int bit)
+{
+ bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT);
+}
+
+static inline int
+test_bit(unsigned long *bitmap, unsigned int bit)
+{
+ return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1;
+}
+
+static size_t
+strxspn(const char *s, const char *map, int parity)
+{
+ unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT];
+ size_t n = 0;
+
+ /* Create bitmap */
+ memset(matchmap, 0, sizeof matchmap);
+ while ( *map )
+ set_bit(matchmap, (unsigned char) *map++);
+
+ /* Make sure the null character never matches */
+ if ( parity )
+ set_bit(matchmap, 0);
+
+ /* Calculate span length */
+ while ( test_bit(matchmap, (unsigned char) *s++)^parity )
+ n++;
+
+ return n;
+}
+
+size_t
+strspn(const char *s, const char *accept)
+{
+ return strxspn(s, accept, 0);
+}
+
+size_t
+strcspn(const char *s, const char *reject)
+{
+ return strxspn(s, reject, 1);
+}
+
+char *
+strpbrk(const char *s, const char *accept)
+{
+ const char *ss = s+strxspn(s, accept, 1);
+
+ return *ss ? (char *)ss : NULL;
+}
+
diff --git a/klibc/klibc/strstr.c b/klibc/klibc/strstr.c
new file mode 100644
index 0000000000..10222dfd30
--- /dev/null
+++ b/klibc/klibc/strstr.c
@@ -0,0 +1,10 @@
+/*
+ * strstr.c
+ */
+
+#include <string.h>
+
+char *strstr(const char *haystack, const char *needle)
+{
+ return (char *)memmem(haystack, strlen(haystack), needle, strlen(needle));
+}
diff --git a/klibc/klibc/strtoimax.c b/klibc/klibc/strtoimax.c
new file mode 100644
index 0000000000..0cdd088e51
--- /dev/null
+++ b/klibc/klibc/strtoimax.c
@@ -0,0 +1,3 @@
+#define TYPE intmax_t
+#define NAME strtoimax
+#include "strtox.c"
diff --git a/klibc/klibc/strtok.c b/klibc/klibc/strtok.c
new file mode 100644
index 0000000000..6e84f1dff3
--- /dev/null
+++ b/klibc/klibc/strtok.c
@@ -0,0 +1,16 @@
+/*
+ * strtok.c
+ */
+
+#include <string.h>
+
+char *strtok(char *s, const char *delim)
+{
+ static char *holder;
+
+ if ( s )
+ holder = s;
+
+ return strsep(&holder, delim);
+}
+
diff --git a/klibc/klibc/strtol.c b/klibc/klibc/strtol.c
new file mode 100644
index 0000000000..9efc8b9e4a
--- /dev/null
+++ b/klibc/klibc/strtol.c
@@ -0,0 +1,3 @@
+#define TYPE signed long
+#define NAME strtol
+#include "strtox.c"
diff --git a/klibc/klibc/strtoll.c b/klibc/klibc/strtoll.c
new file mode 100644
index 0000000000..a9428c7f14
--- /dev/null
+++ b/klibc/klibc/strtoll.c
@@ -0,0 +1,3 @@
+#define TYPE signed long long
+#define NAME strtoll
+#include "strtox.c"
diff --git a/klibc/klibc/strtoul.c b/klibc/klibc/strtoul.c
new file mode 100644
index 0000000000..3189aaa7ce
--- /dev/null
+++ b/klibc/klibc/strtoul.c
@@ -0,0 +1,3 @@
+#define TYPE unsigned long
+#define NAME strtoul
+#include "strtox.c"
diff --git a/klibc/klibc/strtoull.c b/klibc/klibc/strtoull.c
new file mode 100644
index 0000000000..83c14e9128
--- /dev/null
+++ b/klibc/klibc/strtoull.c
@@ -0,0 +1,3 @@
+#define TYPE unsigned long long
+#define NAME strtoull
+#include "strtox.c"
diff --git a/klibc/klibc/strtoumax.c b/klibc/klibc/strtoumax.c
new file mode 100644
index 0000000000..a3797105e8
--- /dev/null
+++ b/klibc/klibc/strtoumax.c
@@ -0,0 +1,3 @@
+#define TYPE uintmax_t
+#define NAME strtoumax
+#include "strtox.c"
diff --git a/klibc/klibc/strtox.c b/klibc/klibc/strtox.c
new file mode 100644
index 0000000000..7c228b6fa4
--- /dev/null
+++ b/klibc/klibc/strtox.c
@@ -0,0 +1,13 @@
+/*
+ * strtox.c
+ *
+ * strto...() functions, by macro definition
+ */
+
+#include <stddef.h>
+#include <inttypes.h>
+
+TYPE NAME (const char *nptr, char **endptr, int base)
+{
+ return (TYPE) strntoumax(nptr, endptr, base, ~(size_t)0);
+}
diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl
new file mode 100644
index 0000000000..b530a9b8c7
--- /dev/null
+++ b/klibc/klibc/syscalls.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+($arch, $file) = @ARGV;
+
+if (!open(FILE, "< $file")) {
+ print STDERR "$file: $!\n";
+ exit(1);
+}
+
+while ( defined($line = <FILE>) ) {
+ chomp $line;
+ $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks
+ next unless $line;
+
+ if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([^\(\<\>]+[^\@\:A-Za-z0-9_])([A-Za-z0-9_]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*$/ ) {
+ $archs = $1;
+ $type = $2;
+ $sname = $3;
+ $stype = $4;
+ $fname = $5;
+ $argv = $6;
+
+ $doit = 1;
+ if ( $archs ne '' ) {
+ die "$0: Internal error"
+ unless ( $archs =~ /^\<(|\!)([^\>\!]+)\>/ );
+ $not = $1;
+ $list = $2;
+
+ $doit = ($not eq '') ? 0 : 1;
+
+ @list = split(/,/, $list);
+ foreach $a ( @list ) {
+ if ( $a eq $arch ) {
+ $doit = ($not eq '') ? 1 : 0;
+ last;
+ }
+ }
+ }
+ next if ( ! $doit );
+
+ $type =~ s/\s*$//;
+
+ $stype =~ s/^\@/_/;
+
+ if ( $fname eq '' ) {
+ $fname = $sname;
+ } else {
+ $fname =~ s/^\:\://;
+ }
+
+ @args = split(/\s*\,\s*/, $argv);
+
+ open(OUT, "> syscalls/${fname}.c")
+ or die "$0: Cannot open syscalls/${fname}.c\n";
+
+ if ( $fname eq "rt_sigaction") {
+ print OUT "#ifdef __x86_64__\n\n";
+ print OUT "struct sigaction;\n\n";
+ print OUT "#endif\n\n"
+ }
+
+ print OUT "#include \"syscommon.h\"\n\n";
+
+ if ( $fname ne $sname ) {
+ print OUT "#undef __NR_${fname}\n";
+ print OUT "#define __NR_${fname} __NR_${sname}\n\n";
+ }
+
+ print OUT "_syscall", scalar(@args), $stype, "(", $type, ',', $fname;
+
+ $i = 0;
+ foreach $arg ( @args ) {
+ print OUT ",", $arg, ",a",$i++;
+ }
+ print OUT ");\n";
+ close(OUT);
+ } else {
+ print STDERR "$file:$.: Could not parse input\n";
+ exit(1);
+ }
+}
diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h
new file mode 100644
index 0000000000..224e240e38
--- /dev/null
+++ b/klibc/klibc/syscommon.h
@@ -0,0 +1,29 @@
+/*
+ * syscommon.h
+ *
+ * Common header file for system call stubs
+ */
+
+#define __IN_SYS_COMMON
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+#include <poll.h>
+#include <sched.h>
+#include <sys/dirent.h>
+#include <sys/klog.h>
+#include <sys/mman.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/select.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/uio.h>
+#include <sys/utime.h>
+#include <sys/utsname.h>
+#include <sys/vfs.h>
+#include <sys/wait.h>
+#include <unistd.h>
diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c
new file mode 100644
index 0000000000..b031d4f0e7
--- /dev/null
+++ b/klibc/klibc/syslog.c
@@ -0,0 +1,74 @@
+/*
+ * syslog.c
+ *
+ * Issue syslog messages via the kernel printk queue.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* Maximum size for a kernel message */
+#define BUFLEN 1024
+
+/* Logging node */
+#define LOGDEV "/dev/kmsg"
+
+/* Max length of ID string */
+#define MAXID 31
+
+int __syslog_fd = -1;
+static char id[MAXID+1];
+
+void openlog(const char *ident, int option, int facility)
+{
+ int fd;
+
+ (void)option; (void)facility; /* Unused */
+
+ if ( __syslog_fd == -1 ) {
+ __syslog_fd = fd = open(LOGDEV, O_WRONLY);
+ if ( fd == -1 )
+ return;
+ fcntl(fd, F_SETFD, (long)FD_CLOEXEC);
+ }
+
+ strncpy(id, ident?ident:"", MAXID);
+ id[MAXID] = '\0'; /* Make sure it's null-terminated */
+}
+
+void syslog(int prio, const char *format, ...)
+{
+ va_list ap;
+ char buf[BUFLEN];
+ int rv, len;
+ int fd;
+
+ if ( __syslog_fd == -1 )
+ openlog(NULL, 0, 0);
+
+ fd = __syslog_fd;
+ if ( fd == -1 )
+ fd = 2; /* Failed to open log, write to stderr */
+
+ buf[0] = '<';
+ buf[1] = LOG_PRI(prio)+'0';
+ buf[2] = '>';
+ len = 3;
+
+ if ( *id )
+ len += sprintf(buf+3, "%s: ", id);
+
+ va_start(ap, format);
+ rv = vsnprintf(buf+len, BUFLEN-len, format, ap);
+ va_end(ap);
+
+ len += rv;
+ if ( len > BUFLEN-1 ) len = BUFLEN-1;
+ buf[len] = '\n';
+
+ write(fd, buf, len+1);
+}
diff --git a/klibc/klibc/system.c b/klibc/klibc/system.c
new file mode 100644
index 0000000000..643bf5e1cc
--- /dev/null
+++ b/klibc/klibc/system.c
@@ -0,0 +1,61 @@
+/*
+ * system.c
+ *
+ * The system() function. If this turns out to actually be *used*,
+ * we may want to try to detect the very simple cases (no shell magic)
+ * and handle them internally, instead of requiring that /bin/sh be
+ * present.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+int system(const char *string)
+{
+ pid_t pid;
+ struct sigaction ignore, old_int, old_quit;
+ sigset_t masked, oldmask;
+ static const char *argv[] = { "/bin/sh", "-c", NULL, NULL };
+ int status;
+
+ /* Block SIGCHLD and ignore SIGINT and SIGQUIT */
+ /* Do this before the fork() to avoid races */
+
+ ignore.sa_handler = SIG_IGN;
+ sigemptyset(&ignore.sa_mask);
+ ignore.sa_flags = 0;
+ sigaction(SIGINT, &ignore, &old_int);
+ sigaction(SIGQUIT, &ignore, &old_quit);
+
+ sigemptyset(&masked);
+ sigaddset(&masked, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &masked, &oldmask);
+
+ pid = fork();
+
+ if ( pid < 0 )
+ return -1;
+ else if ( pid == 0 ) {
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+
+ argv[2] = string;
+
+ execve(argv[0], (char * const *)argv, (char * const *)environ);
+ _exit(127);
+ }
+
+ /* else... */
+
+ waitpid(pid, &status, 0);
+
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+
+ return status;
+}
diff --git a/klibc/klibc/tests/getenvtest.c b/klibc/klibc/tests/getenvtest.c
new file mode 100644
index 0000000000..07cac0cef7
--- /dev/null
+++ b/klibc/klibc/tests/getenvtest.c
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[], char *envp[])
+{
+ int i;
+
+ /* Verify envp == environ */
+ printf("Verifying envp == environ... %s\n",
+ (envp == environ) ? "ok" : "ERROR");
+
+ /* Test argc/argv */
+ printf("argc = %d, argv = %p\n", argc, argv);
+ for ( i = 0 ; i < argc ; i++ ) {
+ printf("argv[%2d] = %s\n", i, argv[i]);
+ }
+
+ /* Test environ */
+ printf("PATH = %s\n", getenv("PATH"));
+ printf("HOME = %s\n", getenv("HOME"));
+ printf("TERM = %s\n", getenv("TERM"));
+ printf("USER = %s\n", getenv("USER"));
+
+ return 0;
+}
diff --git a/klibc/klibc/tests/getopttest.c b/klibc/klibc/tests/getopttest.c
new file mode 100644
index 0000000000..90ceaa2c58
--- /dev/null
+++ b/klibc/klibc/tests/getopttest.c
@@ -0,0 +1,31 @@
+/*
+ * getopttest.c
+ *
+ * Simple test for getopt, set the environment variable GETOPTTEST
+ * to give the argument string to getopt()
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int main(int argc, char * const *argv)
+{
+ const char *parser;
+ char showchar[] = "\'?\'";
+ int c;
+
+ parser = getenv("GETOPTTEST");
+ if ( !parser ) parser = "abzf:o:";
+
+ do {
+ c = getopt(argc, argv, parser);
+ showchar[1] = c;
+ printf("c = %s, optind = %d (%s), optarg = \"%s\", optopt = \'%c\'\n",
+ (c == EOF) ? "EOF" : showchar,
+ optind, argv[optind], optarg, optopt);
+ } while ( c != -1 );
+
+ return 0;
+}
+
diff --git a/klibc/klibc/tests/hello.c b/klibc/klibc/tests/hello.c
new file mode 100644
index 0000000000..20457af153
--- /dev/null
+++ b/klibc/klibc/tests/hello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+ printf("Hello, World!\n");
+ return 0;
+}
diff --git a/klibc/klibc/tests/idtest.c b/klibc/klibc/tests/idtest.c
new file mode 100644
index 0000000000..c3c44479c5
--- /dev/null
+++ b/klibc/klibc/tests/idtest.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void)
+{
+ printf("pid = %u\n", getpid());
+ printf("ppid = %u\n", getppid());
+ printf("uid = %u\n", getuid());
+ printf("euid = %u\n", geteuid());
+ printf("gid = %u\n", getgid());
+ printf("egid = %u\n", getegid());
+ sleep(10);
+ return 0;
+}
diff --git a/klibc/klibc/tests/malloctest.c b/klibc/klibc/tests/malloctest.c
new file mode 100644
index 0000000000..64e8e79851
--- /dev/null
+++ b/klibc/klibc/tests/malloctest.c
@@ -0,0 +1,4145 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define NCYCLES 4096
+
+int sizes[NCYCLES] = {
+ 11986,
+ 277806,
+ 2659,
+ 46,
+ 0,
+ 775553,
+ 1991,
+ 21,
+ 7638,
+ 250197,
+ 155828,
+ 5777,
+ 9,
+ 315006,
+ 900788,
+ 0,
+ 24893,
+ 119996,
+ 72299,
+ 171266,
+ 357,
+ 560,
+ 368,
+ 22952,
+ 54058,
+ 12638,
+ 39155,
+ 2738,
+ 217563,
+ 26853,
+ 47,
+ 75,
+ 1167,
+ 16917,
+ 1899,
+ 2905,
+ 9337,
+ 62243,
+ 14214,
+ 270523,
+ 4024,
+ 21,
+ 32,
+ 14892,
+ 625144,
+ 13,
+ 21700,
+ 8804,
+ 254147,
+ 0,
+ 6,
+ 836004,
+ 1718,
+ 2289,
+ 15554,
+ 412857,
+ 185097,
+ 806709,
+ 64,
+ 18602,
+ 17064,
+ 1779,
+ 78153,
+ 170600,
+ 199100,
+ 546528,
+ 0,
+ 21,
+ 20609,
+ 16514,
+ 548196,
+ 311446,
+ 53484,
+ 0,
+ 551,
+ 22225,
+ 24,
+ 153989,
+ 457309,
+ 526833,
+ 227979,
+ 757167,
+ 429560,
+ 0,
+ 835,
+ 1702,
+ 475275,
+ 798416,
+ 753,
+ 0,
+ 11126,
+ 145779,
+ 2006,
+ 0,
+ 8182,
+ 0,
+ 569432,
+ 9671,
+ 36,
+ 5523,
+ 407325,
+ 0,
+ 65,
+ 9293,
+ 0,
+ 6793,
+ 468701,
+ 73,
+ 0,
+ 186236,
+ 0,
+ 328405,
+ 125616,
+ 508013,
+ 380519,
+ 599518,
+ 83,
+ 151973,
+ 466906,
+ 9029,
+ 159725,
+ 1316,
+ 1,
+ 911532,
+ 1508,
+ 19050,
+ 972850,
+ 126,
+ 439377,
+ 29,
+ 37928,
+ 149628,
+ 54,
+ 130248,
+ 2,
+ 143,
+ 0,
+ 716873,
+ 3327,
+ 5,
+ 116131,
+ 5124,
+ 559621,
+ 2886,
+ 534,
+ 186432,
+ 441,
+ 7348,
+ 10331,
+ 1,
+ 260935,
+ 7,
+ 4370,
+ 405415,
+ 2,
+ 84518,
+ 1970,
+ 1,
+ 281910,
+ 46,
+ 274,
+ 2273,
+ 370565,
+ 4190,
+ 820641,
+ 577970,
+ 32809,
+ 974893,
+ 398067,
+ 380698,
+ 4,
+ 25978,
+ 153,
+ 882668,
+ 312365,
+ 9523,
+ 156421,
+ 0,
+ 268143,
+ 6,
+ 2,
+ 42987,
+ 212,
+ 12303,
+ 6723,
+ 1179,
+ 0,
+ 120924,
+ 3877,
+ 330421,
+ 310445,
+ 39264,
+ 8,
+ 85380,
+ 464716,
+ 0,
+ 33657,
+ 6285,
+ 0,
+ 4491,
+ 229,
+ 50,
+ 373197,
+ 6029,
+ 19,
+ 86884,
+ 243745,
+ 335656,
+ 90945,
+ 38973,
+ 572950,
+ 164129,
+ 0,
+ 3,
+ 17,
+ 13579,
+ 4448,
+ 47,
+ 3,
+ 132966,
+ 726249,
+ 498503,
+ 256,
+ 0,
+ 25841,
+ 0,
+ 7,
+ 945380,
+ 11872,
+ 69,
+ 3799,
+ 77223,
+ 1914,
+ 73,
+ 810968,
+ 10223,
+ 257918,
+ 184252,
+ 350,
+ 8101,
+ 725,
+ 9,
+ 2,
+ 2089,
+ 175,
+ 247,
+ 185964,
+ 36517,
+ 3723,
+ 313465,
+ 209,
+ 1300,
+ 128071,
+ 7425,
+ 2436,
+ 62,
+ 13753,
+ 9514,
+ 41,
+ 409141,
+ 46643,
+ 20866,
+ 15664,
+ 388548,
+ 84692,
+ 9549,
+ 610,
+ 7213,
+ 14,
+ 14930,
+ 244719,
+ 4748,
+ 41682,
+ 401098,
+ 102506,
+ 176535,
+ 0,
+ 5133,
+ 548,
+ 5234,
+ 56,
+ 11101,
+ 87638,
+ 336579,
+ 291705,
+ 640250,
+ 768165,
+ 370,
+ 2809,
+ 3,
+ 0,
+ 445122,
+ 47190,
+ 24885,
+ 143556,
+ 84,
+ 504726,
+ 610020,
+ 40355,
+ 902230,
+ 4360,
+ 1747,
+ 3496,
+ 489501,
+ 19,
+ 801601,
+ 62189,
+ 48,
+ 2645,
+ 320601,
+ 27304,
+ 17740,
+ 344,
+ 10,
+ 991,
+ 925503,
+ 0,
+ 315,
+ 251,
+ 3611,
+ 1756,
+ 683,
+ 165,
+ 380132,
+ 181101,
+ 453041,
+ 892056,
+ 67191,
+ 252592,
+ 32407,
+ 56242,
+ 8,
+ 297173,
+ 542903,
+ 830334,
+ 585236,
+ 422555,
+ 44769,
+ 0,
+ 68,
+ 4143,
+ 38754,
+ 73539,
+ 44579,
+ 94001,
+ 428537,
+ 38554,
+ 106612,
+ 0,
+ 182987,
+ 831731,
+ 3605,
+ 752851,
+ 52,
+ 72,
+ 120872,
+ 963754,
+ 31,
+ 764,
+ 240592,
+ 99101,
+ 328538,
+ 440325,
+ 12211,
+ 151282,
+ 353436,
+ 2991,
+ 40710,
+ 5212,
+ 5106,
+ 139122,
+ 148915,
+ 498505,
+ 1366,
+ 516,
+ 29190,
+ 17,
+ 224208,
+ 40,
+ 89,
+ 19190,
+ 8,
+ 25377,
+ 10029,
+ 720,
+ 97963,
+ 0,
+ 614,
+ 244567,
+ 2113,
+ 903675,
+ 8388,
+ 6,
+ 390705,
+ 325006,
+ 284272,
+ 108086,
+ 17,
+ 2628,
+ 952530,
+ 20474,
+ 898276,
+ 138661,
+ 3883,
+ 903,
+ 569993,
+ 376918,
+ 5849,
+ 103404,
+ 794499,
+ 35388,
+ 5,
+ 0,
+ 961626,
+ 27415,
+ 1927,
+ 92036,
+ 46241,
+ 35978,
+ 7426,
+ 399884,
+ 29490,
+ 252655,
+ 675971,
+ 3509,
+ 54170,
+ 170790,
+ 831341,
+ 134579,
+ 0,
+ 790422,
+ 35,
+ 930830,
+ 97394,
+ 20265,
+ 670,
+ 38497,
+ 1759,
+ 71209,
+ 93,
+ 736,
+ 11,
+ 886,
+ 1961,
+ 7,
+ 210607,
+ 62226,
+ 186736,
+ 1518,
+ 5,
+ 5,
+ 13,
+ 66989,
+ 442321,
+ 0,
+ 607939,
+ 11253,
+ 210875,
+ 495530,
+ 2,
+ 221136,
+ 377663,
+ 372,
+ 200658,
+ 18591,
+ 129783,
+ 803411,
+ 867506,
+ 757446,
+ 48836,
+ 34,
+ 200,
+ 114983,
+ 7287,
+ 22849,
+ 226669,
+ 13,
+ 0,
+ 20164,
+ 7828,
+ 39,
+ 49448,
+ 26740,
+ 185566,
+ 9927,
+ 36192,
+ 91068,
+ 338368,
+ 926,
+ 27746,
+ 534794,
+ 936132,
+ 2922,
+ 5,
+ 183162,
+ 256846,
+ 242551,
+ 134318,
+ 212959,
+ 167162,
+ 470,
+ 477045,
+ 532116,
+ 483794,
+ 733,
+ 5335,
+ 83074,
+ 4686,
+ 9567,
+ 1,
+ 195100,
+ 40354,
+ 87338,
+ 369,
+ 800,
+ 0,
+ 194504,
+ 469051,
+ 363532,
+ 850574,
+ 5085,
+ 167027,
+ 794511,
+ 124320,
+ 303231,
+ 132195,
+ 13225,
+ 46333,
+ 4313,
+ 89,
+ 799,
+ 51482,
+ 0,
+ 26,
+ 12659,
+ 1045,
+ 23621,
+ 0,
+ 74926,
+ 490979,
+ 6,
+ 3188,
+ 9448,
+ 174730,
+ 38982,
+ 102317,
+ 189621,
+ 853,
+ 29227,
+ 43374,
+ 423,
+ 420951,
+ 686,
+ 128,
+ 31291,
+ 0,
+ 402819,
+ 663143,
+ 55903,
+ 142,
+ 2,
+ 331584,
+ 197164,
+ 7,
+ 671983,
+ 53,
+ 5020,
+ 9782,
+ 123,
+ 743407,
+ 1276,
+ 1115,
+ 1169,
+ 122752,
+ 824690,
+ 292030,
+ 2094,
+ 144626,
+ 0,
+ 297278,
+ 440,
+ 742,
+ 95879,
+ 17682,
+ 10654,
+ 31,
+ 22183,
+ 746,
+ 0,
+ 0,
+ 11185,
+ 28,
+ 394987,
+ 36,
+ 474,
+ 243749,
+ 1431,
+ 56702,
+ 76,
+ 15619,
+ 33071,
+ 12181,
+ 158647,
+ 261786,
+ 1,
+ 119783,
+ 48816,
+ 6278,
+ 4121,
+ 61122,
+ 69,
+ 48790,
+ 345335,
+ 275917,
+ 964393,
+ 424,
+ 586433,
+ 20519,
+ 18156,
+ 756400,
+ 27736,
+ 458706,
+ 1,
+ 3286,
+ 929624,
+ 1883,
+ 2,
+ 1086,
+ 439501,
+ 552,
+ 157132,
+ 5565,
+ 105061,
+ 8199,
+ 23,
+ 178797,
+ 0,
+ 130644,
+ 1,
+ 6952,
+ 754,
+ 500,
+ 647683,
+ 0,
+ 959079,
+ 622561,
+ 1131,
+ 559783,
+ 6862,
+ 175420,
+ 408671,
+ 463461,
+ 55908,
+ 606496,
+ 169,
+ 49060,
+ 247,
+ 953,
+ 333030,
+ 0,
+ 23399,
+ 29193,
+ 9303,
+ 15,
+ 515402,
+ 34961,
+ 365856,
+ 633043,
+ 173,
+ 556089,
+ 1809,
+ 12215,
+ 14,
+ 316,
+ 20642,
+ 9,
+ 15,
+ 190391,
+ 951463,
+ 25059,
+ 13654,
+ 385040,
+ 4272,
+ 929033,
+ 208813,
+ 35166,
+ 42849,
+ 662648,
+ 254811,
+ 4230,
+ 812459,
+ 681,
+ 390168,
+ 5381,
+ 4662,
+ 173257,
+ 478863,
+ 103,
+ 89332,
+ 0,
+ 0,
+ 589484,
+ 19369,
+ 94,
+ 9,
+ 639917,
+ 1110,
+ 393,
+ 101040,
+ 911,
+ 152899,
+ 0,
+ 2,
+ 0,
+ 0,
+ 335691,
+ 43694,
+ 62273,
+ 200121,
+ 2250,
+ 621004,
+ 149918,
+ 41063,
+ 218229,
+ 0,
+ 497924,
+ 16832,
+ 587071,
+ 0,
+ 0,
+ 729918,
+ 2,
+ 808513,
+ 9417,
+ 718,
+ 0,
+ 2769,
+ 28704,
+ 1335,
+ 734726,
+ 219157,
+ 786230,
+ 981004,
+ 350788,
+ 884529,
+ 0,
+ 87872,
+ 34647,
+ 85469,
+ 4524,
+ 339838,
+ 38228,
+ 0,
+ 4151,
+ 1145,
+ 0,
+ 351,
+ 167956,
+ 810075,
+ 689,
+ 251212,
+ 583068,
+ 2929,
+ 189456,
+ 2089,
+ 48749,
+ 278952,
+ 77134,
+ 0,
+ 0,
+ 45595,
+ 281829,
+ 969602,
+ 43999,
+ 69824,
+ 856982,
+ 61732,
+ 336,
+ 25488,
+ 213,
+ 46683,
+ 1909,
+ 174097,
+ 57930,
+ 91466,
+ 828418,
+ 95740,
+ 378828,
+ 128065,
+ 68068,
+ 0,
+ 13312,
+ 26006,
+ 6760,
+ 51,
+ 276081,
+ 640068,
+ 634985,
+ 7131,
+ 784882,
+ 790126,
+ 628585,
+ 205824,
+ 764965,
+ 17793,
+ 3159,
+ 649924,
+ 0,
+ 37383,
+ 9919,
+ 353,
+ 0,
+ 149003,
+ 620629,
+ 95928,
+ 2560,
+ 504343,
+ 1000,
+ 32,
+ 43836,
+ 407031,
+ 207,
+ 800894,
+ 3222,
+ 51028,
+ 7,
+ 6,
+ 22010,
+ 0,
+ 21174,
+ 12893,
+ 824932,
+ 7305,
+ 70,
+ 624258,
+ 372139,
+ 21504,
+ 387996,
+ 418931,
+ 914268,
+ 576,
+ 0,
+ 0,
+ 618224,
+ 787516,
+ 133014,
+ 422,
+ 383124,
+ 656318,
+ 4420,
+ 6082,
+ 244813,
+ 38585,
+ 3200,
+ 1,
+ 2,
+ 11882,
+ 113,
+ 45581,
+ 13121,
+ 95475,
+ 807219,
+ 8195,
+ 995116,
+ 13,
+ 2146,
+ 369925,
+ 60103,
+ 25,
+ 125165,
+ 51300,
+ 4894,
+ 173261,
+ 74186,
+ 1044,
+ 122992,
+ 1243,
+ 21703,
+ 26294,
+ 197,
+ 333825,
+ 426872,
+ 719580,
+ 3598,
+ 106,
+ 0,
+ 9932,
+ 61509,
+ 146,
+ 721428,
+ 964781,
+ 319850,
+ 573802,
+ 7458,
+ 317889,
+ 0,
+ 133086,
+ 87836,
+ 60496,
+ 304249,
+ 1565,
+ 27,
+ 42,
+ 899324,
+ 189637,
+ 8648,
+ 104570,
+ 901598,
+ 447765,
+ 24,
+ 108,
+ 120127,
+ 828626,
+ 8,
+ 899514,
+ 28,
+ 13,
+ 7576,
+ 163390,
+ 1625,
+ 3023,
+ 155175,
+ 2,
+ 391,
+ 1,
+ 493073,
+ 398,
+ 210771,
+ 26266,
+ 287999,
+ 38255,
+ 249666,
+ 598202,
+ 119601,
+ 216933,
+ 91205,
+ 0,
+ 7247,
+ 77077,
+ 565383,
+ 29102,
+ 253641,
+ 48855,
+ 19722,
+ 463536,
+ 40182,
+ 65393,
+ 829444,
+ 598402,
+ 1590,
+ 798,
+ 467,
+ 834847,
+ 3007,
+ 13711,
+ 0,
+ 195,
+ 101662,
+ 255749,
+ 129201,
+ 11965,
+ 1781,
+ 13349,
+ 3100,
+ 718066,
+ 99,
+ 712450,
+ 888215,
+ 42503,
+ 43171,
+ 494946,
+ 0,
+ 2175,
+ 12387,
+ 25662,
+ 78,
+ 739030,
+ 0,
+ 19,
+ 427526,
+ 4275,
+ 5583,
+ 0,
+ 2447,
+ 132398,
+ 26437,
+ 3873,
+ 440035,
+ 21,
+ 6,
+ 35432,
+ 41523,
+ 7179,
+ 712703,
+ 428868,
+ 2793,
+ 6,
+ 286277,
+ 1882,
+ 95116,
+ 2959,
+ 86,
+ 115425,
+ 81386,
+ 59836,
+ 37,
+ 247598,
+ 34732,
+ 249,
+ 500110,
+ 5589,
+ 40319,
+ 575,
+ 12145,
+ 385829,
+ 565600,
+ 582150,
+ 92,
+ 223209,
+ 0,
+ 910,
+ 1048,
+ 47329,
+ 90944,
+ 235,
+ 8739,
+ 686685,
+ 1753,
+ 126,
+ 434,
+ 609477,
+ 25021,
+ 6610,
+ 52675,
+ 4,
+ 717846,
+ 150864,
+ 418583,
+ 17751,
+ 513794,
+ 181362,
+ 329556,
+ 10426,
+ 717019,
+ 457,
+ 616,
+ 388984,
+ 17,
+ 8338,
+ 59531,
+ 32,
+ 99565,
+ 376146,
+ 134578,
+ 966,
+ 0,
+ 0,
+ 174,
+ 2105,
+ 555,
+ 8990,
+ 298,
+ 169932,
+ 247281,
+ 240918,
+ 298655,
+ 158743,
+ 15994,
+ 95708,
+ 51,
+ 2985,
+ 4294,
+ 731934,
+ 185640,
+ 1483,
+ 87,
+ 742033,
+ 9,
+ 1345,
+ 3680,
+ 133530,
+ 9355,
+ 800111,
+ 28508,
+ 0,
+ 369,
+ 31681,
+ 24,
+ 8237,
+ 313380,
+ 4732,
+ 275423,
+ 951592,
+ 0,
+ 41381,
+ 225515,
+ 393004,
+ 526,
+ 187,
+ 19515,
+ 6006,
+ 28923,
+ 310151,
+ 2390,
+ 374,
+ 0,
+ 19142,
+ 72,
+ 114,
+ 193305,
+ 24035,
+ 397067,
+ 18,
+ 14839,
+ 3473,
+ 164,
+ 104622,
+ 378958,
+ 2218,
+ 0,
+ 89053,
+ 105183,
+ 312265,
+ 82146,
+ 147210,
+ 3419,
+ 5178,
+ 34948,
+ 46836,
+ 41319,
+ 842825,
+ 595972,
+ 0,
+ 249625,
+ 325,
+ 608,
+ 372328,
+ 119634,
+ 7504,
+ 920214,
+ 7302,
+ 444532,
+ 359213,
+ 27265,
+ 1755,
+ 48,
+ 126799,
+ 651270,
+ 818220,
+ 799493,
+ 724024,
+ 64047,
+ 73699,
+ 206999,
+ 209,
+ 1581,
+ 0,
+ 42937,
+ 301144,
+ 73416,
+ 0,
+ 242058,
+ 29660,
+ 3,
+ 34709,
+ 162719,
+ 2863,
+ 3992,
+ 5212,
+ 151814,
+ 3092,
+ 198001,
+ 44331,
+ 36,
+ 407,
+ 364771,
+ 1349,
+ 502772,
+ 214726,
+ 607,
+ 388583,
+ 137660,
+ 337124,
+ 13279,
+ 10549,
+ 943075,
+ 164068,
+ 19157,
+ 38443,
+ 26351,
+ 0,
+ 67167,
+ 735,
+ 46486,
+ 130305,
+ 232330,
+ 744,
+ 882337,
+ 2,
+ 69275,
+ 126354,
+ 9370,
+ 2845,
+ 299,
+ 38988,
+ 37834,
+ 0,
+ 306433,
+ 9139,
+ 237132,
+ 0,
+ 500,
+ 13462,
+ 373684,
+ 107453,
+ 381924,
+ 347915,
+ 4329,
+ 1668,
+ 3960,
+ 370661,
+ 3614,
+ 636048,
+ 0,
+ 487449,
+ 64925,
+ 333894,
+ 11,
+ 52192,
+ 531200,
+ 155554,
+ 461,
+ 1547,
+ 994361,
+ 11955,
+ 321056,
+ 37425,
+ 14249,
+ 69151,
+ 621862,
+ 174,
+ 79607,
+ 34,
+ 77577,
+ 13723,
+ 267550,
+ 13801,
+ 698,
+ 12,
+ 171556,
+ 57354,
+ 676845,
+ 0,
+ 24965,
+ 908955,
+ 570483,
+ 0,
+ 296387,
+ 983966,
+ 85012,
+ 130298,
+ 151946,
+ 384474,
+ 731455,
+ 150699,
+ 772,
+ 216131,
+ 346,
+ 130935,
+ 3472,
+ 18,
+ 426045,
+ 677262,
+ 808,
+ 17030,
+ 5188,
+ 0,
+ 491153,
+ 67299,
+ 19,
+ 60342,
+ 69,
+ 0,
+ 76478,
+ 95763,
+ 0,
+ 28778,
+ 147869,
+ 335927,
+ 27846,
+ 2163,
+ 22750,
+ 162,
+ 23,
+ 11391,
+ 469099,
+ 5852,
+ 63,
+ 0,
+ 0,
+ 22193,
+ 165,
+ 489007,
+ 9249,
+ 12477,
+ 2841,
+ 223532,
+ 13877,
+ 173,
+ 3570,
+ 45477,
+ 233073,
+ 23296,
+ 64377,
+ 4910,
+ 8,
+ 76246,
+ 411147,
+ 287411,
+ 10450,
+ 3667,
+ 1,
+ 500933,
+ 31363,
+ 257,
+ 1705,
+ 6036,
+ 49934,
+ 13738,
+ 13485,
+ 61608,
+ 561978,
+ 76493,
+ 16377,
+ 1817,
+ 0,
+ 235600,
+ 0,
+ 16347,
+ 680478,
+ 5115,
+ 895607,
+ 138270,
+ 369912,
+ 53110,
+ 0,
+ 647083,
+ 85,
+ 458681,
+ 163227,
+ 52767,
+ 196,
+ 267719,
+ 14047,
+ 147293,
+ 814457,
+ 174896,
+ 0,
+ 34138,
+ 36,
+ 21575,
+ 3,
+ 0,
+ 0,
+ 38391,
+ 2597,
+ 2,
+ 1433,
+ 3807,
+ 36476,
+ 287,
+ 141530,
+ 29389,
+ 495655,
+ 30014,
+ 0,
+ 550766,
+ 11958,
+ 348,
+ 226760,
+ 15,
+ 251353,
+ 675788,
+ 518308,
+ 215,
+ 81987,
+ 409862,
+ 559596,
+ 114283,
+ 4925,
+ 0,
+ 17,
+ 14221,
+ 0,
+ 162,
+ 766370,
+ 4898,
+ 998,
+ 493,
+ 138418,
+ 265159,
+ 12152,
+ 5229,
+ 1204,
+ 1814,
+ 432530,
+ 2889,
+ 144,
+ 1149,
+ 35886,
+ 636931,
+ 6640,
+ 1508,
+ 414118,
+ 858,
+ 20039,
+ 17398,
+ 3,
+ 5094,
+ 6,
+ 13996,
+ 6754,
+ 362,
+ 451487,
+ 11471,
+ 7896,
+ 330009,
+ 244269,
+ 99928,
+ 0,
+ 14311,
+ 9949,
+ 15251,
+ 283923,
+ 123754,
+ 188360,
+ 93902,
+ 854384,
+ 548001,
+ 531788,
+ 26298,
+ 328479,
+ 941,
+ 246535,
+ 106320,
+ 28769,
+ 440,
+ 4,
+ 61262,
+ 55615,
+ 170,
+ 989327,
+ 692534,
+ 8063,
+ 445842,
+ 4434,
+ 255349,
+ 117781,
+ 6,
+ 9249,
+ 136216,
+ 38165,
+ 307012,
+ 12,
+ 2341,
+ 18062,
+ 371882,
+ 662154,
+ 12623,
+ 176847,
+ 332220,
+ 590935,
+ 33682,
+ 0,
+ 121374,
+ 67,
+ 46841,
+ 495890,
+ 640,
+ 19,
+ 14737,
+ 11032,
+ 17,
+ 5993,
+ 302562,
+ 827710,
+ 165346,
+ 49607,
+ 87863,
+ 308513,
+ 735300,
+ 1914,
+ 2900,
+ 207308,
+ 9068,
+ 83494,
+ 179,
+ 417,
+ 41605,
+ 74681,
+ 652171,
+ 4013,
+ 29811,
+ 13966,
+ 8136,
+ 78,
+ 61182,
+ 674187,
+ 0,
+ 331121,
+ 0,
+ 18559,
+ 386,
+ 77,
+ 348439,
+ 975358,
+ 18,
+ 33700,
+ 47396,
+ 204751,
+ 2350,
+ 26503,
+ 0,
+ 83653,
+ 446,
+ 10844,
+ 485,
+ 9241,
+ 88347,
+ 232419,
+ 936900,
+ 43250,
+ 2,
+ 26112,
+ 811955,
+ 20723,
+ 102069,
+ 42255,
+ 8431,
+ 119508,
+ 4080,
+ 13565,
+ 12,
+ 46110,
+ 62096,
+ 638777,
+ 44025,
+ 152985,
+ 13362,
+ 3,
+ 12331,
+ 193337,
+ 56419,
+ 14593,
+ 3837,
+ 282314,
+ 403454,
+ 48589,
+ 135,
+ 18350,
+ 2160,
+ 90,
+ 918216,
+ 7083,
+ 105534,
+ 742826,
+ 399028,
+ 1470,
+ 23770,
+ 480,
+ 677884,
+ 340472,
+ 107406,
+ 0,
+ 5002,
+ 445,
+ 748948,
+ 534012,
+ 592464,
+ 6539,
+ 819632,
+ 3138,
+ 4,
+ 39397,
+ 229683,
+ 12204,
+ 2439,
+ 65131,
+ 817226,
+ 22596,
+ 0,
+ 1046,
+ 94638,
+ 0,
+ 95403,
+ 1230,
+ 790056,
+ 19976,
+ 43085,
+ 14251,
+ 139187,
+ 20232,
+ 693,
+ 3058,
+ 27654,
+ 65690,
+ 40948,
+ 15001,
+ 21089,
+ 14425,
+ 322459,
+ 13571,
+ 228154,
+ 536814,
+ 761221,
+ 28030,
+ 2322,
+ 921,
+ 1,
+ 1137,
+ 187815,
+ 8,
+ 34911,
+ 4527,
+ 15,
+ 46,
+ 78801,
+ 0,
+ 73605,
+ 44,
+ 28233,
+ 1370,
+ 73409,
+ 198159,
+ 66586,
+ 3,
+ 2576,
+ 15,
+ 35460,
+ 263237,
+ 44997,
+ 2873,
+ 240,
+ 1781,
+ 269,
+ 46,
+ 272778,
+ 28404,
+ 8232,
+ 417073,
+ 234591,
+ 9,
+ 720349,
+ 1176,
+ 16195,
+ 0,
+ 9705,
+ 0,
+ 14,
+ 947048,
+ 163,
+ 76288,
+ 1115,
+ 267020,
+ 3416,
+ 414217,
+ 441004,
+ 95131,
+ 765002,
+ 6196,
+ 9069,
+ 27017,
+ 137039,
+ 65247,
+ 266489,
+ 484945,
+ 187008,
+ 45405,
+ 5700,
+ 9,
+ 7751,
+ 12,
+ 294,
+ 3093,
+ 6350,
+ 103303,
+ 6045,
+ 252345,
+ 140207,
+ 22390,
+ 234867,
+ 443326,
+ 1,
+ 0,
+ 89972,
+ 8637,
+ 427150,
+ 22146,
+ 0,
+ 310432,
+ 390333,
+ 10461,
+ 1632,
+ 31403,
+ 908653,
+ 0,
+ 6543,
+ 163479,
+ 67608,
+ 195543,
+ 315889,
+ 822964,
+ 383536,
+ 954954,
+ 1619,
+ 241,
+ 96053,
+ 104556,
+ 767302,
+ 2469,
+ 12,
+ 164330,
+ 78,
+ 141,
+ 170519,
+ 268214,
+ 53338,
+ 48342,
+ 721,
+ 58980,
+ 4345,
+ 1,
+ 856265,
+ 87289,
+ 57219,
+ 775679,
+ 123992,
+ 695804,
+ 113025,
+ 832,
+ 117420,
+ 16634,
+ 352,
+ 24729,
+ 14973,
+ 25622,
+ 131290,
+ 0,
+ 22,
+ 87740,
+ 5917,
+ 533,
+ 2934,
+ 34261,
+ 9174,
+ 0,
+ 1656,
+ 764587,
+ 54652,
+ 35597,
+ 36389,
+ 577889,
+ 63957,
+ 26808,
+ 34556,
+ 56,
+ 15641,
+ 137,
+ 1,
+ 3,
+ 11724,
+ 197397,
+ 39027,
+ 87902,
+ 320,
+ 791479,
+ 7,
+ 487864,
+ 0,
+ 433,
+ 25733,
+ 6956,
+ 15407,
+ 312557,
+ 526302,
+ 383019,
+ 340215,
+ 96,
+ 276158,
+ 6493,
+ 135613,
+ 2000,
+ 1218,
+ 930,
+ 276808,
+ 273249,
+ 8896,
+ 397,
+ 735095,
+ 20648,
+ 2079,
+ 5349,
+ 205,
+ 356313,
+ 841954,
+ 8255,
+ 266874,
+ 0,
+ 965,
+ 287993,
+ 1549,
+ 207833,
+ 75,
+ 178180,
+ 39072,
+ 0,
+ 43254,
+ 3847,
+ 227,
+ 2712,
+ 161043,
+ 463264,
+ 74720,
+ 795789,
+ 12,
+ 6812,
+ 202804,
+ 29379,
+ 64241,
+ 132121,
+ 790622,
+ 493588,
+ 0,
+ 48,
+ 147352,
+ 925197,
+ 38149,
+ 18380,
+ 0,
+ 270280,
+ 633,
+ 3373,
+ 31294,
+ 7830,
+ 0,
+ 0,
+ 11371,
+ 56143,
+ 5393,
+ 74724,
+ 495109,
+ 0,
+ 18993,
+ 21524,
+ 0,
+ 53889,
+ 400509,
+ 204563,
+ 0,
+ 11625,
+ 9635,
+ 0,
+ 1678,
+ 12096,
+ 59,
+ 817112,
+ 10002,
+ 128209,
+ 11593,
+ 17313,
+ 15200,
+ 106796,
+ 261401,
+ 707077,
+ 0,
+ 314030,
+ 798591,
+ 14175,
+ 5668,
+ 2766,
+ 0,
+ 566,
+ 5543,
+ 24112,
+ 154482,
+ 5642,
+ 0,
+ 38410,
+ 3,
+ 4,
+ 700724,
+ 25024,
+ 5,
+ 407,
+ 564150,
+ 672,
+ 143,
+ 2049,
+ 574708,
+ 65858,
+ 213412,
+ 3797,
+ 511,
+ 30907,
+ 1212,
+ 765,
+ 2127,
+ 481,
+ 130048,
+ 113816,
+ 39861,
+ 153169,
+ 503378,
+ 523944,
+ 111,
+ 55083,
+ 698,
+ 275,
+ 3,
+ 3195,
+ 1657,
+ 0,
+ 317881,
+ 6672,
+ 543,
+ 153011,
+ 77240,
+ 9338,
+ 889850,
+ 29518,
+ 872485,
+ 181927,
+ 376086,
+ 266,
+ 409,
+ 4,
+ 14856,
+ 31943,
+ 2448,
+ 8,
+ 75,
+ 383097,
+ 294366,
+ 0,
+ 173084,
+ 753160,
+ 66457,
+ 725783,
+ 51,
+ 127651,
+ 1073,
+ 12598,
+ 140080,
+ 0,
+ 296375,
+ 581720,
+ 217346,
+ 8272,
+ 2051,
+ 185390,
+ 520645,
+ 1260,
+ 13873,
+ 168040,
+ 19690,
+ 103347,
+ 295011,
+ 548404,
+ 48,
+ 4,
+ 916417,
+ 1948,
+ 621365,
+ 263245,
+ 2792,
+ 86803,
+ 181193,
+ 558081,
+ 50907,
+ 442770,
+ 51448,
+ 340276,
+ 1346,
+ 607,
+ 459627,
+ 0,
+ 30,
+ 73298,
+ 15389,
+ 12264,
+ 2719,
+ 2936,
+ 143043,
+ 209970,
+ 0,
+ 42,
+ 6657,
+ 317419,
+ 0,
+ 32622,
+ 524000,
+ 0,
+ 310331,
+ 303778,
+ 268710,
+ 9,
+ 10410,
+ 25343,
+ 949506,
+ 784353,
+ 3861,
+ 46823,
+ 251292,
+ 75008,
+ 269798,
+ 87731,
+ 112813,
+ 571679,
+ 385,
+ 3,
+ 2811,
+ 36025,
+ 9243,
+ 935128,
+ 906,
+ 10688,
+ 25,
+ 86757,
+ 307,
+ 55,
+ 22,
+ 2,
+ 61,
+ 620426,
+ 484530,
+ 633806,
+ 0,
+ 1342,
+ 9293,
+ 992181,
+ 503,
+ 195433,
+ 46150,
+ 893091,
+ 3207,
+ 2865,
+ 72894,
+ 830299,
+ 355,
+ 327479,
+ 0,
+ 35573,
+ 3068,
+ 15699,
+ 31187,
+ 55378,
+ 416067,
+ 91721,
+ 159,
+ 0,
+ 255139,
+ 2104,
+ 19,
+ 606757,
+ 323,
+ 902659,
+ 365655,
+ 400,
+ 903,
+ 408,
+ 385,
+ 21774,
+ 701290,
+ 234426,
+ 17020,
+ 950,
+ 0,
+ 0,
+ 429,
+ 1245,
+ 405871,
+ 1097,
+ 280634,
+ 74,
+ 158233,
+ 1583,
+ 180333,
+ 42114,
+ 575973,
+ 539327,
+ 59252,
+ 121928,
+ 165,
+ 148501,
+ 55757,
+ 7494,
+ 127728,
+ 7832,
+ 68504,
+ 619770,
+ 70995,
+ 312816,
+ 7307,
+ 38265,
+ 46248,
+ 363304,
+ 269442,
+ 77112,
+ 448331,
+ 910442,
+ 474418,
+ 152752,
+ 752,
+ 104912,
+ 408492,
+ 691709,
+ 632381,
+ 48519,
+ 20524,
+ 344294,
+ 14670,
+ 0,
+ 21607,
+ 81162,
+ 181458,
+ 0,
+ 908322,
+ 7261,
+ 10888,
+ 58054,
+ 1788,
+ 970933,
+ 5925,
+ 121553,
+ 36152,
+ 588267,
+ 23615,
+ 1850,
+ 30728,
+ 3599,
+ 1319,
+ 6027,
+ 0,
+ 32141,
+ 984156,
+ 436781,
+ 15003,
+ 621407,
+ 9412,
+ 562911,
+ 189740,
+ 377895,
+ 656800,
+ 197,
+ 14413,
+ 99382,
+ 384,
+ 11480,
+ 0,
+ 86118,
+ 881961,
+ 1905,
+ 82061,
+ 4140,
+ 741153,
+ 26,
+ 687,
+ 12251,
+ 10945,
+ 209267,
+ 220602,
+ 135881,
+ 6,
+ 237945,
+ 158,
+ 5,
+ 76303,
+ 81344,
+ 986042,
+ 956063,
+ 30282,
+ 186055,
+ 357802,
+ 12492,
+ 577476,
+ 838,
+ 0,
+ 11,
+ 117602,
+ 0,
+ 187928,
+ 96860,
+ 4268,
+ 3478,
+ 818264,
+ 1649,
+ 17175,
+ 272,
+ 158951,
+ 440987,
+ 677594,
+ 14935,
+ 37953,
+ 0,
+ 198,
+ 160404,
+ 12,
+ 287803,
+ 2386,
+ 10,
+ 271663,
+ 319152,
+ 361322,
+ 68370,
+ 428,
+ 182707,
+ 387429,
+ 1152,
+ 360065,
+ 25218,
+ 2790,
+ 42228,
+ 13,
+ 110942,
+ 452491,
+ 1,
+ 665638,
+ 2308,
+ 1196,
+ 87306,
+ 66,
+ 219,
+ 0,
+ 130736,
+ 334,
+ 605,
+ 5979,
+ 2681,
+ 0,
+ 123463,
+ 11219,
+ 283681,
+ 19269,
+ 553,
+ 6217,
+ 130965,
+ 714409,
+ 242,
+ 674833,
+ 237581,
+ 133284,
+ 683,
+ 1758,
+ 278193,
+ 518726,
+ 44,
+ 420361,
+ 325228,
+ 14955,
+ 10,
+ 11994,
+ 64157,
+ 1937,
+ 20214,
+ 848,
+ 27804,
+ 151341,
+ 79236,
+ 316393,
+ 158883,
+ 1196,
+ 334,
+ 22797,
+ 185955,
+ 13857,
+ 397357,
+ 7948,
+ 6038,
+ 0,
+ 2621,
+ 16,
+ 155267,
+ 44809,
+ 9171,
+ 21328,
+ 12212,
+ 40200,
+ 2600,
+ 439,
+ 804014,
+ 10938,
+ 96135,
+ 43696,
+ 158715,
+ 4,
+ 284558,
+ 191,
+ 270254,
+ 7923,
+ 880603,
+ 21032,
+ 107700,
+ 172,
+ 700823,
+ 5613,
+ 78816,
+ 258290,
+ 214398,
+ 821856,
+ 295325,
+ 0,
+ 1,
+ 23559,
+ 63895,
+ 21249,
+ 717490,
+ 956952,
+ 944819,
+ 793,
+ 356,
+ 757716,
+ 111773,
+ 394826,
+ 25665,
+ 4358,
+ 640216,
+ 1152,
+ 37175,
+ 150192,
+ 106071,
+ 28992,
+ 67,
+ 1685,
+ 134242,
+ 2,
+ 102045,
+ 1457,
+ 419589,
+ 6789,
+ 677,
+ 94675,
+ 11300,
+ 2595,
+ 8,
+ 926535,
+ 265194,
+ 0,
+ 886048,
+ 246242,
+ 1494,
+ 191,
+ 169985,
+ 649765,
+ 0,
+ 201,
+ 1069,
+ 679163,
+ 16627,
+ 274639,
+ 84438,
+ 3,
+ 1301,
+ 247496,
+ 5879,
+ 710904,
+ 403652,
+ 958241,
+ 361,
+ 139732,
+ 6042,
+ 15985,
+ 2378,
+ 267031,
+ 223767,
+ 9656,
+ 241717,
+ 33863,
+ 14314,
+ 205697,
+ 1274,
+ 168000,
+ 621777,
+ 837913,
+ 89654,
+ 659829,
+ 69,
+ 503884,
+ 432717,
+ 70443,
+ 110891,
+ 19655,
+ 132432,
+ 620401,
+ 428,
+ 0,
+ 425662,
+ 0,
+ 0,
+ 0,
+ 194489,
+ 7601,
+ 26870,
+ 0,
+ 63,
+ 594,
+ 12278,
+ 582479,
+ 213723,
+ 424489,
+ 96446,
+ 990664,
+ 46966,
+ 44137,
+ 829810,
+ 104,
+ 19707,
+ 16,
+ 0,
+ 2499,
+ 167075,
+ 140972,
+ 249283,
+ 6620,
+ 68368,
+ 856414,
+ 9255,
+ 14315,
+ 0,
+ 11432,
+ 24329,
+ 216463,
+ 299556,
+ 818401,
+ 246607,
+ 697733,
+ 229,
+ 144,
+ 389394,
+ 664634,
+ 0,
+ 19393,
+ 657903,
+ 52912,
+ 952177,
+ 536931,
+ 187271,
+ 17687,
+ 970155,
+ 232571,
+ 234016,
+ 159980,
+ 13510,
+ 32952,
+ 0,
+ 0,
+ 24132,
+ 18806,
+ 15624,
+ 28364,
+ 472126,
+ 626978,
+ 599,
+ 112843,
+ 502933,
+ 915660,
+ 63920,
+ 0,
+ 84,
+ 10899,
+ 904823,
+ 126,
+ 469132,
+ 590052,
+ 195831,
+ 443113,
+ 294149,
+ 15944,
+ 2271,
+ 282974,
+ 211,
+ 0,
+ 22934,
+ 82283,
+ 49973,
+ 41707,
+ 87530,
+ 0,
+ 910528,
+ 0,
+ 36029,
+ 423337,
+ 817512,
+ 223671,
+ 27800,
+ 398847,
+ 198528,
+ 1,
+ 560679,
+ 518270,
+ 23033,
+ 501059,
+ 0,
+ 3909,
+ 272062,
+ 261581,
+ 187,
+ 52043,
+ 334,
+ 24354,
+ 3947,
+ 8549,
+ 37863,
+ 328851,
+ 963771,
+ 1,
+ 3930,
+ 82416,
+ 6,
+ 2943,
+ 122101,
+ 82577,
+ 85,
+ 89540,
+ 5135,
+ 109236,
+ 18297,
+ 1,
+ 177371,
+ 4541,
+ 769577,
+ 178,
+ 417,
+ 960566,
+ 33803,
+ 911651,
+ 248160,
+ 153725,
+ 43981,
+ 809174,
+ 116,
+ 486900,
+ 4842,
+ 148490,
+ 131534,
+ 4347,
+ 239949,
+ 984096,
+ 749756,
+ 429499,
+ 2794,
+ 78209,
+ 18812,
+ 21111,
+ 490,
+ 328042,
+ 12,
+ 132119,
+ 505103,
+ 353148,
+ 0,
+ 373656,
+ 951244,
+ 491,
+ 355778,
+ 30620,
+ 317,
+ 60175,
+ 220,
+ 214496,
+ 41249,
+ 5169,
+ 78367,
+ 506804,
+ 0,
+ 1368,
+ 407,
+ 295126,
+ 1288,
+ 86,
+ 97614,
+ 61640,
+ 244723,
+ 3,
+ 0,
+ 869827,
+ 527246,
+ 52,
+ 107036,
+ 240739,
+ 780281,
+ 113084,
+ 62009,
+ 740343,
+ 483201,
+ 8649,
+ 16419,
+ 1,
+ 801574,
+ 95524,
+ 326126,
+ 26912,
+ 877040,
+ 10262,
+ 5895,
+ 0,
+ 132633,
+ 59171,
+ 306347,
+ 702701,
+ 196245,
+ 12642,
+ 32723,
+ 24608,
+ 30287,
+ 45775,
+ 18281,
+ 7587,
+ 144532,
+ 5,
+ 35,
+ 99862,
+ 215127,
+ 170875,
+ 61461,
+ 77790,
+ 5,
+ 0,
+ 129358,
+ 0,
+ 105084,
+ 21399,
+ 42233,
+ 85397,
+ 480654,
+ 555988,
+ 89575,
+ 42346,
+ 20004,
+ 11102,
+ 21321,
+ 185,
+ 379267,
+ 849147,
+ 121514,
+ 3388,
+ 33662,
+ 12,
+ 164898,
+ 226,
+ 274,
+ 385003,
+ 365052,
+ 693376,
+ 41245,
+ 9010,
+ 41594,
+ 89835,
+ 10490,
+ 272,
+ 128437,
+ 0,
+ 122648,
+ 277,
+ 116505,
+ 38372,
+ 4,
+ 1376,
+ 0,
+ 46317,
+ 139368,
+ 36398,
+ 193899,
+ 30632,
+ 26371,
+ 7548,
+ 367643,
+ 954849,
+ 25889,
+ 36567,
+ 176,
+ 140631,
+ 4690,
+ 975031,
+ 80965,
+ 500471,
+ 8442,
+ 43,
+ 27758,
+ 301501,
+ 3797,
+ 80,
+ 384440,
+ 928477,
+ 4960,
+ 24566,
+ 33245,
+ 14638,
+ 228354,
+ 54347,
+ 861285,
+ 12841,
+ 2,
+ 157402,
+ 646747,
+ 53763,
+ 1,
+ 214732,
+ 49471,
+ 49757,
+ 998,
+ 201135,
+ 566,
+ 73512,
+ 194240,
+ 391773,
+ 21510,
+ 13,
+ 829894,
+ 783200,
+ 565329,
+ 2101,
+ 12,
+ 191043,
+ 1621,
+ 18443,
+ 279,
+ 294135,
+ 526503,
+ 729735,
+ 4639,
+ 444138,
+ 5835,
+ 12372,
+ 46362,
+ 1543,
+ 870907,
+ 83262,
+ 0,
+ 38331,
+ 95,
+ 1194,
+ 909,
+ 8053,
+ 453066,
+ 845561,
+ 411,
+ 3229,
+ 1,
+ 158,
+ 1431,
+ 835137,
+ 21774,
+ 7298,
+ 148388,
+ 224649,
+ 379318,
+ 520138,
+ 39781,
+ 172130,
+ 362634,
+ 487495,
+ 51957,
+ 158,
+ 1770,
+ 7,
+ 18010,
+ 1063,
+ 171484,
+ 19924,
+ 279867,
+ 469956,
+ 189785,
+ 0,
+ 814,
+ 60580,
+ 944349,
+ 18743,
+ 553235,
+ 0,
+ 95475,
+ 99,
+ 0,
+ 5,
+ 42623,
+ 178418,
+ 398940,
+ 5700,
+ 69023,
+ 5786,
+ 0,
+ 10531,
+ 551,
+ 86308,
+ 63451,
+ 32704,
+ 176903,
+ 0,
+ 251689,
+ 11589,
+ 25711,
+ 43437,
+ 1431,
+ 304,
+ 52965,
+ 34816,
+ 268688,
+ 47756,
+ 825323,
+ 122608,
+ 81246,
+ 69974,
+ 360515,
+ 99973,
+ 143015,
+ 5063,
+ 4499,
+ 34459,
+ 171982,
+ 677943,
+ 489082,
+ 257515,
+ 3765,
+ 5,
+ 7416,
+ 602206,
+ 74122,
+ 3,
+ 686204,
+ 5493,
+ 28901,
+ 11349,
+ 549668,
+ 257082,
+ 82000,
+ 17031,
+ 1517,
+ 7442,
+ 937160,
+ 722,
+ 0,
+ 72952,
+ 377192,
+ 438266,
+ 555,
+ 31436,
+ 284,
+ 56390,
+ 0,
+ 585856,
+ 27635,
+ 519344,
+ 126131,
+ 360273,
+ 845073,
+ 0,
+ 191965,
+ 55652,
+ 23,
+ 112773,
+ 639025,
+ 84749,
+ 0,
+ 330822,
+ 7173,
+ 126217,
+ 871,
+ 112112,
+ 0,
+ 664,
+ 530474,
+ 1,
+ 379564,
+ 172617,
+ 647308,
+ 0,
+ 356,
+ 17,
+ 84345,
+ 457,
+ 0,
+ 8,
+ 6,
+ 136602,
+ 634424,
+ 0,
+ 177298,
+ 100726,
+ 91661,
+ 383792,
+ 1665,
+ 43583,
+ 15775,
+ 4083,
+ 4277,
+ 345749,
+ 969599,
+ 65804,
+ 19327,
+ 0,
+ 352514,
+ 4225,
+ 9,
+ 103767,
+ 0,
+ 0,
+ 148436,
+ 850,
+ 33,
+ 2146,
+ 20153,
+ 50,
+ 9063,
+ 50329,
+ 348379,
+ 2569,
+ 83697,
+ 37073,
+ 715486,
+ 629,
+ 4753,
+ 442,
+ 259203,
+ 287223,
+ 48625,
+ 9,
+ 70184,
+ 45946,
+ 144947,
+ 0,
+ 60285,
+ 28640,
+ 7626,
+ 134159,
+ 33,
+ 12452,
+ 150566,
+ 348293,
+ 124426,
+ 353952,
+ 11,
+ 22,
+ 776742,
+ 29072,
+ 132168,
+ 254533,
+ 319957,
+ 1602,
+ 1659,
+ 209341,
+ 32847,
+ 92392,
+ 753005,
+ 1392,
+ 10271,
+ 28557,
+ 6717,
+ 941745,
+ 0,
+ 0,
+ 0,
+ 78645,
+ 45320,
+ 11193,
+ 1448,
+ 130626,
+ 377907,
+ 795535,
+ 24285,
+ 26094,
+ 266691,
+ 64449,
+ 77400,
+ 191410,
+ 1,
+ 1346,
+ 25224,
+ 489637,
+ 47052,
+ 248592,
+ 76689,
+ 0,
+ 7722,
+ 47285,
+ 3152,
+ 285577,
+ 0,
+ 149366,
+ 264346,
+ 1,
+ 208602,
+ 320459,
+ 131771,
+ 1421,
+ 350,
+ 723283,
+ 714934,
+ 0,
+ 566439,
+ 11656,
+ 34189,
+ 125484,
+ 943273,
+ 15,
+ 7789,
+ 0,
+ 7427,
+ 464278,
+ 680924,
+ 651102,
+ 87794,
+ 39640,
+ 838644,
+ 964500,
+ 1,
+ 1765,
+ 272604,
+ 10,
+ 837347,
+ 44845,
+ 130,
+ 163357,
+ 4150,
+ 403331,
+ 839132,
+ 44876,
+ 272792,
+ 592527,
+ 57225,
+ 128826,
+ 2915,
+ 2,
+ 3570,
+ 2410,
+ 199,
+ 171358,
+ 5931,
+ 53620,
+ 55299,
+ 1868,
+ 24123,
+ 165,
+ 346513,
+ 16527,
+ 133,
+ 517412,
+ 195700,
+ 730365,
+ 896209,
+ 152760,
+ 24577,
+ 65,
+ 8218,
+ 349642,
+ 901345,
+ 5127,
+ 5102,
+ 238318,
+ 955,
+ 631921,
+ 12218,
+ 55101,
+ 930381,
+ 219503,
+ 469237,
+ 132,
+ 16701,
+ 494,
+ 199729,
+ 0,
+ 32139,
+ 314,
+ 172,
+ 2947,
+ 106997,
+ 4871,
+ 236,
+ 6146,
+ 1843,
+ 128,
+ 0,
+ 254240,
+ 2964,
+ 14825,
+ 60624,
+ 2108,
+ 286953,
+ 654931,
+ 0,
+ 0,
+ 396587,
+ 19852,
+ 70311,
+ 363561,
+ 282,
+ 17966,
+ 924254,
+ 104173,
+ 130816,
+ 179096,
+ 105466,
+ 136,
+ 618261,
+ 358433,
+ 25587,
+ 49357,
+ 102,
+ 133746,
+ 620776,
+ 17084,
+ 406881,
+ 802675,
+ 349,
+ 69,
+ 8761,
+ 278482,
+ 16336,
+ 128,
+ 160096,
+ 25857,
+ 280,
+ 39639,
+ 726299,
+ 293905,
+ 4621,
+ 41,
+ 649,
+ 3655,
+ 269286,
+ 578026,
+ 0,
+ 11156,
+ 1,
+ 744858,
+ 531,
+ 48155,
+ 28435,
+ 7991,
+ 447,
+ 10201,
+ 379341,
+ 0,
+ 5773,
+ 0,
+ 295,
+ 228592,
+ 331155,
+ 104089,
+ 628069,
+ 29693,
+ 22,
+ 13,
+ 0,
+ 0,
+ 554349,
+ 6082,
+ 238,
+ 23,
+ 151873,
+ 805937,
+ 0,
+ 194076,
+ 6450,
+ 3,
+ 128322,
+ 69149,
+ 95511,
+ 86,
+ 844368,
+ 415964,
+ 51985,
+ 308686,
+ 553403,
+ 624943,
+ 365800,
+ 4,
+ 120263,
+ 91239,
+ 195248,
+ 58010,
+ 19,
+ 415112,
+ 136806,
+ 42,
+ 571848,
+ 55306,
+ 29454,
+ 3,
+ 144926,
+ 189,
+ 0,
+ 161943,
+ 592155,
+ 10930,
+ 279297,
+ 56932,
+ 957430,
+ 10244,
+ 190296,
+ 807209,
+ 781,
+ 1466,
+ 235055,
+ 33,
+ 196,
+ 58280,
+ 436,
+ 408649,
+ 221,
+ 711143,
+ 10495,
+ 2441,
+ 275720,
+ 2,
+ 15391,
+ 132107,
+ 102610,
+ 688549,
+ 237142,
+ 3041,
+ 14,
+ 308623,
+ 0,
+ 0,
+ 287,
+ 295147,
+ 61443,
+ 229,
+ 207,
+ 2051,
+ 64,
+ 13479,
+ 55656,
+ 570134,
+ 50387,
+ 225869,
+ 20615,
+ 258465,
+ 64932,
+ 112461,
+ 164521,
+ 907269,
+ 758563,
+ 22901,
+ 0,
+ 7944,
+ 48,
+ 154921,
+ 2784,
+ 548608,
+ 0,
+ 12524,
+ 142556,
+ 0,
+ 13882,
+ 507227,
+ 316598,
+ 987551,
+ 0,
+ 894687,
+ 1964,
+ 364,
+ 10316,
+ 440269,
+ 9,
+ 776723,
+ 72288,
+ 54604,
+ 185101,
+ 142,
+ 362,
+ 11679,
+ 77,
+ 79,
+ 529321,
+ 364,
+ 42387,
+ 0,
+ 570879,
+ 417503,
+ 604871,
+ 578806,
+ 1102,
+ 66584,
+ 615440,
+ 146744,
+ 19441,
+ 170478,
+ 144069,
+ 36170,
+ 145376,
+ 842283,
+ 193612,
+ 3,
+ 359429,
+ 368596,
+ 0,
+ 11064,
+ 7726,
+ 229410,
+ 63569,
+ 67402,
+ 91,
+ 203201,
+ 213513,
+ 0,
+ 704479,
+ 1325,
+ 0,
+ 385154,
+ 13,
+ 806763,
+ 197132,
+ 6183,
+ 45760,
+ 99377,
+ 0,
+ 972077,
+ 4043,
+ 195700,
+ 34229,
+ 0,
+ 154027,
+ 633,
+ 6,
+ 32142,
+ 0,
+ 29,
+ 620842,
+ 14099,
+ 495465,
+ 26937,
+ 0,
+ 0,
+ 432,
+ 227704,
+ 0,
+ 63,
+ 0,
+ 19,
+ 863491,
+ 20,
+ 1,
+ 160713,
+ 24607,
+ 85800,
+ 3566,
+ 37854,
+ 81913,
+ 121573,
+ 816,
+ 20,
+ 133253,
+ 692231,
+ 4869,
+ 255175,
+ 15028,
+ 9383,
+ 542877,
+ 4608,
+ 369610,
+ 243635,
+ 385285,
+ 391565,
+ 286009,
+ 0,
+ 61685,
+ 416318,
+ 208,
+ 67019,
+ 788416,
+ 88,
+ 165056,
+ 0,
+ 439589,
+ 160,
+ 105528,
+ 152,
+ 160624,
+ 865,
+ 390229,
+ 714086,
+ 6007,
+ 30229,
+ 481306,
+ 173266,
+ 1135,
+ 2266,
+ 8,
+ 59,
+ 104722,
+ 647885,
+ 579471,
+ 21309,
+ 230834,
+ 140278,
+ 31858,
+ 3288,
+ 36011,
+ 151387,
+ 594217,
+ 22439,
+ 418638,
+ 76859,
+ 29363,
+ 154809,
+ 275533,
+ 39,
+ 472996,
+ 22076,
+ 7481,
+ 155705,
+ 10406,
+ 214779,
+ 223,
+ 1312,
+ 16391,
+ 17203,
+ 55605,
+ 44579,
+ 69332,
+ 303,
+ 19217,
+ 26288,
+ 126212,
+ 316,
+ 98,
+ 114,
+ 37382,
+ 137591,
+ 439749,
+ 12972,
+ 54,
+ 154879,
+ 0,
+ 102680,
+ 7639,
+ 309119,
+ 263550,
+ 766,
+ 1124,
+ 56,
+ 686608,
+ 123767,
+ 518054,
+ 18,
+ 672385,
+ 3161,
+ 53791,
+ 26769,
+ 451670,
+ 61,
+ 148245,
+ 2713,
+ 96725,
+ 4794,
+ 33247,
+ 297946,
+ 33380,
+ 0,
+ 20034,
+ 5647,
+ 17227,
+ 76444,
+ 0,
+ 21011,
+ 675,
+ 13226,
+ 1027,
+ 990842,
+ 124459,
+ 34406,
+ 53,
+ 69540,
+ 134,
+ 0,
+ 168521,
+ 6,
+ 4075,
+ 1137,
+ 63740,
+ 220,
+ 10434,
+ 1171,
+ 28950,
+ 0,
+ 79680,
+ 993269,
+ 355622,
+ 15,
+ 0,
+ 1452,
+ 21667,
+ 22208,
+ 494484,
+ 33984,
+ 691308,
+ 10,
+ 693686,
+ 196,
+ 9,
+ 70676,
+ 157660,
+ 775,
+ 165,
+ 468432,
+ 1083,
+ 515154,
+ 778344,
+ 70241,
+ 42,
+ 40931,
+ 277125,
+ 43837,
+ 301881,
+ 1332,
+ 56712,
+ 9013,
+ 1299,
+ 7564,
+ 31092,
+ 1975,
+ 113517,
+ 833295,
+ 245021,
+ 36503,
+ 23586,
+ 149327,
+ 89175,
+ 10512,
+ 484348,
+ 187793,
+ 954609,
+ 53199,
+ 792175,
+ 126,
+ 12369,
+ 405,
+ 0,
+ 6614,
+ 322857,
+ 166,
+ 571874,
+ 60839,
+ 180975,
+ 146722,
+ 411565,
+ 1536,
+ 1,
+ 11,
+ 116230,
+ 60514,
+ 9003,
+ 2325,
+ 43763,
+ 63,
+ 355553,
+ 0,
+ 389876,
+ 14672,
+ 11526,
+ 160209,
+ 65,
+ 10283,
+ 966,
+ 10,
+ 58333,
+ 129920,
+ 2850,
+ 83346,
+ 0,
+ 14,
+ 295819,
+ 679550,
+ 143928,
+ 29489,
+ 82324,
+ 36558,
+ 267118,
+ 143313,
+ 90107,
+ 12789,
+ 951,
+ 0,
+ 187619,
+ 295317,
+ 82,
+ 41326,
+ 309682,
+ 907327,
+ 809358,
+ 324,
+ 139157,
+ 12,
+ 78366,
+ 671811,
+ 354,
+ 131,
+ 70525,
+ 35830,
+ 281018,
+ 91456,
+ 92523,
+ 54874,
+ 48273,
+ 2423,
+ 0,
+ 81,
+ 361314,
+ 374811,
+ 394758,
+ 15350,
+ 795,
+ 3,
+ 16779,
+ 796684,
+ 477556,
+ 73927,
+ 26643,
+ 119281,
+ 62692,
+ 17039,
+ 454778,
+ 952,
+ 48973,
+ 19529,
+ 151,
+ 239121,
+ 93509,
+ 254702,
+ 1307,
+ 10029,
+ 7973,
+ 546706,
+ 806644,
+ 680517,
+ 223,
+ 0,
+ 2,
+ 0,
+ 402421,
+ 619193,
+ 15685,
+ 2,
+ 939715,
+ 519198,
+ 0,
+ 444312,
+ 23204,
+ 35669,
+ 32467,
+ 0,
+ 799725,
+ 5883,
+ 2217,
+ 32292,
+ 355557,
+ 22179,
+ 1066,
+ 15704,
+ 610,
+ 37819,
+ 403626,
+ 83101,
+ 10989,
+ 311607,
+ 43394,
+ 72576,
+ 335450,
+ 85964,
+ 73734,
+ 105142,
+ 38292,
+ 0,
+ 181516,
+ 33959,
+ 611797,
+ 221838,
+ 5931,
+ 7666,
+ 1044,
+ 477173,
+ 13591,
+ 405,
+ 521,
+ 190653,
+ 184191,
+ 0,
+ 215,
+ 847195,
+ 22782,
+ 11912,
+ 27345,
+ 2572,
+ 0,
+ 566350,
+ 7,
+ 52302,
+ 26641,
+ 587826,
+ 127,
+ 2,
+ 44449,
+ 153198,
+ 14,
+ 926,
+ 285,
+ 0,
+ 938196,
+ 52255,
+ 9153,
+ 807,
+ 12548,
+ 358324,
+ 18521,
+ 104956,
+ 42738,
+ 116,
+ 135772,
+ 189554,
+ 38,
+ 54,
+ 36,
+ 89768,
+ 17170,
+ 75,
+ 34502,
+ 45489,
+ 172796,
+ 971810,
+ 16153,
+ 499280,
+ 1,
+ 879663,
+ 53830,
+ 186,
+ 539,
+ 242059,
+ 268,
+ 402,
+ 2732,
+ 68057,
+ 18463,
+ 198560,
+ 10068,
+ 591753,
+ 6116,
+ 699280,
+ 1,
+ 0,
+ 114258,
+ 277,
+ 149,
+ 283821,
+ 352561,
+ 88172,
+ 684476,
+ 3450,
+ 87,
+ 99936,
+ 3155,
+ 72983,
+ 31619,
+ 8832,
+ 58666,
+ 0,
+ 59023,
+ 306091,
+ 352150,
+ 255063,
+ 992708,
+ 23,
+ 4896,
+ 18165,
+ 424401,
+ 227613,
+ 5175,
+ 347,
+ 139846,
+ 11962,
+ 714,
+ 3501,
+ 82367,
+ 11110,
+ 10,
+ 12874,
+ 0,
+ 0,
+ 222712,
+ 169,
+ 123281,
+ 0,
+ 268149,
+ 101,
+ 17446,
+ 4262,
+ 489,
+ 0,
+ 30,
+ 0,
+ 277235,
+ 28,
+ 71,
+ 23,
+ 61219,
+ 953631,
+ 477548,
+ 662491,
+ 273,
+ 44787,
+ 4130,
+ 14483,
+ 470571,
+ 735977,
+ 406648,
+ 815898,
+ 5985,
+ 462696,
+ 937510,
+ 9,
+ 0,
+ 111727,
+ 93,
+ 331435,
+ 336402,
+ 78690,
+ 49,
+ 0,
+ 87422,
+ 1242,
+ 0,
+ 8783,
+ 8540,
+ 314,
+ 33411,
+ 805718,
+ 247,
+ 6870,
+ 523743,
+ 8323,
+ 612593,
+ 430,
+ 354048,
+ 264913,
+ 83,
+ 114063,
+ 202825,
+ 35202,
+ 32823,
+ 185554,
+ 85760,
+ 45159,
+ 5971,
+ 267733,
+ 4545,
+ 116,
+ 6910,
+ 24833,
+ 218,
+ 922362,
+ 221735,
+ 740,
+ 7112,
+ 31,
+ 15739,
+ 523589,
+ 4,
+ 95996,
+ 936,
+ 823951,
+ 0,
+ 88,
+ 160,
+ 375419,
+ 663627,
+ 3741,
+ 22896,
+ 114326,
+ 415962,
+ 880100,
+ 6222,
+ 18650,
+ 35524,
+ 195076,
+ 506,
+ 451640,
+ 541336,
+ 70903,
+ 3946,
+ 1,
+ 61765,
+ 1,
+ 2696,
+ 753129,
+ 289,
+ 225234,
+ 378692,
+ 1703,
+ 6751,
+ 1,
+ 820,
+ 7677,
+ 589,
+ 12412,
+ 317,
+ 69,
+ 226031,
+ 134523,
+ 318253,
+ 66677,
+ 111025,
+ 96,
+ 0,
+ 96,
+ 523528,
+ 1017,
+ 0,
+ 258740,
+ 420947,
+ 4600,
+ 400684,
+ 12174,
+ 11770,
+ 52,
+ 5959,
+ 82658,
+ 531787,
+ 202,
+ 548430,
+ 964,
+ 1054,
+ 34,
+ 96897,
+ 25445,
+ 47609,
+ 386052,
+ 97004,
+ 1935,
+ 30074,
+ 13458,
+ 494105,
+ 54,
+ 65575,
+ 594698,
+ 2340,
+ 20259,
+ 84,
+ 2774,
+ 534,
+ 972534,
+ 115057,
+ 0,
+ 11379,
+ 0,
+ 271,
+ 266305,
+ 132595,
+ 2,
+ 773561,
+ 52365,
+ 3585,
+ 351,
+ 148206,
+ 778964,
+ 149379,
+ 596,
+ 284914,
+ 2900,
+ 35596,
+ 1547,
+ 212027,
+ 8100,
+ 12248,
+ 3013,
+ 1814,
+ 183415,
+ 273633,
+ 15812,
+ 0,
+ 966680,
+ 14830,
+ 134309,
+ 0,
+ 416450,
+ 206611,
+ 816,
+ 82258,
+ 9873,
+ 3155,
+ 53485,
+ 779805,
+ 107690,
+ 254475,
+ 102504,
+ 72495,
+ 17301,
+ 472130,
+ 6895,
+ 245420,
+ 7299,
+ 110508,
+ 27776,
+ 246134,
+ 0,
+ 330853,
+ 0,
+ 271767,
+ 61886,
+ 24123,
+ 309681,
+ 58325,
+ 608865,
+ 20666,
+ 87349,
+ 229228,
+ 246,
+ 457768,
+ 5374,
+ 69643,
+ 148,
+ 618375,
+ 45236,
+ 352565,
+ 133904,
+ 152,
+ 10688,
+ 18,
+ 0,
+ 276036,
+ 493281,
+ 11156,
+ 12566,
+ 5762,
+ 113,
+ 24179,
+ 98,
+ 327,
+ 893,
+ 209180,
+ 140805,
+ 0,
+ 2341,
+ 66309,
+ 30305,
+ 630559,
+ 3682,
+ 152767,
+ 265822,
+ 142868,
+ 1535,
+ 728603,
+ 69081,
+ 353151,
+ 237995,
+ 1075,
+ 925071,
+ 86,
+ 6748,
+ 0,
+ 684186,
+ 735,
+ 13793,
+ 4790,
+ 73175,
+ 69677,
+ 367627,
+ 238650,
+ 303543,
+ 1,
+ 26059,
+ 21392,
+ 10,
+ 288609,
+ 0,
+ 76345,
+ 158496,
+ 7000,
+ 1865,
+ 20385,
+ 0,
+ 54213,
+ 9948,
+ 102667,
+ 6963,
+ 71,
+ 555744,
+ 5626,
+ 2512,
+ 1124,
+ 7171,
+ 628,
+ 29225,
+ 321687,
+ 61519,
+ 4,
+ 8352,
+ 9156,
+};
+
+char *pointers[NCYCLES];
+
+int main(void)
+{
+ int r, i, j, sp, sq;
+ char *p, *q, *ep, *eq;
+ int ok;
+ int err = 0;
+
+ for ( r = 0 ; r < 4 ; r++ ) {
+ for ( i = 0 ; i < NCYCLES ; i++ ) {
+ pointers[i] = p = malloc(sp = sizes[i]);
+ ep = p+sp;
+ ok = 1;
+ for ( j = 0 ; j < i ; j++ ) {
+ q = pointers[j];
+ sq = sizes[j];
+ eq = q+sq;
+
+ if ( (p < q && ep > q) || (p >= q && p < eq) ) {
+ ok = 0;
+ err = 1;
+ break;
+ }
+ }
+ printf("Allocated %6d bytes at %p, ok = %d\n", sp, p, ok);
+
+ if ( p )
+ memset(p, 0xee, sp); /* Poison this memory */
+ }
+
+ for ( i = 0 ; i < NCYCLES ; i++ ) {
+ free(pointers[i]);
+ printf("Freed %6d bytes at %p\n", sizes[i], pointers[i]);
+ }
+ }
+
+ return err;
+}
+
diff --git a/klibc/klibc/tests/memstrtest.c b/klibc/klibc/tests/memstrtest.c
new file mode 100644
index 0000000000..14d5173cb2
--- /dev/null
+++ b/klibc/klibc/tests/memstrtest.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void)
+{
+ unsigned char t1[256], t2[256];
+ int i;
+ int r;
+
+ for(i = 0; i < sizeof(t1); i++)
+ t1[i] = t2[i] = (unsigned char)i;
+
+ r = memcmp(t1, t2, sizeof(t1));
+ printf("memcmp r = %d\n", r);
+ r = memcmp(t1, t2, sizeof(t1)/2);
+ printf("memcmp r = %d\n", r);
+ t1[255] = 0;
+ r = memcmp(t1, t2, sizeof(t1));
+ printf("memcmp r = %d\n", r);
+
+ for (i = 0; i < sizeof(t1); i++)
+ t1[i] = 0xaa;
+ memset(t2, 0xaa, sizeof(t2));
+ r = memcmp(t1, t2, sizeof(t1));
+ printf("memcmp r = %d\n", r);
+ return 0;
+}
+
diff --git a/klibc/klibc/tests/microhello.c b/klibc/klibc/tests/microhello.c
new file mode 100644
index 0000000000..e57cd05a50
--- /dev/null
+++ b/klibc/klibc/tests/microhello.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void)
+{
+ const char hello[] = "Hello, World!\n";
+ _fwrite(hello, sizeof hello-1, stdout);
+ return 0;
+}
diff --git a/klibc/klibc/tests/minihello.c b/klibc/klibc/tests/minihello.c
new file mode 100644
index 0000000000..7698e0666b
--- /dev/null
+++ b/klibc/klibc/tests/minihello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+ fputs("Hello, World!\n", stdout);
+ return 0;
+}
diff --git a/klibc/klibc/tests/minips.c b/klibc/klibc/tests/minips.c
new file mode 100644
index 0000000000..c599150858
--- /dev/null
+++ b/klibc/klibc/tests/minips.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright 1998 by Albert Cahalan; all rights reserved.
+ * This file may be used subject to the terms and conditions of the
+ * GNU Library General Public License Version 2, or any later version
+ * at your option, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ */
+
+/* This is a minimal /bin/ps, designed to be smaller than the old ps
+ * while still supporting some of the more important features of the
+ * new ps. (for total size, note that this ps does not need libproc)
+ * It is suitable for Linux-on-a-floppy systems only.
+ *
+ * Maintainers: do not compile or install for normal systems.
+ * Anyone needing this will want to tweak their compiler anyway.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include <asm/param.h> /* HZ */
+#include <asm/page.h> /* PAGE_SIZE */
+
+static int P_euid;
+static int P_pid;
+static char P_cmd[16];
+static char P_state;
+static int P_ppid, P_pgrp, P_session, P_tty, P_tpgid;
+static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;
+static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_it_real_value;
+static unsigned long P_start_time, P_vsize;
+static long P_rss;
+static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;
+static unsigned P_signal, P_blocked, P_sigignore, P_sigcatch;
+static unsigned long P_wchan, P_nswap, P_cnswap;
+
+
+#if 0
+static int screen_cols = 80;
+static int w_count;
+#endif
+
+static int want_one_pid;
+static const char *want_one_command;
+static int select_notty;
+static int select_all;
+
+static int ps_format;
+static int old_h_option;
+
+/* we only pretend to support this */
+static int show_args; /* implicit with -f and all BSD options */
+static int bsd_c_option; /* this option overrides the above */
+
+static int ps_argc; /* global argc */
+static char **ps_argv; /* global argv */
+static int thisarg; /* index into ps_argv */
+static char *flagptr; /* current location in ps_argv[thisarg] */
+
+
+#ifndef PAGE_SIZE
+#warning PAGE_SIZE not defined, assuming it is 4096
+#define PAGE_SIZE 4096
+#endif
+
+#ifndef HZ
+#warning HZ not defined, assuming it is 100
+#define HZ 100
+#endif
+
+
+
+static void usage(void){
+ fprintf(stderr,
+ "-C select by command name (minimal ps only accepts one)\n"
+ "-p select by process ID (minimal ps only accepts one)\n"
+ "-e all processes (same as ax)\n"
+ "a all processes w/ tty, including other users\n"
+ "x processes w/o controlling ttys\n"
+ "-f full format\n"
+ "-j,j job control format\n"
+ "v virtual memory format\n"
+ "-l,l long format\n"
+ "u user-oriented format\n"
+ "-o user-defined format (limited support, only \"ps -o pid=\")\n"
+ "h no header\n"
+/*
+ "-A all processes (same as ax)\n"
+ "c true command name\n"
+ "-w,w wide output\n"
+*/
+ );
+ exit(1);
+}
+
+/*
+ * Return the next argument, or call the usage function.
+ * This handles both: -oFOO -o FOO
+ */
+static const char *get_opt_arg(void){
+ const char *ret;
+ ret = flagptr+1; /* assume argument is part of ps_argv[thisarg] */
+ if(*ret) return ret;
+ if(++thisarg >= ps_argc) usage(); /* there is nothing left */
+ /* argument is the new ps_argv[thisarg] */
+ ret = ps_argv[thisarg];
+ if(!ret || !*ret) usage();
+ return ret;
+}
+
+
+/* return the PID, or 0 if nothing good */
+static void parse_pid(const char *str){
+ char *endp;
+ int num;
+ if(!str) goto bad;
+ num = strtol(str, &endp, 0);
+ if(*endp != '\0') goto bad;
+ if(num<1) goto bad;
+ if(want_one_pid) goto bad;
+ want_one_pid = num;
+ return;
+bad:
+ usage();
+}
+
+/***************** parse SysV options, including Unix98 *****************/
+static void parse_sysv_option(void){
+ do{
+ switch(*flagptr){
+ /**** selection ****/
+ case 'C': /* end */
+ if(want_one_command) usage();
+ want_one_command = get_opt_arg();
+ return; /* can't have any more options */
+ case 'p': /* end */
+ parse_pid(get_opt_arg());
+ return; /* can't have any more options */
+ case 'A':
+ case 'e':
+ select_all++;
+ select_notty++;
+case 'w': /* here for now, since the real one is not used */
+ break;
+ /**** output format ****/
+ case 'f':
+ show_args = 1;
+ /* FALL THROUGH */
+ case 'j':
+ case 'l':
+ if(ps_format) usage();
+ ps_format = *flagptr;
+ break;
+ case 'o': /* end */
+ /* We only support a limited form: "ps -o pid=" (yes, just "pid=") */
+ if(strcmp(get_opt_arg(),"pid=")) usage();
+ if(ps_format) usage();
+ ps_format = 'o';
+ old_h_option++;
+ return; /* can't have any more options */
+ /**** other stuff ****/
+#if 0
+ case 'w':
+ w_count++;
+ break;
+#endif
+ default:
+ usage();
+ } /* switch */
+ }while(*++flagptr);
+}
+
+/************************* parse BSD options **********************/
+static void parse_bsd_option(void){
+ do{
+ switch(*flagptr){
+ /**** selection ****/
+ case 'a':
+ select_all++;
+ break;
+ case 'x':
+ select_notty++;
+ break;
+ case 'p': /* end */
+ parse_pid(get_opt_arg());
+ return; /* can't have any more options */
+ /**** output format ****/
+ case 'j':
+ case 'l':
+ case 'u':
+ case 'v':
+ if(ps_format) usage();
+ ps_format = 0x80 | *flagptr; /* use 0x80 to tell BSD from SysV */
+ break;
+ /**** other stuff ****/
+ case 'c':
+ bsd_c_option++;
+#if 0
+ break;
+#endif
+ case 'w':
+#if 0
+ w_count++;
+#endif
+ break;
+ case 'h':
+ old_h_option++;
+ break;
+ default:
+ usage();
+ } /* switch */
+ }while(*++flagptr);
+}
+
+#if 0
+/* not used yet */
+static void choose_dimensions(void){
+ struct winsize ws;
+ char *columns;
+ /* screen_cols is 80 by default */
+ if(ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>30) screen_cols = ws.ws_col;
+ columns = getenv("COLUMNS");
+ if(columns && *columns){
+ long t;
+ char *endptr;
+ t = strtol(columns, &endptr, 0);
+ if(!*endptr && (t>30) && (t<(long)999999999)) screen_cols = (int)t;
+ }
+ if(w_count && (screen_cols<132)) screen_cols=132;
+ if(w_count>1) screen_cols=999999999;
+}
+#endif
+
+static void arg_parse(int argc, char *argv[]){
+ int sel = 0; /* to verify option sanity */
+ ps_argc = argc;
+ ps_argv = argv;
+ thisarg = 0;
+ /**** iterate over the args ****/
+ while(++thisarg < ps_argc){
+ flagptr = ps_argv[thisarg];
+ switch(*flagptr){
+ case '0' ... '9':
+ show_args = 1;
+ parse_pid(flagptr);
+ break;
+ case '-':
+ flagptr++;
+ parse_sysv_option();
+ break;
+ default:
+ show_args = 1;
+ parse_bsd_option();
+ break;
+ }
+ }
+ /**** sanity check and clean-up ****/
+ if(want_one_pid) sel++;
+ if(want_one_command) sel++;
+ if(select_notty || select_all) sel++;
+ if(sel>1 || select_notty>1 || select_all>1 || bsd_c_option>1 || old_h_option>1) usage();
+ if(bsd_c_option) show_args = 0;
+}
+
+/* return 1 if it works, or 0 for failure */
+static int stat2proc(int pid) {
+ char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */
+ int num;
+ int fd;
+ char* tmp;
+ struct stat sb; /* stat() used to get EUID */
+ snprintf(buf, 32, "/proc/%d/stat", pid);
+ if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0;
+ num = read(fd, buf, sizeof buf - 1);
+ fstat(fd, &sb);
+ P_euid = sb.st_uid;
+ close(fd);
+ if(num<80) return 0;
+ buf[num] = '\0';
+ tmp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
+ *tmp = '\0'; /* replace trailing ')' with NUL */
+ /* parse these two strings separately, skipping the leading "(". */
+ memset(P_cmd, 0, sizeof P_cmd); /* clear */
+ sscanf(buf, "%d (%15c", &P_pid, P_cmd); /* comm[16] in kernel */
+ num = sscanf(tmp + 2, /* skip space after ')' too */
+ "%c "
+ "%d %d %d %d %d "
+ "%lu %lu %lu %lu %lu %lu %lu "
+ "%ld %ld %ld %ld %ld %ld "
+ "%lu %lu "
+ "%ld "
+ "%lu %lu %lu %lu %lu %lu "
+ "%u %u %u %u " /* no use for RT signals */
+ "%lu %lu %lu",
+ &P_state,
+ &P_ppid, &P_pgrp, &P_session, &P_tty, &P_tpgid,
+ &P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime,
+ &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_it_real_value,
+ &P_start_time, &P_vsize,
+ &P_rss,
+ &P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip,
+ &P_signal, &P_blocked, &P_sigignore, &P_sigcatch,
+ &P_wchan, &P_nswap, &P_cnswap
+ );
+/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */
+ P_vsize /= 1024;
+ P_rss *= (PAGE_SIZE/1024);
+ if(num < 30) return 0;
+ if(P_pid != pid) return 0;
+ return 1;
+}
+
+static const char *do_time(unsigned long t){
+ int hh,mm,ss;
+ static char buf[32];
+ int cnt = 0;
+ t /= HZ;
+ ss = t%60;
+ t /= 60;
+ mm = t%60;
+ t /= 60;
+ hh = t%24;
+ t /= 24;
+ if(t) cnt = snprintf(buf, sizeof buf, "%d-", (int)t);
+ snprintf(cnt + buf, sizeof(buf)-cnt, "%02d:%02d:%02d", hh, mm, ss);
+ return buf;
+}
+
+static void print_proc(void){
+ char tty[16];
+ snprintf(tty, sizeof tty, "%3d,%-3d", (P_tty>>8)&0xff, P_tty&0xff);
+ switch(ps_format){
+ case 0:
+ printf("%5d %s %s", P_pid, tty, do_time(P_utime+P_stime));
+ break;
+ case 'o':
+ printf("%d\n", P_pid);
+ return; /* don't want the command */
+ case 'l':
+ printf(
+ "%03x %c %5d %5d %5d - %3d %3d - "
+ "%5ld %06x %s %s",
+ (unsigned)P_flags&0x777, P_state, P_euid, P_pid, P_ppid,
+ (int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024),
+ (unsigned)(P_wchan&0xffffff), tty, do_time(P_utime+P_stime)
+ );
+ break;
+ case 'f':
+ printf(
+ "%5d %5d %5d - - %s %s",
+ P_euid, P_pid, P_ppid, tty, do_time(P_utime+P_stime)
+ );
+ break;
+ case 'j':
+ printf(
+ "%5d %5d %5d %s %s",
+ P_pid, P_pgrp, P_session, tty, do_time(P_utime+P_stime)
+ );
+ break;
+ case 'u'|0x80:
+ printf(
+ "%5d %5d - - %5ld %5ld %s %c - %s",
+ P_euid, P_pid, P_vsize, P_rss, tty, P_state,
+ do_time(P_utime+P_stime)
+ );
+ break;
+ case 'v'|0x80:
+ printf(
+ "%5d %s %c %s %6d - - %5d -",
+ P_pid, tty, P_state, do_time(P_utime+P_stime), (int)P_maj_flt,
+ (int)P_rss
+ );
+ break;
+ case 'j'|0x80:
+ printf(
+ "%5d %5d %5d %5d %s %5d %c %5d %s",
+ P_ppid, P_pid, P_pgrp, P_session, tty, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime)
+ );
+ break;
+ case 'l'|0x80:
+ printf(
+ "%03x %5d %5d %5d %3d %3d "
+ "%5ld %4ld %06x %c %s %s",
+ (unsigned)P_flags&0x777, P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice,
+ P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, tty, do_time(P_utime+P_stime)
+ );
+ break;
+ default:
+ }
+ if(show_args) printf(" [%s]\n", P_cmd);
+ else printf(" %s\n", P_cmd);
+}
+
+
+int main(int argc, char *argv[]){
+ arg_parse(argc, argv);
+#if 0
+ choose_dimensions();
+#endif
+ if(!old_h_option){
+ const char *head;
+ switch(ps_format){
+ default: /* can't happen */
+ case 0: head = " PID TTY TIME CMD"; break;
+ case 'l': head = " F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD"; break;
+ case 'f': head = " UID PID PPID C STIME TTY TIME CMD"; break;
+ case 'j': head = " PID PGID SID TTY TIME CMD"; break;
+ case 'u'|0x80: head = " UID PID %CPU %MEM VSZ RSS TTY S START TIME COMMAND"; break;
+ case 'v'|0x80: head = " PID TTY S TIME MAJFL TRS DRS RSS %MEM COMMAND"; break;
+ case 'j'|0x80: head = " PPID PID PGID SID TTY TPGID S UID TIME COMMAND"; break;
+ case 'l'|0x80: head = " F UID PID PPID PRI NI VSZ RSS WCHAN S TTY TIME COMMAND"; break;
+ }
+ printf("%s\n",head);
+ }
+ if(want_one_pid){
+ if(stat2proc(want_one_pid)) print_proc();
+ else exit(1);
+ }else{
+ struct dirent *ent; /* dirent handle */
+ DIR *dir;
+ int ouruid;
+ int found_a_proc;
+ found_a_proc = 0;
+ ouruid = getuid();
+ dir = opendir("/proc");
+ while(( ent = readdir(dir) )){
+ if(*ent->d_name<'0' || *ent->d_name>'9') continue;
+ if(!stat2proc(atoi(ent->d_name))) continue;
+ if(want_one_command){
+ if(strcmp(want_one_command,P_cmd)) continue;
+ }else{
+ if(!select_notty && P_tty==-1) continue;
+ if(!select_all && P_euid!=ouruid) continue;
+ }
+ found_a_proc++;
+ print_proc();
+ }
+ closedir(dir);
+ exit(!found_a_proc);
+ }
+ return 0;
+}
diff --git a/klibc/klibc/tests/nfs_no_rpc.c b/klibc/klibc/tests/nfs_no_rpc.c
new file mode 100644
index 0000000000..11b9f61fea
--- /dev/null
+++ b/klibc/klibc/tests/nfs_no_rpc.c
@@ -0,0 +1,538 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <sys/mount.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Default path we try to mount. "%s" gets replaced by our IP address */
+#define NFS_ROOT "/tftpboot/%s"
+#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
+#define NFS_MAXPATHLEN 1024
+#define NFS_MNT_PROGRAM 100005
+#define NFS_MNT_PORT 627
+#define NFS_PROGRAM 100003
+#define NFS_PORT 2049
+#define NFS2_VERSION 2
+#define NFS3_VERSION 3
+#define NFS_MNT_PROGRAM 100005
+#define NFS_MNT_VERSION 1
+#define NFS_MNT3_VERSION 3
+#define MNTPROC_MNT 1
+#define MOUNTPROC3_MNT 1
+#define RPC_PMAP_PROGRAM 100000
+#define RPC_PMAP_VERSION 2
+#define RPC_PMAP_PORT 111
+
+#define NFS2_FHSIZE 32
+#define NFS3_FHSIZE 64
+
+#define RPC_VERSION 2
+
+enum rpc_msg_type {
+ RPC_CALL = 0,
+ RPC_REPLY = 1
+};
+
+enum rpc_auth_flavor {
+ RPC_AUTH_NULL = 0,
+ RPC_AUTH_UNIX = 1,
+ RPC_AUTH_SHORT = 2,
+ RPC_AUTH_DES = 3,
+ RPC_AUTH_KRB = 4,
+};
+
+enum rpc_reply_stat {
+ RPC_MSG_ACCEPTED = 0,
+ RPC_MSG_DENIED = 1
+};
+
+#define NFS_MAXFHSIZE 64
+struct nfs_fh {
+ unsigned short size;
+ unsigned char data[NFS_MAXFHSIZE];
+};
+
+struct nfs2_fh {
+ char data[NFS2_FHSIZE];
+};
+
+#define NFS_MOUNT_VERSION 4
+
+struct nfs_mount_data {
+ int version;
+ int fd;
+ struct nfs2_fh old_root;
+ int flags;
+ int rsize;
+ int wsize;
+ int timeo;
+ int retrans;
+ int acregmin;
+ int acregmax;
+ int acdirmin;
+ int acdirmax;
+ struct sockaddr_in addr;
+ char hostname[256];
+ int namlen;
+ unsigned int bsize;
+ struct nfs_fh root;
+};
+
+#define NFS_MOUNT_SOFT 0x0001 /* 1 */
+#define NFS_MOUNT_INTR 0x0002 /* 1 */
+#define NFS_MOUNT_SECURE 0x0004 /* 1 */
+#define NFS_MOUNT_POSIX 0x0008 /* 1 */
+#define NFS_MOUNT_NOCTO 0x0010 /* 1 */
+#define NFS_MOUNT_NOAC 0x0020 /* 1 */
+#define NFS_MOUNT_TCP 0x0040 /* 2 */
+#define NFS_MOUNT_VER3 0x0080 /* 3 */
+#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
+#define NFS_MOUNT_NONLM 0x0200 /* 3 */
+#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
+#define NFS_MOUNT_FLAGMASK 0xFFFF
+
+static char nfs_root_name[256];
+static u_int32_t root_server_addr;
+static char root_server_path[256];
+
+/* Address of NFS server */
+static u_int32_t servaddr;
+
+/* Name of directory to mount */
+static char nfs_path[NFS_MAXPATHLEN];
+
+/* NFS-related data */
+static struct nfs_mount_data nfs_data = {
+ .version = NFS_MOUNT_VERSION,
+ .flags = NFS_MOUNT_NONLM, /* No lockd in nfs root yet */
+ .rsize = NFS_DEF_FILE_IO_BUFFER_SIZE,
+ .wsize = NFS_DEF_FILE_IO_BUFFER_SIZE,
+ .bsize = 0,
+ .timeo = 7,
+ .retrans = 3,
+ .acregmin = 3,
+ .acregmax = 60,
+ .acdirmin = 30,
+ .acdirmax = 60,
+};
+static int nfs_port = -1;
+static int mount_port;
+
+/***************************************************************************
+
+ Parsing of options
+
+ ***************************************************************************/
+
+/*
+ * The following integer options are recognized
+ */
+static struct nfs_int_opts {
+ const char *name;
+ int *val;
+} root_int_opts[] = {
+ { "port", &nfs_port },
+ { "rsize", &nfs_data.rsize },
+ { "wsize", &nfs_data.wsize },
+ { "timeo", &nfs_data.timeo },
+ { "retrans", &nfs_data.retrans },
+ { "acregmin", &nfs_data.acregmin },
+ { "acregmax", &nfs_data.acregmax },
+ { "acdirmin", &nfs_data.acdirmin },
+ { "acdirmax", &nfs_data.acdirmax },
+ { NULL, NULL }
+};
+
+/*
+ * And now the flag options
+ */
+static struct nfs_bool_opts {
+ const char *name;
+ int and_mask;
+ int or_mask;
+} root_bool_opts[] = {
+ { "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT },
+ { "hard", ~NFS_MOUNT_SOFT, 0 },
+ { "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR },
+ { "nointr", ~NFS_MOUNT_INTR, 0 },
+ { "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX },
+ { "noposix", ~NFS_MOUNT_POSIX, 0 },
+ { "cto", ~NFS_MOUNT_NOCTO, 0 },
+ { "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO },
+ { "ac", ~NFS_MOUNT_NOAC, 0 },
+ { "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC },
+ { "lock", ~NFS_MOUNT_NONLM, 0 },
+ { "nolock", ~NFS_MOUNT_NONLM, NFS_MOUNT_NONLM },
+#ifdef CONFIG_NFS_V3
+ { "v2", ~NFS_MOUNT_VER3, 0 },
+ { "v3", ~NFS_MOUNT_VER3, NFS_MOUNT_VER3 },
+#endif
+ { "udp", ~NFS_MOUNT_TCP, 0 },
+ { "tcp", ~NFS_MOUNT_TCP, NFS_MOUNT_TCP },
+ { "broken_suid",~NFS_MOUNT_BROKEN_SUID, NFS_MOUNT_BROKEN_SUID },
+ { NULL, 0, 0 }
+};
+/*
+ * Parse option string.
+ */
+static void root_nfs_parse(char *name, char *buf)
+{
+ char *options, *val, *cp;
+
+ if ((options = strchr(name, ','))) {
+ *options++ = 0;
+ cp = strtok(options, ",");
+ while (cp) {
+ if ((val = strchr(cp, '='))) {
+ struct nfs_int_opts *opts = root_int_opts;
+ *val++ = '\0';
+ while (opts->name && strcmp(opts->name, cp))
+ opts++;
+ if (opts->name)
+ *(opts->val) = (int) strtoul(val, NULL, 10);
+ } else {
+ struct nfs_bool_opts *opts = root_bool_opts;
+ while (opts->name && strcmp(opts->name, cp))
+ opts++;
+ if (opts->name) {
+ nfs_data.flags &= opts->and_mask;
+ nfs_data.flags |= opts->or_mask;
+ }
+ }
+ cp = strtok(NULL, ",");
+ }
+ }
+ if (name[0] && strcmp(name, "default")) {
+ strncpy(buf, name, NFS_MAXPATHLEN-1);
+ buf[NFS_MAXPATHLEN-1] = 0;
+ }
+}
+
+/*
+ * Prepare the NFS data structure and parse all options.
+ */
+static int root_nfs_name(char *name)
+{
+ char buf[NFS_MAXPATHLEN];
+ struct utsname uname_buf;
+
+ /* Set some default values */
+ strcpy(buf, NFS_ROOT);
+
+ /* Process options received from the remote server */
+ root_nfs_parse(root_server_path, buf);
+
+ /* Override them by options set on kernel command-line */
+ root_nfs_parse(name, buf);
+
+ uname(&uname_buf);
+ if (strlen(buf) + strlen(uname_buf.nodename) > NFS_MAXPATHLEN) {
+ printf("nfsroot: Pathname for remote directory too long.\n");
+ return -1;
+ }
+ sprintf(nfs_path, buf, uname_buf.nodename);
+
+ return 1;
+}
+
+/***************************************************************************
+
+ Routines to actually mount the root directory
+
+ ***************************************************************************/
+
+/*
+ * Construct sockaddr_in from address and port number.
+ */
+static inline void
+set_sockaddr(struct sockaddr_in *sin, u_int32_t addr, u_int16_t port)
+{
+ memset(sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = addr;
+ sin->sin_port = port;
+}
+
+/*
+ * Extremely crude RPC-over-UDP call. We get an already encoded request
+ * to pass, we do that and put the reply into buffer. That (and callers
+ * below - getport, getfh2 and getfh3) should be replaced with proper
+ * librpc use. Now, if we only had one that wasn't bloated as a dead
+ * gnu that had lied for a while under the sun...
+ */
+
+static u_int32_t XID;
+static int flag;
+static void timeout(int n)
+{
+ (void)n;
+ flag = 1;
+}
+static int do_call(struct sockaddr_in *sin, u_int32_t msg[], u_int32_t rmsg[],
+ u_int32_t len, u_int32_t rlen)
+{
+ struct sockaddr_in from;
+ int slen = sizeof(struct sockaddr_in);
+ struct timeval tv = {1, 0};
+ int n;
+ int fd;
+
+ signal(SIGALRM, timeout);
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0)
+ goto Esocket;
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, sizeof(tv));
+ len *= 4;
+ if (sendto(fd, msg, len, 0, (struct sockaddr *)sin, slen)!=(int)len)
+ goto Esend;
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, sizeof(tv));
+ alarm(0);
+ flag = 0;
+ alarm(5);
+ rlen *= 4;
+ do {
+ slen = sizeof(from);
+ n = recvfrom(fd, rmsg, rlen, 0, (struct sockaddr*)&from, &slen);
+ if (flag || n < 0)
+ goto Erecv;
+ } while (memcmp(&from, sin, sizeof(from)) || rmsg[0] != msg[0]);
+
+ if (n < 6*4 || n % 4 || ntohl(rmsg[1]) != 1 || rmsg[2] ||
+ rmsg[3] || rmsg[4] || rmsg[5])
+ goto Einval;
+ alarm(0);
+ close(fd);
+ return n / 4 - 6;
+
+Esend: printf("rpc: write failed\n");
+ goto out;
+Erecv: printf("rpc: read failed\n");
+ goto out;
+Einval: printf("rpc: invalid response\n");
+ goto out;
+Esocket:printf("rpc: can't create socket\n");
+ return -1;
+out:
+ alarm(0);
+ close(fd);
+ return -1;
+}
+
+enum {
+ PMAP_GETPORT = 3
+};
+
+static void do_header(u_int32_t msg[], u_int32_t prog, u_int32_t vers, u_int32_t proc)
+{
+ msg[0] = XID++;
+ msg[1] = htonl(RPC_CALL);
+ msg[2] = htonl(RPC_VERSION);
+ msg[3] = htonl(prog);
+ msg[4] = htonl(vers);
+ msg[5] = htonl(proc);
+ msg[6] = htonl(RPC_AUTH_NULL);
+ msg[7] = htonl(0);
+ msg[8] = htonl(RPC_AUTH_NULL);
+ msg[9] = htonl(0);
+}
+
+static int getport(u_int32_t prog, u_int32_t vers, u_int32_t prot)
+{
+ struct sockaddr_in sin;
+ unsigned msg[14];
+ unsigned rmsg[7];
+ int n;
+ set_sockaddr(&sin, servaddr, htons(RPC_PMAP_PORT));
+ do_header(msg, RPC_PMAP_PROGRAM, RPC_PMAP_VERSION, PMAP_GETPORT);
+ msg[10] = htonl(prog);
+ msg[11] = htonl(vers);
+ msg[12] = htonl(prot);
+ msg[13] = htonl(0);
+ n = do_call(&sin, msg, rmsg, 14, 7);
+ if (n <= 0)
+ return -1;
+ else
+ return ntohl(rmsg[6]);
+}
+
+static int getfh2(void)
+{
+ struct sockaddr_in sin;
+ unsigned msg[10+1+256/4];
+ unsigned rmsg[6 + 1 + NFS2_FHSIZE/4];
+ int n;
+ int len = strlen(nfs_path);
+ set_sockaddr(&sin, servaddr, mount_port);
+
+ if (len > 255) {
+ printf("nfsroot: pathname is too long");
+ return -1;
+ }
+ memset(msg, 0, sizeof(msg));
+ do_header(msg, NFS_MNT_PROGRAM, NFS_MNT_VERSION, MNTPROC_MNT);
+ msg[10] = htonl(len);
+ strcpy((char*)&msg[11], nfs_path);
+ n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 7 + NFS2_FHSIZE/4);
+ if (n < 0)
+ return -1;
+ if (n != NFS2_FHSIZE/4 + 1)
+ goto Esize;
+ if (rmsg[6]) {
+ printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6]));
+ return -1;
+ }
+ nfs_data.root.size = NFS2_FHSIZE;
+ memcpy(nfs_data.root.data, &rmsg[7], NFS2_FHSIZE);
+ return 0;
+Esize:
+ printf("nfsroot: bad fhandle size");
+ return -1;
+}
+
+static int getfh3(void)
+{
+ struct sockaddr_in sin;
+ unsigned msg[10+1+256/4];
+ unsigned rmsg[6 + 1 + 1 + NFS3_FHSIZE/4];
+ int n;
+ int len = strlen(nfs_path);
+ int size;
+ set_sockaddr(&sin, servaddr, mount_port);
+
+ if (len > 255) {
+ printf("nfsroot: pathname is too long");
+ return -1;
+ }
+ memset(msg, 0, sizeof(msg));
+ do_header(msg, NFS_MNT_PROGRAM, NFS_MNT3_VERSION, MOUNTPROC3_MNT);
+ msg[10] = htonl(len);
+ strcpy((char*)&msg[11], nfs_path);
+ n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 8 + NFS3_FHSIZE/4);
+ if (n < 0)
+ return -1;
+ if (n <= 2)
+ goto Esize;
+ if (rmsg[6]) {
+ printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6]));
+ return -1;
+ }
+ size = ntohl(rmsg[7]);
+ if (size > NFS3_FHSIZE || n != 2 + size/4)
+ goto Esize;
+ nfs_data.root.size = size;
+ memcpy(nfs_data.root.data, &rmsg[8], size);
+ return 0;
+Esize:
+ printf("nfsroot: bad fhandle size");
+ return -1;
+}
+
+/*
+ * Use portmapper to find mountd and nfsd port numbers if not overriden
+ * by the user. Use defaults if portmapper is not available.
+ * XXX: Is there any nfs server with no portmapper?
+ */
+static int root_nfs_ports(void)
+{
+ int port;
+ int nfsd_ver, mountd_ver;
+ int proto;
+
+ if (nfs_data.flags & NFS_MOUNT_VER3) {
+ nfsd_ver = NFS3_VERSION;
+ mountd_ver = NFS_MNT3_VERSION;
+ } else {
+ nfsd_ver = NFS2_VERSION;
+ mountd_ver = NFS_MNT_VERSION;
+ }
+
+ proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
+
+ if (nfs_port < 0) {
+ if ((port = getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) {
+ printf("nfsroot: Unable to get nfsd port "
+ "number from server, using default\n");
+ port = NFS_PORT;
+ }
+ nfs_port = htons(port);
+ printf("nfsroot: Portmapper on server returned %d "
+ "as nfsd port\n", port);
+ }
+
+ if ((port = getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
+ printf("nfsroot: Unable to get mountd port "
+ "number from server, using default\n");
+ port = NFS_MNT_PORT;
+ }
+ mount_port = htons(port);
+ printf("nfsroot: mountd port is %d\n", port);
+
+ return 0;
+}
+
+int main(void)
+{
+ unsigned char *p;
+ struct timeval tv;
+ char *s;
+
+ /* FIX: use getopt() instead of this */
+
+ s = getenv("root_server_addr");
+ if (s)
+ root_server_addr = strtoul(s, NULL, 10);
+ s = getenv("root_server_path");
+ if (s)
+ strncpy(root_server_path, s, 255);
+ s = getenv("nfs_root_name");
+ if (s)
+ strncpy(nfs_root_name, s, 255);
+
+ /*
+ * Decode the root directory path name and NFS options from
+ * the kernel command line. This has to go here in order to
+ * be able to use the client IP address for the remote root
+ * directory (necessary for pure RARP booting).
+ */
+ if (root_nfs_name(nfs_root_name) < 0)
+ return 0;
+ if ((servaddr = root_server_addr) == INADDR_NONE) {
+ printf("nfsroot: No NFS server available, giving up.\n");
+ return 0;
+ }
+
+ p = (char *) &servaddr;
+ sprintf(nfs_data.hostname, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+
+#ifdef NFSROOT_DEBUG
+ printf("nfsroot: Mounting %s on server %s as root\n",
+ nfs_path, nfs_data.hostname);
+ printf("nfsroot: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
+ nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
+ printf("nfsroot: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
+ nfs_data.acregmin, nfs_data.acregmax,
+ nfs_data.acdirmin, nfs_data.acdirmax);
+ printf("nfsroot: nfsd port = %d, mountd port = %d, flags = %08x\n",
+ nfs_port, mount_port, nfs_data.flags);
+#endif
+
+ gettimeofday(&tv, NULL);
+ XID = (tv.tv_sec << 15) ^ tv.tv_usec;
+
+ if (root_nfs_ports() < 0)
+ return 0;
+ if (nfs_data.flags & NFS_MOUNT_VER3) {
+ if (getfh3())
+ return 0;
+ } else {
+ if (getfh2())
+ return 0;
+ }
+ set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port);
+ return mount("/dev/root", "/mnt", "nfs", 0, &nfs_data) == 0;
+}
diff --git a/klibc/klibc/tests/setjmptest.c b/klibc/klibc/tests/setjmptest.c
new file mode 100644
index 0000000000..a199eedab8
--- /dev/null
+++ b/klibc/klibc/tests/setjmptest.c
@@ -0,0 +1,36 @@
+/*
+ * setjmptest.c
+ */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+static jmp_buf buf;
+
+void do_stuff(int v)
+{
+ printf("setjmp returned %d\n", v);
+ longjmp(buf, v+1);
+}
+
+void recurse(int ctr, int v)
+{
+ if ( ctr-- ) {
+ recurse(ctr, v);
+ } else {
+ do_stuff(v);
+ }
+ _fwrite(".", 1, stdout);
+}
+
+int main(void)
+{
+ int v;
+
+ v = setjmp(buf);
+
+ if ( v < 256 )
+ recurse(v,v);
+
+ return 0;
+}
diff --git a/klibc/klibc/tests/testrand48.c b/klibc/klibc/tests/testrand48.c
new file mode 100644
index 0000000000..bf046b6bda
--- /dev/null
+++ b/klibc/klibc/tests/testrand48.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void)
+{
+ unsigned short seed1[] = { 0x1234, 0x5678, 0x9abc };
+ unsigned short *oldseed;
+
+ oldseed = seed48(seed1);
+ printf("Initial seed: %#06x %#06x %#06x\n",
+ oldseed[0], oldseed[1], oldseed[2]);
+
+ printf("lrand48() = %ld\n", lrand48());
+
+ seed48(seed1);
+ printf("mrand48() = %ld\n", mrand48());
+
+ return 1;
+}
diff --git a/klibc/klibc/tests/testvsnp.c b/klibc/klibc/tests/testvsnp.c
new file mode 100644
index 0000000000..c86e8b30fb
--- /dev/null
+++ b/klibc/klibc/tests/testvsnp.c
@@ -0,0 +1,115 @@
+#include <assert.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(void)
+{
+ int r, i;
+ char buffer[512];
+
+ r = snprintf(buffer, 512, "Hello, %d", 37);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'d", 37373737);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'x", 0xdeadbeef);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#X", 0xdeadbeef);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#llo", 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ /* Make sure overflow works correctly */
+ memset(buffer, '\xff', 512);
+ r = snprintf(buffer, 16, "Hello, %'#llo", 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+ for ( i = 16 ; i < 512 ; i++ )
+ assert ( buffer[i] == '\xff' );
+
+ r = snprintf(buffer, 512, "Hello, %'#40.20llo", 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#-40.20llo", 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#*.*llo", 40, 20, 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, 20, 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, -20, 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %'#*.*llx", -40, -20, 0123456701234567ULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %p", &buffer);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %P", &buffer);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %20p", &buffer);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %-20p", &buffer);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 512, "Hello, %-20p", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 20, "Hello, %'-20p", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 15, "Hello, %'-20p", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 3, "Hello, %'-20p", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ /* This shouldn't change buffer in any way! */
+ r = snprintf(buffer, 0, "Hello, %'-20p", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ for ( i = -30 ; i <= 30 ; i++ ) {
+ r = snprintf(buffer, 40, "Hello, %'*p", i, NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+ }
+
+ r = snprintf(buffer, 40, "Hello, %'-20s", "String");
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'20s", "String");
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'020s", "String");
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'-20s", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'20s", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'020s", NULL);
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'-20c", '*');
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'20c", '*');
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ r = snprintf(buffer, 40, "Hello, %'020c", '*');
+ printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r);
+
+ return 0;
+}
+
diff --git a/klibc/klibc/time.c b/klibc/klibc/time.c
new file mode 100644
index 0000000000..8f6e89738d
--- /dev/null
+++ b/klibc/klibc/time.c
@@ -0,0 +1,27 @@
+/*
+ * time.c
+ */
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_time
+
+_syscall1(time_t,time,time_t *,t);
+
+#else
+
+time_t time(time_t *t)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ if ( t )
+ *t = (time_t)tv.tv_sec;
+
+ return (time_t)tv.tv_sec;
+}
+
+#endif
diff --git a/klibc/klibc/umount.c b/klibc/klibc/umount.c
new file mode 100644
index 0000000000..9a8e62a779
--- /dev/null
+++ b/klibc/klibc/umount.c
@@ -0,0 +1,12 @@
+/*
+ * umount.c
+ *
+ * Single-argument form of umount
+ */
+
+#include <sys/mount.h>
+
+int umount(const char *dir)
+{
+ return umount2(dir, 0);
+}
diff --git a/klibc/klibc/unsetenv.c b/klibc/klibc/unsetenv.c
new file mode 100644
index 0000000000..5f39f3d8f9
--- /dev/null
+++ b/klibc/klibc/unsetenv.c
@@ -0,0 +1,40 @@
+/*
+ * unsetenv.c
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int unsetenv(const char *name)
+{
+ size_t len;
+ char **p, *q;
+ const char *z;
+
+ if ( !name || !name[0] ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ len = 0;
+ for ( z = name ; *z ; z++ ) {
+ len++;
+ if ( *z == '=' ) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ for ( p = environ ; (q = *p) ; p++ ) {
+ if ( !strncmp(name,q,len) && q[len] == '=' )
+ break;
+ }
+
+ for ( ; (q = *p) ; p++ ) {
+ p[0] = p[1];
+ }
+
+ return 0;
+}
diff --git a/klibc/klibc/usleep.c b/klibc/klibc/usleep.c
new file mode 100644
index 0000000000..b63352eebf
--- /dev/null
+++ b/klibc/klibc/usleep.c
@@ -0,0 +1,15 @@
+/*
+ * usleep.c
+ */
+
+#include <errno.h>
+#include <time.h>
+
+void usleep(unsigned long usec)
+{
+ struct timespec ts;
+
+ ts.tv_sec = usec/1000000UL;
+ ts.tv_nsec = (usec%1000000UL) * 1000;
+ while ( nanosleep(&ts,&ts) == -1 && errno == EINTR );
+}
diff --git a/klibc/klibc/utime.c b/klibc/klibc/utime.c
new file mode 100644
index 0000000000..a00b589629
--- /dev/null
+++ b/klibc/klibc/utime.c
@@ -0,0 +1,30 @@
+/*
+ * utime.c
+ */
+
+#include <utime.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_utime
+
+_syscall2(int,utime,const char *,filename,const struct utimbuf *,buf);
+
+#else
+
+static inline _syscall2(int,utimes,const char *,filename, const struct timeval *,tvp);
+
+int utime(const char *filename, const struct utimbuf *buf)
+{
+ struct timeval tvp[2];
+
+ tvp[0].tv_sec = buf->actime;
+ tvp[0].tv_usec = 0;
+ tvp[1].tv_sec = buf->modtime;
+ tvp[1].tv_usec = 0;
+
+ return utimes(filename, tvp);
+}
+
+#endif
diff --git a/klibc/klibc/vfprintf.c b/klibc/klibc/vfprintf.c
new file mode 100644
index 0000000000..39cf9838f6
--- /dev/null
+++ b/klibc/klibc/vfprintf.c
@@ -0,0 +1,26 @@
+/*
+ * vfprintf.c
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#define BUFFER_SIZE 32768
+
+int vfprintf(FILE *file, const char *format, va_list ap)
+{
+ int rv;
+ char buffer[BUFFER_SIZE];
+
+ rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
+
+ if ( rv < 0 )
+ return rv;
+
+ if ( rv > BUFFER_SIZE-1 )
+ rv = BUFFER_SIZE-1;
+
+ return _fwrite(buffer, rv, file);
+}
diff --git a/klibc/klibc/vprintf.c b/klibc/klibc/vprintf.c
new file mode 100644
index 0000000000..7d6066586f
--- /dev/null
+++ b/klibc/klibc/vprintf.c
@@ -0,0 +1,11 @@
+/*
+ * vprintf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int vprintf(const char *format, va_list ap)
+{
+ return vfprintf(stdout, format, ap);
+}
diff --git a/klibc/klibc/vsnprintf.c b/klibc/klibc/vsnprintf.c
new file mode 100644
index 0000000000..5cb9331954
--- /dev/null
+++ b/klibc/klibc/vsnprintf.c
@@ -0,0 +1,433 @@
+/*
+ * vsnprintf.c
+ *
+ * vsnprintf(), from which the rest of the printf()
+ * family is built
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+enum flags {
+ FL_ZERO = 0x01, /* Zero modifier */
+ FL_MINUS = 0x02, /* Minus modifier */
+ FL_PLUS = 0x04, /* Plus modifier */
+ FL_TICK = 0x08, /* ' modifier */
+ FL_SPACE = 0x10, /* Space modifier */
+ FL_HASH = 0x20, /* # modifier */
+ FL_SIGNED = 0x40, /* Number is signed */
+ FL_UPPER = 0x80 /* Upper case digits */
+};
+
+/* These may have to be adjusted on certain implementations */
+enum ranks {
+ rank_char = -2,
+ rank_short = -1,
+ rank_int = 0,
+ rank_long = 1,
+ rank_longlong = 2
+};
+
+#define MIN_RANK rank_char
+#define MAX_RANK rank_longlong
+
+#define INTMAX_RANK rank_longlong
+#define SIZE_T_RANK rank_long
+#define PTRDIFF_T_RANK rank_long
+
+#define EMIT(x) ({ if (o<n){*q++ = (x);} o++; })
+
+static size_t
+format_int(char *q, size_t n, uintmax_t val, enum flags flags,
+ int base, int width, int prec)
+{
+ char *qq;
+ size_t o = 0, oo;
+ static const char lcdigits[] = "0123456789abcdef";
+ static const char ucdigits[] = "0123456789ABCDEF";
+ const char *digits;
+ uintmax_t tmpval;
+ int minus = 0;
+ int ndigits = 0, nchars;
+ int tickskip, b4tick;
+
+ /* Select type of digits */
+ digits = (flags & FL_UPPER) ? ucdigits : lcdigits;
+
+ /* If signed, separate out the minus */
+ if ( flags & FL_SIGNED && (intmax_t)val < 0 ) {
+ minus = 1;
+ val = (uintmax_t)(-(intmax_t)val);
+ }
+
+ /* Count the number of digits needed. This returns zero for 0. */
+ tmpval = val;
+ while ( tmpval ) {
+ tmpval /= base;
+ ndigits++;
+ }
+
+ /* Adjust ndigits for size of output */
+
+ if ( flags & FL_HASH && base == 8 ) {
+ if ( prec < ndigits+1 )
+ prec = ndigits+1;
+ }
+
+ if ( ndigits < prec ) {
+ ndigits = prec; /* Mandatory number padding */
+ } else if ( val == 0 ) {
+ ndigits = 1; /* Zero still requires space */
+ }
+
+ /* For ', figure out what the skip should be */
+ if ( flags & FL_TICK ) {
+ tickskip = (base == 16) ? 4 : 3;
+ } else {
+ tickskip = ndigits; /* No tick marks */
+ }
+
+ /* Tick marks aren't digits, but generated by the number converter */
+ ndigits += (ndigits-1)/tickskip;
+
+ /* Now compute the number of nondigits */
+ nchars = ndigits;
+
+ if ( minus || (flags & (FL_PLUS|FL_SPACE)) )
+ nchars++; /* Need space for sign */
+ if ( (flags & FL_HASH) && base == 16 ) {
+ nchars += 2; /* Add 0x for hex */
+ }
+
+ /* Emit early space padding */
+ if ( !(flags & (FL_MINUS|FL_ZERO)) && width > nchars ) {
+ while ( width > nchars ) {
+ EMIT(' ');
+ width--;
+ }
+ }
+
+ /* Emit nondigits */
+ if ( minus )
+ EMIT('-');
+ else if ( flags & FL_PLUS )
+ EMIT('+');
+ else if ( flags & FL_SPACE )
+ EMIT(' ');
+
+ if ( (flags & FL_HASH) && base == 16 ) {
+ EMIT('0');
+ EMIT((flags & FL_UPPER) ? 'X' : 'x');
+ }
+
+ /* Emit zero padding */
+ if ( (flags & (FL_MINUS|FL_ZERO)) == FL_ZERO && width > ndigits ) {
+ while ( width > nchars ) {
+ EMIT('0');
+ width--;
+ }
+ }
+
+ /* Generate the number. This is done from right to left. */
+ q += ndigits; /* Advance the pointer to end of number */
+ o += ndigits;
+ qq = q; oo = o; /* Temporary values */
+
+ b4tick = tickskip;
+ while ( ndigits > 0 ) {
+ if ( !b4tick-- ) {
+ qq--; oo--; ndigits--;
+ if ( oo < n ) *qq = '_';
+ b4tick = tickskip-1;
+ }
+ qq--; oo--; ndigits--;
+ if ( oo < n ) *qq = digits[val%base];
+ val /= base;
+ }
+
+ /* Emit late space padding */
+ while ( (flags & FL_MINUS) && width > nchars ) {
+ EMIT(' ');
+ width--;
+ }
+
+ return o;
+}
+
+
+int vsnprintf(char *buffer, size_t n, const char *format, va_list ap)
+{
+ const char *p = format;
+ char ch;
+ char *q = buffer;
+ size_t o = 0; /* Number of characters output */
+ uintmax_t val = 0;
+ int rank = rank_int; /* Default rank */
+ int width = 0;
+ int prec = -1;
+ int base;
+ size_t sz;
+ enum flags flags = 0;
+ enum {
+ st_normal, /* Ground state */
+ st_flags, /* Special flags */
+ st_width, /* Field width */
+ st_prec, /* Field precision */
+ st_modifiers /* Length or conversion modifiers */
+ } state = st_normal;
+ const char *sarg; /* %s string argument */
+ char carg; /* %c char argument */
+ int slen; /* String length */
+
+ while ( (ch = *p++) ) {
+ switch ( state ) {
+ case st_normal:
+ if ( ch == '%' ) {
+ state = st_flags;
+ flags = 0; rank = rank_int; width = 0; prec = -1;
+ } else {
+ EMIT(ch);
+ }
+ break;
+
+ case st_flags:
+ switch ( ch ) {
+ case '-':
+ flags |= FL_MINUS;
+ break;
+ case '+':
+ flags |= FL_PLUS;
+ break;
+ case '\'':
+ flags |= FL_TICK;
+ break;
+ case ' ':
+ flags |= FL_SPACE;
+ break;
+ case '#':
+ flags |= FL_HASH;
+ break;
+ case '0':
+ flags |= FL_ZERO;
+ break;
+ default:
+ state = st_width;
+ p--; /* Process this character again */
+ break;
+ }
+ break;
+
+ case st_width:
+ if ( ch >= '0' && ch <= '9' ) {
+ width = width*10+(ch-'0');
+ } else if ( ch == '*' ) {
+ width = va_arg(ap, int);
+ if ( width < 0 ) {
+ width = -width;
+ flags |= FL_MINUS;
+ }
+ } else if ( ch == '.' ) {
+ prec = 0; /* Precision given */
+ state = st_prec;
+ } else {
+ state = st_modifiers;
+ p--; /* Process this character again */
+ }
+ break;
+
+ case st_prec:
+ if ( ch >= '0' && ch <= '9' ) {
+ prec = prec*10+(ch-'0');
+ } else if ( ch == '*' ) {
+ prec = va_arg(ap, int);
+ if ( prec < 0 )
+ prec = -1;
+ } else {
+ state = st_modifiers;
+ p--; /* Process this character again */
+ }
+ break;
+
+ case st_modifiers:
+ switch ( ch ) {
+ /* Length modifiers - nonterminal sequences */
+ case 'h':
+ rank--; /* Shorter rank */
+ break;
+ case 'l':
+ rank++; /* Longer rank */
+ break;
+ case 'j':
+ rank = INTMAX_RANK;
+ break;
+ case 'z':
+ rank = SIZE_T_RANK;
+ break;
+ case 't':
+ rank = PTRDIFF_T_RANK;
+ break;
+ case 'L':
+ case 'q':
+ rank += 2;
+ break;
+ default:
+ /* Output modifiers - terminal sequences */
+ state = st_normal; /* Next state will be normal */
+ if ( rank < MIN_RANK ) /* Canonicalize rank */
+ rank = MIN_RANK;
+ else if ( rank > MAX_RANK )
+ rank = MAX_RANK;
+
+ switch ( ch ) {
+ case 'P': /* Upper case pointer */
+ flags |= FL_UPPER;
+ /* fall through */
+ case 'p': /* Pointer */
+ base = 16;
+ prec = (CHAR_BIT*sizeof(void *)+3)/4;
+ flags |= FL_HASH;
+ val = (uintmax_t)(uintptr_t)va_arg(ap, void *);
+ goto is_integer;
+
+ case 'd': /* Signed decimal output */
+ case 'i':
+ base = 10;
+ flags |= FL_SIGNED;
+ switch (rank) {
+ case rank_char:
+ /* Yes, all these casts are needed... */
+ val = (uintmax_t)(intmax_t)(signed char)va_arg(ap, signed int);
+ break;
+ case rank_short:
+ val = (uintmax_t)(intmax_t)(signed short)va_arg(ap, signed int);
+ break;
+ case rank_int:
+ val = (uintmax_t)(intmax_t)va_arg(ap, signed int);
+ break;
+ case rank_long:
+ val = (uintmax_t)(intmax_t)va_arg(ap, signed long);
+ break;
+ case rank_longlong:
+ val = (uintmax_t)(intmax_t)va_arg(ap, signed long long);
+ break;
+ }
+ goto is_integer;
+ case 'o': /* Octal */
+ base = 8;
+ goto is_unsigned;
+ case 'u': /* Unsigned decimal */
+ base = 10;
+ goto is_unsigned;
+ case 'X': /* Upper case hexadecimal */
+ flags |= FL_UPPER;
+ /* fall through */
+ case 'x': /* Hexadecimal */
+ base = 16;
+ goto is_unsigned;
+
+ is_unsigned:
+ switch (rank) {
+ case rank_char:
+ val = (uintmax_t)(unsigned char)va_arg(ap, unsigned int);
+ break;
+ case rank_short:
+ val = (uintmax_t)(unsigned short)va_arg(ap, unsigned int);
+ break;
+ case rank_int:
+ val = (uintmax_t)va_arg(ap, unsigned int);
+ break;
+ case rank_long:
+ val = (uintmax_t)va_arg(ap, unsigned long);
+ break;
+ case rank_longlong:
+ val = (uintmax_t)va_arg(ap, unsigned long long);
+ break;
+ }
+ /* fall through */
+
+ is_integer:
+ sz = format_int(q, (o<n) ? n-o : 0, val, flags, base, width, prec);
+ q += sz; o += sz;
+ break;
+
+ case 'c': /* Character */
+ carg = (char)va_arg(ap, int);
+ sarg = &carg;
+ slen = 1;
+ goto is_string;
+ case 's': /* String */
+ sarg = va_arg(ap, const char *);
+ sarg = sarg ? sarg : "(null)";
+ slen = strlen(sarg);
+ goto is_string;
+
+ is_string:
+ {
+ char sch;
+ int i;
+
+ if ( prec != -1 && slen > prec )
+ slen = prec;
+
+ if ( width > slen && !(flags & FL_MINUS) ) {
+ char pad = (flags & FL_ZERO) ? '0' : ' ';
+ while ( width > slen ) {
+ EMIT(pad);
+ width--;
+ }
+ }
+ for ( i = slen ; i ; i-- ) {
+ sch = *sarg++;
+ EMIT(sch);
+ }
+ if ( width > slen && (flags & FL_MINUS) ) {
+ while ( width > slen ) {
+ EMIT(' ');
+ width--;
+ }
+ }
+ }
+ break;
+
+ case 'n': /* Output the number of characters written */
+ {
+ switch (rank) {
+ case rank_char:
+ *va_arg(ap, signed char *) = o;
+ break;
+ case rank_short:
+ *va_arg(ap, signed short *) = o;
+ break;
+ case rank_int:
+ *va_arg(ap, signed int *) = o;
+ break;
+ case rank_long:
+ *va_arg(ap, signed long *) = o;
+ break;
+ case rank_longlong:
+ *va_arg(ap, signed long long *) = o;
+ break;
+ }
+ }
+ break;
+
+ default: /* Anything else, including % */
+ EMIT(ch);
+ break;
+ }
+ }
+ }
+ }
+
+ /* Null-terminate the string */
+ if ( o<n )
+ *q = '\0'; /* No overflow */
+ else if ( n>0 )
+ buffer[n-1] = '\0'; /* Overflow - terminate at end of buffer */
+
+ return o;
+}
diff --git a/klibc/klibc/vsprintf.c b/klibc/klibc/vsprintf.c
new file mode 100644
index 0000000000..4a6100e70c
--- /dev/null
+++ b/klibc/klibc/vsprintf.c
@@ -0,0 +1,11 @@
+/*
+ * vsprintf.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int vsprintf(char *buffer, const char *format, va_list ap)
+{
+ return vsnprintf(buffer, ~(size_t)0, format, ap);
+}
diff --git a/klibc/klibc/vsscanf.c b/klibc/klibc/vsscanf.c
new file mode 100644
index 0000000000..12a82b2747
--- /dev/null
+++ b/klibc/klibc/vsscanf.c
@@ -0,0 +1,365 @@
+/*
+ * vsscanf.c
+ *
+ * vsscanf(), from which the rest of the scanf()
+ * family is built
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+#ifndef LONG_BIT
+#define LONG_BIT (CHAR_BIT*sizeof(long))
+#endif
+
+enum flags {
+ FL_SPLAT = 0x01, /* Drop the value, do not assign */
+ FL_INV = 0x02, /* Character-set with inverse */
+ FL_WIDTH = 0x04, /* Field width specified */
+ FL_MINUS = 0x08, /* Negative number */
+};
+
+enum ranks {
+ rank_char = -2,
+ rank_short = -1,
+ rank_int = 0,
+ rank_long = 1,
+ rank_longlong = 2,
+ rank_ptr = INT_MAX /* Special value used for pointers */
+};
+
+#define MIN_RANK rank_char
+#define MAX_RANK rank_longlong
+
+#define INTMAX_RANK rank_longlong
+#define SIZE_T_RANK rank_long
+#define PTRDIFF_T_RANK rank_long
+
+enum bail {
+ bail_none = 0, /* No error condition */
+ bail_eof, /* Hit EOF */
+ bail_err /* Conversion mismatch */
+};
+
+static inline const char *
+skipspace(const char *p)
+{
+ while ( isspace((unsigned char)*p) ) p++;
+ return p;
+}
+
+#undef set_bit
+static inline void
+set_bit(unsigned long *bitmap, unsigned int bit)
+{
+ bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT);
+}
+
+#undef test_bit
+static inline int
+test_bit(unsigned long *bitmap, unsigned int bit)
+{
+ return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1;
+}
+
+int vsscanf(const char *buffer, const char *format, va_list ap)
+{
+ const char *p = format;
+ char ch;
+ const char *q = buffer;
+ const char *qq;
+ uintmax_t val = 0;
+ int rank = rank_int; /* Default rank */
+ unsigned int width = UINT_MAX;
+ int base;
+ enum flags flags = 0;
+ enum {
+ st_normal, /* Ground state */
+ st_flags, /* Special flags */
+ st_width, /* Field width */
+ st_modifiers, /* Length or conversion modifiers */
+ st_match_init, /* Initial state of %[ sequence */
+ st_match, /* Main state of %[ sequence */
+ st_match_range, /* After - in a %[ sequence */
+ } state = st_normal;
+ char *sarg = NULL; /* %s %c or %[ string argument */
+ enum bail bail = bail_none;
+ int sign;
+ int converted = 0; /* Successful conversions */
+ unsigned long matchmap[((1 << CHAR_BIT)+(LONG_BIT-1))/LONG_BIT];
+ int matchinv = 0; /* Is match map inverted? */
+ unsigned char range_start = 0;
+
+ while ( (ch = *p++) && !bail ) {
+ switch ( state ) {
+ case st_normal:
+ if ( ch == '%' ) {
+ state = st_flags;
+ flags = 0; rank = rank_int; width = UINT_MAX;
+ } else if ( isspace((unsigned char)ch) ) {
+ q = skipspace(q);
+ } else {
+ if ( *q == ch )
+ q++;
+ else
+ bail = bail_err; /* Match failure */
+ }
+ break;
+
+ case st_flags:
+ switch ( ch ) {
+ case '*':
+ flags |= FL_SPLAT;
+ break;
+ case '0' ... '9':
+ width = (ch-'0');
+ state = st_width;
+ flags |= FL_WIDTH;
+ break;
+ default:
+ state = st_modifiers;
+ p--; /* Process this character again */
+ break;
+ }
+ break;
+
+ case st_width:
+ if ( ch >= '0' && ch <= '9' ) {
+ width = width*10+(ch-'0');
+ } else {
+ state = st_modifiers;
+ p--; /* Process this character again */
+ }
+ break;
+
+ case st_modifiers:
+ switch ( ch ) {
+ /* Length modifiers - nonterminal sequences */
+ case 'h':
+ rank--; /* Shorter rank */
+ break;
+ case 'l':
+ rank++; /* Longer rank */
+ break;
+ case 'j':
+ rank = INTMAX_RANK;
+ break;
+ case 'z':
+ rank = SIZE_T_RANK;
+ break;
+ case 't':
+ rank = PTRDIFF_T_RANK;
+ break;
+ case 'L':
+ case 'q':
+ rank = rank_longlong; /* long double/long long */
+ break;
+
+ default:
+ /* Output modifiers - terminal sequences */
+ state = st_normal; /* Next state will be normal */
+ if ( rank < MIN_RANK ) /* Canonicalize rank */
+ rank = MIN_RANK;
+ else if ( rank > MAX_RANK )
+ rank = MAX_RANK;
+
+ switch ( ch ) {
+ case 'P': /* Upper case pointer */
+ case 'p': /* Pointer */
+#if 0 /* Enable this to allow null pointers by name */
+ q = skipspace(q);
+ if ( !isdigit((unsigned char)*q) ) {
+ static const char * const nullnames[] =
+ { "null", "nul", "nil", "(null)", "(nul)", "(nil)", 0 };
+ const char * const *np;
+
+ /* Check to see if it's a null pointer by name */
+ for ( np = nullnames ; *np ; np++ ) {
+ if ( !strncasecmp(q, *np, strlen(*np)) ) {
+ val = (uintmax_t)((void *)NULL);
+ goto set_integer;
+ }
+ }
+ /* Failure */
+ bail = bail_err;
+ break;
+ }
+ /* else */
+#endif
+ rank = rank_ptr;
+ base = 0; sign = 0;
+ goto scan_int;
+
+ case 'i': /* Base-independent integer */
+ base = 0; sign = 1;
+ goto scan_int;
+
+ case 'd': /* Decimal integer */
+ base = 10; sign = 1;
+ goto scan_int;
+
+ case 'o': /* Octal integer */
+ base = 8; sign = 0;
+ goto scan_int;
+
+ case 'u': /* Unsigned decimal integer */
+ base = 10; sign = 0;
+ goto scan_int;
+
+ case 'x': /* Hexadecimal integer */
+ case 'X':
+ base = 16; sign = 0;
+ goto scan_int;
+
+ case 'n': /* Number of characters consumed */
+ val = (q-buffer);
+ goto set_integer;
+
+ scan_int:
+ q = skipspace(q);
+ if ( !*q ) {
+ bail = bail_eof;
+ break;
+ }
+ val = strntoumax(q, (char **)&qq, base, width);
+ if ( qq == q ) {
+ bail = bail_err;
+ break;
+ }
+ q = qq;
+ converted++;
+ /* fall through */
+
+ set_integer:
+ if ( !(flags & FL_SPLAT) ) {
+ switch(rank) {
+ case rank_char:
+ *va_arg(ap, unsigned char *) = (unsigned char)val;
+ break;
+ case rank_short:
+ *va_arg(ap, unsigned short *) = (unsigned short)val;
+ break;
+ case rank_int:
+ *va_arg(ap, unsigned int *) = (unsigned int)val;
+ break;
+ case rank_long:
+ *va_arg(ap, unsigned long *) = (unsigned long)val;
+ break;
+ case rank_longlong:
+ *va_arg(ap, unsigned long long *) = (unsigned long long)val;
+ break;
+ case rank_ptr:
+ *va_arg(ap, void **) = (void *)(uintptr_t)val;
+ break;
+ }
+ }
+ break;
+
+ case 'c': /* Character */
+ width = (flags & FL_WIDTH) ? width : 1; /* Default width == 1 */
+ sarg = va_arg(ap, char *);
+ while ( width-- ) {
+ if ( !*q ) {
+ bail = bail_eof;
+ break;
+ }
+ *sarg++ = *q++;
+ }
+ if ( !bail )
+ converted++;
+ break;
+
+ case 's': /* String */
+ {
+ char *sp;
+ sp = sarg = va_arg(ap, char *);
+ while ( width-- && *q && !isspace((unsigned char)*q) ) {
+ *sp++ = *q++;
+ }
+ if ( sarg != sp ) {
+ *sp = '\0'; /* Terminate output */
+ converted++;
+ } else {
+ bail = bail_eof;
+ }
+ }
+ break;
+
+ case '[': /* Character range */
+ sarg = va_arg(ap, char *);
+ state = st_match_init;
+ matchinv = 0;
+ memset(matchmap, 0, sizeof matchmap);
+ break;
+
+ case '%': /* %% sequence */
+ if ( *q == '%' )
+ q++;
+ else
+ bail = bail_err;
+ break;
+
+ default: /* Anything else */
+ bail = bail_err; /* Unknown sequence */
+ break;
+ }
+ }
+ break;
+
+ case st_match_init: /* Initial state for %[ match */
+ if ( ch == '^' && !(flags & FL_INV) ) {
+ matchinv = 1;
+ } else {
+ set_bit(matchmap, (unsigned char)ch);
+ state = st_match;
+ }
+ break;
+
+ case st_match: /* Main state for %[ match */
+ if ( ch == ']' ) {
+ goto match_run;
+ } else if ( ch == '-' ) {
+ range_start = (unsigned char)ch;
+ state = st_match_range;
+ } else {
+ set_bit(matchmap, (unsigned char)ch);
+ }
+ break;
+
+ case st_match_range: /* %[ match after - */
+ if ( ch == ']' ) {
+ set_bit(matchmap, (unsigned char)'-'); /* - was last character */
+ goto match_run;
+ } else {
+ int i;
+ for ( i = range_start ; i < (unsigned char)ch ; i++ )
+ set_bit(matchmap, i);
+ state = st_match;
+ }
+ break;
+
+ match_run: /* Match expression finished */
+ qq = q;
+ while ( width && *q && test_bit(matchmap, (unsigned char)*q)^matchinv ) {
+ *sarg++ = *q++;
+ }
+ if ( q != qq ) {
+ *sarg = '\0';
+ converted++;
+ } else {
+ bail = *q ? bail_err : bail_eof;
+ }
+ break;
+ }
+ }
+
+ if ( bail == bail_eof && !converted )
+ converted = -1; /* Return EOF (-1) */
+
+ return converted;
+}
diff --git a/klibc/klibc/wait.c b/klibc/klibc/wait.c
new file mode 100644
index 0000000000..5e0bbe29c5
--- /dev/null
+++ b/klibc/klibc/wait.c
@@ -0,0 +1,12 @@
+/*
+ * wait.c
+ */
+
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+pid_t wait(int *status)
+{
+ return wait4((pid_t)-1, status, 0, NULL);
+}
diff --git a/klibc/klibc/wait3.c b/klibc/klibc/wait3.c
new file mode 100644
index 0000000000..48840ad155
--- /dev/null
+++ b/klibc/klibc/wait3.c
@@ -0,0 +1,12 @@
+/*
+ * wait3.c
+ */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+pid_t wait3(int *status, int options, struct rusage *rusage)
+{
+ return wait4((pid_t)-1, status, options, rusage);
+}
diff --git a/klibc/klibc/waitpid.c b/klibc/klibc/waitpid.c
new file mode 100644
index 0000000000..f7c5cbfbc0
--- /dev/null
+++ b/klibc/klibc/waitpid.c
@@ -0,0 +1,12 @@
+/*
+ * waitpid.c
+ */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+pid_t waitpid(pid_t pid, int *status, int options)
+{
+ return wait4(pid, status, options, NULL);
+}