chiark / gitweb /
[PATCH] added klibc version 0.82 (cvs tree) to the udev tree.
authorgreg@kroah.com <greg@kroah.com>
Thu, 23 Oct 2003 01:37:40 +0000 (18:37 -0700)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:05:23 +0000 (21:05 -0700)
Not hooked up to the build yet.

364 files changed:
klibc/MCONFIG [new file with mode: 0644]
klibc/Makefile
klibc/README [new file with mode: 0644]
klibc/klibc/CAVEATS [new file with mode: 0644]
klibc/klibc/LICENSE [new file with mode: 0644]
klibc/klibc/MCONFIG [new file with mode: 0644]
klibc/klibc/Makefile [new file with mode: 0644]
klibc/klibc/README [new file with mode: 0644]
klibc/klibc/SOCKETCALLS [new file with mode: 0644]
klibc/klibc/SYSCALLS [new file with mode: 0644]
klibc/klibc/__shared_init.c [new file with mode: 0644]
klibc/klibc/__signal.c [new file with mode: 0644]
klibc/klibc/__static_init.c [new file with mode: 0644]
klibc/klibc/abort.c [new file with mode: 0644]
klibc/klibc/alarm.c [new file with mode: 0644]
klibc/klibc/arch/README [new file with mode: 0644]
klibc/klibc/arch/alpha/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/alpha/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/alpha/README-gcc [new file with mode: 0644]
klibc/klibc/arch/alpha/crt0.S [new file with mode: 0644]
klibc/klibc/arch/alpha/divide.c [new file with mode: 0644]
klibc/klibc/arch/alpha/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/alpha/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/alpha/include/machine/asm.h [new file with mode: 0644]
klibc/klibc/arch/alpha/pipe.c [new file with mode: 0644]
klibc/klibc/arch/alpha/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/arm/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/arm/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/arm/crt0.S [new file with mode: 0644]
klibc/klibc/arch/arm/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/arm/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/arm/setjmp-arm.S [new file with mode: 0644]
klibc/klibc/arch/arm/setjmp-thumb.S [new file with mode: 0644]
klibc/klibc/arch/cris/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/cris/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/cris/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/i386/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/i386/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/i386/crt0.S [new file with mode: 0644]
klibc/klibc/arch/i386/exits.S [new file with mode: 0644]
klibc/klibc/arch/i386/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/i386/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/i386/include/klibc/diverr.h [new file with mode: 0644]
klibc/klibc/arch/i386/libgcc/__ashldi3.S [new file with mode: 0644]
klibc/klibc/arch/i386/libgcc/__ashrdi3.S [new file with mode: 0644]
klibc/klibc/arch/i386/libgcc/__lshrdi3.S [new file with mode: 0644]
klibc/klibc/arch/i386/libgcc/__muldi3.S [new file with mode: 0644]
klibc/klibc/arch/i386/libgcc/__negdi2.S [new file with mode: 0644]
klibc/klibc/arch/i386/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/i386/socketcall.S [new file with mode: 0644]
klibc/klibc/arch/ia64/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/ia64/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/ia64/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/m68k/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/m68k/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/m68k/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/mips/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/mips/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/mips/crt0.S [new file with mode: 0644]
klibc/klibc/arch/mips/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/mips/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/mips/include/machine/asm.h [new file with mode: 0644]
klibc/klibc/arch/mips/include/sgidefs.h [new file with mode: 0644]
klibc/klibc/arch/mips/pipe.S [new file with mode: 0644]
klibc/klibc/arch/mips/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/mips/vfork.S [new file with mode: 0644]
klibc/klibc/arch/mips64/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/mips64/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/mips64/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/parisc/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/parisc/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/parisc/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/ppc/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/ppc/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/ppc/crt0.S [new file with mode: 0644]
klibc/klibc/arch/ppc/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/ppc/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/ppc/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/ppc64/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/ppc64/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/ppc64/crt0.S [new file with mode: 0644]
klibc/klibc/arch/ppc64/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/s390/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/s390/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/s390/crt0.S [new file with mode: 0644]
klibc/klibc/arch/s390/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/s390/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/s390/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/s390x/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/s390x/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/s390x/crt0.S [new file with mode: 0644]
klibc/klibc/arch/s390x/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/s390x/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/s390x/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/sh/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/sh/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/sh/crt0.S [new file with mode: 0644]
klibc/klibc/arch/sh/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/sh/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/sh/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/sparc/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/sparc/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/sparc/crt0.S [new file with mode: 0644]
klibc/klibc/arch/sparc/crt0i.S [new file with mode: 0644]
klibc/klibc/arch/sparc/divrem.m4 [new file with mode: 0644]
klibc/klibc/arch/sparc/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/sparc/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/sparc/include/machine/asm.h [new file with mode: 0644]
klibc/klibc/arch/sparc/include/machine/frame.h [new file with mode: 0644]
klibc/klibc/arch/sparc/include/machine/trap.h [new file with mode: 0644]
klibc/klibc/arch/sparc/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/sparc/smul.S [new file with mode: 0644]
klibc/klibc/arch/sparc/umul.S [new file with mode: 0644]
klibc/klibc/arch/sparc64/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/sparc64/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/sparc64/crt0.S [new file with mode: 0644]
klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/sparc64/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/sparc64/setjmp.S [new file with mode: 0644]
klibc/klibc/arch/x86_64/MCONFIG [new file with mode: 0644]
klibc/klibc/arch/x86_64/Makefile.inc [new file with mode: 0644]
klibc/klibc/arch/x86_64/crt0.S [new file with mode: 0644]
klibc/klibc/arch/x86_64/exits.S [new file with mode: 0644]
klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h [new file with mode: 0644]
klibc/klibc/arch/x86_64/include/klibc/archsys.h [new file with mode: 0644]
klibc/klibc/arch/x86_64/setjmp.S [new file with mode: 0644]
klibc/klibc/assert.c [new file with mode: 0644]
klibc/klibc/atexit.c [new file with mode: 0644]
klibc/klibc/atexit.h [new file with mode: 0644]
klibc/klibc/atoi.c [new file with mode: 0644]
klibc/klibc/atol.c [new file with mode: 0644]
klibc/klibc/atoll.c [new file with mode: 0644]
klibc/klibc/atox.c [new file with mode: 0644]
klibc/klibc/brk.c [new file with mode: 0644]
klibc/klibc/bsd_signal.c [new file with mode: 0644]
klibc/klibc/calloc.c [new file with mode: 0644]
klibc/klibc/closelog.c [new file with mode: 0644]
klibc/klibc/creat.c [new file with mode: 0644]
klibc/klibc/ctypes.c [new file with mode: 0644]
klibc/klibc/exec_l.c [new file with mode: 0644]
klibc/klibc/execl.c [new file with mode: 0644]
klibc/klibc/execle.c [new file with mode: 0644]
klibc/klibc/execlp.c [new file with mode: 0644]
klibc/klibc/execlpe.c [new file with mode: 0644]
klibc/klibc/execv.c [new file with mode: 0644]
klibc/klibc/execvp.c [new file with mode: 0644]
klibc/klibc/execvpe.c [new file with mode: 0644]
klibc/klibc/exitc.c [new file with mode: 0644]
klibc/klibc/fdatasync.c [new file with mode: 0644]
klibc/klibc/fgetc.c [new file with mode: 0644]
klibc/klibc/fgets.c [new file with mode: 0644]
klibc/klibc/fopen.c [new file with mode: 0644]
klibc/klibc/fork.c [new file with mode: 0644]
klibc/klibc/fprintf.c [new file with mode: 0644]
klibc/klibc/fputc.c [new file with mode: 0644]
klibc/klibc/fputs.c [new file with mode: 0644]
klibc/klibc/fread.c [new file with mode: 0644]
klibc/klibc/fread2.c [new file with mode: 0644]
klibc/klibc/fwrite.c [new file with mode: 0644]
klibc/klibc/fwrite2.c [new file with mode: 0644]
klibc/klibc/getcwd.c [new file with mode: 0644]
klibc/klibc/getdomainname.c [new file with mode: 0644]
klibc/klibc/getenv.c [new file with mode: 0644]
klibc/klibc/gethostname.c [new file with mode: 0644]
klibc/klibc/getopt.c [new file with mode: 0644]
klibc/klibc/getpriority.c [new file with mode: 0644]
klibc/klibc/globals.c [new file with mode: 0644]
klibc/klibc/include/alloca.h [new file with mode: 0644]
klibc/klibc/include/arpa/inet.h [new file with mode: 0644]
klibc/klibc/include/assert.h [new file with mode: 0644]
klibc/klibc/include/bits32/bitsize/limits.h [new file with mode: 0644]
klibc/klibc/include/bits32/bitsize/stddef.h [new file with mode: 0644]
klibc/klibc/include/bits32/bitsize/stdint.h [new file with mode: 0644]
klibc/klibc/include/bits32/bitsize/stdintconst.h [new file with mode: 0644]
klibc/klibc/include/bits32/bitsize/stdintlimits.h [new file with mode: 0644]
klibc/klibc/include/bits64/bitsize/limits.h [new file with mode: 0644]
klibc/klibc/include/bits64/bitsize/stddef.h [new file with mode: 0644]
klibc/klibc/include/bits64/bitsize/stdint.h [new file with mode: 0644]
klibc/klibc/include/bits64/bitsize/stdintconst.h [new file with mode: 0644]
klibc/klibc/include/bits64/bitsize/stdintlimits.h [new file with mode: 0644]
klibc/klibc/include/ctype.h [new file with mode: 0644]
klibc/klibc/include/dirent.h [new file with mode: 0644]
klibc/klibc/include/elf.h [new file with mode: 0644]
klibc/klibc/include/endian.h [new file with mode: 0644]
klibc/klibc/include/errno.h [new file with mode: 0644]
klibc/klibc/include/fcntl.h [new file with mode: 0644]
klibc/klibc/include/grp.h [new file with mode: 0644]
klibc/klibc/include/inttypes.h [new file with mode: 0644]
klibc/klibc/include/klibc/compiler.h [new file with mode: 0644]
klibc/klibc/include/klibc/diverr.h [new file with mode: 0644]
klibc/klibc/include/klibc/extern.h [new file with mode: 0644]
klibc/klibc/include/limits.h [new file with mode: 0644]
klibc/klibc/include/net/if.h [new file with mode: 0644]
klibc/klibc/include/net/if_arp.h [new file with mode: 0644]
klibc/klibc/include/net/if_ether.h [new file with mode: 0644]
klibc/klibc/include/net/if_packet.h [new file with mode: 0644]
klibc/klibc/include/netinet/in.h [new file with mode: 0644]
klibc/klibc/include/netinet/in6.h [new file with mode: 0644]
klibc/klibc/include/netinet/ip.h [new file with mode: 0644]
klibc/klibc/include/netinet/tcp.h [new file with mode: 0644]
klibc/klibc/include/netinet/udp.h [new file with mode: 0644]
klibc/klibc/include/poll.h [new file with mode: 0644]
klibc/klibc/include/sched.h [new file with mode: 0644]
klibc/klibc/include/setjmp.h [new file with mode: 0644]
klibc/klibc/include/signal.h [new file with mode: 0644]
klibc/klibc/include/stdarg.h [new file with mode: 0644]
klibc/klibc/include/stddef.h [new file with mode: 0644]
klibc/klibc/include/stdint.h [new file with mode: 0644]
klibc/klibc/include/stdio.h [new file with mode: 0644]
klibc/klibc/include/stdlib.h [new file with mode: 0644]
klibc/klibc/include/string.h [new file with mode: 0644]
klibc/klibc/include/sys/dirent.h [new file with mode: 0644]
klibc/klibc/include/sys/fsuid.h [new file with mode: 0644]
klibc/klibc/include/sys/ioctl.h [new file with mode: 0644]
klibc/klibc/include/sys/klog.h [new file with mode: 0644]
klibc/klibc/include/sys/mman.h [new file with mode: 0644]
klibc/klibc/include/sys/module.h [new file with mode: 0644]
klibc/klibc/include/sys/mount.h [new file with mode: 0644]
klibc/klibc/include/sys/param.h [new file with mode: 0644]
klibc/klibc/include/sys/reboot.h [new file with mode: 0644]
klibc/klibc/include/sys/resource.h [new file with mode: 0644]
klibc/klibc/include/sys/select.h [new file with mode: 0644]
klibc/klibc/include/sys/socket.h [new file with mode: 0644]
klibc/klibc/include/sys/socketcalls.h [new file with mode: 0644]
klibc/klibc/include/sys/stat.h [new file with mode: 0644]
klibc/klibc/include/sys/syscall.h [new file with mode: 0644]
klibc/klibc/include/sys/time.h [new file with mode: 0644]
klibc/klibc/include/sys/times.h [new file with mode: 0644]
klibc/klibc/include/sys/types.h [new file with mode: 0644]
klibc/klibc/include/sys/uio.h [new file with mode: 0644]
klibc/klibc/include/sys/utime.h [new file with mode: 0644]
klibc/klibc/include/sys/utsname.h [new file with mode: 0644]
klibc/klibc/include/sys/vfs.h [new file with mode: 0644]
klibc/klibc/include/sys/wait.h [new file with mode: 0644]
klibc/klibc/include/syslog.h [new file with mode: 0644]
klibc/klibc/include/termios.h [new file with mode: 0644]
klibc/klibc/include/time.h [new file with mode: 0644]
klibc/klibc/include/unistd.h [new file with mode: 0644]
klibc/klibc/include/utime.h [new file with mode: 0644]
klibc/klibc/inet/bindresvport.c [new file with mode: 0644]
klibc/klibc/inet/inet_addr.c [new file with mode: 0644]
klibc/klibc/inet/inet_aton.c [new file with mode: 0644]
klibc/klibc/inet/inet_ntoa.c [new file with mode: 0644]
klibc/klibc/inet/inet_ntop.c [new file with mode: 0644]
klibc/klibc/inet/inet_pton.c [new file with mode: 0644]
klibc/klibc/interp.S [new file with mode: 0644]
klibc/klibc/isatty.c [new file with mode: 0644]
klibc/klibc/libgcc/__divdi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__divsi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__moddi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__modsi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__udivdi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__udivmoddi4.c [new file with mode: 0644]
klibc/klibc/libgcc/__udivmodsi4.c [new file with mode: 0644]
klibc/klibc/libgcc/__udivsi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__umoddi3.c [new file with mode: 0644]
klibc/klibc/libgcc/__umodsi3.c [new file with mode: 0644]
klibc/klibc/llseek.c [new file with mode: 0644]
klibc/klibc/lrand48.c [new file with mode: 0644]
klibc/klibc/makeerrlist.pl [new file with mode: 0644]
klibc/klibc/malloc.c [new file with mode: 0644]
klibc/klibc/malloc.h [new file with mode: 0644]
klibc/klibc/memccpy.c [new file with mode: 0644]
klibc/klibc/memchr.c [new file with mode: 0644]
klibc/klibc/memcmp.c [new file with mode: 0644]
klibc/klibc/memcpy.c [new file with mode: 0644]
klibc/klibc/memmem.c [new file with mode: 0644]
klibc/klibc/memmove.c [new file with mode: 0644]
klibc/klibc/memset.c [new file with mode: 0644]
klibc/klibc/memswap.c [new file with mode: 0644]
klibc/klibc/mmap.c [new file with mode: 0644]
klibc/klibc/nice.c [new file with mode: 0644]
klibc/klibc/onexit.c [new file with mode: 0644]
klibc/klibc/pause.c [new file with mode: 0644]
klibc/klibc/perror.c [new file with mode: 0644]
klibc/klibc/printf.c [new file with mode: 0644]
klibc/klibc/pty.c [new file with mode: 0644]
klibc/klibc/puts.c [new file with mode: 0644]
klibc/klibc/qsort.c [new file with mode: 0644]
klibc/klibc/raise.c [new file with mode: 0644]
klibc/klibc/readdir.c [new file with mode: 0644]
klibc/klibc/realloc.c [new file with mode: 0644]
klibc/klibc/reboot.c [new file with mode: 0644]
klibc/klibc/recv.c [new file with mode: 0644]
klibc/klibc/sbrk.c [new file with mode: 0644]
klibc/klibc/seed48.c [new file with mode: 0644]
klibc/klibc/select.c [new file with mode: 0644]
klibc/klibc/send.c [new file with mode: 0644]
klibc/klibc/setegid.c [new file with mode: 0644]
klibc/klibc/setenv.c [new file with mode: 0644]
klibc/klibc/seteuid.c [new file with mode: 0644]
klibc/klibc/setpgrp.c [new file with mode: 0644]
klibc/klibc/setresgid.c [new file with mode: 0644]
klibc/klibc/setresuid.c [new file with mode: 0644]
klibc/klibc/sha1hash.c [new file with mode: 0644]
klibc/klibc/sigaction.c [new file with mode: 0644]
klibc/klibc/siglist.c [new file with mode: 0644]
klibc/klibc/siglongjmp.c [new file with mode: 0644]
klibc/klibc/signal.c [new file with mode: 0644]
klibc/klibc/sigpending.c [new file with mode: 0644]
klibc/klibc/sigprocmask.c [new file with mode: 0644]
klibc/klibc/sigsuspend.c [new file with mode: 0644]
klibc/klibc/sleep.c [new file with mode: 0644]
klibc/klibc/snprintf.c [new file with mode: 0644]
klibc/klibc/socketcalls.pl [new file with mode: 0644]
klibc/klibc/socketcommon.h [new file with mode: 0644]
klibc/klibc/sprintf.c [new file with mode: 0644]
klibc/klibc/srand48.c [new file with mode: 0644]
klibc/klibc/sscanf.c [new file with mode: 0644]
klibc/klibc/strcat.c [new file with mode: 0644]
klibc/klibc/strchr.c [new file with mode: 0644]
klibc/klibc/strcmp.c [new file with mode: 0644]
klibc/klibc/strcpy.c [new file with mode: 0644]
klibc/klibc/strdup.c [new file with mode: 0644]
klibc/klibc/strerror.c [new file with mode: 0644]
klibc/klibc/strlen.c [new file with mode: 0644]
klibc/klibc/strncat.c [new file with mode: 0644]
klibc/klibc/strncmp.c [new file with mode: 0644]
klibc/klibc/strncpy.c [new file with mode: 0644]
klibc/klibc/strntoimax.c [new file with mode: 0644]
klibc/klibc/strntoumax.c [new file with mode: 0644]
klibc/klibc/strrchr.c [new file with mode: 0644]
klibc/klibc/strsep.c [new file with mode: 0644]
klibc/klibc/strspn.c [new file with mode: 0644]
klibc/klibc/strstr.c [new file with mode: 0644]
klibc/klibc/strtoimax.c [new file with mode: 0644]
klibc/klibc/strtok.c [new file with mode: 0644]
klibc/klibc/strtol.c [new file with mode: 0644]
klibc/klibc/strtoll.c [new file with mode: 0644]
klibc/klibc/strtoul.c [new file with mode: 0644]
klibc/klibc/strtoull.c [new file with mode: 0644]
klibc/klibc/strtoumax.c [new file with mode: 0644]
klibc/klibc/strtox.c [new file with mode: 0644]
klibc/klibc/syscalls.pl [new file with mode: 0644]
klibc/klibc/syscommon.h [new file with mode: 0644]
klibc/klibc/syslog.c [new file with mode: 0644]
klibc/klibc/system.c [new file with mode: 0644]
klibc/klibc/tests/getenvtest.c [new file with mode: 0644]
klibc/klibc/tests/getopttest.c [new file with mode: 0644]
klibc/klibc/tests/hello.c [new file with mode: 0644]
klibc/klibc/tests/idtest.c [new file with mode: 0644]
klibc/klibc/tests/malloctest.c [new file with mode: 0644]
klibc/klibc/tests/memstrtest.c [new file with mode: 0644]
klibc/klibc/tests/microhello.c [new file with mode: 0644]
klibc/klibc/tests/minihello.c [new file with mode: 0644]
klibc/klibc/tests/minips.c [new file with mode: 0644]
klibc/klibc/tests/nfs_no_rpc.c [new file with mode: 0644]
klibc/klibc/tests/setjmptest.c [new file with mode: 0644]
klibc/klibc/tests/testrand48.c [new file with mode: 0644]
klibc/klibc/tests/testvsnp.c [new file with mode: 0644]
klibc/klibc/time.c [new file with mode: 0644]
klibc/klibc/umount.c [new file with mode: 0644]
klibc/klibc/unsetenv.c [new file with mode: 0644]
klibc/klibc/usleep.c [new file with mode: 0644]
klibc/klibc/utime.c [new file with mode: 0644]
klibc/klibc/vfprintf.c [new file with mode: 0644]
klibc/klibc/vprintf.c [new file with mode: 0644]
klibc/klibc/vsnprintf.c [new file with mode: 0644]
klibc/klibc/vsprintf.c [new file with mode: 0644]
klibc/klibc/vsscanf.c [new file with mode: 0644]
klibc/klibc/wait.c [new file with mode: 0644]
klibc/klibc/wait3.c [new file with mode: 0644]
klibc/klibc/waitpid.c [new file with mode: 0644]
klibc/version [new file with mode: 0644]

diff --git a/klibc/MCONFIG b/klibc/MCONFIG
new file mode 100644 (file)
index 0000000..ed7755b
--- /dev/null
@@ -0,0 +1,41 @@
+# -*- makefile -*-
+#
+# Makefile configuration, without explicit rules
+#
+
+ARCH    = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+CROSS   = 
+CC     = $(CROSS)gcc
+LD      = $(CROSS)ld
+KLIBSRC = $(SRCROOT)/klibc
+REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -I$(KLIBSRC) \
+         -I$(KLIBSRC)/arch/$(ARCH)/include \
+         -I$(KLIBSRC)/include/bits$(BITSIZE) \
+         -D__KLIBC__ -DBITSIZE=$(BITSIZE) -I$(KLIBSRC)/include \
+         -I$(SRCROOT)/linux/include
+LDFLAGS =
+AR      = $(CROSS)ar
+RANLIB  = $(CROSS)ranlib
+NM     = $(CROSS)nm
+PERL    = perl
+STRIP   = $(CROSS)strip --strip-all -R .comment -R .note
+
+HOST_CC      = gcc
+HOST_LDFLAGS = -s
+HOST_LIBS    =
+
+CRT0    = $(KLIBSRC)/crt0.o
+KLIBC   = $(KLIBSRC)/libc.a
+LIBGCC  = $(shell $(CC) --print-libgcc)
+
+#
+# This indicates the location of the final version of the shared library.
+# THIS MUST BE AN ABSOLUTE PATH WITH NO FINAL SLASH.
+# Leave this empty to make it the root.
+#
+SHLIBDIR = /lib
+
+#
+# Include arch-specific rule fragments
+#
+include $(KLIBSRC)/arch/$(ARCH)/MCONFIG
index 288a86270763df15f549ec942adce184ec77a83a..5f9a7d6a6e9d41a01a64014a280ac9125bfe7321 100644 (file)
@@ -1,3 +1,6 @@
+SUBDIRS = klibc
 
 
-clean:
-       @echo "all clean"
+all:
+
+%:
+       @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
diff --git a/klibc/README b/klibc/README
new file mode 100644 (file)
index 0000000..577de2b
--- /dev/null
@@ -0,0 +1,16 @@
+Please see klibc/README for how to set up the tree before building.
+
+klibc is archived at:
+
+       ftp://ftp.zytor.com/pub/linux/libs/klibc/
+
+There is a mailing list for klibc and early-userspace issues at:
+
+       http://www.zytor.com/mailman/listinfo/klibc/
+
+There is also a cvsweb repository at:
+
+       http://www.zytor.com/cvsweb.cgi/klibc/
+
+There is no direct public CVS access yet, however.
+
diff --git a/klibc/klibc/CAVEATS b/klibc/klibc/CAVEATS
new file mode 100644 (file)
index 0000000..c7131ac
--- /dev/null
@@ -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 (file)
index 0000000..b512ff9
--- /dev/null
@@ -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 (file)
index 0000000..a46a98a
--- /dev/null
@@ -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 (file)
index 0000000..470a276
--- /dev/null
@@ -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 (file)
index 0000000..7d57518
--- /dev/null
@@ -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 (file)
index 0000000..1ab4e36
--- /dev/null
@@ -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 (file)
index 0000000..1ec94ac
--- /dev/null
@@ -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 (file)
index 0000000..63e3f46
--- /dev/null
@@ -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 (file)
index 0000000..b5081d3
--- /dev/null
@@ -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 (file)
index 0000000..dcb8d01
--- /dev/null
@@ -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 (file)
index 0000000..9280d98
--- /dev/null
@@ -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 (file)
index 0000000..ca7bb37
--- /dev/null
@@ -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 (file)
index 0000000..eceb23d
--- /dev/null
@@ -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 (file)
index 0000000..5987ed5
--- /dev/null
@@ -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 (file)
index 0000000..2a1100f
--- /dev/null
@@ -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 (file)
index 0000000..9aaba72
--- /dev/null
@@ -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 (file)
index 0000000..6c29581
--- /dev/null
@@ -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 (file)
index 0000000..49d77cd
--- /dev/null
@@ -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 (file)
index 0000000..9dc570a
--- /dev/null
@@ -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 (file)
index 0000000..16ed658
--- /dev/null
@@ -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 (file)
index 0000000..e22db90
--- /dev/null
@@ -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 (file)
index 0000000..5aee9ed
--- /dev/null
@@ -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 (file)
index 0000000..e1ad642
--- /dev/null
@@ -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 (file)
index 0000000..6fbea32
--- /dev/null
@@ -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 (file)
index 0000000..3ec8c05
--- /dev/null
@@ -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 (file)
index 0000000..8cd3640
--- /dev/null
@@ -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 (file)
index 0000000..c956b50
--- /dev/null
@@ -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 (file)
index 0000000..1a77e53
--- /dev/null
@@ -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 (file)
index 0000000..bcb30b4
--- /dev/null
@@ -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 (file)
index 0000000..b581c5f
--- /dev/null
@@ -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 (file)
index 0000000..27809eb
--- /dev/null
@@ -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 (file)
index 0000000..41183fd
--- /dev/null
@@ -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 (file)
index 0000000..dfdc70a
--- /dev/null
@@ -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 (file)
index 0000000..367ee89
--- /dev/null
@@ -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 (file)
index 0000000..171248a
--- /dev/null
@@ -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 (file)
index 0000000..1c82eda
--- /dev/null
@@ -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 (file)
index 0000000..59ff563
--- /dev/null
@@ -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 (file)
index 0000000..db04314
--- /dev/null
@@ -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 (file)
index 0000000..e21487b
--- /dev/null
@@ -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 (file)
index 0000000..410aba0
--- /dev/null
@@ -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 (file)
index 0000000..80ed4be
--- /dev/null
@@ -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 (file)
index 0000000..ba43f90
--- /dev/null
@@ -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 (file)
index 0000000..6e521ac
--- /dev/null
@@ -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 (file)
index 0000000..c164588
--- /dev/null
@@ -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 (file)
index 0000000..6c95cb2
--- /dev/null
@@ -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 (file)
index 0000000..bea900c
--- /dev/null
@@ -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 (file)
index 0000000..6bac1e6
--- /dev/null
@@ -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 (file)
index 0000000..631a478
--- /dev/null
@@ -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 (file)
index 0000000..1fb364f
--- /dev/null
@@ -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 (file)
index 0000000..ef5940a
--- /dev/null
@@ -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 (file)
index 0000000..2ba69b3
--- /dev/null
@@ -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 (file)
index 0000000..9abec14
--- /dev/null
@@ -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 (file)
index 0000000..8f6bed8
--- /dev/null
@@ -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 (file)
index 0000000..52b5184
--- /dev/null
@@ -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 (file)
index 0000000..09a2d2f
--- /dev/null
@@ -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 (file)
index 0000000..42d9dd5
--- /dev/null
@@ -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 (file)
index 0000000..40e5be2
--- /dev/null
@@ -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 (file)
index 0000000..f696cdf
--- /dev/null
@@ -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 (file)
index 0000000..e5239a6
--- /dev/null
@@ -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 (file)
index 0000000..eb103ac
--- /dev/null
@@ -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 (file)
index 0000000..d79f614
--- /dev/null
@@ -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 (file)
index 0000000..4d29375
--- /dev/null
@@ -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 (file)
index 0000000..aca8083
--- /dev/null
@@ -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 (file)
index 0000000..6a817e5
--- /dev/null
@@ -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 (file)
index 0000000..4a9529a
--- /dev/null
@@ -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 (file)
index 0000000..81e5106
--- /dev/null
@@ -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 (file)
index 0000000..93a3170
--- /dev/null
@@ -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 (file)
index 0000000..f7a983d
--- /dev/null
@@ -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 (file)
index 0000000..5013ba8
--- /dev/null
@@ -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 (file)
index 0000000..fcb0992
--- /dev/null
@@ -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 (file)
index 0000000..6e87a48
--- /dev/null
@@ -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 (file)
index 0000000..f7274b0
--- /dev/null
@@ -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 (file)
index 0000000..53e2fcc
--- /dev/null
@@ -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 (file)
index 0000000..33a5ff3
--- /dev/null
@@ -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 (file)
index 0000000..1c50301
--- /dev/null
@@ -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 (file)
index 0000000..6997693
--- /dev/null
@@ -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 (file)
index 0000000..434d0aa
--- /dev/null
@@ -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 (file)
index 0000000..2f352e8
--- /dev/null
@@ -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 (file)
index 0000000..4f81fee
--- /dev/null
@@ -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 (file)
index 0000000..e32c33f
--- /dev/null
@@ -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 (file)
index 0000000..45aa551
--- /dev/null
@@ -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 (file)
index 0000000..49c3e7e
--- /dev/null
@@ -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 (file)
index 0000000..11a641e
--- /dev/null
@@ -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 (file)
index 0000000..1cd0948
--- /dev/null
@@ -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 (file)
index 0000000..9713268
--- /dev/null
@@ -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 (file)
index 0000000..1c8232b
--- /dev/null
@@ -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 (file)
index 0000000..eff8f95
--- /dev/null
@@ -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 (file)
index 0000000..de35664
--- /dev/null
@@ -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 (file)
index 0000000..dd3ed0d
--- /dev/null
@@ -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 (file)
index 0000000..15f7113
--- /dev/null
@@ -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 (file)
index 0000000..251c57d
--- /dev/null
@@ -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 (file)
index 0000000..6cd4e5c
--- /dev/null
@@ -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 (file)
index 0000000..16d7ea1
--- /dev/null
@@ -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 (file)
index 0000000..c9938a5
--- /dev/null
@@ -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 (file)
index 0000000..28dd932
--- /dev/null
@@ -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 (file)
index 0000000..5f8050a
--- /dev/null
@@ -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 (file)
index 0000000..63f7602
--- /dev/null
@@ -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 (file)
index 0000000..cb94f46
--- /dev/null
@@ -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 (file)
index 0000000..0186810
--- /dev/null
@@ -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 (file)
index 0000000..148cb4b
--- /dev/null
@@ -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 (file)
index 0000000..97652a3
--- /dev/null
@@ -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 (file)
index 0000000..aa4171d
--- /dev/null
@@ -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 (file)
index 0000000..92c1c74
--- /dev/null
@@ -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 (file)
index 0000000..fe6e68d
--- /dev/null
@@ -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 (file)
index 0000000..b622bd8
--- /dev/null
@@ -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 (file)
index 0000000..b09175c
--- /dev/null
@@ -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 (file)
index 0000000..42c3ef6
--- /dev/null
@@ -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 (file)
index 0000000..f41ee2b
--- /dev/null
@@ -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 (file)
index 0000000..0eb218b
--- /dev/null
@@ -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 (file)
index 0000000..6a7193d
--- /dev/null
@@ -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 (file)
index 0000000..d490c63
--- /dev/null
@@ -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 (file)
index 0000000..d59f987
--- /dev/null
@@ -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 (file)
index 0000000..23af82e
--- /dev/null
@@ -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 (file)
index 0000000..022a31e
--- /dev/null
@@ -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 (file)
index 0000000..651e4f7
--- /dev/null
@@ -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 (file)
index 0000000..b04d47f
--- /dev/null
@@ -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 (file)
index 0000000..ecb14cc
--- /dev/null
@@ -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 (file)
index 0000000..c84443f
--- /dev/null
@@ -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 (file)
index 0000000..c562708
--- /dev/null
@@ -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 (file)
index 0000000..618f4fb
--- /dev/null
@@ -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 (file)
index 0000000..90d0a0d
--- /dev/null
@@ -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 (file)
index 0000000..3bd8b0a
--- /dev/null
@@ -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 (file)
index 0000000..45f547b
--- /dev/null
@@ -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 (file)
index 0000000..6d3ff23
--- /dev/null
@@ -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 (file)
index 0000000..078dd8b
--- /dev/null
@@ -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 (file)
index 0000000..a60d641
--- /dev/null
@@ -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 (file)
index 0000000..a6ec0bf
--- /dev/null
@@ -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 (file)
index 0000000..e65484e
--- /dev/null
@@ -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 (file)
index 0000000..25df79e
--- /dev/null
@@ -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 (file)
index 0000000..56f8d93
--- /dev/null
@@ -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 (file)
index 0000000..0a08c4e
--- /dev/null
@@ -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 (file)
index 0000000..9acc867
--- /dev/null
@@ -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 (file)
index 0000000..228a1b7
--- /dev/null
@@ -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 (file)
index 0000000..2359d4f
--- /dev/null
@@ -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 (file)
index 0000000..9bd2217
--- /dev/null
@@ -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 (file)
index 0000000..a9398b8
--- /dev/null
@@ -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 (file)
index 0000000..cdae11e
--- /dev/null
@@ -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 (file)
index 0000000..4581113
--- /dev/null
@@ -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 (file)
index 0000000..b073988
--- /dev/null
@@ -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 (file)
index 0000000..65c9aa4
--- /dev/null
@@ -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 (file)
index 0000000..fef972f
--- /dev/null
@@ -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 (file)
index 0000000..9856b76
--- /dev/null
@@ -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 (file)
index 0000000..b1065ee
--- /dev/null
@@ -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 (file)
index 0000000..afd791a
--- /dev/null
@@ -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 (file)
index 0000000..6e5d789
--- /dev/null
@@ -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 (file)
index 0000000..53079b0
--- /dev/null
@@ -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 (file)
index 0000000..83eee16
--- /dev/null
@@ -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 (file)
index 0000000..88a145a
--- /dev/null
@@ -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 (file)
index 0000000..5c84184
--- /dev/null
@@ -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 (file)
index 0000000..d7e4db8
--- /dev/null
@@ -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 (file)
index 0000000..df3823e
--- /dev/null
@@ -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 (file)
index 0000000..61aff16
--- /dev/null
@@ -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 (file)
index 0000000..4b68f96
--- /dev/null
@@ -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 (file)
index 0000000..8f7dba9
--- /dev/null
@@ -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 (file)
index 0000000..9e5ac81
--- /dev/null
@@ -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 (file)
index 0000000..0a73188
--- /dev/null
@@ -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 (file)
index 0000000..82ec832
--- /dev/null
@@ -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 (file)
index 0000000..350ec69
--- /dev/null
@@ -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 (file)
index 0000000..4cd68a3
--- /dev/null
@@ -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 (file)
index 0000000..84fc94c
--- /dev/null
@@ -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 (file)
index 0000000..6c5062e
--- /dev/null
@@ -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 (file)
index 0000000..5a992dc
--- /dev/null
@@ -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 (file)
index 0000000..d6db2cc
--- /dev/null
@@ -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 (file)
index 0000000..72ae91f
--- /dev/null
@@ -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 (file)
index 0000000..41a4d94
--- /dev/null
@@ -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 (file)
index 0000000..043b148
--- /dev/null
@@ -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 (file)
index 0000000..58cc37c
--- /dev/null
@@ -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 (file)
index 0000000..f90e524
--- /dev/null
@@ -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 (file)
index 0000000..bf6e695
--- /dev/null
@@ -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 (file)
index 0000000..40b4649
--- /dev/null
@@ -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 (file)
index 0000000..8157dd0
--- /dev/null
@@ -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 (file)
index 0000000..b44fe01
--- /dev/null
@@ -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 (file)
index 0000000..7b20da0
--- /dev/null
@@ -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 (file)
index 0000000..3e72621
--- /dev/null
@@ -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 (file)
index 0000000..f569f52
--- /dev/null
@@ -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 (file)
index 0000000..65f2db0
--- /dev/null
@@ -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 (file)
index 0000000..d110d17
--- /dev/null
@@ -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 (file)
index 0000000..2cb90a4
--- /dev/null
@@ -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 (file)
index 0000000..10dd138
--- /dev/null
@@ -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 (file)
index 0000000..bd0f3e7
--- /dev/null
@@ -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 (file)
index 0000000..10dbbd8
--- /dev/null
@@ -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 (file)
index 0000000..b2e6665
--- /dev/null
@@ -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 (file)
index 0000000..e90959c
--- /dev/null
@@ -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 (file)
index 0000000..03ceb31
--- /dev/null
@@ -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 (file)
index 0000000..e00fa63
--- /dev/null
@@ -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 (file)
index 0000000..5c284b2
--- /dev/null
@@ -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 (file)
index 0000000..4d8c8d3
--- /dev/null
@@ -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 (file)
index 0000000..f9c3467
--- /dev/null
@@ -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 (file)
index 0000000..f1532e5
--- /dev/null
@@ -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 (file)
index 0000000..1aa8e7b
--- /dev/null
@@ -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 (file)
index 0000000..a25f1b4
--- /dev/null
@@ -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 (file)
index 0000000..060ef22
--- /dev/null
@@ -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 (file)
index 0000000..b5e8e0e
--- /dev/null
@@ -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 (file)
index 0000000..92dc843
--- /dev/null
@@ -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 (file)
index 0000000..46584ca
--- /dev/null
@@ -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 (file)
index 0000000..8aecbe6
--- /dev/null
@@ -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 (file)
index 0000000..bb5d307
--- /dev/null
@@ -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 (file)
index 0000000..b809b4e
--- /dev/null
@@ -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 (file)
index 0000000..8710d92
--- /dev/null
@@ -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 (file)
index 0000000..5e61039
--- /dev/null
@@ -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 (file)
index 0000000..b504eb6
--- /dev/null
@@ -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 (file)
index 0000000..ffd2beb
--- /dev/null
@@ -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 (file)
index 0000000..cc324b8
--- /dev/null
@@ -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 (file)
index 0000000..900c147
--- /dev/null
@@ -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 (file)
index 0000000..2022a30
--- /dev/null
@@ -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 (file)
index 0000000..5e621af
--- /dev/null
@@ -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 (file)
index 0000000..38dd162
--- /dev/null
@@ -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 (file)
index 0000000..bce6928
--- /dev/null
@@ -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 (file)
index 0000000..0700f4b
--- /dev/null
@@ -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 (file)
index 0000000..823486b
--- /dev/null
@@ -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 (file)
index 0000000..b0cee4c
--- /dev/null
@@ -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 (file)
index 0000000..0fc5f5d
--- /dev/null
@@ -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 (file)
index 0000000..3d8a2f6
--- /dev/null
@@ -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 (file)
index 0000000..96b3b59
--- /dev/null
@@ -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 (file)
index 0000000..313c90e
--- /dev/null
@@ -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 (file)
index 0000000..63a0661
--- /dev/null
@@ -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 (file)
index 0000000..eaf5661
--- /dev/null
@@ -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 (file)
index 0000000..ef14bde
--- /dev/null
@@ -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 (file)
index 0000000..7caf8c9
--- /dev/null
@@ -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 (file)
index 0000000..cbc2b89
--- /dev/null
@@ -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 (file)
index 0000000..dac9f9a
--- /dev/null
@@ -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 (file)
index 0000000..f7bb5aa
--- /dev/null
@@ -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 (file)
index 0000000..907c7f9
--- /dev/null
@@ -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 (file)
index 0000000..4eccf82
--- /dev/null
@@ -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 (file)
index 0000000..657f9c4
--- /dev/null
@@ -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 (file)
index 0000000..a25873c
--- /dev/null
@@ -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 (file)
index 0000000..fc2525d
--- /dev/null
@@ -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 (file)
index 0000000..d1d635d
--- /dev/null
@@ -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 (file)
index 0000000..f2990f5
--- /dev/null
@@ -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 (file)
index 0000000..8c1577c
--- /dev/null
@@ -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 (file)
index 0000000..cad6989
--- /dev/null
@@ -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 (file)
index 0000000..b6c0acf
--- /dev/null
@@ -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 (file)
index 0000000..08a5e56
--- /dev/null
@@ -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 (file)
index 0000000..c69c231
--- /dev/null
@@ -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 (file)
index 0000000..a9b434c
--- /dev/null
@@ -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 (file)
index 0000000..3dfa03a
--- /dev/null
@@ -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 (file)
index 0000000..b5f327b
--- /dev/null
@@ -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 (file)
index 0000000..e04a4d0
--- /dev/null
@@ -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 (file)
index 0000000..e581b49
--- /dev/null
@@ -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 (file)
index 0000000..5340aa6
--- /dev/null
@@ -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 (file)
index 0000000..377bab7
--- /dev/null
@@ -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 (file)
index 0000000..6c14b3c
--- /dev/null
@@ -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 (file)
index 0000000..3039436
--- /dev/null
@@ -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 (file)
index 0000000..ff5e1ff
--- /dev/null
@@ -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 (file)
index 0000000..be13cae
--- /dev/null
@@ -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 (file)
index 0000000..24a7e04
--- /dev/null
@@ -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 (file)
index 0000000..3e61365
--- /dev/null
@@ -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 (file)
index 0000000..cf62b8b
--- /dev/null
@@ -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 (file)
index 0000000..901ce2a
--- /dev/null
@@ -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 (file)
index 0000000..1c45654
--- /dev/null
@@ -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 (file)
index 0000000..61f6bef
--- /dev/null
@@ -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 (file)
index 0000000..cba6f8f
--- /dev/null
@@ -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 (file)
index 0000000..c007d48
--- /dev/null
@@ -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 (file)
index 0000000..e3db972
--- /dev/null
@@ -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 (file)
index 0000000..fdffc16
--- /dev/null
@@ -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 (file)
index 0000000..4d05de2
--- /dev/null
@@ -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 (file)
index 0000000..121ed1f
--- /dev/null
@@ -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 (file)
index 0000000..20a2350
--- /dev/null
@@ -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 (file)
index 0000000..e053f71
--- /dev/null
@@ -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 (file)
index 0000000..22f68de
--- /dev/null
@@ -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 (file)
index 0000000..c5c5fa2
--- /dev/null
@@ -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 (file)
index 0000000..f6bc172
--- /dev/null
@@ -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 (file)
index 0000000..b9171c3
--- /dev/null
@@ -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 (file)
index 0000000..0f59938
--- /dev/null
@@ -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 (file)
index 0000000..c1f042a
--- /dev/null
@@ -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 (file)
index 0000000..522cc59
--- /dev/null
@@ -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 (file)
index 0000000..10440e3
--- /dev/null
@@ -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 (file)
index 0000000..3d28cba
--- /dev/null
@@ -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 (file)
index 0000000..f0d97a3
--- /dev/null
@@ -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 (file)
index 0000000..70a9c01
--- /dev/null
@@ -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 (file)
index 0000000..5748728
--- /dev/null
@@ -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 (file)
index 0000000..45585cd
--- /dev/null
@@ -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 (file)
index 0000000..3423759
--- /dev/null
@@ -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 (file)
index 0000000..5907ca2
--- /dev/null
@@ -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 (file)
index 0000000..ecebf27
--- /dev/null
@@ -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 (file)
index 0000000..e2197ea
--- /dev/null
@@ -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 (file)
index 0000000..dcbb9c9
--- /dev/null
@@ -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 (file)
index 0000000..bb216a1
--- /dev/null
@@ -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 (file)
index 0000000..577c200
--- /dev/null
@@ -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 (file)
index 0000000..772c859
--- /dev/null
@@ -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 (file)
index 0000000..4d30610
--- /dev/null
@@ -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 (file)
index 0000000..03ab3c1
--- /dev/null
@@ -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 (file)
index 0000000..f8353c8
--- /dev/null
@@ -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 (file)
index 0000000..2404bb1
--- /dev/null
@@ -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 (file)
index 0000000..8c53d0f
--- /dev/null
@@ -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 (file)
index 0000000..09f2416
--- /dev/null
@@ -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 (file)
index 0000000..d1118ff
--- /dev/null
@@ -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 (file)
index 0000000..6d1ac39
--- /dev/null
@@ -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 (file)
index 0000000..001dd04
--- /dev/null
@@ -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 (file)
index 0000000..f1a8c6b
--- /dev/null
@@ -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 (file)
index 0000000..a587acb
--- /dev/null
@@ -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 (file)
index 0000000..600d512
--- /dev/null
@@ -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 (file)
index 0000000..ebd3471
--- /dev/null
@@ -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 (file)
index 0000000..dce7355
--- /dev/null
@@ -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 (file)
index 0000000..2ba1239
--- /dev/null
@@ -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 (file)
index 0000000..982d0c6
--- /dev/null
@@ -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 (file)
index 0000000..afbcf3c
--- /dev/null
@@ -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 (file)
index 0000000..3a90f67
--- /dev/null
@@ -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 (file)
index 0000000..85cdea2
--- /dev/null
@@ -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 (file)
index 0000000..eb3777e
--- /dev/null
@@ -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 (file)
index 0000000..c642851
--- /dev/null
@@ -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 (file)
index 0000000..cf4daf6
--- /dev/null
@@ -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 (file)
index 0000000..7a5acaa
--- /dev/null
@@ -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 (file)
index 0000000..31f28af
--- /dev/null
@@ -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 (file)
index 0000000..a3df16d
--- /dev/null
@@ -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 (file)
index 0000000..81aab9e
--- /dev/null
@@ -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 (file)
index 0000000..a5f9477
--- /dev/null
@@ -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 (file)
index 0000000..192f836
--- /dev/null
@@ -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 (file)
index 0000000..f44774f
--- /dev/null
@@ -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 (file)
index 0000000..8372eba
--- /dev/null
@@ -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 (file)
index 0000000..eb170c2
--- /dev/null
@@ -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 (file)
index 0000000..754a306
--- /dev/null
@@ -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 (file)
index 0000000..4d773f9
--- /dev/null
@@ -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 (file)
index 0000000..99d9575
--- /dev/null
@@ -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 (file)
index 0000000..98a41c3
--- /dev/null
@@ -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 (file)
index 0000000..a8fe45f
--- /dev/null
@@ -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 (file)
index 0000000..f53a266
--- /dev/null
@@ -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 (file)
index 0000000..4e30637
--- /dev/null
@@ -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 (file)
index 0000000..3b42464
--- /dev/null
@@ -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 (file)
index 0000000..58a7a07
--- /dev/null
@@ -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 (file)
index 0000000..856a964
--- /dev/null
@@ -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 (file)
index 0000000..10222df
--- /dev/null
@@ -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 (file)
index 0000000..0cdd088
--- /dev/null
@@ -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 (file)
index 0000000..6e84f1d
--- /dev/null
@@ -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 (file)
index 0000000..9efc8b9
--- /dev/null
@@ -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 (file)
index 0000000..a9428c7
--- /dev/null
@@ -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 (file)
index 0000000..3189aaa
--- /dev/null
@@ -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 (file)
index 0000000..83c14e9
--- /dev/null
@@ -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 (file)
index 0000000..a379710
--- /dev/null
@@ -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 (file)
index 0000000..7c228b6
--- /dev/null
@@ -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 (file)
index 0000000..b530a9b
--- /dev/null
@@ -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 (file)
index 0000000..224e240
--- /dev/null
@@ -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 (file)
index 0000000..b031d4f
--- /dev/null
@@ -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 (file)
index 0000000..643bf5e
--- /dev/null
@@ -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 (file)
index 0000000..07cac0c
--- /dev/null
@@ -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 (file)
index 0000000..90ceaa2
--- /dev/null
@@ -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 (file)
index 0000000..20457af
--- /dev/null
@@ -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 (file)
index 0000000..c3c4447
--- /dev/null
@@ -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 (file)
index 0000000..64e8e79
--- /dev/null
@@ -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 (file)
index 0000000..14d5173
--- /dev/null
@@ -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 (file)
index 0000000..e57cd05
--- /dev/null
@@ -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 (file)
index 0000000..7698e06
--- /dev/null
@@ -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 (file)
index 0000000..c599150
--- /dev/null
@@ -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 (file)
index 0000000..11b9f61
--- /dev/null
@@ -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 (file)
index 0000000..a199eed
--- /dev/null
@@ -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 (file)
index 0000000..bf046b6
--- /dev/null
@@ -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 (file)
index 0000000..c86e8b3
--- /dev/null
@@ -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 (file)
index 0000000..8f6e897
--- /dev/null
@@ -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 (file)
index 0000000..9a8e62a
--- /dev/null
@@ -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 (file)
index 0000000..5f39f3d
--- /dev/null
@@ -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 (file)
index 0000000..b63352e
--- /dev/null
@@ -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 (file)
index 0000000..a00b589
--- /dev/null
@@ -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 (file)
index 0000000..39cf983
--- /dev/null
@@ -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 (file)
index 0000000..7d60665
--- /dev/null
@@ -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 (file)
index 0000000..5cb9331
--- /dev/null
@@ -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 (file)
index 0000000..4a6100e
--- /dev/null
@@ -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 (file)
index 0000000..12a82b2
--- /dev/null
@@ -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 (file)
index 0000000..5e0bbe2
--- /dev/null
@@ -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 (file)
index 0000000..48840ad
--- /dev/null
@@ -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 (file)
index 0000000..f7c5cbf
--- /dev/null
@@ -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);
+}
diff --git a/klibc/version b/klibc/version
new file mode 100644 (file)
index 0000000..e6e9cf4
--- /dev/null
@@ -0,0 +1 @@
+0.82