about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--COPYING504
-rw-r--r--COPYRIGHT31
-rw-r--r--INSTALL61
-rw-r--r--Makefile97
-rw-r--r--README44
-rw-r--r--crt/crt1.c0
-rw-r--r--crt/crti.c0
-rw-r--r--crt/crtn.c0
-rw-r--r--crt/i386/crt1.s17
-rw-r--r--dist/config.mak25
-rw-r--r--include/alloca.h9
-rw-r--r--include/arpa/inet.h33
-rw-r--r--include/arpa/nameser.h465
-rw-r--r--include/arpa/telnet.h251
-rw-r--r--include/assert.h17
-rwxr-xr-xinclude/bits/alltypes.h.sh115
-rw-r--r--include/bits/endian.h1
-rw-r--r--include/bits/errno.h125
-rw-r--r--include/bits/fcntl.h59
-rw-r--r--include/bits/fenv.h34
-rw-r--r--include/bits/float.h11
-rw-r--r--include/bits/in.h89
-rw-r--r--include/bits/ioctl.h182
-rw-r--r--include/bits/ipc.h22
-rw-r--r--include/bits/limits.h32
-rw-r--r--include/bits/mman.h39
-rw-r--r--include/bits/posix.h2
-rw-r--r--include/bits/pthread.h6
-rw-r--r--include/bits/reg.h19
-rw-r--r--include/bits/setjmp.h1
-rw-r--r--include/bits/shm.h18
-rw-r--r--include/bits/signal.h98
-rw-r--r--include/bits/socket.h189
-rw-r--r--include/bits/stat.h25
-rw-r--r--include/bits/statfs.h16
-rw-r--r--include/bits/stdint.h23
-rw-r--r--include/bits/stdio.h10
-rw-r--r--include/bits/sysmacros.h7
-rw-r--r--include/bits/tcp.h1
-rw-r--r--include/bits/termios.h158
-rw-r--r--include/bits/uio.h4
-rw-r--r--include/bits/user.h77
-rw-r--r--include/bits/wait.h11
-rw-r--r--include/bits/wexitstatus.h9
-rw-r--r--include/byteswap.h0
-rw-r--r--include/cpio.h29
-rw-r--r--include/ctype.h53
-rw-r--r--include/dirent.h41
-rw-r--r--include/dlfcn.h19
-rw-r--r--include/elf.h2524
-rw-r--r--include/endian.h17
-rw-r--r--include/errno.h18
-rw-r--r--include/fcntl.h43
-rw-r--r--include/features.h1
-rw-r--r--include/fenv.h28
-rw-r--r--include/float.h34
-rw-r--r--include/fnmatch.h25
-rw-r--r--include/ftw.h31
-rw-r--r--include/getopt.h33
-rw-r--r--include/glob.h41
-rw-r--r--include/grp.h35
-rw-r--r--include/iconv.h22
-rw-r--r--include/inttypes.h227
-rw-r--r--include/langinfo.h85
-rw-r--r--include/libgen.h15
-rw-r--r--include/libintl.h25
-rw-r--r--include/limits.h101
-rw-r--r--include/linux/loop.h69
-rw-r--r--include/linux/version.h2
-rw-r--r--include/locale.h84
-rw-r--r--include/malloc.h0
-rw-r--r--include/math.h300
-rw-r--r--include/mntent.h43
-rw-r--r--include/net/ethernet.h47
-rw-r--r--include/net/if.h122
-rw-r--r--include/net/if_arp.h133
-rw-r--r--include/net/route.h116
-rw-r--r--include/netdb.h148
-rw-r--r--include/netinet/icmp6.h305
-rw-r--r--include/netinet/if_ether.h108
-rw-r--r--include/netinet/in.h158
-rw-r--r--include/netinet/ip.h186
-rw-r--r--include/netinet/ip6.h142
-rw-r--r--include/netinet/ip_icmp.h192
-rw-r--r--include/netinet/tcp.h6
-rw-r--r--include/netinet/udp.h35
-rw-r--r--include/nl_types.h24
-rw-r--r--include/paths.h40
-rw-r--r--include/poll.h35
-rw-r--r--include/pthread.h216
-rw-r--r--include/pty.h17
-rw-r--r--include/pwd.h38
-rw-r--r--include/regex.h59
-rw-r--r--include/resolv.h143
-rw-r--r--include/sched.h37
-rw-r--r--include/search.h6
-rw-r--r--include/semaphore.h27
-rw-r--r--include/setjmp.h30
-rw-r--r--include/shadow.h44
-rw-r--r--include/signal.h98
-rw-r--r--include/stdarg.h32
-rw-r--r--include/stdbool.h13
-rw-r--r--include/stddef.h19
-rw-r--r--include/stdint.h107
-rw-r--r--include/stdio.h144
-rw-r--r--include/stdlib.h129
-rw-r--r--include/string.h72
-rw-r--r--include/strings.h36
-rw-r--r--include/stropts.h16
-rw-r--r--include/sys/epoll.h61
-rw-r--r--include/sys/file.h21
-rw-r--r--include/sys/ioctl.h14
-rw-r--r--include/sys/ipc.h23
-rw-r--r--include/sys/kd.h8
-rw-r--r--include/sys/klog.h14
-rw-r--r--include/sys/mman.h37
-rw-r--r--include/sys/mount.h28
-rw-r--r--include/sys/msg.h36
-rw-r--r--include/sys/param.h15
-rw-r--r--include/sys/poll.h1
-rw-r--r--include/sys/prctl.h64
-rw-r--r--include/sys/procfs.h81
-rw-r--r--include/sys/ptrace.h77
-rw-r--r--include/sys/reboot.h18
-rw-r--r--include/sys/reg.h9
-rw-r--r--include/sys/resource.h74
-rw-r--r--include/sys/select.h34
-rw-r--r--include/sys/sem.h69
-rw-r--r--include/sys/shm.h18
-rw-r--r--include/sys/signalfd.h40
-rw-r--r--include/sys/socket.h64
-rw-r--r--include/sys/soundcard.h1
-rw-r--r--include/sys/stat.h90
-rw-r--r--include/sys/statfs.h10
-rw-r--r--include/sys/statvfs.h30
-rw-r--r--include/sys/stropts.h1
-rw-r--r--include/sys/swap.h11
-rw-r--r--include/sys/sysctl.h9
-rw-r--r--include/sys/sysinfo.h29
-rw-r--r--include/sys/sysmacros.h6
-rw-r--r--include/sys/time.h49
-rw-r--r--include/sys/times.h17
-rw-r--r--include/sys/types.h56
-rw-r--r--include/sys/ucontext.h1
-rw-r--r--include/sys/uio.h14
-rw-r--r--include/sys/un.h13
-rw-r--r--include/sys/user.h15
-rw-r--r--include/sys/utsname.h21
-rw-r--r--include/sys/vfs.h1
-rw-r--r--include/sys/vt.h1
-rw-r--r--include/sys/wait.h28
-rw-r--r--include/syslog.h54
-rw-r--r--include/tar.h33
-rw-r--r--include/termios.h39
-rw-r--r--include/time.h113
-rw-r--r--include/ucontext.h38
-rw-r--r--include/ulimit.h17
-rw-r--r--include/unistd.h464
-rw-r--r--include/utime.h24
-rw-r--r--include/utmp.h23
-rw-r--r--include/utmpx.h52
-rw-r--r--include/wchar.h152
-rw-r--r--include/wctype.h44
-rw-r--r--include/wordexp.h40
-rw-r--r--src/conf/fpathconf.c35
-rw-r--r--src/conf/pathconf.c6
-rw-r--r--src/conf/sysconf.c222
-rw-r--r--src/ctype/__ctype_get_mb_cur_max.c6
-rw-r--r--src/ctype/isalnum.c6
-rw-r--r--src/ctype/isalpha.c7
-rw-r--r--src/ctype/isascii.c6
-rw-r--r--src/ctype/isblank.c6
-rw-r--r--src/ctype/iscntrl.c6
-rw-r--r--src/ctype/isdigit.c7
-rw-r--r--src/ctype/isgraph.c4
-rw-r--r--src/ctype/islower.c7
-rw-r--r--src/ctype/isprint.c4
-rw-r--r--src/ctype/ispunct.c6
-rw-r--r--src/ctype/isspace.c6
-rw-r--r--src/ctype/isupper.c7
-rw-r--r--src/ctype/iswalnum.c9
-rw-r--r--src/ctype/iswalpha.c6
-rw-r--r--src/ctype/iswblank.c8
-rw-r--r--src/ctype/iswcntrl.c10
-rw-r--r--src/ctype/iswctype.c63
-rw-r--r--src/ctype/iswdigit.c9
-rw-r--r--src/ctype/iswgraph.c7
-rw-r--r--src/ctype/iswlower.c6
-rw-r--r--src/ctype/iswprint.c10
-rw-r--r--src/ctype/iswpunct.c138
-rw-r--r--src/ctype/iswspace.c15
-rw-r--r--src/ctype/iswupper.c6
-rw-r--r--src/ctype/iswxdigit.c7
-rw-r--r--src/ctype/isxdigit.c6
-rw-r--r--src/ctype/toascii.c7
-rw-r--r--src/ctype/tolower.c7
-rw-r--r--src/ctype/toupper.c7
-rw-r--r--src/ctype/towctrans.c246
-rw-r--r--src/ctype/wcswidth.c8
-rw-r--r--src/ctype/wctrans.c16
-rw-r--r--src/ctype/wcwidth.c185
-rw-r--r--src/dirent/__dirent.h9
-rw-r--r--src/dirent/__getdents.c12
-rw-r--r--src/dirent/alphasort.c10
-rw-r--r--src/dirent/closedir.c11
-rw-r--r--src/dirent/dirfd.c7
-rw-r--r--src/dirent/fdopendir.c26
-rw-r--r--src/dirent/opendir.c25
-rw-r--r--src/dirent/readdir.c32
-rw-r--r--src/dirent/readdir_r.c30
-rw-r--r--src/dirent/rewinddir.c13
-rw-r--r--src/dirent/scandir.c50
-rw-r--r--src/dirent/seekdir.c12
-rw-r--r--src/dirent/telldir.c7
-rw-r--r--src/env/__environ.c7
-rw-r--r--src/env/__libc_start_main.c26
-rw-r--r--src/env/clearenv.c9
-rw-r--r--src/env/getenv.c14
-rw-r--r--src/env/putenv.c59
-rw-r--r--src/env/setenv.c31
-rw-r--r--src/env/unsetenv.c32
-rw-r--r--src/errno/__errno_location.c11
-rw-r--r--src/errno/__strerror.h101
-rw-r--r--src/errno/strerror.c22
-rw-r--r--src/exit/_Exit.c9
-rw-r--r--src/exit/abort.c8
-rw-r--r--src/exit/assert.c9
-rw-r--r--src/exit/atexit.c57
-rw-r--r--src/exit/exit.c28
-rw-r--r--src/fcntl/creat.c9
-rw-r--r--src/fcntl/fcntl.c22
-rw-r--r--src/fcntl/open.c21
-rw-r--r--src/fcntl/openat.c21
-rw-r--r--src/internal/atomic.h110
-rw-r--r--src/internal/clone.h22
-rw-r--r--src/internal/futex.h16
-rw-r--r--src/internal/libc.c3
-rw-r--r--src/internal/libc.h43
-rw-r--r--src/internal/locale_impl.h5
-rw-r--r--src/internal/pthread_impl.h68
-rw-r--r--src/internal/stdio_impl.h100
-rw-r--r--src/internal/syscall.c11
-rw-r--r--src/internal/syscall.h469
-rw-r--r--src/internal/util.h5
-rw-r--r--src/ipc/ftok.c10
-rw-r--r--src/ipc/ipc.h13
-rw-r--r--src/ipc/semctl.c18
-rw-r--r--src/ipc/semget.c12
-rw-r--r--src/ipc/semop.c12
-rw-r--r--src/ipc/shmat.c17
-rw-r--r--src/ipc/shmctl.c12
-rw-r--r--src/ipc/shmdt.c12
-rw-r--r--src/ipc/shmget.c12
-rw-r--r--src/linux/brk.c6
-rw-r--r--src/linux/chroot.c8
-rw-r--r--src/linux/daemon.c31
-rw-r--r--src/linux/epoll_create.c7
-rw-r--r--src/linux/epoll_create1.c7
-rw-r--r--src/linux/epoll_ctl.c7
-rw-r--r--src/linux/epoll_pwait.c7
-rw-r--r--src/linux/epoll_wait.c7
-rw-r--r--src/linux/getdtablesize.c9
-rw-r--r--src/linux/gethostid.c4
-rw-r--r--src/linux/getopt_long.c52
-rw-r--r--src/linux/getpagesize.c7
-rw-r--r--src/linux/getpass.c39
-rw-r--r--src/linux/initgroups.c15
-rw-r--r--src/linux/klogctl.c7
-rw-r--r--src/linux/mntent.c57
-rw-r--r--src/linux/mount.c8
-rw-r--r--src/linux/prctl.c13
-rw-r--r--src/linux/reboot.c8
-rw-r--r--src/linux/sbrk.c7
-rw-r--r--src/linux/sendfile.c10
-rw-r--r--src/linux/setgroups.c9
-rw-r--r--src/linux/sethostname.c8
-rw-r--r--src/linux/settimeofday.c7
-rw-r--r--src/linux/signalfd.c7
-rw-r--r--src/linux/stime.c7
-rw-r--r--src/linux/swapoff.c8
-rw-r--r--src/linux/swapon.c8
-rw-r--r--src/linux/sysinfo.c9
-rw-r--r--src/linux/umount.c8
-rw-r--r--src/linux/umount2.c8
-rw-r--r--src/linux/utimes.c13
-rw-r--r--src/linux/wait3.c11
-rw-r--r--src/linux/wait4.c19
-rw-r--r--src/locale/catclose.c6
-rw-r--r--src/locale/catgets.c6
-rw-r--r--src/locale/catopen.c6
-rw-r--r--src/locale/duplocale.c11
-rw-r--r--src/locale/freelocale.c7
-rw-r--r--src/locale/iconv.c568
-rw-r--r--src/locale/intl.c67
-rw-r--r--src/locale/isalnum_l.c6
-rw-r--r--src/locale/isalpha_l.c6
-rw-r--r--src/locale/isblank_l.c6
-rw-r--r--src/locale/iscntrl_l.c6
-rw-r--r--src/locale/isdigit_l.c6
-rw-r--r--src/locale/isgraph_l.c6
-rw-r--r--src/locale/islower_l.c6
-rw-r--r--src/locale/isprint_l.c6
-rw-r--r--src/locale/ispunct_l.c6
-rw-r--r--src/locale/isspace_l.c6
-rw-r--r--src/locale/isupper_l.c6
-rw-r--r--src/locale/isxdigit_l.c6
-rw-r--r--src/locale/langinfo.c58
-rw-r--r--src/locale/localeconv.c22
-rw-r--r--src/locale/newlocale.c11
-rw-r--r--src/locale/nl_langinfo.c13
-rw-r--r--src/locale/setlocale.c9
-rw-r--r--src/locale/strcoll.c6
-rw-r--r--src/locale/strxfrm.c9
-rw-r--r--src/locale/tmp390
-rw-r--r--src/locale/tolower_l.c6
-rw-r--r--src/locale/toupper_l.c6
-rw-r--r--src/locale/wcscoll.c7
-rw-r--r--src/locale/wcsxfrm.c12
-rw-r--r--src/malloc/DESIGN22
-rw-r--r--src/malloc/__brk.c7
-rw-r--r--src/malloc/__simple_malloc.c44
-rw-r--r--src/malloc/calloc.c23
-rw-r--r--src/malloc/malloc.c515
-rw-r--r--src/malloc/memalign.c13
-rw-r--r--src/malloc/posix_memalign.c47
-rw-r--r--src/math/__fpclassify.c14
-rw-r--r--src/math/__fpclassifyf.c14
-rw-r--r--src/math/__fpclassifyl.c16
-rw-r--r--src/math/e_acos.c99
-rw-r--r--src/math/e_acosf.c77
-rw-r--r--src/math/e_acosh.c59
-rw-r--r--src/math/e_acoshf.c45
-rw-r--r--src/math/e_asin.c109
-rw-r--r--src/math/e_asinf.c80
-rw-r--r--src/math/e_atan2.c120
-rw-r--r--src/math/e_atan2f.c93
-rw-r--r--src/math/e_atanh.c59
-rw-r--r--src/math/e_atanhf.c42
-rw-r--r--src/math/e_cosh.c82
-rw-r--r--src/math/e_coshf.c59
-rw-r--r--src/math/e_exp.c155
-rw-r--r--src/math/e_expf.c91
-rw-r--r--src/math/e_fmod.c129
-rw-r--r--src/math/e_fmodf.c101
-rw-r--r--src/math/e_hypot.c121
-rw-r--r--src/math/e_hypotf.c79
-rw-r--r--src/math/e_log.c131
-rw-r--r--src/math/e_log10.c83
-rw-r--r--src/math/e_log10f.c51
-rw-r--r--src/math/e_logf.c81
-rw-r--r--src/math/e_pow.c300
-rw-r--r--src/math/e_powf.c243
-rw-r--r--src/math/e_rem_pio2.c163
-rw-r--r--src/math/e_rem_pio2f.c175
-rw-r--r--src/math/e_remainder.c69
-rw-r--r--src/math/e_remainderf.c61
-rw-r--r--src/math/e_scalb.c35
-rw-r--r--src/math/e_scalbf.c31
-rw-r--r--src/math/e_sinh.c75
-rw-r--r--src/math/e_sinhf.c56
-rw-r--r--src/math/e_sqrt.c442
-rw-r--r--src/math/e_sqrtf.c85
-rw-r--r--src/math/i386/e_exp.s36
-rw-r--r--src/math/i386/e_expf.s1
-rw-r--r--src/math/i386/e_log.s6
-rw-r--r--src/math/i386/e_log10.s6
-rw-r--r--src/math/i386/e_log10f.s6
-rw-r--r--src/math/i386/e_logf.s6
-rw-r--r--src/math/i386/e_remainder.s16
-rw-r--r--src/math/i386/e_remainderf.s0
-rw-r--r--src/math/i386/e_sqrt.s4
-rw-r--r--src/math/i386/e_sqrtf.s4
-rw-r--r--src/math/i386/s_ceil.s0
-rw-r--r--src/math/i386/s_ceilf.s0
-rw-r--r--src/math/i386/s_fabs.s5
-rw-r--r--src/math/i386/s_fabsf.s5
-rw-r--r--src/math/i386/s_floor.s0
-rw-r--r--src/math/i386/s_floorf.s0
-rw-r--r--src/math/i386/s_ldexp.s0
-rw-r--r--src/math/i386/s_ldexpf.s0
-rw-r--r--src/math/i386/s_rint.s5
-rw-r--r--src/math/i386/s_rintf.s5
-rw-r--r--src/math/i386/s_scalbln.s11
-rw-r--r--src/math/i386/s_scalblnf.s11
-rw-r--r--src/math/i386/s_trunc.s36
-rw-r--r--src/math/i386/s_truncf.s0
-rw-r--r--src/math/k_cos.c85
-rw-r--r--src/math/k_cosf.c52
-rw-r--r--src/math/k_rem_pio2.c300
-rw-r--r--src/math/k_rem_pio2f.c192
-rw-r--r--src/math/k_sin.c68
-rw-r--r--src/math/k_sinf.c42
-rw-r--r--src/math/k_tan.c149
-rw-r--r--src/math/k_tanf.c105
-rw-r--r--src/math/math_private.h143
-rw-r--r--src/math/s_asinh.c53
-rw-r--r--src/math/s_asinhf.c45
-rw-r--r--src/math/s_atan.c115
-rw-r--r--src/math/s_atanf.c95
-rw-r--r--src/math/s_cbrt.c77
-rw-r--r--src/math/s_cbrtf.c67
-rw-r--r--src/math/s_ceil.c68
-rw-r--r--src/math/s_ceilf.c49
-rw-r--r--src/math/s_copysign.c30
-rw-r--r--src/math/s_copysignf.c33
-rw-r--r--src/math/s_cos.c74
-rw-r--r--src/math/s_cosf.c47
-rw-r--r--src/math/s_erf.c298
-rw-r--r--src/math/s_erff.c207
-rw-r--r--src/math/s_expm1.c217
-rw-r--r--src/math/s_expm1f.c122
-rw-r--r--src/math/s_fabs.c27
-rw-r--r--src/math/s_fabsf.c30
-rw-r--r--src/math/s_floor.c69
-rw-r--r--src/math/s_floorf.c58
-rw-r--r--src/math/s_ilogb.c45
-rw-r--r--src/math/s_ilogbf.c37
-rw-r--r--src/math/s_ldexp.c6
-rw-r--r--src/math/s_ldexpf.c6
-rw-r--r--src/math/s_llrint.c8
-rw-r--r--src/math/s_log1p.c157
-rw-r--r--src/math/s_log1pf.c96
-rw-r--r--src/math/s_logb.c34
-rw-r--r--src/math/s_logbf.c31
-rw-r--r--src/math/s_lrint.c8
-rw-r--r--src/math/s_lrintf.c8
-rw-r--r--src/math/s_modf.c71
-rw-r--r--src/math/s_modff.c52
-rw-r--r--src/math/s_nextafter.c72
-rw-r--r--src/math/s_nextafterf.c63
-rw-r--r--src/math/s_remquo.c149
-rw-r--r--src/math/s_remquof.c118
-rw-r--r--src/math/s_rint.c80
-rw-r--r--src/math/s_rintf.c45
-rw-r--r--src/math/s_round.c48
-rw-r--r--src/math/s_roundf.c48
-rw-r--r--src/math/s_scalbln.c61
-rw-r--r--src/math/s_scalblnf.c57
-rw-r--r--src/math/s_sin.c74
-rw-r--r--src/math/s_sinf.c45
-rw-r--r--src/math/s_tan.c68
-rw-r--r--src/math/s_tanf.c40
-rw-r--r--src/math/s_tanh.c74
-rw-r--r--src/math/s_tanhf.c52
-rw-r--r--src/math/s_trunc.c58
-rw-r--r--src/math/s_truncf.c50
-rw-r--r--src/misc/basename.c12
-rw-r--r--src/misc/bswap_32.c7
-rw-r--r--src/misc/bswap_64.c9
-rw-r--r--src/misc/crypt.c2578
-rw-r--r--src/misc/cuserid.c13
-rw-r--r--src/misc/dirname.c15
-rw-r--r--src/misc/ffs.c9
-rw-r--r--src/misc/ftw.c9
-rw-r--r--src/misc/getdomainname.c9
-rw-r--r--src/misc/getgrouplist.c11
-rw-r--r--src/misc/getopt.c63
-rw-r--r--src/misc/getpriority.c9
-rw-r--r--src/misc/getrlimit.c15
-rw-r--r--src/misc/getrusage.c20
-rw-r--r--src/misc/getsubopt.c23
-rw-r--r--src/misc/ioctl.c13
-rw-r--r--src/misc/lockf.c33
-rw-r--r--src/misc/nftw.c121
-rw-r--r--src/misc/openpty.c33
-rw-r--r--src/misc/pty.c35
-rw-r--r--src/misc/realpath.c6
-rw-r--r--src/misc/sched_yield.c10
-rw-r--r--src/misc/setpriority.c7
-rw-r--r--src/misc/setrlimit.c11
-rw-r--r--src/misc/syslog.c115
-rw-r--r--src/misc/uname.c8
-rw-r--r--src/mman/madvise.c10
-rw-r--r--src/mman/mlock.c7
-rw-r--r--src/mman/mlockall.c7
-rw-r--r--src/mman/mmap.c18
-rw-r--r--src/mman/mprotect.c7
-rw-r--r--src/mman/mremap.c19
-rw-r--r--src/mman/msync.c8
-rw-r--r--src/mman/munlock.c7
-rw-r--r--src/mman/munlockall.c7
-rw-r--r--src/mman/munmap.c11
-rw-r--r--src/mman/posix_madvise.c6
-rw-r--r--src/multibyte/btowc.c7
-rw-r--r--src/multibyte/decode.c47
-rw-r--r--src/multibyte/internal.c60
-rw-r--r--src/multibyte/internal.h61
-rw-r--r--src/multibyte/mblen.c17
-rw-r--r--src/multibyte/mbrlen.c18
-rw-r--r--src/multibyte/mbrtowc.c58
-rw-r--r--src/multibyte/mbsinit.c17
-rw-r--r--src/multibyte/mbsnrtowcs.c61
-rw-r--r--src/multibyte/mbsrtowcs.c121
-rw-r--r--src/multibyte/mbstowcs.c18
-rw-r--r--src/multibyte/mbtowc.c19
-rw-r--r--src/multibyte/wcrtomb.c38
-rw-r--r--src/multibyte/wcsnrtombs.c51
-rw-r--r--src/multibyte/wcsrtombs.c58
-rw-r--r--src/multibyte/wcstombs.c17
-rw-r--r--src/multibyte/wctob.c8
-rw-r--r--src/multibyte/wctomb.c18
-rw-r--r--src/network/__dns.c267
-rw-r--r--src/network/__dns.h14
-rw-r--r--src/network/__ipparse.c40
-rw-r--r--src/network/accept.c14
-rw-r--r--src/network/bind.c9
-rw-r--r--src/network/connect.c14
-rw-r--r--src/network/dn_expand.c28
-rw-r--r--src/network/ent.c26
-rw-r--r--src/network/freeaddrinfo.c7
-rw-r--r--src/network/gai_strerror.c21
-rw-r--r--src/network/getaddrinfo.c224
-rw-r--r--src/network/gethostbyaddr.c15
-rw-r--r--src/network/gethostbyaddr_r.c71
-rw-r--r--src/network/gethostbyname.c63
-rw-r--r--src/network/gethostbyname2.c16
-rw-r--r--src/network/gethostbyname2_r.c99
-rw-r--r--src/network/gethostbyname_r.c11
-rw-r--r--src/network/getnameinfo.c54
-rw-r--r--src/network/getpeername.c9
-rw-r--r--src/network/getservbyname.c12
-rw-r--r--src/network/getservbyname_r.c41
-rw-r--r--src/network/getservbyport.c12
-rw-r--r--src/network/getservbyport_r.c43
-rw-r--r--src/network/getsockname.c9
-rw-r--r--src/network/getsockopt.c13
-rw-r--r--src/network/h_errno.c1
-rw-r--r--src/network/hstrerror.c16
-rw-r--r--src/network/htonl.c10
-rw-r--r--src/network/htons.c10
-rw-r--r--src/network/in6addr_any.c3
-rw-r--r--src/network/in6addr_loopback.c3
-rw-r--r--src/network/inet_addr.c11
-rw-r--r--src/network/inet_aton.c7
-rw-r--r--src/network/inet_ntoa.c10
-rw-r--r--src/network/inet_ntop.c48
-rw-r--r--src/network/inet_pton.c31
-rw-r--r--src/network/listen.c9
-rw-r--r--src/network/ntohl.c10
-rw-r--r--src/network/ntohs.c10
-rw-r--r--src/network/proto.c58
-rw-r--r--src/network/recv.c14
-rw-r--r--src/network/recvfrom.c17
-rw-r--r--src/network/recvmsg.c14
-rw-r--r--src/network/res_init.c4
-rw-r--r--src/network/res_query.c20
-rw-r--r--src/network/send.c14
-rw-r--r--src/network/sendmsg.c14
-rw-r--r--src/network/sendto.c17
-rw-r--r--src/network/serv.c16
-rw-r--r--src/network/setsockopt.c9
-rw-r--r--src/network/shutdown.c9
-rw-r--r--src/network/sockatmark.c11
-rw-r--r--src/network/socket.c9
-rw-r--r--src/network/socketcall.h24
-rw-r--r--src/network/socketpair.c9
-rw-r--r--src/passwd/getgr_r.c53
-rw-r--r--src/passwd/getgrent.c39
-rw-r--r--src/passwd/getgrent_a.c46
-rw-r--r--src/passwd/getpw_r.c46
-rw-r--r--src/passwd/getpwent.c39
-rw-r--r--src/passwd/getpwent_a.c37
-rw-r--r--src/passwd/getspent.c14
-rw-r--r--src/passwd/getspnam.c17
-rw-r--r--src/passwd/getspnam_r.c89
-rw-r--r--src/passwd/lckpwdf.c11
-rw-r--r--src/passwd/pwf.h13
-rw-r--r--src/prng/__rand48_step.c14
-rw-r--r--src/prng/__seed48.c1
-rw-r--r--src/prng/drand48.c19
-rw-r--r--src/prng/lcong48.c9
-rw-r--r--src/prng/lrand48.c15
-rw-r--r--src/prng/mrand48.c15
-rw-r--r--src/prng/rand.c13
-rw-r--r--src/prng/rand_r.c6
-rw-r--r--src/prng/random.c8
-rw-r--r--src/prng/seed48.c12
-rw-r--r--src/prng/srand48.c6
-rw-r--r--src/prng/srandom.c8
-rw-r--r--src/process/execl.c20
-rw-r--r--src/process/execle.c22
-rw-r--r--src/process/execlp.c20
-rw-r--r--src/process/execv.c8
-rw-r--r--src/process/execve.c8
-rw-r--r--src/process/execvp.c34
-rw-r--r--src/process/fork.c9
-rw-r--r--src/process/system.c45
-rw-r--r--src/process/vfork.c8
-rw-r--r--src/process/wait.c6
-rw-r--r--src/process/waitid.c7
-rw-r--r--src/process/waitpid.c7
-rw-r--r--src/regex/fnmatch.c150
-rw-r--r--src/regex/glob.c238
-rw-r--r--src/regex/regcomp.c3362
-rw-r--r--src/regex/regerror.c75
-rw-r--r--src/regex/regexec.c1107
-rw-r--r--src/regex/tre-mem.c163
-rw-r--r--src/regex/tre.h269
-rw-r--r--src/select/poll.c12
-rw-r--r--src/select/pselect.c15
-rw-r--r--src/select/select.c12
-rw-r--r--src/setjmp/i386/longjmp.s22
-rw-r--r--src/setjmp/i386/setjmp.s23
-rw-r--r--src/setjmp/longjmp.c0
-rw-r--r--src/setjmp/setjmp.c0
-rw-r--r--src/signal/bsd_signal.c6
-rw-r--r--src/signal/getitimer.c12
-rw-r--r--src/signal/i386/sigsetjmp.s13
-rw-r--r--src/signal/kill.c7
-rw-r--r--src/signal/killpg.c11
-rw-r--r--src/signal/raise.c7
-rw-r--r--src/signal/setitimer.c15
-rw-r--r--src/signal/sigaction.c48
-rw-r--r--src/signal/sigaddset.c13
-rw-r--r--src/signal/sigaltstack.c8
-rw-r--r--src/signal/sigdelset.c13
-rw-r--r--src/signal/sigemptyset.c8
-rw-r--r--src/signal/sigfillset.c8
-rw-r--r--src/signal/sighold.c11
-rw-r--r--src/signal/sigignore.c12
-rw-r--r--src/signal/siginterrupt.c13
-rw-r--r--src/signal/sigismember.c12
-rw-r--r--src/signal/siglongjmp.c12
-rw-r--r--src/signal/signal.c13
-rw-r--r--src/signal/sigpause.c11
-rw-r--r--src/signal/sigpending.c7
-rw-r--r--src/signal/sigprocmask.c23
-rw-r--r--src/signal/sigqueue.c14
-rw-r--r--src/signal/sigrelse.c11
-rw-r--r--src/signal/sigrtmax.c4
-rw-r--r--src/signal/sigrtmin.c4
-rw-r--r--src/signal/sigset.c28
-rw-r--r--src/signal/sigsetjmp.c17
-rw-r--r--src/signal/sigsuspend.c7
-rw-r--r--src/signal/sigtimedwait.c12
-rw-r--r--src/signal/sigwait.c11
-rw-r--r--src/signal/sigwaitinfo.c7
-rw-r--r--src/stat/chmod.c7
-rw-r--r--src/stat/fchmod.c7
-rw-r--r--src/stat/fchmodat.c7
-rw-r--r--src/stat/fstat.c10
-rw-r--r--src/stat/fstatat.c10
-rw-r--r--src/stat/fstatvfs.c13
-rw-r--r--src/stat/lstat.c10
-rw-r--r--src/stat/mkdir.c7
-rw-r--r--src/stat/mkdirat.c7
-rw-r--r--src/stat/mkfifo.c6
-rw-r--r--src/stat/mkfifoat.c6
-rw-r--r--src/stat/mknod.c10
-rw-r--r--src/stat/mknodat.c7
-rw-r--r--src/stat/stat.c10
-rw-r--r--src/stat/statvfs.c13
-rw-r--r--src/stat/umask.c7
-rw-r--r--src/stdio/__fclose_ca.c6
-rw-r--r--src/stdio/__fdopen.c52
-rw-r--r--src/stdio/__fopen_rb_ca.c18
-rw-r--r--src/stdio/__fpending.c6
-rw-r--r--src/stdio/__ofl.c3
-rw-r--r--src/stdio/__overflow.c52
-rw-r--r--src/stdio/__scanf.c487
-rw-r--r--src/stdio/__scanf.h16
-rw-r--r--src/stdio/__stdio_close.c6
-rw-r--r--src/stdio/__stdio_read.c6
-rw-r--r--src/stdio/__stdio_seek.c15
-rw-r--r--src/stdio/__stdio_write.c9
-rw-r--r--src/stdio/__uflow.c7
-rw-r--r--src/stdio/__underflow.c38
-rw-r--r--src/stdio/asprintf.c14
-rw-r--r--src/stdio/clearerr.c10
-rw-r--r--src/stdio/dprintf.c12
-rw-r--r--src/stdio/fclose.c21
-rw-r--r--src/stdio/feof.c10
-rw-r--r--src/stdio/ferror.c10
-rw-r--r--src/stdio/fflush.c50
-rw-r--r--src/stdio/fgetc.c10
-rw-r--r--src/stdio/fgetpos.c11
-rw-r--r--src/stdio/fgets.c34
-rw-r--r--src/stdio/fgetwc.c51
-rw-r--r--src/stdio/fgetws.c27
-rw-r--r--src/stdio/fileno.c8
-rw-r--r--src/stdio/fmemopen.c16
-rw-r--r--src/stdio/fopen.c34
-rw-r--r--src/stdio/fprintf.c12
-rw-r--r--src/stdio/fputc.c10
-rw-r--r--src/stdio/fputs.c10
-rw-r--r--src/stdio/fputwc.c33
-rw-r--r--src/stdio/fputws.c23
-rw-r--r--src/stdio/fread.c49
-rw-r--r--src/stdio/freopen.c47
-rw-r--r--src/stdio/fscanf.c12
-rw-r--r--src/stdio/fseek.c38
-rw-r--r--src/stdio/fsetpos.c8
-rw-r--r--src/stdio/ftell.c35
-rw-r--r--src/stdio/fwide.c10
-rw-r--r--src/stdio/fwrite.c51
-rw-r--r--src/stdio/fwscanf.c13
-rw-r--r--src/stdio/getc.c6
-rw-r--r--src/stdio/getc_unlocked.c8
-rw-r--r--src/stdio/getchar.c6
-rw-r--r--src/stdio/getchar_unlocked.c6
-rw-r--r--src/stdio/getdelim.c59
-rw-r--r--src/stdio/getline.c6
-rw-r--r--src/stdio/gets.c8
-rw-r--r--src/stdio/getw.c7
-rw-r--r--src/stdio/getwc.c6
-rw-r--r--src/stdio/getwchar.c8
-rw-r--r--src/stdio/pclose.c10
-rw-r--r--src/stdio/perror.c27
-rw-r--r--src/stdio/popen.c43
-rw-r--r--src/stdio/printf.c12
-rw-r--r--src/stdio/putc.c8
-rw-r--r--src/stdio/putc_unlocked.c8
-rw-r--r--src/stdio/putchar.c6
-rw-r--r--src/stdio/putchar_unlocked.c7
-rw-r--r--src/stdio/puts.c6
-rw-r--r--src/stdio/putw.c6
-rw-r--r--src/stdio/putwc.c6
-rw-r--r--src/stdio/putwchar.c8
-rw-r--r--src/stdio/remove.c7
-rw-r--r--src/stdio/rename.c7
-rw-r--r--src/stdio/rewind.c6
-rw-r--r--src/stdio/scanf.c12
-rw-r--r--src/stdio/setbuf.c6
-rw-r--r--src/stdio/setvbuf.c22
-rw-r--r--src/stdio/snprintf.c13
-rw-r--r--src/stdio/sprintf.c12
-rw-r--r--src/stdio/sscanf.c12
-rw-r--r--src/stdio/stderr.c13
-rw-r--r--src/stdio/stdin.c13
-rw-r--r--src/stdio/stdout.c17
-rw-r--r--src/stdio/swscanf.c13
-rw-r--r--src/stdio/tempnam.c42
-rw-r--r--src/stdio/tmpfile.c23
-rw-r--r--src/stdio/tmpnam.c38
-rw-r--r--src/stdio/ungetc.c33
-rw-r--r--src/stdio/ungetwc.c45
-rw-r--r--src/stdio/vasprintf.c27
-rw-r--r--src/stdio/vdprintf.c14
-rw-r--r--src/stdio/vfprintf.c640
-rw-r--r--src/stdio/vfscanf.c43
-rw-r--r--src/stdio/vfwscanf.c28
-rw-r--r--src/stdio/vprintf.c6
-rw-r--r--src/stdio/vscanf.c7
-rw-r--r--src/stdio/vsnprintf.c33
-rw-r--r--src/stdio/vsprintf.c7
-rw-r--r--src/stdio/vsscanf.c21
-rw-r--r--src/stdio/vswscanf.c19
-rw-r--r--src/stdio/vwscanf.c8
-rw-r--r--src/stdio/wscanf.c13
-rw-r--r--src/stdlib/abs.c4
-rw-r--r--src/stdlib/atof.c6
-rw-r--r--src/stdlib/atoi.c15
-rw-r--r--src/stdlib/atol.c16
-rw-r--r--src/stdlib/atoll.c16
-rw-r--r--src/stdlib/bsearch.c20
-rw-r--r--src/stdlib/div.c6
-rw-r--r--src/stdlib/frexp.c23
-rw-r--r--src/stdlib/frexpf.c23
-rw-r--r--src/stdlib/frexpl.c25
-rw-r--r--src/stdlib/imaxabs.c6
-rw-r--r--src/stdlib/imaxdiv.c6
-rw-r--r--src/stdlib/labs.c4
-rw-r--r--src/stdlib/ldiv.c6
-rw-r--r--src/stdlib/llabs.c4
-rw-r--r--src/stdlib/lldiv.c6
-rw-r--r--src/stdlib/qsort.c50
-rw-r--r--src/stdlib/strtod.c6
-rw-r--r--src/stdlib/strtof.c6
-rw-r--r--src/stdlib/strtoimax.c25
-rw-r--r--src/stdlib/strtol.c17
-rw-r--r--src/stdlib/strtold.c93
-rw-r--r--src/stdlib/strtoll.c17
-rw-r--r--src/stdlib/strtoul.c14
-rw-r--r--src/stdlib/strtoull.c14
-rw-r--r--src/stdlib/strtoumax.c123
-rw-r--r--src/stdlib/wcstoimax.c24
-rw-r--r--src/stdlib/wcstol.c18
-rw-r--r--src/stdlib/wcstoll.c18
-rw-r--r--src/stdlib/wcstoul.c15
-rw-r--r--src/stdlib/wcstoull.c15
-rw-r--r--src/stdlib/wcstoumax.c47
-rw-r--r--src/string/bcmp.c7
-rw-r--r--src/string/bcopy.c7
-rw-r--r--src/string/bzero.c7
-rw-r--r--src/string/index.c7
-rw-r--r--src/string/memchr.c24
-rw-r--r--src/string/memcmp.c8
-rw-r--r--src/string/memcpy.c29
-rw-r--r--src/string/memmove.c14
-rw-r--r--src/string/mempcpy.c7
-rw-r--r--src/string/memset.c21
-rw-r--r--src/string/rindex.c7
-rw-r--r--src/string/stpcpy.c29
-rw-r--r--src/string/stpncpy.c32
-rw-r--r--src/string/strcasecmp.c9
-rw-r--r--src/string/strcasestr.c7
-rw-r--r--src/string/strcat.c7
-rw-r--r--src/string/strchr.c23
-rw-r--r--src/string/strchrnul.c7
-rw-r--r--src/string/strcmp.c7
-rw-r--r--src/string/strcpy.c16
-rw-r--r--src/string/strcspn.c20
-rw-r--r--src/string/strdup.c13
-rw-r--r--src/string/strerror_r.c11
-rw-r--r--src/string/strlcat.c8
-rw-r--r--src/string/strlcpy.c32
-rw-r--r--src/string/strlen.c21
-rw-r--r--src/string/strncasecmp.c10
-rw-r--r--src/string/strncat.c10
-rw-r--r--src/string/strncmp.c9
-rw-r--r--src/string/strncpy.c9
-rw-r--r--src/string/strndup.c12
-rw-r--r--src/string/strnlen.c7
-rw-r--r--src/string/strpbrk.c7
-rw-r--r--src/string/strrchr.c9
-rw-r--r--src/string/strsep.c12
-rw-r--r--src/string/strsignal.c98
-rw-r--r--src/string/strspn.c22
-rw-r--r--src/string/strstr.c166
-rw-r--r--src/string/strtok.c13
-rw-r--r--src/string/strtok_r.c12
-rw-r--r--src/string/swab.c13
-rw-r--r--src/string/wcscat.c7
-rw-r--r--src/string/wcschr.c8
-rw-r--r--src/string/wcscmp.c7
-rw-r--r--src/string/wcscpy.c8
-rw-r--r--src/string/wcscspn.c10
-rw-r--r--src/string/wcslen.c8
-rw-r--r--src/string/wcsncat.c10
-rw-r--r--src/string/wcsncmp.c7
-rw-r--r--src/string/wcsncpy.c9
-rw-r--r--src/string/wcspbrk.c7
-rw-r--r--src/string/wcsrchr.c8
-rw-r--r--src/string/wcsspn.c8
-rw-r--r--src/string/wcsstr.c117
-rw-r--r--src/string/wcswcs.c6
-rw-r--r--src/string/wmemchr.c8
-rw-r--r--src/string/wmemcmp.c8
-rw-r--r--src/string/wmemcpy.c9
-rw-r--r--src/string/wmemmove.c11
-rw-r--r--src/string/wmemset.c9
-rw-r--r--src/stub/utmpx.c30
-rw-r--r--src/temp/mkdtemp.c21
-rw-r--r--src/temp/mkstemp.c26
-rw-r--r--src/temp/mktemp.c29
-rw-r--r--src/termios/cfgetospeed.c12
-rw-r--r--src/termios/cfsetospeed.c22
-rw-r--r--src/termios/tcdrain.c7
-rw-r--r--src/termios/tcflow.c7
-rw-r--r--src/termios/tcflush.c7
-rw-r--r--src/termios/tcgetattr.c10
-rw-r--r--src/termios/tcgetsid.c10
-rw-r--r--src/termios/tcsendbreak.c8
-rw-r--r--src/termios/tcsetattr.c13
-rw-r--r--src/thread/__futex.c8
-rw-r--r--src/thread/__lock.c12
-rw-r--r--src/thread/__set_thread_area.c9
-rw-r--r--src/thread/__timedwait.c21
-rw-r--r--src/thread/__unmapself.c0
-rw-r--r--src/thread/__wait.c16
-rw-r--r--src/thread/__wake.c9
-rw-r--r--src/thread/cancellation.c22
-rw-r--r--src/thread/clone.c26
-rw-r--r--src/thread/i386/__unmapself.s22
-rw-r--r--src/thread/i386/clone.s35
-rw-r--r--src/thread/pthread_attr_destroy.c6
-rw-r--r--src/thread/pthread_attr_getdetachstate.c7
-rw-r--r--src/thread/pthread_attr_getguardsize.c7
-rw-r--r--src/thread/pthread_attr_getscope.c6
-rw-r--r--src/thread/pthread_attr_getstacksize.c7
-rw-r--r--src/thread/pthread_attr_init.c7
-rw-r--r--src/thread/pthread_attr_setdetachstate.c7
-rw-r--r--src/thread/pthread_attr_setguardsize.c8
-rw-r--r--src/thread/pthread_attr_setscope.c6
-rw-r--r--src/thread/pthread_attr_setstacksize.c8
-rw-r--r--src/thread/pthread_barrier_destroy.c6
-rw-r--r--src/thread/pthread_barrier_init.c8
-rw-r--r--src/thread/pthread_barrier_wait.c31
-rw-r--r--src/thread/pthread_cancel.c7
-rw-r--r--src/thread/pthread_cond_broadcast.c8
-rw-r--r--src/thread/pthread_cond_destroy.c6
-rw-r--r--src/thread/pthread_cond_init.c7
-rw-r--r--src/thread/pthread_cond_signal.c8
-rw-r--r--src/thread/pthread_cond_timedwait.c26
-rw-r--r--src/thread/pthread_cond_wait.c6
-rw-r--r--src/thread/pthread_create.c189
-rw-r--r--src/thread/pthread_detach.c11
-rw-r--r--src/thread/pthread_equal.c6
-rw-r--r--src/thread/pthread_exit.c25
-rw-r--r--src/thread/pthread_getspecific.c8
-rw-r--r--src/thread/pthread_join.c12
-rw-r--r--src/thread/pthread_key_create.c25
-rw-r--r--src/thread/pthread_key_delete.c7
-rw-r--r--src/thread/pthread_kill.c7
-rw-r--r--src/thread/pthread_mutex_destroy.c6
-rw-r--r--src/thread/pthread_mutex_init.c9
-rw-r--r--src/thread/pthread_mutex_lock.c9
-rw-r--r--src/thread/pthread_mutex_timedlock.c15
-rw-r--r--src/thread/pthread_mutex_trylock.c28
-rw-r--r--src/thread/pthread_mutex_unlock.c19
-rw-r--r--src/thread/pthread_mutexattr_destroy.c6
-rw-r--r--src/thread/pthread_mutexattr_gettype.c7
-rw-r--r--src/thread/pthread_mutexattr_init.c7
-rw-r--r--src/thread/pthread_mutexattr_settype.c8
-rw-r--r--src/thread/pthread_once.c38
-rw-r--r--src/thread/pthread_rwlock_destroy.c6
-rw-r--r--src/thread/pthread_rwlock_init.c9
-rw-r--r--src/thread/pthread_rwlock_rdlock.c8
-rw-r--r--src/thread/pthread_rwlock_timedrdlock.c15
-rw-r--r--src/thread/pthread_rwlock_timedwrlock.c17
-rw-r--r--src/thread/pthread_rwlock_tryrdlock.c13
-rw-r--r--src/thread/pthread_rwlock_trywrlock.c13
-rw-r--r--src/thread/pthread_rwlock_unlock.c17
-rw-r--r--src/thread/pthread_rwlock_wrlock.c13
-rw-r--r--src/thread/pthread_self.c39
-rw-r--r--src/thread/pthread_setcancelstate.c10
-rw-r--r--src/thread/pthread_setcanceltype.c10
-rw-r--r--src/thread/pthread_setspecific.c18
-rw-r--r--src/thread/pthread_spin_destroy.c6
-rw-r--r--src/thread/pthread_spin_init.c6
-rw-r--r--src/thread/pthread_spin_lock.c7
-rw-r--r--src/thread/pthread_spin_trylock.c6
-rw-r--r--src/thread/pthread_spin_unlock.c6
-rw-r--r--src/thread/pthread_testcancel.c7
-rw-r--r--src/time/__asctime.c27
-rw-r--r--src/time/__time.h9
-rw-r--r--src/time/__time_to_tm.c81
-rw-r--r--src/time/__tm_to_time.c33
-rw-r--r--src/time/asctime.c9
-rw-r--r--src/time/asctime_r.c8
-rw-r--r--src/time/clock.c9
-rw-r--r--src/time/clock_gettime.c7
-rw-r--r--src/time/ctime.c6
-rw-r--r--src/time/ctime_r.c8
-rw-r--r--src/time/difftime.c6
-rw-r--r--src/time/gettimeofday.c9
-rw-r--r--src/time/gmtime.c11
-rw-r--r--src/time/gmtime_r.c10
-rw-r--r--src/time/localtime.c12
-rw-r--r--src/time/localtime_r.c11
-rw-r--r--src/time/mktime.c24
-rw-r--r--src/time/nanosleep.c13
-rw-r--r--src/time/strftime.c172
-rw-r--r--src/time/strptime.c178
-rw-r--r--src/time/time.c12
-rw-r--r--src/time/times.c7
-rw-r--r--src/time/timezone.s27
-rw-r--r--src/time/tzset.c173
-rw-r--r--src/time/utime.c12
-rw-r--r--src/unistd/_exit.c7
-rw-r--r--src/unistd/access.c7
-rw-r--r--src/unistd/alarm.c7
-rw-r--r--src/unistd/chdir.c7
-rw-r--r--src/unistd/chown.c7
-rw-r--r--src/unistd/close.c11
-rw-r--r--src/unistd/confstr.c17
-rw-r--r--src/unistd/ctermid.c23
-rw-r--r--src/unistd/dup.c7
-rw-r--r--src/unistd/dup2.c7
-rw-r--r--src/unistd/faccessat.c7
-rw-r--r--src/unistd/fchdir.c7
-rw-r--r--src/unistd/fchown.c7
-rw-r--r--src/unistd/fchownat.c7
-rw-r--r--src/unistd/fdatasync.c7
-rw-r--r--src/unistd/fsync.c8
-rw-r--r--src/unistd/ftruncate.c15
-rw-r--r--src/unistd/getcwd.c8
-rw-r--r--src/unistd/getegid.c7
-rw-r--r--src/unistd/geteuid.c7
-rw-r--r--src/unistd/getgid.c7
-rw-r--r--src/unistd/getgroups.c8
-rw-r--r--src/unistd/gethostname.c14
-rw-r--r--src/unistd/getlogin.c7
-rw-r--r--src/unistd/getlogin_r.c13
-rw-r--r--src/unistd/getpgid.c7
-rw-r--r--src/unistd/getpgrp.c7
-rw-r--r--src/unistd/getpid.c7
-rw-r--r--src/unistd/getppid.c7
-rw-r--r--src/unistd/getsid.c7
-rw-r--r--src/unistd/getuid.c7
-rw-r--r--src/unistd/isatty.c8
-rw-r--r--src/unistd/lchown.c7
-rw-r--r--src/unistd/link.c7
-rw-r--r--src/unistd/linkat.c7
-rw-r--r--src/unistd/lseek.c16
-rw-r--r--src/unistd/nice.c7
-rw-r--r--src/unistd/pause.c12
-rw-r--r--src/unistd/pipe.c7
-rw-r--r--src/unistd/pread.c14
-rw-r--r--src/unistd/pwrite.c14
-rw-r--r--src/unistd/read.c12
-rw-r--r--src/unistd/readlink.c7
-rw-r--r--src/unistd/readlinkat.c7
-rw-r--r--src/unistd/readv.c12
-rw-r--r--src/unistd/renameat.c7
-rw-r--r--src/unistd/rmdir.c7
-rw-r--r--src/unistd/setegid.c6
-rw-r--r--src/unistd/seteuid.c6
-rw-r--r--src/unistd/setgid.c9
-rw-r--r--src/unistd/setpgid.c7
-rw-r--r--src/unistd/setpgrp.c6
-rw-r--r--src/unistd/setregid.c9
-rw-r--r--src/unistd/setreuid.c9
-rw-r--r--src/unistd/setsid.c7
-rw-r--r--src/unistd/setuid.c9
-rw-r--r--src/unistd/sleep.c10
-rw-r--r--src/unistd/symlink.c7
-rw-r--r--src/unistd/symlinkat.c7
-rw-r--r--src/unistd/sync.c7
-rw-r--r--src/unistd/tcgetpgrp.c11
-rw-r--r--src/unistd/tcsetpgrp.c9
-rw-r--r--src/unistd/truncate.c15
-rw-r--r--src/unistd/ttyname.c14
-rw-r--r--src/unistd/ttyname_r.c19
-rw-r--r--src/unistd/ualarm.c8
-rw-r--r--src/unistd/unlink.c7
-rw-r--r--src/unistd/unlinkat.c7
-rw-r--r--src/unistd/usleep.c11
-rw-r--r--src/unistd/write.c12
-rw-r--r--src/unistd/writev.c12
-rw-r--r--tools/gen-musl-gcc.sh30
1021 files changed, 45711 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 00000000..223ede7d
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 00000000..30a74a21
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,31 @@
+musl as a whole is licensed under the GNU LGPL version 2.1 or later.
+See the file COPYING for the text of this license.
+
+See below for the copyright status on all code included in musl:
+
+The TRE regular expression implementation (src/regex/reg* and
+src/regex/tre*) is Copyright © 2001-2006 Ville Laurikari and licensed
+under the terms of the GNU LGPL version 2.1 or later. The included
+version was heavily modified in Spring 2006 by Rich Felker in the
+interests of size, simplicity, and namespace cleanliness.
+
+Most of the math library code (src/math/*) is Copyright © 1993 Sun
+Microsystems, Inc. Some files are Copyright © 2003 Steven G. Kargl and
+labelled as such. All have been licensed under extremely permissive
+terms which are compatible with the GNU LGPL. See the comments in the
+individual files for details.
+
+The implementation of DES for crypt (src/misc/crypt.c) is Copyright ©
+1994 David Burren. It is licensed under a BSD license compatible with
+the GNU LGPL.
+
+All files which have no copyright comments are original works
+Copyright © 2005-2011 Rich Felker, the main author of this library.
+The decision to exclude such comments is intentional, as it should be
+possible to carry around the complete source code on tiny storage
+media. All public header files (include/*) should be treated as Public
+Domain as they intentionally contain no content which can be covered
+by copyright. Some source modules may fall in this category as well.
+If you believe that a file is so trivial that it should be in the
+Public Domain, please contact me and, if I agree, I will explicitly
+release it from copyright.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 00000000..2470a5bf
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,61 @@
+
+A quick-and-simple guide to installing musl:
+
+
+STEP 1: Configuration
+
+Edit config.mak to override installation prefix, compiler options,
+etc. as needed. The defaults should be okay for trying out musl with
+static linking only. The only arch supported at present is i386. If
+you're on an x86_64 machine, you can add -m32 to the compiler options
+to build a working 32bit musl. In this case you will also need to add
+-m32 in two locations in the generated tools/musl-gcc script if you
+intend to use it.
+
+DO NOT set the prefix to /, /usr, or even /usr/local unless you really
+know what you're doing! You'll probably break your system such that
+you'll no longer be able to compile and link programs against glibc!
+This kind of setup should only be used if you're building a system
+where musl is the default/primary/only libc.
+
+The default prefix is /usr/local/musl for a reason, but some people
+may prefer /opt/musl or $HOME/musl.
+
+
+STEP 2: Compiling
+
+Run "make". (GNU make is required.)
+
+
+STEP 3: Installation
+
+With appropriate privileges, run "make install".
+
+
+STEP 4: Using the gcc wrapper.
+
+musl comes with a script "musl-gcc" (installed in /usr/local/bin by
+default) that can be used to compile and link C programs against musl.
+It requires a version of gcc with the -wrapper option (gcc 4.x should
+work). For example:
+
+cat > hello.c <<EOF
+#include <stdio.h>
+int main()
+{
+	printf("hello, world!\n");
+	return 0;
+}
+EOF
+musl-gcc hello.c
+./a.out
+
+For compiling programs that use autoconf, you'll need to configure
+them with a command like this:
+
+CC=musl-gcc ./configure
+
+Be aware that (at present) libraries linked against glibc are unlikely
+to be usable, and the musl-gcc wrapper inhibits search of the system
+library paths in any case. You'll need to compile any prerequisite
+libraries (like ncurses, glib, etc.) yourself.
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..e4235cb5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,97 @@
+#
+# Makefile for musl (requires GNU make)
+#
+# This is how simple every makefile should be...
+# No, I take that back - actually most should be less than half this size.
+#
+# Use config.mak to override any of the following variables.
+# Do not make changes here.
+#
+
+exec_prefix = /usr/local
+bindir = $(exec_prefix)/bin
+
+prefix = /usr/local/musl
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
+
+SRCS = $(sort $(wildcard src/*/*.c))
+OBJS = $(SRCS:.c=.o)
+LOBJS = $(OBJS:.o=.lo)
+GENH = include/bits/alltypes.h
+
+CFLAGS  = -Os -nostdinc -ffreestanding -pipe
+LDFLAGS = -nostdlib -shared -Wl,-Bsymbolic
+INC     = -I./include -I./src/internal
+PIC     = -fPIC
+AR      = $(CROSS_COMPILE)ar
+RANLIB  = $(CROSS_COMPILE)ranlib
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+ALL_INCLUDES = $(sort $(wildcard include/*.h include/*/*.h) $(GENH))
+
+EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv
+EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
+CRT_LIBS = lib/crt1.o lib/crti.o lib/crtn.o
+LIBC_LIBS = lib/libc.a
+ALL_LIBS = $(LIBC_LIBS) $(CRT_LIBS) $(EMPTY_LIBS)
+
+ALL_TOOLS = tools/musl-gcc
+
+-include config.mak
+
+all: $(ALL_LIBS) $(ALL_TOOLS)
+
+install: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%) $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%)
+
+clean:
+	rm -f crt/*.o
+	rm -f $(OBJS)
+	rm -f $(LOBJS)
+	rm -f $(ALL_LIBS) lib/*
+	rm -f $(ALL_TOOLS)
+	rm -f $(GENH) 
+
+include/bits/alltypes.h: include/bits/alltypes.h.sh
+	sh $< > $@
+
+%.o: $(ARCH)/%.s
+	$(CC) $(CFLAGS) $(INC) -c -o $@ $<
+
+%.o: %.c $(GENH)
+	$(CC) $(CFLAGS) $(INC) -c -o $@ $<
+
+%.lo: $(ARCH)/%.s
+	$(CC) $(CFLAGS) $(INC) $(PIC) -c -o $@ $<
+
+%.lo: %.c $(GENH)
+	$(CC) $(CFLAGS) $(INC) $(PIC) -c -o $@ $<
+
+lib/libc.so: $(LOBJS)
+	$(CC) $(LDFLAGS) -o $@ $(LOBJS) -lgcc
+	$(OBJCOPY) --weaken $@
+
+lib/libc.a: $(OBJS)
+	rm -f $@
+	$(AR) rc $@ $(OBJS)
+	$(RANLIB) $@
+
+$(EMPTY_LIBS):
+	$(AR) rc $@
+
+lib/%.o: crt/%.o
+	cp $< $@
+
+tools/musl-gcc: tools/gen-musl-gcc.sh config.mak
+	sh $< "$(prefix)" > $@ || { rm -f $@ ; exit 1 ; }
+	chmod +x $@
+
+$(DESTDIR)$(bindir)/%: tools/%
+	install -D $< $@
+
+$(DESTDIR)$(prefix)/%: %
+	install -D -m 644 $< $@
+
+.PRECIOUS: $(CRT_LIBS:lib/%=crt/%)
+
+.PHONY: all clean install
diff --git a/README b/README
new file mode 100644
index 00000000..a57541c6
--- /dev/null
+++ b/README
@@ -0,0 +1,44 @@
+
+musl libc - a new standard library to power a new generation of
+Linux-based devices. musl is lightweight, fast, simple, free, and
+strives to be correct in the sense of standards-conformance and
+safety.
+
+musl is an alternative to glibc, eglibc, uClibc, dietlibc, and klibc.
+For reasons why one might prefer musl, please see the FAQ and libc
+comparison chart on the project website,
+
+    http://www.etalabs.net/musl/
+
+For installation instructions, see the INSTALL file.
+
+Please refer to the COPYRIGHT file for details on the copyright status
+of code included in musl, and the COPYING file for the license (LGPL)
+under which the library as a whole is distributed.
+
+
+
+Greetings libc hackers!
+
+This package is an _alpha_ release of musl, intended for the curious
+and the adventurous. While it can be used to build a complete small
+Linux system (musl is self-hosted on the system I use to develop it),
+at this point doing so requires a lot of manual effort. Nonetheless, I
+hope low-level Linux enthusiasts will try out building some compact
+static binaries with musl using the provided gcc wrapper (which allows
+you to link programs with musl on a "standard" glibc Linux system),
+find whatever embarassing bugs I've let slip through, and provide
+feedback on issues encountered building various software against musl.
+
+Please visit #musl on Freenode IRC or contact me via email at dalias
+AT etalabs DOT net for bug reports, support requests, or to get
+involved in development. As this has been a one-person project so far,
+mailing lists will be setup in due time on an as-needed basis.
+
+Thank you for trying out musl.
+
+Cheers,
+
+Rich Felker / dalias
+
+
diff --git a/crt/crt1.c b/crt/crt1.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/crt/crt1.c
diff --git a/crt/crti.c b/crt/crti.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/crt/crti.c
diff --git a/crt/crtn.c b/crt/crtn.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/crt/crtn.c
diff --git a/crt/i386/crt1.s b/crt/i386/crt1.s
new file mode 100644
index 00000000..050adec8
--- /dev/null
+++ b/crt/i386/crt1.s
@@ -0,0 +1,17 @@
+.text
+.global _start
+_start:
+	xorl %ebp,%ebp
+	popl %ecx
+	movl %esp,%eax
+	andl $-16,%esp
+	pushl %esp
+	pushl %esp
+	pushl %edx
+	pushl $0
+	pushl $0
+	pushl %eax
+	pushl %ecx
+	pushl $main
+	call __libc_start_main
+.L0:	jmp .L0
diff --git a/dist/config.mak b/dist/config.mak
new file mode 100644
index 00000000..51205522
--- /dev/null
+++ b/dist/config.mak
@@ -0,0 +1,25 @@
+#
+# musl config.mak template (original in dist/config.mak)
+#
+
+# Target CPU architecture. Supported values: i386
+ARCH = i386
+
+# Installation prefix. DO NOT use /, /usr, or /usr/local !
+prefix = /usr/local/musl
+
+# Installation prefix for musl-gcc compiler wrapper.
+exec_prefix = /usr/local
+
+# Uncomment if you want to build i386 musl on a 64-bit host
+#CFLAGS += -m32
+
+# Uncomment for smaller code size.
+#CFLAGS += -fomit-frame-pointer -mno-accumulate-outgoing-args
+
+# Uncomment for warnings (as errors). Might need tuning to your gcc version.
+#CFLAGS += -Werror -Wall -Wpointer-arith -Wcast-align -Wno-parentheses -Wno-char-subscripts -Wno-uninitialized -Wno-sequence-point -Wno-missing-braces -Wno-unused-value
+#CFLAGS += -Wno-pointer-sign
+
+# Uncomment if you want to build a shared library (experimental).
+#LIBC_LIBS += lib/libc.so
diff --git a/include/alloca.h b/include/alloca.h
new file mode 100644
index 00000000..ac78e460
--- /dev/null
+++ b/include/alloca.h
@@ -0,0 +1,9 @@
+#ifndef	_ALLOCA_H
+#define	_ALLOCA_H
+
+#define	__NEED_size_t
+#include <bits/alltypes.h>
+
+void *alloca(size_t);
+
+#endif
diff --git a/include/arpa/inet.h b/include/arpa/inet.h
new file mode 100644
index 00000000..93427130
--- /dev/null
+++ b/include/arpa/inet.h
@@ -0,0 +1,33 @@
+#ifndef _ARPA_INET_H
+#define	_ARPA_INET_H
+
+#include <netinet/in.h>
+#include <inttypes.h>
+
+#define __NEED_socklen_t
+#define __NEED_in_addr_t
+#define __NEED_in_port_t
+#define __NEED_uint16_t
+#define __NEED_uint32_t
+#define __NEED_struct_in_addr
+
+#include <bits/alltypes.h>
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+in_addr_t inet_addr (const char *);
+char *inet_ntoa (struct in_addr);
+int inet_pton (int, const char *, void *);
+const char *inet_ntop (int, const void *, char *, socklen_t);
+
+int inet_aton (const char *, struct in_addr *); /* nonstandard but widely used */
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+#endif
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
new file mode 100644
index 00000000..0f854600
--- /dev/null
+++ b/include/arpa/nameser.h
@@ -0,0 +1,465 @@
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
+
+#define __NAMESER	19991006
+#define NS_PACKETSZ	512
+#define NS_MAXDNAME	1025
+#define NS_MAXMSG	65535
+#define NS_MAXCDNAME	255
+#define NS_MAXLABEL	63
+#define NS_HFIXEDSZ	12
+#define NS_QFIXEDSZ	4
+#define NS_RRFIXEDSZ	10
+#define NS_INT32SZ	4
+#define NS_INT16SZ	2
+#define NS_INT8SZ	1
+#define NS_INADDRSZ	4
+#define NS_IN6ADDRSZ	16
+#define NS_CMPRSFLGS	0xc0
+#define NS_DEFAULTPORT	53
+
+typedef enum __ns_sect {
+	ns_s_qd = 0,
+	ns_s_zn = 0,
+	ns_s_an = 1,
+	ns_s_pr = 1,
+	ns_s_ns = 2,
+	ns_s_ud = 2,
+	ns_s_ar = 3,
+	ns_s_max = 4
+} ns_sect;
+
+typedef struct __ns_msg {
+	const unsigned char *_msg, *_eom;
+	uint16_t _id, _flags, _counts[ns_s_max];
+	const unsigned char *_sections[ns_s_max];
+	ns_sect _sect;
+	int _rrnum;
+	const unsigned char *_msg_ptr;
+} ns_msg;
+
+struct _ns_flagdata {  int mask, shift;  };
+extern const struct _ns_flagdata _ns_flagdata[];
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+
+typedef	struct __ns_rr {
+	char		name[NS_MAXDNAME];
+	uint16_t	type;
+	uint16_t	rr_class;
+	uint32_t	ttl;
+	uint16_t	rdlength;
+	const unsigned char *rdata;
+} ns_rr;
+
+#define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr)	((ns_type)((rr).type + 0))
+#define ns_rr_class(rr)	((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr)	((rr).ttl + 0)
+#define ns_rr_rdlen(rr)	((rr).rdlength + 0)
+#define ns_rr_rdata(rr)	((rr).rdata + 0)
+
+typedef enum __ns_flag {
+	ns_f_qr,
+	ns_f_opcode,
+	ns_f_aa,
+	ns_f_tc,
+	ns_f_rd,
+	ns_f_ra,
+	ns_f_z,
+	ns_f_ad,
+	ns_f_cd,
+	ns_f_rcode,
+	ns_f_max
+} ns_flag;
+
+typedef enum __ns_opcode {
+	ns_o_query = 0,
+	ns_o_iquery = 1,
+	ns_o_status = 2,
+	ns_o_notify = 4,
+	ns_o_update = 5,
+	ns_o_max = 6
+} ns_opcode;
+
+typedef	enum __ns_rcode {
+	ns_r_noerror = 0,
+	ns_r_formerr = 1,
+	ns_r_servfail = 2,
+	ns_r_nxdomain = 3,
+	ns_r_notimpl = 4,
+	ns_r_refused = 5,
+	ns_r_yxdomain = 6,
+	ns_r_yxrrset = 7,
+	ns_r_nxrrset = 8,
+	ns_r_notauth = 9,
+	ns_r_notzone = 10,
+	ns_r_max = 11,
+	ns_r_badvers = 16,
+	ns_r_badsig = 16,
+	ns_r_badkey = 17,
+	ns_r_badtime = 18
+} ns_rcode;
+
+typedef enum __ns_update_operation {
+	ns_uop_delete = 0,
+	ns_uop_add = 1,
+	ns_uop_max = 2
+} ns_update_operation;
+
+struct ns_tsig_key {
+        char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+        unsigned char *data;
+        int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+struct ns_tcp_tsig_state {
+	int counter;
+	struct dst_key *key;
+	void *ctx;
+	unsigned char sig[NS_PACKETSZ];
+	int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+typedef enum __ns_type {
+	ns_t_invalid = 0,
+	ns_t_a = 1,
+	ns_t_ns = 2,
+	ns_t_md = 3,
+	ns_t_mf = 4,
+	ns_t_cname = 5,
+	ns_t_soa = 6,
+	ns_t_mb = 7,
+	ns_t_mg = 8,
+	ns_t_mr = 9,
+	ns_t_null = 10,
+	ns_t_wks = 11,
+	ns_t_ptr = 12,
+	ns_t_hinfo = 13,
+	ns_t_minfo = 14,
+	ns_t_mx = 15,
+	ns_t_txt = 16,
+	ns_t_rp = 17,
+	ns_t_afsdb = 18,
+	ns_t_x25 = 19,
+	ns_t_isdn = 20,
+	ns_t_rt = 21,
+	ns_t_nsap = 22,
+	ns_t_nsap_ptr = 23,
+	ns_t_sig = 24,
+	ns_t_key = 25,
+	ns_t_px = 26,
+	ns_t_gpos = 27,
+	ns_t_aaaa = 28,
+	ns_t_loc = 29,
+	ns_t_nxt = 30,
+	ns_t_eid = 31,
+	ns_t_nimloc = 32,
+	ns_t_srv = 33,
+	ns_t_atma = 34,
+	ns_t_naptr = 35,
+	ns_t_kx = 36,
+	ns_t_cert = 37,
+	ns_t_a6 = 38,
+	ns_t_dname = 39,
+	ns_t_sink = 40,
+	ns_t_opt = 41,
+	ns_t_apl = 42,
+	ns_t_tkey = 249,
+	ns_t_tsig = 250,
+	ns_t_ixfr = 251,
+	ns_t_axfr = 252,
+	ns_t_mailb = 253,
+	ns_t_maila = 254,
+	ns_t_any = 255,
+	ns_t_zxfr = 256,
+	ns_t_max = 65536
+} ns_type;
+
+#define	ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+		      (t) == ns_t_mailb || (t) == ns_t_maila)
+#define	ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+		       (t) == ns_t_zxfr)
+
+typedef enum __ns_class {
+	ns_c_invalid = 0,
+	ns_c_in = 1,
+	ns_c_2 = 2,
+	ns_c_chaos = 3,
+	ns_c_hs = 4,
+	ns_c_none = 254,
+	ns_c_any = 255,
+	ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_key_types {
+	ns_kt_rsa = 1,
+	ns_kt_dh  = 2,
+	ns_kt_dsa = 3,
+	ns_kt_private = 254
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+	cert_t_pkix = 1,
+	cert_t_spki = 2,
+	cert_t_pgp  = 3,
+	cert_t_url  = 253,
+	cert_t_oid  = 254
+} ns_cert_types;
+
+#define	NS_KEY_TYPEMASK		0xC000
+#define	NS_KEY_TYPE_AUTH_CONF	0x0000
+#define	NS_KEY_TYPE_CONF_ONLY	0x8000
+#define	NS_KEY_TYPE_AUTH_ONLY	0x4000
+#define	NS_KEY_TYPE_NO_KEY	0xC000
+#define	NS_KEY_NO_AUTH		0x8000
+#define	NS_KEY_NO_CONF		0x4000
+#define	NS_KEY_RESERVED2	0x2000
+#define	NS_KEY_EXTENDED_FLAGS	0x1000
+#define	NS_KEY_RESERVED4	0x0800
+#define	NS_KEY_RESERVED5	0x0400
+#define	NS_KEY_NAME_TYPE	0x0300
+#define	NS_KEY_NAME_USER	0x0000
+#define	NS_KEY_NAME_ENTITY	0x0200
+#define	NS_KEY_NAME_ZONE	0x0100
+#define	NS_KEY_NAME_RESERVED	0x0300
+#define	NS_KEY_RESERVED8	0x0080
+#define	NS_KEY_RESERVED9	0x0040
+#define	NS_KEY_RESERVED10	0x0020
+#define	NS_KEY_RESERVED11	0x0010
+#define	NS_KEY_SIGNATORYMASK	0x000F
+#define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+				  NS_KEY_RESERVED4 | \
+				  NS_KEY_RESERVED5 | \
+				  NS_KEY_RESERVED8 | \
+				  NS_KEY_RESERVED9 | \
+				  NS_KEY_RESERVED10 | \
+				  NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF
+#define	NS_ALG_MD5RSA		1
+#define	NS_ALG_DH               2
+#define	NS_ALG_DSA              3
+#define	NS_ALG_DSS              NS_ALG_DSA
+#define	NS_ALG_EXPIRE_ONLY	253
+#define	NS_ALG_PRIVATE_OID	254
+
+#define NS_KEY_PROT_TLS         1
+#define NS_KEY_PROT_EMAIL       2
+#define NS_KEY_PROT_DNSSEC      3
+#define NS_KEY_PROT_IPSEC       4
+#define NS_KEY_PROT_ANY		255
+
+#define	NS_MD5RSA_MIN_BITS	 512
+#define	NS_MD5RSA_MAX_BITS	4096
+#define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+#define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE	((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE	((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE         41
+#define NS_DSA_MIN_SIZE         213
+#define NS_DSA_MAX_BYTES        405
+
+#define	NS_SIG_TYPE	0
+#define	NS_SIG_ALG	2
+#define	NS_SIG_LABELS	3
+#define	NS_SIG_OTTL	4
+#define	NS_SIG_EXPIR	8
+#define	NS_SIG_SIGNED	12
+#define	NS_SIG_FOOT	16
+#define	NS_SIG_SIGNER	18
+#define	NS_NXT_BITS 8
+#define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+#define NS_OPT_DNSSEC_OK        0x8000U
+#define NS_OPT_NSID		3
+
+#define NS_GET16(s, cp) do { \
+	register const unsigned char *t_cp = (const unsigned char *)(cp); \
+	(s) = ((uint16_t)t_cp[0] << 8) \
+	    | ((uint16_t)t_cp[1]) \
+	    ; \
+	(cp) += NS_INT16SZ; \
+} while (0)
+
+#define NS_GET32(l, cp) do { \
+	register const unsigned char *t_cp = (const unsigned char *)(cp); \
+	(l) = ((uint32_t)t_cp[0] << 24) \
+	    | ((uint32_t)t_cp[1] << 16) \
+	    | ((uint32_t)t_cp[2] << 8) \
+	    | ((uint32_t)t_cp[3]) \
+	    ; \
+	(cp) += NS_INT32SZ; \
+} while (0)
+
+#define NS_PUT16(s, cp) do { \
+	register uint16_t t_s = (uint16_t)(s); \
+	register unsigned char *t_cp = (unsigned char *)(cp); \
+	*t_cp++ = t_s >> 8; \
+	*t_cp   = t_s; \
+	(cp) += NS_INT16SZ; \
+} while (0)
+
+#define NS_PUT32(l, cp) do { \
+	register uint32_t t_l = (uint32_t)(l); \
+	register unsigned char *t_cp = (unsigned char *)(cp); \
+	*t_cp++ = t_l >> 24; \
+	*t_cp++ = t_l >> 16; \
+	*t_cp++ = t_l >> 8; \
+	*t_cp   = t_l; \
+	(cp) += NS_INT32SZ; \
+} while (0)
+
+
+
+
+#define	__BIND		19950621
+
+typedef struct {
+	unsigned	id :16;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned	qr: 1;
+	unsigned	opcode: 4;
+	unsigned	aa: 1;
+	unsigned	tc: 1;
+	unsigned	rd: 1;
+	unsigned	ra: 1;
+	unsigned	unused :1;
+	unsigned	ad: 1;
+	unsigned	cd: 1;
+	unsigned	rcode :4;
+#else
+	unsigned	rd :1;
+	unsigned	tc :1;
+	unsigned	aa :1;
+	unsigned	opcode :4;
+	unsigned	qr :1;
+	unsigned	rcode :4;
+	unsigned	cd: 1;
+	unsigned	ad: 1;
+	unsigned	unused :1;
+	unsigned	ra :1;
+#endif
+	unsigned	qdcount :16;
+	unsigned	ancount :16;
+	unsigned	nscount :16;
+	unsigned	arcount :16;
+} HEADER;
+
+#define PACKETSZ	NS_PACKETSZ
+#define MAXDNAME	NS_MAXDNAME
+#define MAXCDNAME	NS_MAXCDNAME
+#define MAXLABEL	NS_MAXLABEL
+#define	HFIXEDSZ	NS_HFIXEDSZ
+#define QFIXEDSZ	NS_QFIXEDSZ
+#define RRFIXEDSZ	NS_RRFIXEDSZ
+#define	INT32SZ		NS_INT32SZ
+#define	INT16SZ		NS_INT16SZ
+#define INT8SZ		NS_INT8SZ
+#define	INADDRSZ	NS_INADDRSZ
+#define	IN6ADDRSZ	NS_IN6ADDRSZ
+#define	INDIR_MASK	NS_CMPRSFLGS
+#define NAMESERVER_PORT	NS_DEFAULTPORT
+
+#define S_ZONE		ns_s_zn
+#define S_PREREQ	ns_s_pr
+#define S_UPDATE	ns_s_ud
+#define S_ADDT		ns_s_ar
+
+#define QUERY		ns_o_query
+#define IQUERY		ns_o_iquery
+#define STATUS		ns_o_status
+#define	NS_NOTIFY_OP	ns_o_notify
+#define	NS_UPDATE_OP	ns_o_update
+
+#define NOERROR		ns_r_noerror
+#define FORMERR		ns_r_formerr
+#define SERVFAIL	ns_r_servfail
+#define NXDOMAIN	ns_r_nxdomain
+#define NOTIMP		ns_r_notimpl
+#define REFUSED		ns_r_refused
+#define YXDOMAIN	ns_r_yxdomain
+#define YXRRSET		ns_r_yxrrset
+#define NXRRSET		ns_r_nxrrset
+#define NOTAUTH		ns_r_notauth
+#define NOTZONE		ns_r_notzone
+
+#define DELETE		ns_uop_delete
+#define ADD		ns_uop_add
+
+#define T_A		ns_t_a
+#define T_NS		ns_t_ns
+#define T_MD		ns_t_md
+#define T_MF		ns_t_mf
+#define T_CNAME		ns_t_cname
+#define T_SOA		ns_t_soa
+#define T_MB		ns_t_mb
+#define T_MG		ns_t_mg
+#define T_MR		ns_t_mr
+#define T_NULL		ns_t_null
+#define T_WKS		ns_t_wks
+#define T_PTR		ns_t_ptr
+#define T_HINFO		ns_t_hinfo
+#define T_MINFO		ns_t_minfo
+#define T_MX		ns_t_mx
+#define T_TXT		ns_t_txt
+#define	T_RP		ns_t_rp
+#define T_AFSDB		ns_t_afsdb
+#define T_X25		ns_t_x25
+#define T_ISDN		ns_t_isdn
+#define T_RT		ns_t_rt
+#define T_NSAP		ns_t_nsap
+#define T_NSAP_PTR	ns_t_nsap_ptr
+#define	T_SIG		ns_t_sig
+#define	T_KEY		ns_t_key
+#define	T_PX		ns_t_px
+#define	T_GPOS		ns_t_gpos
+#define	T_AAAA		ns_t_aaaa
+#define	T_LOC		ns_t_loc
+#define	T_NXT		ns_t_nxt
+#define	T_EID		ns_t_eid
+#define	T_NIMLOC	ns_t_nimloc
+#define	T_SRV		ns_t_srv
+#define T_ATMA		ns_t_atma
+#define T_NAPTR		ns_t_naptr
+#define T_A6		ns_t_a6
+#define T_DNAME		ns_t_dname
+#define	T_TSIG		ns_t_tsig
+#define	T_IXFR		ns_t_ixfr
+#define T_AXFR		ns_t_axfr
+#define T_MAILB		ns_t_mailb
+#define T_MAILA		ns_t_maila
+#define T_ANY		ns_t_any
+
+#define C_IN		ns_c_in
+#define C_CHAOS		ns_c_chaos
+#define C_HS		ns_c_hs
+#define C_NONE		ns_c_none
+#define C_ANY		ns_c_any
+
+#define	GETSHORT		NS_GET16
+#define	GETLONG			NS_GET32
+#define	PUTSHORT		NS_PUT16
+#define	PUTLONG			NS_PUT32
+
+#endif
diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h
new file mode 100644
index 00000000..e2ad9742
--- /dev/null
+++ b/include/arpa/telnet.h
@@ -0,0 +1,251 @@
+#ifndef _ARPA_TELNET_H
+#define	_ARPA_TELNET_H
+
+#define	IAC	255
+#define	DONT	254
+#define	DO	253
+#define	WONT	252
+#define	WILL	251
+#define	SB	250
+#define	GA	249
+#define	EL	248
+#define	EC	247
+#define	AYT	246
+#define	AO	245
+#define	IP	244
+#define	BREAK	243
+#define	DM	242
+#define	NOP	241
+#define	SE	240
+#define EOR     239
+#define	ABORT	238
+#define	SUSP	237
+#define	xEOF	236
+
+#define SYNCH	242
+
+#define telcmds ((char [][6]){ "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0 })
+
+#define	TELCMD_FIRST	xEOF
+#define	TELCMD_LAST	IAC
+#define	TELCMD_OK(x)	((unsigned int)(x) <= TELCMD_LAST && \
+			 (unsigned int)(x) >= TELCMD_FIRST)
+#define	TELCMD(x)	telcmds[(x)-TELCMD_FIRST]
+
+#define TELOPT_BINARY	0
+#define TELOPT_ECHO	1
+#define	TELOPT_RCP	2
+#define	TELOPT_SGA	3
+#define	TELOPT_NAMS	4
+#define	TELOPT_STATUS	5
+#define	TELOPT_TM	6
+#define	TELOPT_RCTE	7
+#define TELOPT_NAOL 	8
+#define TELOPT_NAOP 	9
+#define TELOPT_NAOCRD	10
+#define TELOPT_NAOHTS	11
+#define TELOPT_NAOHTD	12
+#define TELOPT_NAOFFD	13
+#define TELOPT_NAOVTS	14
+#define TELOPT_NAOVTD	15
+#define TELOPT_NAOLFD	16
+#define TELOPT_XASCII	17
+#define	TELOPT_LOGOUT	18
+#define	TELOPT_BM	19
+#define	TELOPT_DET	20
+#define	TELOPT_SUPDUP	21
+#define	TELOPT_SUPDUPOUTPUT 22
+#define	TELOPT_SNDLOC	23
+#define	TELOPT_TTYPE	24
+#define	TELOPT_EOR	25
+#define	TELOPT_TUID	26
+#define	TELOPT_OUTMRK	27
+#define	TELOPT_TTYLOC	28
+#define	TELOPT_3270REGIME 29
+#define	TELOPT_X3PAD	30
+#define	TELOPT_NAWS	31
+#define	TELOPT_TSPEED	32
+#define	TELOPT_LFLOW	33
+#define TELOPT_LINEMODE	34
+#define TELOPT_XDISPLOC	35
+#define TELOPT_OLD_ENVIRON 36
+#define	TELOPT_AUTHENTICATION 37/* Authenticate */
+#define	TELOPT_ENCRYPT	38
+#define TELOPT_NEW_ENVIRON 39
+#define	TELOPT_EXOPL	255
+
+
+#define	NTELOPTS	(1+TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char *telopts[NTELOPTS+1] = {
+	"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+	"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+	"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+	"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+	"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+	"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+	"TACACS UID", "OUTPUT MARKING", "TTYLOC",
+	"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+	"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
+	"ENCRYPT", "NEW-ENVIRON",
+	0,
+};
+#define	TELOPT_FIRST	TELOPT_BINARY
+#define	TELOPT_LAST	TELOPT_NEW_ENVIRON
+#define	TELOPT_OK(x)	((unsigned int)(x) <= TELOPT_LAST)
+#define	TELOPT(x)	telopts[(x)-TELOPT_FIRST]
+#endif
+
+#define	TELQUAL_IS	0
+#define	TELQUAL_SEND	1
+#define	TELQUAL_INFO	2
+#define	TELQUAL_REPLY	2
+#define	TELQUAL_NAME	3
+
+#define	LFLOW_OFF		0
+#define	LFLOW_ON		1
+#define	LFLOW_RESTART_ANY	2
+#define	LFLOW_RESTART_XON	3
+
+
+#define	LM_MODE		1
+#define	LM_FORWARDMASK	2
+#define	LM_SLC		3
+
+#define	MODE_EDIT	0x01
+#define	MODE_TRAPSIG	0x02
+#define	MODE_ACK	0x04
+#define MODE_SOFT_TAB	0x08
+#define MODE_LIT_ECHO	0x10
+
+#define	MODE_MASK	0x1f
+
+#define MODE_FLOW		0x0100
+#define MODE_ECHO		0x0200
+#define MODE_INBIN		0x0400
+#define MODE_OUTBIN		0x0800
+#define MODE_FORCE		0x1000
+
+#define	SLC_SYNCH	1
+#define	SLC_BRK		2
+#define	SLC_IP		3
+#define	SLC_AO		4
+#define	SLC_AYT		5
+#define	SLC_EOR		6
+#define	SLC_ABORT	7
+#define	SLC_EOF		8
+#define	SLC_SUSP	9
+#define	SLC_EC		10
+#define	SLC_EL		11
+#define	SLC_EW		12
+#define	SLC_RP		13
+#define	SLC_LNEXT	14
+#define	SLC_XON		15
+#define	SLC_XOFF	16
+#define	SLC_FORW1	17
+#define	SLC_FORW2	18
+
+#define	NSLC		18
+
+#define	SLC_NAMELIST	"0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+			"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+			"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef	SLC_NAMES
+char *slc_names[] = {
+	SLC_NAMELIST
+};
+#else
+extern char *slc_names[];
+#define	SLC_NAMES SLC_NAMELIST
+#endif
+
+#define	SLC_NAME_OK(x)	((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x)	slc_names[x]
+
+#define	SLC_NOSUPPORT	0
+#define	SLC_CANTCHANGE	1
+#define	SLC_VARIABLE	2
+#define	SLC_DEFAULT	3
+#define	SLC_LEVELBITS	0x03
+
+#define	SLC_FUNC	0
+#define	SLC_FLAGS	1
+#define	SLC_VALUE	2
+
+#define	SLC_ACK		0x80
+#define	SLC_FLUSHIN	0x40
+#define	SLC_FLUSHOUT	0x20
+
+#define	OLD_ENV_VAR	1
+#define	OLD_ENV_VALUE	0
+#define	NEW_ENV_VAR	0
+#define	NEW_ENV_VALUE	1
+#define	ENV_ESC		2
+#define ENV_USERVAR	3
+
+#define	AUTH_WHO_CLIENT		0
+#define	AUTH_WHO_SERVER		1
+#define	AUTH_WHO_MASK		1
+
+#define	AUTH_HOW_ONE_WAY	0
+#define	AUTH_HOW_MUTUAL		2
+#define	AUTH_HOW_MASK		2
+
+#define	AUTHTYPE_NULL		0
+#define	AUTHTYPE_KERBEROS_V4	1
+#define	AUTHTYPE_KERBEROS_V5	2
+#define	AUTHTYPE_SPX		3
+#define	AUTHTYPE_MINK		4
+#define	AUTHTYPE_CNT		5
+
+#define	AUTHTYPE_TEST		99
+
+#ifdef	AUTH_NAMES
+char *authtype_names[] = {
+	"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char *authtype_names[];
+#endif
+
+#define	AUTHTYPE_NAME_OK(x)	((unsigned int)(x) < AUTHTYPE_CNT)
+#define	AUTHTYPE_NAME(x)	authtype_names[x]
+
+#define	ENCRYPT_IS		0
+#define	ENCRYPT_SUPPORT		1
+#define	ENCRYPT_REPLY		2
+#define	ENCRYPT_START		3
+#define	ENCRYPT_END		4
+#define	ENCRYPT_REQSTART	5
+#define	ENCRYPT_REQEND		6
+#define	ENCRYPT_ENC_KEYID	7
+#define	ENCRYPT_DEC_KEYID	8
+#define	ENCRYPT_CNT		9
+
+#define	ENCTYPE_ANY		0
+#define	ENCTYPE_DES_CFB64	1
+#define	ENCTYPE_DES_OFB64	2
+#define	ENCTYPE_CNT		3
+
+#ifdef	ENCRYPT_NAMES
+char *encrypt_names[] = {
+	"IS", "SUPPORT", "REPLY", "START", "END",
+	"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
+	0,
+};
+char *enctype_names[] = {
+	"ANY", "DES_CFB64",  "DES_OFB64",  0,
+};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
+#endif
+
+
+#define	ENCRYPT_NAME_OK(x)	((unsigned int)(x) < ENCRYPT_CNT)
+#define	ENCRYPT_NAME(x)		encrypt_names[x]
+
+#define	ENCTYPE_NAME_OK(x)	((unsigned int)(x) < ENCTYPE_CNT)
+#define	ENCTYPE_NAME(x)		enctype_names[x]
+
+#endif
diff --git a/include/assert.h b/include/assert.h
new file mode 100644
index 00000000..bad2ccd0
--- /dev/null
+++ b/include/assert.h
@@ -0,0 +1,17 @@
+#undef assert
+
+#ifdef NDEBUG
+#define	assert(x) (void)0
+#else
+#define assert(x) ((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __assert_fail (const char *, const char *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/bits/alltypes.h.sh b/include/bits/alltypes.h.sh
new file mode 100755
index 00000000..595bf13e
--- /dev/null
+++ b/include/bits/alltypes.h.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+sed -e << EOF \
+'/^TYPEDEF/s/TYPEDEF \(.*\) \([^ ]*\);$/#if defined(__NEED_\2) \&\& !defined(__DEFINED_\2)\
+typedef \1 \2;\
+#define __DEFINED_\2\
+#endif\
+/
+/^STRUCT/s/STRUCT * \([^ ]*\) \(.*\);$/#if defined(__NEED_struct_\1) \&\& !defined(__DEFINED_struct_\1)\
+struct \1 \2;\
+#define __DEFINED_struct_\1\
+#endif\
+/
+/^UNION/s/UNION * \([^ ]*\) \(.*\);$/#if defined(__NEED_union_\1) \&\& !defined(__DEFINED_union_\1)\
+union \1 \2;\
+#define __DEFINED_union_\1\
+#endif\
+/'
+
+TYPEDEF unsigned size_t;
+TYPEDEF int ssize_t;
+TYPEDEF long ptrdiff_t;
+TYPEDEF struct __va_list * va_list;
+
+TYPEDEF long wchar_t;
+TYPEDEF long wint_t;
+TYPEDEF long wctrans_t;
+TYPEDEF long wctype_t;
+
+TYPEDEF char      int8_t;
+TYPEDEF short     int16_t;
+TYPEDEF int       int32_t;
+TYPEDEF long long int64_t;
+
+TYPEDEF unsigned char      uint8_t;
+TYPEDEF unsigned short     uint16_t;
+TYPEDEF unsigned int       uint32_t;
+TYPEDEF unsigned long long uint64_t;
+
+TYPEDEF unsigned char      __uint8_t;
+TYPEDEF unsigned short     __uint16_t;
+TYPEDEF unsigned int       __uint32_t;
+TYPEDEF unsigned long long __uint64_t;
+
+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 int       int_fast16_t;
+TYPEDEF int       int_fast32_t;
+TYPEDEF int64_t   int_fast64_t;
+
+TYPEDEF unsigned char      uint_fast8_t;
+TYPEDEF unsigned int       uint_fast16_t;
+TYPEDEF unsigned int       uint_fast32_t;
+TYPEDEF uint64_t           uint_fast64_t;
+
+TYPEDEF long          intptr_t;
+TYPEDEF unsigned long uintptr_t;
+
+TYPEDEF long long          intmax_t;
+TYPEDEF unsigned long long uintmax_t;
+
+TYPEDEF long time_t;
+TYPEDEF unsigned int useconds_t;
+TYPEDEF int suseconds_t;
+STRUCT timeval { time_t tv_sec; long tv_usec; };
+STRUCT timespec { time_t tv_sec; long tv_nsec; };
+
+TYPEDEF int pid_t;
+TYPEDEF int id_t;
+TYPEDEF int uid_t;
+TYPEDEF int gid_t;
+TYPEDEF int key_t;
+TYPEDEF struct __pthread * pthread_t;
+
+TYPEDEF long long off_t;
+
+TYPEDEF unsigned int mode_t;
+
+TYPEDEF unsigned int nlink_t;
+TYPEDEF unsigned long long ino_t;
+TYPEDEF long long dev_t;
+TYPEDEF long blksize_t;
+TYPEDEF long long blkcnt_t;
+TYPEDEF unsigned long long fsblkcnt_t;
+TYPEDEF unsigned long long fsfilcnt_t;
+
+TYPEDEF int timer_t;
+TYPEDEF int clockid_t;
+TYPEDEF unsigned long clock_t;
+
+TYPEDEF struct { unsigned long __bits[1024/sizeof(long)]; } sigset_t;
+TYPEDEF struct __siginfo siginfo_t;
+
+TYPEDEF unsigned int socklen_t;
+TYPEDEF unsigned short sa_family_t;
+TYPEDEF unsigned short in_port_t;
+TYPEDEF unsigned int in_addr_t;
+STRUCT in_addr { in_addr_t s_addr; };
+
+TYPEDEF struct __FILE_s FILE;
+
+TYPEDEF int nl_item;
+
+TYPEDEF struct __locale * locale_t;
+
+
+EOF
diff --git a/include/bits/endian.h b/include/bits/endian.h
new file mode 100644
index 00000000..172c338f
--- /dev/null
+++ b/include/bits/endian.h
@@ -0,0 +1 @@
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/include/bits/errno.h b/include/bits/errno.h
new file mode 100644
index 00000000..fddea5ef
--- /dev/null
+++ b/include/bits/errno.h
@@ -0,0 +1,125 @@
+#define EPERM            1
+#define ENOENT           2
+#define ESRCH            3
+#define EINTR            4
+#define EIO              5
+#define ENXIO            6
+#define E2BIG            7
+#define ENOEXEC          8
+#define EBADF            9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define ENOTBLK         15
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define ETXTBSY         26
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         35
+#define ENAMETOOLONG    36
+#define ENOLCK          37
+#define ENOSYS          38
+#define ENOTEMPTY       39
+#define ELOOP           40
+#define EWOULDBLOCK     EAGAIN
+#define ENOMSG          42
+#define EIDRM           43
+#define ECHRNG          44
+#define EL2NSYNC        45
+#define EL3HLT          46
+#define EL3RST          47
+#define ELNRNG          48
+#define EUNATCH         49
+#define ENOCSI          50
+#define EL2HLT          51
+#define EBADE           52
+#define EBADR           53
+#define EXFULL          54
+#define ENOANO          55
+#define EBADRQC         56
+#define EBADSLT         57
+#define EDEADLOCK       EDEADLK
+#define EBFONT          59
+#define ENOSTR          60
+#define ENODATA         61
+#define ETIME           62
+#define ENOSR           63
+#define ENONET          64
+#define ENOPKG          65
+#define EREMOTE         66
+#define ENOLINK         67
+#define EADV            68
+#define ESRMNT          69
+#define ECOMM           70
+#define EPROTO          71
+#define EMULTIHOP       72
+#define EDOTDOT         73
+#define EBADMSG         74
+#define EOVERFLOW       75
+#define ENOTUNIQ        76
+#define EBADFD          77
+#define EREMCHG         78
+#define ELIBACC         79
+#define ELIBBAD         80
+#define ELIBSCN         81
+#define ELIBMAX         82
+#define ELIBEXEC        83
+#define EILSEQ          84
+#define ERESTART        85
+#define ESTRPIPE        86
+#define EUSERS          87
+#define ENOTSOCK        88
+#define EDESTADDRREQ    89
+#define EMSGSIZE        90
+#define EPROTOTYPE      91
+#define ENOPROTOOPT     92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP      95
+#define EPFNOSUPPORT    96
+#define EAFNOSUPPORT    97
+#define EADDRINUSE      98
+#define EADDRNOTAVAIL   99
+#define ENETDOWN        100
+#define ENETUNREACH     101
+#define ENETRESET       102
+#define ECONNABORTED    103
+#define ECONNRESET      104
+#define ENOBUFS         105
+#define EISCONN         106
+#define ENOTCONN        107
+#define ESHUTDOWN       108
+#define ETOOMANYREFS    109
+#define ETIMEDOUT       110
+#define ECONNREFUSED    111
+#define EHOSTDOWN       112
+#define EHOSTUNREACH    113
+#define EALREADY        114
+#define EINPROGRESS     115
+#define ESTALE          116
+#define EUCLEAN         117
+#define ENOTNAM         118
+#define ENAVAIL         119
+#define EISNAM          120
+#define EREMOTEIO       121
+#define EDQUOT          122
+#define ENOMEDIUM       123
+#define EMEDIUMTYPE     124
+#define ECANCELED       125
diff --git a/include/bits/fcntl.h b/include/bits/fcntl.h
new file mode 100644
index 00000000..550152fd
--- /dev/null
+++ b/include/bits/fcntl.h
@@ -0,0 +1,59 @@
+#define O_ACCMODE 03
+#define O_RDONLY  00
+#define O_WRONLY  01
+#define O_RDWR    02
+
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_SYNC       010000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW  0400000
+#define O_CLOEXEC  02000000
+
+#ifdef _GNU_SOURCE
+#define O_ASYNC      020000
+#define O_DIRECT     040000
+#define O_NOATIME  01000000
+#define F_DUPFD_CLOEXEC 1030
+#define FAPPENT O_APPEND
+#define FFSYNC O_FSYNC
+#define FASYNC O_ASYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+#endif
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+
+#define F_GETLK 12
+#define F_SETLK 13
+#define F_SETLKW 14
+
+#define FD_CLOEXEC 1
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+#define AT_FDCWD (-100)
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
+#define AT_SYMLINK_FOLLOW 0x400
+#define AT_EACCESS 0x200
+
+#define POSIX_FADV_NORMAL     0
+#define POSIX_FADV_RANDOM     1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED   3
+#define POSIX_FADV_DONTNEED   4
+#define POSIX_FADV_NOREUSE    5
diff --git a/include/bits/fenv.h b/include/bits/fenv.h
new file mode 100644
index 00000000..24df0417
--- /dev/null
+++ b/include/bits/fenv.h
@@ -0,0 +1,34 @@
+#define FE_INVALID    1
+#define __FE_DENORM   2
+#define FE_DIVBYZERO  4
+#define FE_OVERFLOW   8
+#define FE_UNDERFLOW  16
+#define FE_INEXACT    32
+
+#define FE_ALL_EXCEPT 63
+
+#define FE_TONEAREST  0
+#define FE_DOWNWARD   0x400
+#define FE_UPWARD     0x800
+#define FE_TOWARDZERO 0xc00
+
+typedef unsigned short fexcept_t;
+
+typedef struct {
+	unsigned short __control_word;
+	unsigned short __unused1;
+	unsigned short __status_word;
+	unsigned short __unused2;
+	unsigned short __tags;
+	unsigned short __unused3;
+	unsigned int __eip;
+	unsigned short __cs_selector;
+	unsigned int __opcode:11;
+	unsigned int __unused4:5;
+	unsigned int __data_offset;
+	unsigned short __data_selector;
+	unsigned short __unused5;
+	unsigned int __mxcsr;
+} fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
diff --git a/include/bits/float.h b/include/bits/float.h
new file mode 100644
index 00000000..162b3e46
--- /dev/null
+++ b/include/bits/float.h
@@ -0,0 +1,11 @@
+#define LDBL_MIN     3.3621031431120935063e-4932L
+#define LDBL_MAX     1.1897314953572317650e+4932L
+#define LDBL_EPSILON 1.0842021724855044340e-19L
+
+#define LDBL_MANT_DIG 64
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 18
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
diff --git a/include/bits/in.h b/include/bits/in.h
new file mode 100644
index 00000000..53ca31ca
--- /dev/null
+++ b/include/bits/in.h
@@ -0,0 +1,89 @@
+#define IP_TOS             1
+#define IP_TTL             2
+#define IP_HDRINCL         3
+#define IP_OPTIONS         4
+#define IP_ROUTER_ALERT    5
+#define IP_RECVOPTS        6
+#define IP_RETOPTS         7
+//#define IP_PKTINFO         8
+#define IP_PKTOPTIONS      9
+#define IP_PMTUDISC        10
+#define IP_MTU_DISCOVER    10
+#define IP_RECVERR         11
+#define IP_RECVTTL         12
+#define IP_RECVTOS         13
+#define IP_MULTICAST_IF    32
+#define IP_MULTICAST_TTL   33
+#define IP_MULTICAST_LOOP  34
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT   0
+#define IP_PMTUDISC_WANT   1
+#define IP_PMTUDISC_DO     2
+
+#define SOL_IP 0
+
+#define IP_DEFAULT_MULTICAST_TTL        1
+#define IP_DEFAULT_MULTICAST_LOOP       1
+#define IP_MAX_MEMBERSHIPS              20
+
+struct ip_opts
+{
+	struct in_addr ip_dst;
+	char ip_opts[40];
+};
+
+struct ip_mreq
+{
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_interface;
+};
+
+struct ip_mreqn
+{
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_address;
+	int imr_ifindex;
+};
+
+struct in_pktinfo
+{
+	int ipi_ifindex;
+	struct in_addr ipi_spec_dst;
+	struct in_addr ipi_addr;
+};
+
+#define IPV6_ADDRFORM           1
+#define IPV6_PKTINFO            2
+#define IPV6_HOPOPTS            3
+#define IPV6_DSTOPTS            4
+#define IPV6_RXSRCRT            5
+#define IPV6_PKTOPTIONS         6
+#define IPV6_CHECKSUM           7
+#define IPV6_HOPLIMIT           8
+#define IPV6_NEXTHOP            9
+#define IPV6_AUTHHDR            10
+#define IPV6_UNICAST_HOPS       16
+#define IPV6_MULTICAST_IF       17
+#define IPV6_MULTICAST_HOPS     18
+#define IPV6_MULTICAST_LOOP     19
+#define IPV6_ADD_MEMBERSHIP     20
+#define IPV6_DROP_MEMBERSHIP    21
+#define IPV6_ROUTER_ALERT       22
+
+#define SCM_SRCRT               IPV6_RXSRCRT
+
+#define IPV6_RXHOPOPTS          IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS          IPV6_DSTOPTS
+
+
+#define IPV6_PMTUDISC_DONT      0
+#define IPV6_PMTUDISC_WANT      1
+#define IPV6_PMTUDISC_DO        2
+
+
+#define SOL_IPV6        41
+#define SOL_ICMPV6      58
diff --git a/include/bits/ioctl.h b/include/bits/ioctl.h
new file mode 100644
index 00000000..bb63ffb4
--- /dev/null
+++ b/include/bits/ioctl.h
@@ -0,0 +1,182 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  0U
+#define _IOC_WRITE 1U
+#define _IOC_READ  2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(1,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(2,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(3,(a),(b),sizeof(c))
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425
+#define TIOCTTYGSTRUCT	0x5426
+#define TIOCSBRK	0x5427
+#define TIOCCBRK	0x5428
+#define TIOCGSID	0x5429
+#define TIOCGPTN	0x80045430
+#define TIOCSPTLCK	0x40045431
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458
+#define TIOCSERGETLSR   0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT	0x545C
+#define TIOCGICOUNT	0x545D
+#define TIOCGHAYESESP   0x545E
+#define TIOCSHAYESESP   0x545F
+#define FIOQSIZE	0x5460
+
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE        0x001
+#define TIOCM_DTR       0x002
+#define TIOCM_RTS       0x004
+#define TIOCM_ST        0x008
+#define TIOCM_SR        0x010
+#define TIOCM_CTS       0x020
+#define TIOCM_CAR       0x040
+#define TIOCM_RNG       0x080
+#define TIOCM_DSR       0x100
+#define TIOCM_CD        TIOCM_CAR
+#define TIOCM_RI        TIOCM_RNG
+#define TIOCM_OUT1      0x2000
+#define TIOCM_OUT2      0x4000
+#define TIOCM_LOOP      0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY           0
+#define N_SLIP          1
+#define N_MOUSE         2
+#define N_PPP           3
+#define N_STRIP         4
+#define N_AX25          5
+#define N_X25           6
+#define N_6PACK         7
+#define N_MASC          8
+#define N_R3964         9
+#define N_PROFIBUS_FDL  10
+#define N_IRDA          11
+#define N_SMSBLOCK      12
+#define N_HDLC          13
+#define N_SYNC_PPP      14
+#define N_HCI           15
+
+#define SIOCADDRT       0x890B
+#define SIOCDELRT       0x890C
+#define SIOCRTMSG       0x890D
+
+#define SIOCGIFNAME     0x8910
+#define SIOCSIFLINK     0x8911
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCSIFFLAGS    0x8914
+#define SIOCGIFADDR     0x8915
+#define SIOCSIFADDR     0x8916
+#define SIOCGIFDSTADDR  0x8917
+#define SIOCSIFDSTADDR  0x8918
+#define SIOCGIFBRDADDR  0x8919
+#define SIOCSIFBRDADDR  0x891a
+#define SIOCGIFNETMASK  0x891b
+#define SIOCSIFNETMASK  0x891c
+#define SIOCGIFMETRIC   0x891d
+#define SIOCSIFMETRIC   0x891e
+#define SIOCGIFMEM      0x891f
+#define SIOCSIFMEM      0x8920
+#define SIOCGIFMTU      0x8921
+#define SIOCSIFMTU      0x8922
+#define SIOCSIFHWADDR   0x8924
+#define SIOCGIFENCAP    0x8925
+#define SIOCSIFENCAP    0x8926
+#define SIOCGIFHWADDR   0x8927
+#define SIOCGIFSLAVE    0x8929
+#define SIOCSIFSLAVE    0x8930
+#define SIOCADDMULTI    0x8931
+#define SIOCDELMULTI    0x8932
+#define SIOCGIFINDEX    0x8933
+#define SIOGIFINDEX     SIOCGIFINDEX
+#define SIOCSIFPFLAGS   0x8934
+#define SIOCGIFPFLAGS   0x8935
+#define SIOCDIFADDR     0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT    0x8938
+
+#define SIOCGIFBR       0x8940
+#define SIOCSIFBR       0x8941
+
+#define SIOCGIFTXQLEN   0x8942
+#define SIOCSIFTXQLEN   0x8943
+
+#define SIOCDARP        0x8953
+#define SIOCGARP        0x8954
+#define SIOCSARP        0x8955
+
+#define SIOCDRARP       0x8960
+#define SIOCGRARP       0x8961
+#define SIOCSRARP       0x8962
+
+#define SIOCGIFMAP      0x8970
+#define SIOCSIFMAP      0x8971
+
+#define SIOCADDDLCI     0x8980
+#define SIOCDELDLCI     0x8981
diff --git a/include/bits/ipc.h b/include/bits/ipc.h
new file mode 100644
index 00000000..8e3ef9b9
--- /dev/null
+++ b/include/bits/ipc.h
@@ -0,0 +1,22 @@
+#define IPC_CREAT  01000
+#define IPC_EXCL   02000
+#define IPC_NOWAIT 04000
+
+#define IPC_RMID 0
+#define IPC_SET  1
+#define IPC_STAT 2
+
+#define IPC_PRIVATE ((key_t) 0)
+
+struct ipc_perm
+{
+	key_t key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	int seq;
+	long __pad1;
+	long __pad2;
+};
diff --git a/include/bits/limits.h b/include/bits/limits.h
new file mode 100644
index 00000000..48fdd7a1
--- /dev/null
+++ b/include/bits/limits.h
@@ -0,0 +1,32 @@
+#define PIPE_BUF 4096
+#define PAGESIZE 4096
+#define PAGE_SIZE PAGESIZE
+#define FILESIZEBITS 64
+#define NAME_MAX 255
+#define SYMLINK_MAX 255
+#define PATH_MAX 4096
+#define NZERO 20
+#define NGROUPS_MAX 32
+#define ARG_MAX 131072
+#define IOV_MAX 1024
+#define SYMLOOP_MAX 40
+
+#define WORD_BIT 32
+#define LONG_BIT 32
+
+#define SHRT_MIN  (-1-0x7fff)
+#define SHRT_MAX  0x7fff
+#define USHRT_MAX 0xffff
+
+#define INT_MIN  (-1-0x7fffffff)
+#define INT_MAX  0x7fffffff
+#define UINT_MAX 0xffffffff
+
+#define LONG_MIN  (-1-0x7fffffffL)
+#define LONG_MAX  0x7fffffffL
+#define ULONG_MAX 0xffffffffL
+
+#define LLONG_MIN  (-1-0x7fffffffffffffffLL)
+#define LLONG_MAX  0x7fffffffffffffffLL
+#define ULLONG_MAX 0xffffffffffffffffULL
+
diff --git a/include/bits/mman.h b/include/bits/mman.h
new file mode 100644
index 00000000..e02d488c
--- /dev/null
+++ b/include/bits/mman.h
@@ -0,0 +1,39 @@
+#define MAP_FAILED ((void *) -1)
+
+#define	PROT_NONE      0
+#define	PROT_READ      1
+#define	PROT_WRITE     2
+#define	PROT_EXEC      4
+
+#define	MAP_SHARED     0x01
+#define	MAP_PRIVATE    0x02
+#define	MAP_FIXED      0x10
+
+/* linux extensions */
+#define MAP_TYPE       0x0f
+#define MAP_FILE       0x00
+#define MAP_ANON       0x20
+#define MAP_ANONYMOUS  MAP_ANON
+
+#define MADV_NORMAL     0
+#define MADV_RANDOM     1
+#define MADV_SEQUENTIAL 2
+#define MADV_WILLNEED   3
+#define MADV_DONTNEED   4
+
+#define POSIX_MADV_NORMAL       0
+#define POSIX_MADV_RANDOM       1
+#define POSIX_MADV_SEQUENTIAL   2
+#define POSIX_MADV_WILLNEED     3
+#define POSIX_MADV_DONTNEED     0
+
+#define MS_ASYNC        1
+#define MS_INVALIDATE   2
+#define MS_SYNC         4
+
+#define MCL_CURRENT     1
+#define MCL_FUTURE      2
+
+/* linux extensions */
+#define MREMAP_MAYMOVE  1
+#define MREMAP_FIXED    2
diff --git a/include/bits/posix.h b/include/bits/posix.h
new file mode 100644
index 00000000..30a38714
--- /dev/null
+++ b/include/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG  1
+#define _POSIX_V7_ILP32_OFFBIG  1
diff --git a/include/bits/pthread.h b/include/bits/pthread.h
new file mode 100644
index 00000000..7d19065d
--- /dev/null
+++ b/include/bits/pthread.h
@@ -0,0 +1,6 @@
+struct __ptcb {
+	long __jb[7];
+	int __dummy;
+	struct __ptcb *__next;
+	void *__ptrs[3];
+};
diff --git a/include/bits/reg.h b/include/bits/reg.h
new file mode 100644
index 00000000..8bc2582d
--- /dev/null
+++ b/include/bits/reg.h
@@ -0,0 +1,19 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
+#define EBX 0
+#define ECX 1
+#define EDX 2
+#define ESI 3
+#define EDI 4
+#define EBP 5
+#define EAX 6
+#define DS 7
+#define ES 8
+#define FS 9
+#define GS 10
+#define ORIG_EAX 11
+#define EIP 12
+#define CS 13
+#define EFL 14
+#define UESP 15
+#define SS 16
diff --git a/include/bits/setjmp.h b/include/bits/setjmp.h
new file mode 100644
index 00000000..b6595bd2
--- /dev/null
+++ b/include/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long jmp_buf [7];
diff --git a/include/bits/shm.h b/include/bits/shm.h
new file mode 100644
index 00000000..46774237
--- /dev/null
+++ b/include/bits/shm.h
@@ -0,0 +1,18 @@
+#define SHMLBA 4096
+
+#define SHM_RDONLY 010000
+#define SHM_RND    020000
+
+struct shmid_ds
+{
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
diff --git a/include/bits/signal.h b/include/bits/signal.h
new file mode 100644
index 00000000..2427f37a
--- /dev/null
+++ b/include/bits/signal.h
@@ -0,0 +1,98 @@
+struct __siginfo
+{
+	int si_signo;
+	int si_errno;
+	int si_code;
+	union
+	{
+		char __pad[128 - 3*sizeof(int)];
+		struct {
+			pid_t si_pid;
+			uid_t si_uid;
+			union sigval si_sigval;
+		} __rt;
+		struct {
+			unsigned int si_timer1;
+			unsigned int si_timer2;
+		} __timer;
+		struct {
+			pid_t si_pid;
+			uid_t si_uid;
+			int si_status;
+			clock_t si_utime;
+			clock_t si_stime;
+		} __sigchld;
+		struct {
+			void *si_addr;
+		} __sigfault;
+		struct {
+			long int si_band;
+			int si_fd;
+		} __sigpoll;
+	} __si_fields;
+};
+
+#define si_pid     __si_fields.__sigchld.si_pid
+#define si_uid     __si_fields.__sigchld.si_uid
+#define si_status  __si_fields.__sigchld.si_status
+#define si_utime   __si_fields.__sigchld.si_utime
+#define si_stime   __si_fields.__sigchld.si_stime
+#define si_value   __si_fields.__rt.si_sigval
+#define si_addr    __si_fields.__sigfault.si_addr
+#define si_band    __si_fields.__sigpoll.si_band
+
+#define SA_NOCLDSTOP  1
+#define SA_NOCLDWAIT  2
+#define SA_SIGINFO    4
+#define SA_ONSTACK    0x08000000
+#define SA_RESTART    0x10000000
+#define SA_NODEFER    0x40000000
+#define SA_RESETHAND  0x80000000
+
+#define SS_ONSTACK    1
+#define SS_DISABLE    2
+
+#define SIG_BLOCK     0
+#define SIG_UNBLOCK   1
+#define SIG_SETMASK   2
+
+#define SIG_ERR  ((void (*)(int))-1)
+#define SIG_DFL  ((void (*)(int)) 0)
+#define SIG_IGN  ((void (*)(int)) 1)
+#define SIG_HOLD ((void (*)(int)) 2)
+
+#define NSIG      64
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
diff --git a/include/bits/socket.h b/include/bits/socket.h
new file mode 100644
index 00000000..7a51f792
--- /dev/null
+++ b/include/bits/socket.h
@@ -0,0 +1,189 @@
+struct iovec;
+
+struct msghdr
+{
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+	int msg_iovlen;
+	void *msg_control;
+	socklen_t msg_controllen;
+	int msg_flags;
+};
+
+struct cmsghdr
+{
+	socklen_t cmsg_len;
+	int cmsg_level;
+	int cmsg_type;
+};
+
+struct ucred
+{
+	pid_t pid;
+	uid_t uid;
+	gid_t gid;
+};
+
+struct linger
+{
+	int l_onoff;
+	int l_linger;
+};
+
+#define SHUT_RD 0
+#define SHUT_WD 1
+#define SHUT_RDWR 2
+
+#define SOCK_STREAM    1
+#define SOCK_DGRAM     2
+#define SOCK_RAW       3
+#define SOCK_RDM       4
+#define SOCK_SEQPACKET 5
+#define SOCK_PACKET    10
+
+#define AF_UNSPEC       0
+#define AF_LOCAL        1
+#define AF_UNIX         AF_LOCAL
+#define AF_FILE         AF_LOCAL
+#define AF_INET         2
+#define AF_AX25         3
+#define AF_IPX          4
+#define AF_APPLETALK    5
+#define AF_NETROM       6
+#define AF_BRIDGE       7
+#define AF_ATMPVC       8
+#define AF_X25          9
+#define AF_INET6        10
+#define AF_ROSE         11
+#define AF_DECnet       12
+#define AF_NETBEUI      13
+#define AF_SECURITY     14
+#define AF_KEY          15
+#define AF_NETLINK      16
+#define AF_ROUTE        AF_NETLINK
+#define AF_PACKET       17
+#define AF_ASH          18
+#define AF_ECONET       19
+#define AF_ATMSVC       20
+#define AF_SNA          22
+#define AF_IRDA         23
+#define AF_PPPOX        24
+#define AF_WANPIPE      25
+#define AF_BLUETOOTH    31
+
+#define PF_UNSPEC       0
+#define PF_LOCAL        1
+#define PF_UNIX         PF_LOCAL
+#define PF_FILE         PF_LOCAL
+#define PF_INET         2
+#define PF_AX25         3
+#define PF_IPX          4
+#define PF_APPLETALK    5
+#define PF_NETROM       6
+#define PF_BRIDGE       7
+#define PF_ATMPVC       8
+#define PF_X25          9
+#define PF_INET6        10
+#define PF_ROSE         11
+#define PF_DECnet       12
+#define PF_NETBEUI      13
+#define PF_SECURITY     14
+#define PF_KEY          15
+#define PF_NETLINK      16
+#define PF_ROUTE        PF_NETLINK
+#define PF_PACKET       17
+#define PF_ASH          18
+#define PF_ECONET       19
+#define PF_ATMSVC       20
+#define PF_SNA          22
+#define PF_IRDA         23
+#define PF_PPPOX        24
+#define PF_WANPIPE      25
+#define PF_BLUETOOTH    31
+
+#define SO_DEBUG        1
+#define SO_REUSEADDR    2
+#define SO_TYPE         3
+#define SO_ERROR        4
+#define SO_DONTROUTE    5
+#define SO_BROADCAST    6
+#define SO_SNDBUF       7
+#define SO_RCVBUF       8
+#define SO_KEEPALIVE    9
+#define SO_OOBINLINE    10
+#define SO_NO_CHECK     11
+#define SO_PRIORITY     12
+#define SO_LINGER       13
+#define SO_BSDCOMPAT    14
+#define SO_REUSEPORT    15
+#define SO_PASSCRED     16
+#define SO_PEERCRED     17
+#define SO_RCVLOWAT     18
+#define SO_SNDLOWAT     19
+#define SO_RCVTIMEO     20
+#define SO_SNDTIMEO     21
+
+#define SO_SECURITY_AUTHENTICATION              22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT        23
+#define SO_SECURITY_ENCRYPTION_NETWORK          24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP            29
+#define SCM_TIMESTAMP           SO_TIMESTAMP
+
+#define SO_ACCEPTCONN           30
+
+#define SOL_SOCKET      1
+
+/* ??? */
+#define SOL_RAW         255
+#define SOL_DECNET      261
+#define SOL_X25         262
+#define SOL_PACKET      263
+#define SOL_ATM         264
+#define SOL_AAL         265
+#define SOL_IRDA        266
+
+#define SOMAXCONN       128
+
+#define MSG_OOB       0x0001
+#define MSG_PEEK      0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_CTRUNC    0x0008
+#define MSG_PROXY     0x0010
+#define MSG_TRUNC     0x0020
+#define MSG_DONTWAIT  0x0040
+#define MSG_EOR       0x0080
+#define MSG_WAITALL   0x0100
+#define MSG_FIN       0x0200
+#define MSD_SYN       0x0400
+#define MSG_CONFIRM   0x0800
+#define MSG_RST       0x1000
+#define MSG_ERRQUEUE  0x2000
+#define MSG_NOSIGNAL  0x4000
+#define MSG_MORE      0x8000
+
+/* Internal use only!! to make CMSG_NXTHDR definition readable by mortals */
+#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
+#define __CMSG_NEXT(cmsg) ((unsigned char *)(cmsg) + __CMSG_LEN(cmsg))
+#define __MHDR_END(mhdr) ((unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen)
+
+#define CMSG_DATA(cmsg) ((unsigned char *) (((struct cmsghdr *)(cmsg)) + 1))
+#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) ? (struct cmsghdr *)0 : \
+        (__CMSG_NEXT(cmsg) + sizeof (struct cmsghdr) >= __MHDR_END(mhdr) ? (struct cmsghdr *)0 : \
+        ((struct cmsghdr *)__CMSG_NEXT(cmsg))))
+#define CMSG_FIRSTHDR(mhdr) ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
+
+/* Are these valid? */
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+#define SCM_RIGHTS      0x01
+#define SCM_CREDENTIALS 0x02
diff --git a/include/bits/stat.h b/include/bits/stat.h
new file mode 100644
index 00000000..1ef34698
--- /dev/null
+++ b/include/bits/stat.h
@@ -0,0 +1,25 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat
+{
+	dev_t st_dev;
+	int __st_dev_padding;
+	long __st_ino_truncated;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	int __st_rdev_padding;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	time_t st_atime;
+	unsigned long __st_atime_nsec;
+	time_t st_mtime;
+	unsigned long __st_mtime_nsec;
+	time_t st_ctime;
+	unsigned long __st_ctime_nsec;
+	ino_t st_ino;
+};
diff --git a/include/bits/statfs.h b/include/bits/statfs.h
new file mode 100644
index 00000000..9dda4400
--- /dev/null
+++ b/include/bits/statfs.h
@@ -0,0 +1,16 @@
+struct statvfs {
+	unsigned long f_type;
+	unsigned long f_bsize;
+	fsblkcnt_t f_blocks;
+	fsblkcnt_t f_bfree;
+	fsblkcnt_t f_bavail;
+	fsfilcnt_t f_files;
+	fsfilcnt_t f_ffree;
+	unsigned long f_fsid;
+	unsigned long __unused;
+	unsigned long f_namemax;
+	unsigned long f_frsize;
+	fsfilcnt_t f_favail;
+	unsigned long f_flag;
+	unsigned long __reserved[2];
+};
diff --git a/include/bits/stdint.h b/include/bits/stdint.h
new file mode 100644
index 00000000..8e21a8cb
--- /dev/null
+++ b/include/bits/stdint.h
@@ -0,0 +1,23 @@
+#define INT_FAST8_MIN   INT8_MIN
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+#define INT_FAST64_MIN  INT64_MIN
+
+#define INT_FAST8_MAX   INT8_MAX
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+#define INT_FAST64_MAX  INT64_MAX
+
+#define UINT_FAST8_MAX  UINT8_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_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
+#define SIG_ATOMIC_MIN  INT32_MIN
+#define SIG_ATOMIC_MAX  INT32_MAX
+#define SIZE_MAX        UINT32_MAX
diff --git a/include/bits/stdio.h b/include/bits/stdio.h
new file mode 100644
index 00000000..0afd8b40
--- /dev/null
+++ b/include/bits/stdio.h
@@ -0,0 +1,10 @@
+#define BUFSIZ 1024
+
+#define FILENAME_MAX 4095
+#define FOPEN_MAX 1000
+#define TMP_MAX 10000
+
+#define L_cuserid 20
+#define L_ctermid 20
+#define L_tmpnam 20
+#define P_tmpdir "/tmp"
diff --git a/include/bits/sysmacros.h b/include/bits/sysmacros.h
new file mode 100644
index 00000000..da29022d
--- /dev/null
+++ b/include/bits/sysmacros.h
@@ -0,0 +1,7 @@
+#define major(x) (((x) >> 8) & 0xff)
+#define minor(x) ((x) & 0xff)
+#define makedev(x,y) (((x)<<8)|((y)&0xff))
+
+//#define makedev(x,y) \
+//	((x)*0x100000001ULL)&(0xfffffffffff0)
+//	((y)*0x1001 & 0xffff0ff)
diff --git a/include/bits/tcp.h b/include/bits/tcp.h
new file mode 100644
index 00000000..923231b2
--- /dev/null
+++ b/include/bits/tcp.h
@@ -0,0 +1 @@
+#define TCP_NODELAY 1
diff --git a/include/bits/termios.h b/include/bits/termios.h
new file mode 100644
index 00000000..316baeb2
--- /dev/null
+++ b/include/bits/termios.h
@@ -0,0 +1,158 @@
+struct termios
+{
+	tcflag_t c_iflag;
+	tcflag_t c_oflag;
+	tcflag_t c_cflag;
+	tcflag_t c_lflag;
+	cc_t c_line;
+	cc_t c_cc[NCCS];
+	speed_t __c_ispeed;
+	speed_t __c_ospeed;
+};
+
+#define VINTR     0
+#define VQUIT     1
+#define VERASE    2
+#define VKILL     3
+#define VEOF      4
+#define VTIME     5
+#define VMIN      6
+#define VSWTC     7
+#define VSTART    8
+#define VSTOP     9
+#define VSUSP    10
+#define VEOL     11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+#define VEOL2    16
+
+#define IGNBRK  0000001
+#define BRKINT  0000002
+#define IGNPAR  0000004
+#define PARMRK  0000010
+#define INPCK   0000020
+#define ISTRIP  0000040
+#define INLCR   0000100
+#define IGNCR   0000200
+#define ICRNL   0000400
+#define IUCLC   0001000
+#define IXON    0002000
+#define IXANY   0004000
+#define IXOFF   0010000
+#define IMAXBEL 0020000
+
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define NL0    0000000
+#define NL1    0000400
+#define CRDLY  0003000
+#define CR0    0000000
+#define CR1    0001000
+#define CR2    0002000
+#define CR3    0003000
+#define TABDLY 0014000
+#define TAB0   0000000
+#define TAB1   0004000
+#define TAB2   0010000
+#define TAB3   0014000
+#define BSDLY  0020000
+#define BS0    0000000
+#define BS1    0020000
+#define FFDLY  0100000
+#define FF0    0000000
+#define FF1    0100000
+
+#define VTDLY  0040000
+#define VT0    0000000
+#define VT1    0040000
+
+/* ?? */
+#define XTABS  0014000
+
+#define B0       0000000
+#define B50      0000001
+#define B75      0000002
+#define B110     0000003
+#define B134     0000004
+#define B150     0000005
+#define B200     0000006
+#define B300     0000007
+#define B600     0000010
+#define B1200    0000011
+#define B1800    0000012
+#define B2400    0000013
+#define B4800    0000014
+#define B9600    0000015
+#define B19200   0000016
+#define B38400   0000017
+
+#define B57600   0010001
+#define B115200  0010002
+#define B230400  0010003
+#define B460800  0010004
+#define B500000  0010005
+#define B576000  0010006
+#define B921600  0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CBAUD    0010017
+
+#define CSIZE  0000060
+#define CS5    0000000
+#define CS6    0000020
+#define CS7    0000040
+#define CS8    0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+
+#define CRTSCTS  020000000000
+
+#define ISIG   0000001
+#define ICANON 0000002
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+/* Extensions? */
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+
+#define TCOOFF 0
+#define TCOON  1
+#define TCIOFF 2
+#define TCION  3
+
+#define TCIFLUSH  0
+#define TCOFLUSH  1
+#define TCIOFLUSH 2
+
+#define TCSANOW   0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
diff --git a/include/bits/uio.h b/include/bits/uio.h
new file mode 100644
index 00000000..43252653
--- /dev/null
+++ b/include/bits/uio.h
@@ -0,0 +1,4 @@
+struct iovec {
+	void *iov_base;
+	size_t iov_len;
+};
diff --git a/include/bits/user.h b/include/bits/user.h
new file mode 100644
index 00000000..13ff027b
--- /dev/null
+++ b/include/bits/user.h
@@ -0,0 +1,77 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
+
+struct user_fpregs_struct
+{
+	long int cwd;
+	long int swd;
+	long int twd;
+	long int fip;
+	long int fcs;
+	long int foo;
+	long int fos;
+	long int st_space[20];
+};
+
+struct user_fpxregs_struct
+{
+	unsigned short int cwd;
+	unsigned short int swd;
+	unsigned short int twd;
+	unsigned short int fop;
+	long int fip;
+	long int fcs;
+	long int foo;
+	long int fos;
+	long int mxcsr;
+	long int reserved;
+	long int st_space[32];
+	long int xmm_space[32];
+	long int padding[56];
+};
+
+struct user_regs_struct
+{
+	long int ebx;
+	long int ecx;
+	long int edx;
+	long int esi;
+	long int edi;
+	long int ebp;
+	long int eax;
+	long int xds;
+	long int xes;
+	long int xfs;
+	long int xgs;
+	long int orig_eax;
+	long int eip;
+	long int xcs;
+	long int eflags;
+	long int esp;
+	long int xss;
+};
+
+struct user
+{
+	struct user_regs_struct		regs;
+	int				u_fpvalid;
+	struct user_fpregs_struct	i387;
+	unsigned long int		u_tsize;
+	unsigned long int		u_dsize;
+	unsigned long int		u_ssize;
+	unsigned long			start_code;
+	unsigned long			start_stack;
+	long int			signal;
+	int				reserved;
+	struct user_regs_struct		*u_ar0;
+	struct user_fpregs_struct	*u_fpstate;
+	unsigned long int		magic;
+	char				u_comm[32];
+	int				u_debugreg[8];
+};
+
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
diff --git a/include/bits/wait.h b/include/bits/wait.h
new file mode 100644
index 00000000..ca9b57e0
--- /dev/null
+++ b/include/bits/wait.h
@@ -0,0 +1,11 @@
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WSTOPPED   2
+#define WEXITED    4
+#define WCONTINUED 8
+#define WNOWAIT    0x1000000
+
+#define P_ALL  0
+#define P_PID  1
+#define P_PGID 2
diff --git a/include/bits/wexitstatus.h b/include/bits/wexitstatus.h
new file mode 100644
index 00000000..34a80238
--- /dev/null
+++ b/include/bits/wexitstatus.h
@@ -0,0 +1,9 @@
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) (((s) & 0xff) == 0x7f)
+#define WIFSIGNALED(s) (!WIFSTOPPED(s) && !WIFEXITED(s))
+#endif
diff --git a/include/byteswap.h b/include/byteswap.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/byteswap.h
diff --git a/include/cpio.h b/include/cpio.h
new file mode 100644
index 00000000..39a1f8bb
--- /dev/null
+++ b/include/cpio.h
@@ -0,0 +1,29 @@
+#ifndef _CPIO_H
+#define _CPIO_H
+
+#define MAGIC "070707"
+
+#define C_IRUSR  000400
+#define C_IWUSR  000200
+#define C_IXUSR  000100
+#define C_IRGRP  000040
+#define C_IWGRP  000020
+#define C_IXGRP  000010
+#define C_IROTH  000004
+#define C_IWOTH  000002
+#define C_IXOTH  000001
+
+#define C_ISUID  004000
+#define C_ISGID  002000
+#define C_ISVTX  001000
+
+#define C_ISBLK  060000
+#define C_ISCHR  020000
+#define C_ISDIR  040000
+#define C_ISFIFO 010000
+#define C_ISSOCK 0140000
+#define C_ISLNK  0120000
+#define C_ISCTG  0110000
+#define C_ISREG  0100000
+
+#endif
diff --git a/include/ctype.h b/include/ctype.h
new file mode 100644
index 00000000..02f81fa7
--- /dev/null
+++ b/include/ctype.h
@@ -0,0 +1,53 @@
+#ifndef	_CTYPE_H
+#define	_CTYPE_H
+
+int   isalnum(int);
+int   isalpha(int);
+int   isblank(int);
+int   iscntrl(int);
+int   isdigit(int);
+int   isgraph(int);
+int   islower(int);
+int   isprint(int);
+int   ispunct(int);
+int   isspace(int);
+int   isupper(int);
+int   isxdigit(int);
+int   tolower(int);
+int   toupper(int);
+
+int   isascii(int);
+int   toascii(int);
+
+#define _tolower(a) ((a)|0x20)
+#define _toupper(a) ((a)&0x5f)
+
+#define isalpha(a) ((unsigned)(((a)|32)-'a') < 26)
+#define isdigit(a) ((unsigned)((a)-'0') < 10)
+#define islower(a) ((unsigned)((a)-'a') < 26)
+#define isupper(a) ((unsigned)((a)-'A') < 26)
+#define isprint(a) ((unsigned)((a)-0x20) < 0x5f)
+#define isgraph(a) ((unsigned)((a)-0x21) < 0x5e)
+
+#if 1
+
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+int   isalnum_l(int, locale_t);
+int   isalpha_l(int, locale_t);
+int   isblank_l(int, locale_t);
+int   iscntrl_l(int, locale_t);
+int   isdigit_l(int, locale_t);
+int   isgraph_l(int, locale_t);
+int   islower_l(int, locale_t);
+int   isprint_l(int, locale_t);
+int   ispunct_l(int, locale_t);
+int   isspace_l(int, locale_t);
+int   isupper_l(int, locale_t);
+int   isxdigit_l(int, locale_t);
+int   tolower_l(int, locale_t);
+int   toupper_l(int, locale_t);
+#endif
+
+#endif
diff --git a/include/dirent.h b/include/dirent.h
new file mode 100644
index 00000000..a9170936
--- /dev/null
+++ b/include/dirent.h
@@ -0,0 +1,41 @@
+#ifndef	_DIRENT_H
+#define	_DIRENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_ino_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+typedef struct __DIR_s DIR;
+
+struct dirent
+{
+	ino_t d_ino;
+	off_t d_off;
+	unsigned short d_reclen;
+	unsigned char d_type;
+	char d_name[1];
+};
+
+int            closedir(DIR *);
+DIR           *fdopendir(int);
+DIR           *opendir(const char *);
+struct dirent *readdir(DIR *);
+int            readdir_r(DIR *, struct dirent *, struct dirent **);
+void           rewinddir(DIR *);
+void           seekdir(DIR *, long);
+long           telldir(DIR *);
+int            dirfd(DIR *);
+
+int alphasort(const struct dirent **, const struct dirent **);
+int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
+
+#ifdef __cplusplus
+extern }
+#endif
+
+#endif
diff --git a/include/dlfcn.h b/include/dlfcn.h
new file mode 100644
index 00000000..81b829c8
--- /dev/null
+++ b/include/dlfcn.h
@@ -0,0 +1,19 @@
+#ifndef	_DLFCN_H
+#define	_DLFCN_H
+
+#define RTLD_LAZY   0x10000
+#define RTLD_NOW    0x20000
+#define RTLD_GLOBAL 0x40000
+#define RTLD_LOCAL  0x80000
+
+#if 1
+#define RTLD_NEXT    ((void *) -1l)
+#define RTLD_DEFAULT ((void *) 0)
+#endif
+
+int    dlclose(void *);
+char  *dlerror(void);
+void  *dlopen(const char *, int);
+void  *dlsym(void *, const char *);
+
+#endif
diff --git a/include/elf.h b/include/elf.h
new file mode 100644
index 00000000..b011e784
--- /dev/null
+++ b/include/elf.h
@@ -0,0 +1,2524 @@
+#ifndef _ELF_H
+#define	_ELF_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_NIDENT (16)
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf32_Half	e_type;
+  Elf32_Half	e_machine;
+  Elf32_Word	e_version;
+  Elf32_Addr	e_entry;
+  Elf32_Off	e_phoff;
+  Elf32_Off	e_shoff;
+  Elf32_Word	e_flags;
+  Elf32_Half	e_ehsize;
+  Elf32_Half	e_phentsize;
+  Elf32_Half	e_phnum;
+  Elf32_Half	e_shentsize;
+  Elf32_Half	e_shnum;
+  Elf32_Half	e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf64_Half	e_type;
+  Elf64_Half	e_machine;
+  Elf64_Word	e_version;
+  Elf64_Addr	e_entry;
+  Elf64_Off	e_phoff;
+  Elf64_Off	e_shoff;
+  Elf64_Word	e_flags;
+  Elf64_Half	e_ehsize;
+  Elf64_Half	e_phentsize;
+  Elf64_Half	e_phnum;
+  Elf64_Half	e_shentsize;
+  Elf64_Half	e_shnum;
+  Elf64_Half	e_shstrndx;
+} Elf64_Ehdr;
+
+#define EI_MAG0		0
+#define ELFMAG0		0x7f
+
+#define EI_MAG1		1
+#define ELFMAG1		'E'
+
+#define EI_MAG2		2
+#define ELFMAG2		'L'
+
+#define EI_MAG3		3
+#define ELFMAG3		'F'
+
+
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+#define ELFDATANUM	3
+
+#define EI_VERSION	6
+
+
+#define EI_OSABI	7
+#define ELFOSABI_NONE		0
+#define ELFOSABI_SYSV		0
+#define ELFOSABI_HPUX		1
+#define ELFOSABI_NETBSD		2
+#define ELFOSABI_LINUX		3
+#define ELFOSABI_SOLARIS	6
+#define ELFOSABI_AIX		7
+#define ELFOSABI_IRIX		8
+#define ELFOSABI_FREEBSD	9
+#define ELFOSABI_TRU64		10
+#define ELFOSABI_MODESTO	11
+#define ELFOSABI_OPENBSD	12
+#define ELFOSABI_ARM		97
+#define ELFOSABI_STANDALONE	255
+
+#define EI_ABIVERSION	8
+
+#define EI_PAD		9
+
+
+
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define	ET_NUM		5
+#define ET_LOOS		0xfe00
+#define ET_HIOS		0xfeff
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+
+
+#define EM_NONE		 0
+#define EM_M32		 1
+#define EM_SPARC	 2
+#define EM_386		 3
+#define EM_68K		 4
+#define EM_88K		 5
+#define EM_860		 7
+#define EM_MIPS		 8
+#define EM_S370		 9
+#define EM_MIPS_RS3_LE	10
+
+#define EM_PARISC	15
+#define EM_VPP500	17
+#define EM_SPARC32PLUS	18
+#define EM_960		19
+#define EM_PPC		20
+#define EM_PPC64	21
+#define EM_S390		22
+
+#define EM_V800		36
+#define EM_FR20		37
+#define EM_RH32		38
+#define EM_RCE		39
+#define EM_ARM		40
+#define EM_FAKE_ALPHA	41
+#define EM_SH		42
+#define EM_SPARCV9	43
+#define EM_TRICORE	44
+#define EM_ARC		45
+#define EM_H8_300	46
+#define EM_H8_300H	47
+#define EM_H8S		48
+#define EM_H8_500	49
+#define EM_IA_64	50
+#define EM_MIPS_X	51
+#define EM_COLDFIRE	52
+#define EM_68HC12	53
+#define EM_MMA		54
+#define EM_PCP		55
+#define EM_NCPU		56
+#define EM_NDR1		57
+#define EM_STARCORE	58
+#define EM_ME16		59
+#define EM_ST100	60
+#define EM_TINYJ	61
+#define EM_X86_64	62
+#define EM_PDSP		63
+
+#define EM_FX66		66
+#define EM_ST9PLUS	67
+#define EM_ST7		68
+#define EM_68HC16	69
+#define EM_68HC11	70
+#define EM_68HC08	71
+#define EM_68HC05	72
+#define EM_SVX		73
+#define EM_ST19		74
+#define EM_VAX		75
+#define EM_CRIS		76
+#define EM_JAVELIN	77
+#define EM_FIREPATH	78
+#define EM_ZSP		79
+#define EM_MMIX		80
+#define EM_HUANY	81
+#define EM_PRISM	82
+#define EM_AVR		83
+#define EM_FR30		84
+#define EM_D10V		85
+#define EM_D30V		86
+#define EM_V850		87
+#define EM_M32R		88
+#define EM_MN10300	89
+#define EM_MN10200	90
+#define EM_PJ		91
+#define EM_OPENRISC	92
+#define EM_ARC_A5	93
+#define EM_XTENSA	94
+#define EM_NUM		95
+#define EM_ALPHA	0x9026
+
+#define EV_NONE		0
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+typedef struct {
+  Elf32_Word	sh_name;
+  Elf32_Word	sh_type;
+  Elf32_Word	sh_flags;
+  Elf32_Addr	sh_addr;
+  Elf32_Off	sh_offset;
+  Elf32_Word	sh_size;
+  Elf32_Word	sh_link;
+  Elf32_Word	sh_info;
+  Elf32_Word	sh_addralign;
+  Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+  Elf64_Word	sh_name;
+  Elf64_Word	sh_type;
+  Elf64_Xword	sh_flags;
+  Elf64_Addr	sh_addr;
+  Elf64_Off	sh_offset;
+  Elf64_Xword	sh_size;
+  Elf64_Word	sh_link;
+  Elf64_Word	sh_info;
+  Elf64_Xword	sh_addralign;
+  Elf64_Xword	sh_entsize;
+} Elf64_Shdr;
+
+
+
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_BEFORE	0xff00
+
+#define SHN_AFTER	0xff01
+
+#define SHN_HIPROC	0xff1f
+#define SHN_LOOS	0xff20
+#define SHN_HIOS	0xff3f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_XINDEX	0xffff
+#define SHN_HIRESERVE	0xffff
+
+
+
+#define SHT_NULL	  0
+#define SHT_PROGBITS	  1
+#define SHT_SYMTAB	  2
+#define SHT_STRTAB	  3
+#define SHT_RELA	  4
+#define SHT_HASH	  5
+#define SHT_DYNAMIC	  6
+#define SHT_NOTE	  7
+#define SHT_NOBITS	  8
+#define SHT_REL		  9
+#define SHT_SHLIB	  10
+#define SHT_DYNSYM	  11
+#define SHT_INIT_ARRAY	  14
+#define SHT_FINI_ARRAY	  15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP	  17
+#define SHT_SYMTAB_SHNDX  18
+#define	SHT_NUM		  19
+#define SHT_LOOS	  0x60000000
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_GNU_HASH	  0x6ffffff6
+#define SHT_GNU_LIBLIST	  0x6ffffff7
+#define SHT_CHECKSUM	  0x6ffffff8
+#define SHT_LOSUNW	  0x6ffffffa
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd
+#define SHT_GNU_verneed	  0x6ffffffe
+#define SHT_GNU_versym	  0x6fffffff
+#define SHT_HISUNW	  0x6fffffff
+#define SHT_HIOS	  0x6fffffff
+#define SHT_LOPROC	  0x70000000
+#define SHT_HIPROC	  0x7fffffff
+#define SHT_LOUSER	  0x80000000
+#define SHT_HIUSER	  0x8fffffff
+
+#define SHF_WRITE	     (1 << 0)
+#define SHF_ALLOC	     (1 << 1)
+#define SHF_EXECINSTR	     (1 << 2)
+#define SHF_MERGE	     (1 << 4)
+#define SHF_STRINGS	     (1 << 5)
+#define SHF_INFO_LINK	     (1 << 6)
+#define SHF_LINK_ORDER	     (1 << 7)
+#define SHF_OS_NONCONFORMING (1 << 8)
+
+#define SHF_GROUP	     (1 << 9)
+#define SHF_TLS		     (1 << 10)
+#define SHF_MASKOS	     0x0ff00000
+#define SHF_MASKPROC	     0xf0000000
+#define SHF_ORDERED	     (1 << 30)
+#define SHF_EXCLUDE	     (1 << 31)
+
+#define GRP_COMDAT	0x1
+
+typedef struct {
+  Elf32_Word	st_name;
+  Elf32_Addr	st_value;
+  Elf32_Word	st_size;
+  unsigned char	st_info;
+  unsigned char	st_other;
+  Elf32_Section	st_shndx;
+} Elf32_Sym;
+
+typedef struct {
+  Elf64_Word	st_name;
+  unsigned char	st_info;
+  unsigned char st_other;
+  Elf64_Section	st_shndx;
+  Elf64_Addr	st_value;
+  Elf64_Xword	st_size;
+} Elf64_Sym;
+
+typedef struct {
+  Elf32_Half si_boundto;
+  Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+typedef struct {
+  Elf64_Half si_boundto;
+  Elf64_Half si_flags;
+} Elf64_Syminfo;
+
+#define SYMINFO_BT_SELF		0xffff
+#define SYMINFO_BT_PARENT	0xfffe
+#define SYMINFO_BT_LOWRESERVE	0xff00
+
+#define SYMINFO_FLG_DIRECT	0x0001
+#define SYMINFO_FLG_PASSTHRU	0x0002
+#define SYMINFO_FLG_COPY	0x0004
+#define SYMINFO_FLG_LAZYLOAD	0x0008
+
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+#define STB_LOCAL	0
+#define STB_GLOBAL	1
+#define STB_WEAK	2
+#define	STB_NUM		3
+#define STB_LOOS	10
+#define STB_GNU_UNIQUE	10
+#define STB_HIOS	12
+#define STB_LOPROC	13
+#define STB_HIPROC	15
+
+#define STT_NOTYPE	0
+#define STT_OBJECT	1
+#define STT_FUNC	2
+#define STT_SECTION	3
+#define STT_FILE	4
+#define STT_COMMON	5
+#define STT_TLS		6
+#define	STT_NUM		7
+#define STT_LOOS	10
+#define STT_GNU_IFUNC	10
+#define STT_HIOS	12
+#define STT_LOPROC	13
+#define STT_HIPROC	15
+
+#define STN_UNDEF	0
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+#define STV_DEFAULT	0
+#define STV_INTERNAL	1
+#define STV_HIDDEN	2
+#define STV_PROTECTED	3
+
+
+
+
+typedef struct
+{
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+} Elf32_Rel;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+} Elf64_Rel;
+
+
+
+typedef struct {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+  Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+  Elf64_Sxword	r_addend;
+} Elf64_Rela;
+
+
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+
+
+typedef struct {
+  Elf32_Word	p_type;
+  Elf32_Off	p_offset;
+  Elf32_Addr	p_vaddr;
+  Elf32_Addr	p_paddr;
+  Elf32_Word	p_filesz;
+  Elf32_Word	p_memsz;
+  Elf32_Word	p_flags;
+  Elf32_Word	p_align;
+} Elf32_Phdr;
+
+typedef struct {
+  Elf64_Word	p_type;
+  Elf64_Word	p_flags;
+  Elf64_Off	p_offset;
+  Elf64_Addr	p_vaddr;
+  Elf64_Addr	p_paddr;
+  Elf64_Xword	p_filesz;
+  Elf64_Xword	p_memsz;
+  Elf64_Xword	p_align;
+} Elf64_Phdr;
+
+
+
+#define	PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_TLS		7
+#define	PT_NUM		8
+#define PT_LOOS		0x60000000
+#define PT_GNU_EH_FRAME	0x6474e550
+#define PT_GNU_STACK	0x6474e551
+#define PT_GNU_RELRO	0x6474e552
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa
+#define PT_SUNWSTACK	0x6ffffffb
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+
+
+#define PF_X		(1 << 0)
+#define PF_W		(1 << 1)
+#define PF_R		(1 << 2)
+#define PF_MASKOS	0x0ff00000
+#define PF_MASKPROC	0xf0000000
+
+
+
+#define NT_PRSTATUS	1
+#define NT_FPREGSET	2
+#define NT_PRPSINFO	3
+#define NT_PRXREG	4
+#define NT_TASKSTRUCT	4
+#define NT_PLATFORM	5
+#define NT_AUXV		6
+#define NT_GWINDOWS	7
+#define NT_ASRS		8
+#define NT_PSTATUS	10
+#define NT_PSINFO	13
+#define NT_PRCRED	14
+#define NT_UTSNAME	15
+#define NT_LWPSTATUS	16
+#define NT_LWPSINFO	17
+#define NT_PRFPXREG	20
+#define NT_PRXFPREG	0x46e62b7f
+#define NT_PPC_VMX	0x100
+#define NT_PPC_SPE	0x101
+#define NT_PPC_VSX	0x102
+#define NT_386_TLS	0x200
+#define NT_386_IOPERM	0x201
+#define NT_VERSION	1
+
+
+
+
+typedef struct {
+  Elf32_Sword d_tag;
+  union {
+      Elf32_Word d_val;
+      Elf32_Addr d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Sxword d_tag;
+  union {
+      Elf64_Xword d_val;
+      Elf64_Addr d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define	DT_BIND_NOW	24
+#define	DT_INIT_ARRAY	25
+#define	DT_FINI_ARRAY	26
+#define	DT_INIT_ARRAYSZ	27
+#define	DT_FINI_ARRAYSZ	28
+#define DT_RUNPATH	29
+#define DT_FLAGS	30
+#define DT_ENCODING	32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define	DT_NUM		34
+#define DT_LOOS		0x6000000d
+#define DT_HIOS		0x6ffff000
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+#define	DT_PROCNUM	DT_MIPS_NUM
+
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc
+#define DT_POSFLAG_1	0x6ffffdfd
+
+#define DT_SYMINSZ	0x6ffffdfe
+#define DT_SYMINENT	0x6ffffdff
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))
+#define DT_VALNUM 12
+
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8
+#define DT_GNU_LIBLIST	0x6ffffef9
+#define DT_CONFIG	0x6ffffefa
+#define DT_DEPAUDIT	0x6ffffefb
+#define DT_AUDIT	0x6ffffefc
+#define	DT_PLTPAD	0x6ffffefd
+#define	DT_MOVETAB	0x6ffffefe
+#define DT_SYMINFO	0x6ffffeff
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))
+#define DT_ADDRNUM 11
+
+
+
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+
+#define DT_FLAGS_1	0x6ffffffb
+#define	DT_VERDEF	0x6ffffffc
+
+#define	DT_VERDEFNUM	0x6ffffffd
+#define	DT_VERNEED	0x6ffffffe
+
+#define	DT_VERNEEDNUM	0x6fffffff
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))
+#define DT_VERSIONTAGNUM 16
+
+
+
+#define DT_AUXILIARY    0x7ffffffd
+#define DT_FILTER       0x7fffffff
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+
+#define DF_ORIGIN	0x00000001
+#define DF_SYMBOLIC	0x00000002
+#define DF_TEXTREL	0x00000004
+#define DF_BIND_NOW	0x00000008
+#define DF_STATIC_TLS	0x00000010
+
+
+
+#define DF_1_NOW	0x00000001
+#define DF_1_GLOBAL	0x00000002
+#define DF_1_GROUP	0x00000004
+#define DF_1_NODELETE	0x00000008
+#define DF_1_LOADFLTR	0x00000010
+#define DF_1_INITFIRST	0x00000020
+#define DF_1_NOOPEN	0x00000040
+#define DF_1_ORIGIN	0x00000080
+#define DF_1_DIRECT	0x00000100
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400
+#define DF_1_NODEFLIB	0x00000800
+#define DF_1_NODUMP	0x00001000
+#define DF_1_CONFALT	0x00002000
+#define DF_1_ENDFILTEE	0x00004000
+#define	DF_1_DISPRELDNE	0x00008000
+#define	DF_1_DISPRELPND	0x00010000
+
+
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+
+#define DF_P1_LAZYLOAD	0x00000001
+#define DF_P1_GROUPPERM	0x00000002
+
+
+
+
+typedef struct {
+  Elf32_Half	vd_version;
+  Elf32_Half	vd_flags;
+  Elf32_Half	vd_ndx;
+  Elf32_Half	vd_cnt;
+  Elf32_Word	vd_hash;
+  Elf32_Word	vd_aux;
+  Elf32_Word	vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+  Elf64_Half	vd_version;
+  Elf64_Half	vd_flags;
+  Elf64_Half	vd_ndx;
+  Elf64_Half	vd_cnt;
+  Elf64_Word	vd_hash;
+  Elf64_Word	vd_aux;
+  Elf64_Word	vd_next;
+} Elf64_Verdef;
+
+
+
+#define VER_DEF_NONE	0
+#define VER_DEF_CURRENT	1
+#define VER_DEF_NUM	2
+
+
+#define VER_FLG_BASE	0x1
+#define VER_FLG_WEAK	0x2
+
+
+#define	VER_NDX_LOCAL		0
+#define	VER_NDX_GLOBAL		1
+#define	VER_NDX_LORESERVE	0xff00
+#define	VER_NDX_ELIMINATE	0xff01
+
+
+
+typedef struct {
+  Elf32_Word	vda_name;
+  Elf32_Word	vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+  Elf64_Word	vda_name;
+  Elf64_Word	vda_next;
+} Elf64_Verdaux;
+
+
+
+
+typedef struct {
+  Elf32_Half	vn_version;
+  Elf32_Half	vn_cnt;
+  Elf32_Word	vn_file;
+  Elf32_Word	vn_aux;
+  Elf32_Word	vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+  Elf64_Half	vn_version;
+  Elf64_Half	vn_cnt;
+  Elf64_Word	vn_file;
+  Elf64_Word	vn_aux;
+  Elf64_Word	vn_next;
+} Elf64_Verneed;
+
+
+
+#define VER_NEED_NONE	 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM	 2
+
+
+
+typedef struct {
+  Elf32_Word	vna_hash;
+  Elf32_Half	vna_flags;
+  Elf32_Half	vna_other;
+  Elf32_Word	vna_name;
+  Elf32_Word	vna_next;
+} Elf32_Vernaux;
+
+typedef struct {
+  Elf64_Word	vna_hash;
+  Elf64_Half	vna_flags;
+  Elf64_Half	vna_other;
+  Elf64_Word	vna_name;
+  Elf64_Word	vna_next;
+} Elf64_Vernaux;
+
+
+
+#define VER_FLG_WEAK	0x2
+
+
+
+typedef struct {
+  uint32_t a_type;
+  union {
+      uint32_t a_val;
+  } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+  uint64_t a_type;
+  union {
+      uint64_t a_val;
+  } a_un;
+} Elf64_auxv_t;
+
+
+
+#define AT_NULL		0
+#define AT_IGNORE	1
+#define AT_EXECFD	2
+#define AT_PHDR		3
+#define AT_PHENT	4
+#define AT_PHNUM	5
+#define AT_PAGESZ	6
+#define AT_BASE		7
+#define AT_FLAGS	8
+#define AT_ENTRY	9
+#define AT_NOTELF	10
+#define AT_UID		11
+#define AT_EUID		12
+#define AT_GID		13
+#define AT_EGID		14
+#define AT_CLKTCK	17
+
+
+#define AT_PLATFORM	15
+#define AT_HWCAP	16
+
+
+
+
+#define AT_FPUCW	18
+
+
+#define AT_DCACHEBSIZE	19
+#define AT_ICACHEBSIZE	20
+#define AT_UCACHEBSIZE	21
+
+
+
+#define AT_IGNOREPPC	22
+
+#define	AT_SECURE	23
+
+#define AT_BASE_PLATFORM 24
+
+#define AT_RANDOM	25
+
+#define AT_EXECFN	31
+
+
+
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+
+
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+
+
+
+typedef struct {
+  Elf32_Word n_namesz;
+  Elf32_Word n_descsz;
+  Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+  Elf64_Word n_namesz;
+  Elf64_Word n_descsz;
+  Elf64_Word n_type;
+} Elf64_Nhdr;
+
+
+
+
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+
+#define ELF_NOTE_GNU		"GNU"
+
+
+
+
+
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG
+
+
+
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+#define NT_GNU_BUILD_ID	3
+#define NT_GNU_GOLD_VERSION	4
+
+
+
+typedef struct {
+  Elf32_Xword m_value;
+  Elf32_Word m_info;
+  Elf32_Word m_poffset;
+  Elf32_Half m_repeat;
+  Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+  Elf64_Xword m_value;
+  Elf64_Xword m_info;
+  Elf64_Xword m_poffset;
+  Elf64_Half m_repeat;
+  Elf64_Half m_stride;
+} Elf64_Move;
+
+
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+#define EF_CPU32	0x00810000
+
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+#define R_68K_NUM	23
+
+#define R_386_NONE	   0
+#define R_386_32	   1
+#define R_386_PC32	   2
+#define R_386_GOT32	   3
+#define R_386_PLT32	   4
+#define R_386_COPY	   5
+#define R_386_GLOB_DAT	   6
+#define R_386_JMP_SLOT	   7
+#define R_386_RELATIVE	   8
+#define R_386_GOTOFF	   9
+#define R_386_GOTPC	   10
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14
+#define R_386_TLS_IE	   15
+#define R_386_TLS_GOTIE	   16
+#define R_386_TLS_LE	   17
+#define R_386_TLS_GD	   18
+#define R_386_TLS_LDM	   19
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24
+#define R_386_TLS_GD_PUSH  25
+#define R_386_TLS_GD_CALL  26
+#define R_386_TLS_GD_POP   27
+#define R_386_TLS_LDM_32   28
+#define R_386_TLS_LDM_PUSH 29
+#define R_386_TLS_LDM_CALL 30
+#define R_386_TLS_LDM_POP  31
+#define R_386_TLS_LDO_32   32
+#define R_386_TLS_IE_32	   33
+#define R_386_TLS_LE_32	   34
+#define R_386_TLS_DTPMOD32 35
+#define R_386_TLS_DTPOFF32 36
+#define R_386_TLS_TPOFF32  37
+#define R_386_TLS_GOTDESC  39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC     41
+#define R_386_IRELATIVE	   42
+#define R_386_NUM	   43
+
+
+
+
+
+#define STT_SPARC_REGISTER	13
+
+
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100
+#define EF_SPARC_SUN_US1	0x000200
+#define EF_SPARC_HAL_R1		0x000400
+#define EF_SPARC_SUN_US3	0x000800
+
+
+
+#define R_SPARC_NONE		0
+#define R_SPARC_8		1
+#define R_SPARC_16		2
+#define R_SPARC_32		3
+#define R_SPARC_DISP8		4
+#define R_SPARC_DISP16		5
+#define R_SPARC_DISP32		6
+#define R_SPARC_WDISP30		7
+#define R_SPARC_WDISP22		8
+#define R_SPARC_HI22		9
+#define R_SPARC_22		10
+#define R_SPARC_13		11
+#define R_SPARC_LO10		12
+#define R_SPARC_GOT10		13
+#define R_SPARC_GOT13		14
+#define R_SPARC_GOT22		15
+#define R_SPARC_PC10		16
+#define R_SPARC_PC22		17
+#define R_SPARC_WPLT30		18
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_UA32		23
+
+
+
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_64		32
+#define R_SPARC_OLO10		33
+#define R_SPARC_HH22		34
+#define R_SPARC_HM10		35
+#define R_SPARC_LM22		36
+#define R_SPARC_PC_HH22		37
+#define R_SPARC_PC_HM10		38
+#define R_SPARC_PC_LM22		39
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_GLOB_JMP	42
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+#define R_SPARC_DISP64		46
+#define R_SPARC_PLT64		47
+#define R_SPARC_HIX22		48
+#define R_SPARC_LOX10		49
+#define R_SPARC_H44		50
+#define R_SPARC_M44		51
+#define R_SPARC_L44		52
+#define R_SPARC_REGISTER	53
+#define R_SPARC_UA64		54
+#define R_SPARC_UA16		55
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+
+#define R_SPARC_NUM		253
+
+
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+
+
+#define HWCAP_SPARC_FLUSH	1
+#define HWCAP_SPARC_STBAR	2
+#define HWCAP_SPARC_SWAP	4
+#define HWCAP_SPARC_MULDIV	8
+#define HWCAP_SPARC_V9		16
+#define HWCAP_SPARC_ULTRA3	32
+#define HWCAP_SPARC_BLKINIT	64
+#define HWCAP_SPARC_N2		128
+
+
+
+
+
+#define EF_MIPS_NOREORDER   1
+#define EF_MIPS_PIC	    2
+#define EF_MIPS_CPIC	    4
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000
+
+
+
+#define EF_MIPS_ARCH_1	    0x00000000
+#define EF_MIPS_ARCH_2	    0x10000000
+#define EF_MIPS_ARCH_3	    0x20000000
+#define EF_MIPS_ARCH_4	    0x30000000
+#define EF_MIPS_ARCH_5	    0x40000000
+#define EF_MIPS_ARCH_32	    0x60000000
+#define EF_MIPS_ARCH_64	    0x70000000
+
+
+
+#define E_MIPS_ARCH_1	  0x00000000
+#define E_MIPS_ARCH_2	  0x10000000
+#define E_MIPS_ARCH_3	  0x20000000
+#define E_MIPS_ARCH_4	  0x30000000
+#define E_MIPS_ARCH_5	  0x40000000
+#define E_MIPS_ARCH_32	  0x60000000
+#define E_MIPS_ARCH_64	  0x70000000
+
+
+
+#define SHN_MIPS_ACOMMON    0xff00
+#define SHN_MIPS_TEXT	    0xff01
+#define SHN_MIPS_DATA	    0xff02
+#define SHN_MIPS_SCOMMON    0xff03
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+
+
+#define SHT_MIPS_LIBLIST       0x70000000
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002
+#define SHT_MIPS_GPTAB	       0x70000003
+#define SHT_MIPS_UCODE	       0x70000004
+#define SHT_MIPS_DEBUG	       0x70000005
+#define SHT_MIPS_REGINFO       0x70000006
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+
+
+#define SHF_MIPS_GPREL	 0x10000000
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+
+
+
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+
+#define STB_MIPS_SPLIT_COMMON		13
+
+
+
+typedef union {
+  struct {
+      Elf32_Word gt_current_g_value;
+      Elf32_Word gt_unused;
+  } gt_header;
+  struct {
+      Elf32_Word gt_g_value;
+      Elf32_Word gt_bytes;
+  } gt_entry;
+} Elf32_gptab;
+
+
+
+typedef struct {
+  Elf32_Word	ri_gprmask;
+  Elf32_Word	ri_cprmask[4];
+  Elf32_Sword	ri_gp_value;
+} Elf32_RegInfo;
+
+
+
+typedef struct {
+  unsigned char kind;
+
+  unsigned char size;
+  Elf32_Section section;
+
+  Elf32_Word info;
+} Elf_Options;
+
+
+
+#define ODK_NULL	0
+#define ODK_REGINFO	1
+#define ODK_EXCEPTIONS	2
+#define ODK_PAD		3
+#define ODK_HWPATCH	4
+#define ODK_FILL	5
+#define ODK_TAGS	6
+#define ODK_HWAND	7
+#define ODK_HWOR	8
+
+
+
+#define OEX_FPU_MIN	0x1f
+#define OEX_FPU_MAX	0x1f00
+#define OEX_PAGE0	0x10000
+#define OEX_SMM		0x20000
+#define OEX_FPDBUG	0x40000
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+
+
+#define OHW_R4KEOP	0x1
+#define OHW_R8KPFETCH	0x2
+#define OHW_R5KEOP	0x4
+#define OHW_R5KCVTL	0x8
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+
+
+typedef struct {
+  Elf32_Word hwp_flags1;
+  Elf32_Word hwp_flags2;
+} Elf_Options_Hw;
+
+
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+
+
+#define R_MIPS_NONE		0
+#define R_MIPS_16		1
+#define R_MIPS_32		2
+#define R_MIPS_REL32		3
+#define R_MIPS_26		4
+#define R_MIPS_HI16		5
+#define R_MIPS_LO16		6
+#define R_MIPS_GPREL16		7
+#define R_MIPS_LITERAL		8
+#define R_MIPS_GOT16		9
+#define R_MIPS_PC16		10
+#define R_MIPS_CALL16		11
+#define R_MIPS_GPREL32		12
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38
+#define R_MIPS_TLS_DTPREL32	39
+#define R_MIPS_TLS_DTPMOD64	40
+#define R_MIPS_TLS_DTPREL64	41
+#define R_MIPS_TLS_GD		42
+#define R_MIPS_TLS_LDM		43
+#define R_MIPS_TLS_DTPREL_HI16	44
+#define R_MIPS_TLS_DTPREL_LO16	45
+#define R_MIPS_TLS_GOTTPREL	46
+#define R_MIPS_TLS_TPREL32	47
+#define R_MIPS_TLS_TPREL64	48
+#define R_MIPS_TLS_TPREL_HI16	49
+#define R_MIPS_TLS_TPREL_LO16	50
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+
+#define R_MIPS_NUM		128
+
+
+
+#define PT_MIPS_REGINFO	0x70000000
+#define PT_MIPS_RTPROC  0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+
+
+
+#define PF_MIPS_LOCAL	0x10000000
+
+
+
+#define DT_MIPS_RLD_VERSION  0x70000001
+#define DT_MIPS_TIME_STAMP   0x70000002
+#define DT_MIPS_ICHECKSUM    0x70000003
+#define DT_MIPS_IVERSION     0x70000004
+#define DT_MIPS_FLAGS	     0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008
+#define DT_MIPS_LIBLIST	     0x70000009
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a
+#define DT_MIPS_CONFLICTNO   0x7000000b
+#define DT_MIPS_LIBLISTNO    0x70000010
+#define DT_MIPS_SYMTABNO     0x70000011
+#define DT_MIPS_UNREFEXTNO   0x70000012
+#define DT_MIPS_GOTSYM	     0x70000013
+#define DT_MIPS_HIPAGENO     0x70000014
+#define DT_MIPS_RLD_MAP	     0x70000016
+#define DT_MIPS_DELTA_CLASS  0x70000017
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018
+
+#define DT_MIPS_DELTA_INSTANCE    0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+#define DT_MIPS_DELTA_RELOC  0x7000001b
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+#define DT_MIPS_DELTA_SYM    0x7000001d
+
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+#define DT_MIPS_CXX_FLAGS    0x70000022
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029
+#define DT_MIPS_INTERFACE    0x7000002a
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+#define DT_MIPS_PERF_SUFFIX  0x7000002e
+
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+#define DT_MIPS_GP_VALUE     0x70000030
+#define DT_MIPS_AUX_DYNAMIC  0x70000031
+
+#define DT_MIPS_PLTGOT	     0x70000032
+
+#define DT_MIPS_RWPLT        0x70000034
+#define DT_MIPS_NUM	     0x35
+
+
+
+#define RHF_NONE		   0
+#define RHF_QUICKSTART		   (1 << 0)
+#define RHF_NOTPOT		   (1 << 1)
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+
+
+typedef struct
+{
+  Elf32_Word l_name;
+  Elf32_Word l_time_stamp;
+  Elf32_Word l_checksum;
+  Elf32_Word l_version;
+  Elf32_Word l_flags;
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;
+  Elf64_Word l_time_stamp;
+  Elf64_Word l_checksum;
+  Elf64_Word l_version;
+  Elf64_Word l_flags;
+} Elf64_Lib;
+
+
+
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)
+#define LL_IGNORE_INT_VER (1 << 1)
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+
+
+
+
+#define EF_PARISC_TRAPNIL	0x00010000
+#define EF_PARISC_EXT		0x00020000
+#define EF_PARISC_LSB		0x00040000
+#define EF_PARISC_WIDE		0x00080000
+#define EF_PARISC_NO_KABP	0x00100000
+
+#define EF_PARISC_LAZYSWAP	0x00400000
+#define EF_PARISC_ARCH		0x0000ffff
+
+
+
+#define EFA_PARISC_1_0		    0x020b
+#define EFA_PARISC_1_1		    0x0210
+#define EFA_PARISC_2_0		    0x0214
+
+
+
+#define SHN_PARISC_ANSI_COMMON	0xff00
+
+#define SHN_PARISC_HUGE_COMMON	0xff01
+
+
+
+#define SHT_PARISC_EXT		0x70000000
+#define SHT_PARISC_UNWIND	0x70000001
+#define SHT_PARISC_DOC		0x70000002
+
+
+
+#define SHF_PARISC_SHORT	0x20000000
+#define SHF_PARISC_HUGE		0x40000000
+#define SHF_PARISC_SBP		0x80000000
+
+
+
+#define STT_PARISC_MILLICODE	13
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+
+
+#define R_PARISC_NONE		0
+#define R_PARISC_DIR32		1
+#define R_PARISC_DIR21L		2
+#define R_PARISC_DIR17R		3
+#define R_PARISC_DIR17F		4
+#define R_PARISC_DIR14R		6
+#define R_PARISC_PCREL32	9
+#define R_PARISC_PCREL21L	10
+#define R_PARISC_PCREL17R	11
+#define R_PARISC_PCREL17F	12
+#define R_PARISC_PCREL14R	14
+#define R_PARISC_DPREL21L	18
+#define R_PARISC_DPREL14R	22
+#define R_PARISC_GPREL21L	26
+#define R_PARISC_GPREL14R	30
+#define R_PARISC_LTOFF21L	34
+#define R_PARISC_LTOFF14R	38
+#define R_PARISC_SECREL32	41
+#define R_PARISC_SEGBASE	48
+#define R_PARISC_SEGREL32	49
+#define R_PARISC_PLTOFF21L	50
+#define R_PARISC_PLTOFF14R	54
+#define R_PARISC_LTOFF_FPTR32	57
+#define R_PARISC_LTOFF_FPTR21L	58
+#define R_PARISC_LTOFF_FPTR14R	62
+#define R_PARISC_FPTR64		64
+#define R_PARISC_PLABEL32	65
+#define R_PARISC_PLABEL21L	66
+#define R_PARISC_PLABEL14R	70
+#define R_PARISC_PCREL64	72
+#define R_PARISC_PCREL22F	74
+#define R_PARISC_PCREL14WR	75
+#define R_PARISC_PCREL14DR	76
+#define R_PARISC_PCREL16F	77
+#define R_PARISC_PCREL16WF	78
+#define R_PARISC_PCREL16DF	79
+#define R_PARISC_DIR64		80
+#define R_PARISC_DIR14WR	83
+#define R_PARISC_DIR14DR	84
+#define R_PARISC_DIR16F		85
+#define R_PARISC_DIR16WF	86
+#define R_PARISC_DIR16DF	87
+#define R_PARISC_GPREL64	88
+#define R_PARISC_GPREL14WR	91
+#define R_PARISC_GPREL14DR	92
+#define R_PARISC_GPREL16F	93
+#define R_PARISC_GPREL16WF	94
+#define R_PARISC_GPREL16DF	95
+#define R_PARISC_LTOFF64	96
+#define R_PARISC_LTOFF14WR	99
+#define R_PARISC_LTOFF14DR	100
+#define R_PARISC_LTOFF16F	101
+#define R_PARISC_LTOFF16WF	102
+#define R_PARISC_LTOFF16DF	103
+#define R_PARISC_SECREL64	104
+#define R_PARISC_SEGREL64	112
+#define R_PARISC_PLTOFF14WR	115
+#define R_PARISC_PLTOFF14DR	116
+#define R_PARISC_PLTOFF16F	117
+#define R_PARISC_PLTOFF16WF	118
+#define R_PARISC_PLTOFF16DF	119
+#define R_PARISC_LTOFF_FPTR64	120
+#define R_PARISC_LTOFF_FPTR14WR	123
+#define R_PARISC_LTOFF_FPTR14DR	124
+#define R_PARISC_LTOFF_FPTR16F	125
+#define R_PARISC_LTOFF_FPTR16WF	126
+#define R_PARISC_LTOFF_FPTR16DF	127
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128
+#define R_PARISC_IPLT		129
+#define R_PARISC_EPLT		130
+#define R_PARISC_TPREL32	153
+#define R_PARISC_TPREL21L	154
+#define R_PARISC_TPREL14R	158
+#define R_PARISC_LTOFF_TP21L	162
+#define R_PARISC_LTOFF_TP14R	166
+#define R_PARISC_LTOFF_TP14F	167
+#define R_PARISC_TPREL64	216
+#define R_PARISC_TPREL14WR	219
+#define R_PARISC_TPREL14DR	220
+#define R_PARISC_TPREL16F	221
+#define R_PARISC_TPREL16WF	222
+#define R_PARISC_TPREL16DF	223
+#define R_PARISC_LTOFF_TP64	224
+#define R_PARISC_LTOFF_TP14WR	227
+#define R_PARISC_LTOFF_TP14DR	228
+#define R_PARISC_LTOFF_TP16F	229
+#define R_PARISC_LTOFF_TP16WF	230
+#define R_PARISC_LTOFF_TP16DF	231
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234
+#define R_PARISC_TLS_GD14R	235
+#define R_PARISC_TLS_GDCALL	236
+#define R_PARISC_TLS_LDM21L	237
+#define R_PARISC_TLS_LDM14R	238
+#define R_PARISC_TLS_LDMCALL	239
+#define R_PARISC_TLS_LDO21L	240
+#define R_PARISC_TLS_LDO14R	241
+#define R_PARISC_TLS_DTPMOD32	242
+#define R_PARISC_TLS_DTPMOD64	243
+#define R_PARISC_TLS_DTPOFF32	244
+#define R_PARISC_TLS_DTPOFF64	245
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+
+
+
+
+#define EF_ALPHA_32BIT		1
+#define EF_ALPHA_CANRELAX	2
+
+
+
+
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+
+#define STO_ALPHA_NOPV		0x80
+#define STO_ALPHA_STD_GPLOAD	0x88
+
+
+
+#define R_ALPHA_NONE		0
+#define R_ALPHA_REFLONG		1
+#define R_ALPHA_REFQUAD		2
+#define R_ALPHA_GPREL32		3
+#define R_ALPHA_LITERAL		4
+#define R_ALPHA_LITUSE		5
+#define R_ALPHA_GPDISP		6
+#define R_ALPHA_BRADDR		7
+#define R_ALPHA_HINT		8
+#define R_ALPHA_SREL16		9
+#define R_ALPHA_SREL32		10
+#define R_ALPHA_SREL64		11
+#define R_ALPHA_GPRELHIGH	17
+#define R_ALPHA_GPRELLOW	18
+#define R_ALPHA_GPREL16		19
+#define R_ALPHA_COPY		24
+#define R_ALPHA_GLOB_DAT	25
+#define R_ALPHA_JMP_SLOT	26
+#define R_ALPHA_RELATIVE	27
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+
+#define R_ALPHA_NUM		46
+
+
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+
+
+
+#define EF_PPC_EMB		0x80000000
+
+
+#define EF_PPC_RELOCATABLE	0x00010000
+#define EF_PPC_RELOCATABLE_LIB	0x00008000
+
+
+
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1
+#define R_PPC_ADDR24		2
+#define R_PPC_ADDR16		3
+#define R_PPC_ADDR16_LO		4
+#define R_PPC_ADDR16_HI		5
+#define R_PPC_ADDR16_HA		6
+#define R_PPC_ADDR14		7
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10
+#define R_PPC_REL14		11
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+
+#define R_PPC_TLS		67
+#define R_PPC_DTPMOD32		68
+#define R_PPC_TPREL16		69
+#define R_PPC_TPREL16_LO	70
+#define R_PPC_TPREL16_HI	71
+#define R_PPC_TPREL16_HA	72
+#define R_PPC_TPREL32		73
+#define R_PPC_DTPREL16		74
+#define R_PPC_DTPREL16_LO	75
+#define R_PPC_DTPREL16_HI	76
+#define R_PPC_DTPREL16_HA	77
+#define R_PPC_DTPREL32		78
+#define R_PPC_GOT_TLSGD16	79
+#define R_PPC_GOT_TLSGD16_LO	80
+#define R_PPC_GOT_TLSGD16_HI	81
+#define R_PPC_GOT_TLSGD16_HA	82
+#define R_PPC_GOT_TLSLD16	83
+#define R_PPC_GOT_TLSLD16_LO	84
+#define R_PPC_GOT_TLSLD16_HI	85
+#define R_PPC_GOT_TLSLD16_HA	86
+#define R_PPC_GOT_TPREL16	87
+#define R_PPC_GOT_TPREL16_LO	88
+#define R_PPC_GOT_TPREL16_HI	89
+#define R_PPC_GOT_TPREL16_HA	90
+#define R_PPC_GOT_DTPREL16	91
+#define R_PPC_GOT_DTPREL16_LO	92
+#define R_PPC_GOT_DTPREL16_HI	93
+#define R_PPC_GOT_DTPREL16_HA	94
+
+
+
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116
+
+
+#define R_PPC_DIAB_SDA21_LO	180
+#define R_PPC_DIAB_SDA21_HI	181
+#define R_PPC_DIAB_SDA21_HA	182
+#define R_PPC_DIAB_RELSDA_LO	183
+#define R_PPC_DIAB_RELSDA_HI	184
+#define R_PPC_DIAB_RELSDA_HA	185
+
+
+#define R_PPC_IRELATIVE		248
+
+
+#define R_PPC_REL16		249
+#define R_PPC_REL16_LO		250
+#define R_PPC_REL16_HI		251
+#define R_PPC_REL16_HA		252
+
+
+
+#define R_PPC_TOC16		255
+
+
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_NUM		1
+
+
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32
+#define R_PPC64_ADDR24		R_PPC_ADDR24
+#define R_PPC64_ADDR16		R_PPC_ADDR16
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA
+#define R_PPC64_ADDR14		R_PPC_ADDR14
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24
+#define R_PPC64_REL14		R_PPC_REL14
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37
+#define R_PPC64_ADDR64		38
+#define R_PPC64_ADDR16_HIGHER	39
+#define R_PPC64_ADDR16_HIGHERA	40
+#define R_PPC64_ADDR16_HIGHEST	41
+#define R_PPC64_ADDR16_HIGHESTA	42
+#define R_PPC64_UADDR64		43
+#define R_PPC64_REL64		44
+#define R_PPC64_PLT64		45
+#define R_PPC64_PLTREL64	46
+#define R_PPC64_TOC16		47
+#define R_PPC64_TOC16_LO	48
+#define R_PPC64_TOC16_HI	49
+#define R_PPC64_TOC16_HA	50
+#define R_PPC64_TOC		51
+#define R_PPC64_PLTGOT16	52
+#define R_PPC64_PLTGOT16_LO	53
+#define R_PPC64_PLTGOT16_HI	54
+#define R_PPC64_PLTGOT16_HA	55
+
+#define R_PPC64_ADDR16_DS	56
+#define R_PPC64_ADDR16_LO_DS	57
+#define R_PPC64_GOT16_DS	58
+#define R_PPC64_GOT16_LO_DS	59
+#define R_PPC64_PLT16_LO_DS	60
+#define R_PPC64_SECTOFF_DS	61
+#define R_PPC64_SECTOFF_LO_DS	62
+#define R_PPC64_TOC16_DS	63
+#define R_PPC64_TOC16_LO_DS	64
+#define R_PPC64_PLTGOT16_DS	65
+#define R_PPC64_PLTGOT16_LO_DS	66
+
+
+#define R_PPC64_TLS		67
+#define R_PPC64_DTPMOD64	68
+#define R_PPC64_TPREL16		69
+#define R_PPC64_TPREL16_LO	70
+#define R_PPC64_TPREL16_HI	71
+#define R_PPC64_TPREL16_HA	72
+#define R_PPC64_TPREL64		73
+#define R_PPC64_DTPREL16	74
+#define R_PPC64_DTPREL16_LO	75
+#define R_PPC64_DTPREL16_HI	76
+#define R_PPC64_DTPREL16_HA	77
+#define R_PPC64_DTPREL64	78
+#define R_PPC64_GOT_TLSGD16	79
+#define R_PPC64_GOT_TLSGD16_LO	80
+#define R_PPC64_GOT_TLSGD16_HI	81
+#define R_PPC64_GOT_TLSGD16_HA	82
+#define R_PPC64_GOT_TLSLD16	83
+#define R_PPC64_GOT_TLSLD16_LO	84
+#define R_PPC64_GOT_TLSLD16_HI	85
+#define R_PPC64_GOT_TLSLD16_HA	86
+#define R_PPC64_GOT_TPREL16_DS	87
+#define R_PPC64_GOT_TPREL16_LO_DS 88
+#define R_PPC64_GOT_TPREL16_HI	89
+#define R_PPC64_GOT_TPREL16_HA	90
+#define R_PPC64_GOT_DTPREL16_DS	91
+#define R_PPC64_GOT_DTPREL16_LO_DS 92
+#define R_PPC64_GOT_DTPREL16_HI	93
+#define R_PPC64_GOT_DTPREL16_HA	94
+#define R_PPC64_TPREL16_DS	95
+#define R_PPC64_TPREL16_LO_DS	96
+#define R_PPC64_TPREL16_HIGHER	97
+#define R_PPC64_TPREL16_HIGHERA	98
+#define R_PPC64_TPREL16_HIGHEST	99
+#define R_PPC64_TPREL16_HIGHESTA 100
+#define R_PPC64_DTPREL16_DS	101
+#define R_PPC64_DTPREL16_LO_DS	102
+#define R_PPC64_DTPREL16_HIGHER	103
+#define R_PPC64_DTPREL16_HIGHERA 104
+#define R_PPC64_DTPREL16_HIGHEST 105
+#define R_PPC64_DTPREL16_HIGHESTA 106
+
+
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249
+#define R_PPC64_REL16_LO	250
+#define R_PPC64_REL16_HI	251
+#define R_PPC64_REL16_HA	252
+
+
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_NUM    3
+
+
+
+
+
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+
+
+
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+
+#define STT_ARM_TFUNC		STT_LOPROC
+#define STT_ARM_16BIT		STT_HIPROC
+
+
+#define SHF_ARM_ENTRYSECT	0x10000000
+#define SHF_ARM_COMDEF		0x80000000
+
+
+
+#define PF_ARM_SB		0x10000000
+
+#define PF_ARM_PI		0x20000000
+#define PF_ARM_ABS		0x40000000
+
+
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)
+
+
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1)
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2)
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3)
+
+
+
+
+#define R_ARM_NONE		0
+#define R_ARM_PC24		1
+#define R_ARM_ABS32		2
+#define R_ARM_REL32		3
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5
+#define R_ARM_ABS12		6
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17
+#define R_ARM_TLS_DTPOFF32	18
+#define R_ARM_TLS_TPOFF32	19
+#define R_ARM_COPY		20
+#define R_ARM_GLOB_DAT		21
+#define R_ARM_JUMP_SLOT		22
+#define R_ARM_RELATIVE		23
+#define R_ARM_GOTOFF		24
+#define R_ARM_GOTPC		25
+#define R_ARM_GOT32		26
+#define R_ARM_PLT32		27
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102
+#define R_ARM_THM_PC9		103
+#define R_ARM_TLS_GD32		104
+
+#define R_ARM_TLS_LDM32		105
+
+#define R_ARM_TLS_LDO32		106
+
+#define R_ARM_TLS_IE32		107
+
+#define R_ARM_TLS_LE32		108
+
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+
+#define R_ARM_NUM		256
+
+
+
+
+#define EF_IA_64_MASKOS		0x0000000f
+#define EF_IA_64_ABI64		0x00000010
+#define EF_IA_64_ARCH		0xff000000
+
+
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+
+#define PF_IA_64_NORECOV	0x80000000
+
+
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0)
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1)
+
+
+#define SHF_IA_64_SHORT		0x10000000
+#define SHF_IA_64_NORECOV	0x20000000
+
+
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+
+#define R_IA64_NONE		0x00
+#define R_IA64_IMM14		0x21
+#define R_IA64_IMM22		0x22
+#define R_IA64_IMM64		0x23
+#define R_IA64_DIR32MSB		0x24
+#define R_IA64_DIR32LSB		0x25
+#define R_IA64_DIR64MSB		0x26
+#define R_IA64_DIR64LSB		0x27
+#define R_IA64_GPREL22		0x2a
+#define R_IA64_GPREL64I		0x2b
+#define R_IA64_GPREL32MSB	0x2c
+#define R_IA64_GPREL32LSB	0x2d
+#define R_IA64_GPREL64MSB	0x2e
+#define R_IA64_GPREL64LSB	0x2f
+#define R_IA64_LTOFF22		0x32
+#define R_IA64_LTOFF64I		0x33
+#define R_IA64_PLTOFF22		0x3a
+#define R_IA64_PLTOFF64I	0x3b
+#define R_IA64_PLTOFF64MSB	0x3e
+#define R_IA64_PLTOFF64LSB	0x3f
+#define R_IA64_FPTR64I		0x43
+#define R_IA64_FPTR32MSB	0x44
+#define R_IA64_FPTR32LSB	0x45
+#define R_IA64_FPTR64MSB	0x46
+#define R_IA64_FPTR64LSB	0x47
+#define R_IA64_PCREL60B		0x48
+#define R_IA64_PCREL21B		0x49
+#define R_IA64_PCREL21M		0x4a
+#define R_IA64_PCREL21F		0x4b
+#define R_IA64_PCREL32MSB	0x4c
+#define R_IA64_PCREL32LSB	0x4d
+#define R_IA64_PCREL64MSB	0x4e
+#define R_IA64_PCREL64LSB	0x4f
+#define R_IA64_LTOFF_FPTR22	0x52
+#define R_IA64_LTOFF_FPTR64I	0x53
+#define R_IA64_LTOFF_FPTR32MSB	0x54
+#define R_IA64_LTOFF_FPTR32LSB	0x55
+#define R_IA64_LTOFF_FPTR64MSB	0x56
+#define R_IA64_LTOFF_FPTR64LSB	0x57
+#define R_IA64_SEGREL32MSB	0x5c
+#define R_IA64_SEGREL32LSB	0x5d
+#define R_IA64_SEGREL64MSB	0x5e
+#define R_IA64_SEGREL64LSB	0x5f
+#define R_IA64_SECREL32MSB	0x64
+#define R_IA64_SECREL32LSB	0x65
+#define R_IA64_SECREL64MSB	0x66
+#define R_IA64_SECREL64LSB	0x67
+#define R_IA64_REL32MSB		0x6c
+#define R_IA64_REL32LSB		0x6d
+#define R_IA64_REL64MSB		0x6e
+#define R_IA64_REL64LSB		0x6f
+#define R_IA64_LTV32MSB		0x74
+#define R_IA64_LTV32LSB		0x75
+#define R_IA64_LTV64MSB		0x76
+#define R_IA64_LTV64LSB		0x77
+#define R_IA64_PCREL21BI	0x79
+#define R_IA64_PCREL22		0x7a
+#define R_IA64_PCREL64I		0x7b
+#define R_IA64_IPLTMSB		0x80
+#define R_IA64_IPLTLSB		0x81
+#define R_IA64_COPY		0x84
+#define R_IA64_SUB		0x85
+#define R_IA64_LTOFF22X		0x86
+#define R_IA64_LDXMOV		0x87
+#define R_IA64_TPREL14		0x91
+#define R_IA64_TPREL22		0x92
+#define R_IA64_TPREL64I		0x93
+#define R_IA64_TPREL64MSB	0x96
+#define R_IA64_TPREL64LSB	0x97
+#define R_IA64_LTOFF_TPREL22	0x9a
+#define R_IA64_DTPMOD64MSB	0xa6
+#define R_IA64_DTPMOD64LSB	0xa7
+#define R_IA64_LTOFF_DTPMOD22	0xaa
+#define R_IA64_DTPREL14		0xb1
+#define R_IA64_DTPREL22		0xb2
+#define R_IA64_DTPREL64I	0xb3
+#define R_IA64_DTPREL32MSB	0xb4
+#define R_IA64_DTPREL32LSB	0xb5
+#define R_IA64_DTPREL64MSB	0xb6
+#define R_IA64_DTPREL64LSB	0xb7
+#define R_IA64_LTOFF_DTPREL22	0xba
+
+
+
+
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+
+#define	R_SH_NUM		256
+
+
+
+#define R_390_NONE		0
+#define R_390_8			1
+#define R_390_12		2
+#define R_390_16		3
+#define R_390_32		4
+#define R_390_PC32		5
+#define R_390_GOT12		6
+#define R_390_GOT32		7
+#define R_390_PLT32		8
+#define R_390_COPY		9
+#define R_390_GLOB_DAT		10
+#define R_390_JMP_SLOT		11
+#define R_390_RELATIVE		12
+#define R_390_GOTOFF32		13
+#define R_390_GOTPC		14
+#define R_390_GOT16		15
+#define R_390_PC16		16
+#define R_390_PC16DBL		17
+#define R_390_PLT16DBL		18
+#define R_390_PC32DBL		19
+#define R_390_PLT32DBL		20
+#define R_390_GOTPCDBL		21
+#define R_390_64		22
+#define R_390_PC64		23
+#define R_390_GOT64		24
+#define R_390_PLT64		25
+#define R_390_GOTENT		26
+#define R_390_GOTOFF16		27
+#define R_390_GOTOFF64		28
+#define R_390_GOTPLT12		29
+#define R_390_GOTPLT16		30
+#define R_390_GOTPLT32		31
+#define R_390_GOTPLT64		32
+#define R_390_GOTPLTENT		33
+#define R_390_PLTOFF16		34
+#define R_390_PLTOFF32		35
+#define R_390_PLTOFF64		36
+#define R_390_TLS_LOAD		37
+#define R_390_TLS_GDCALL	38
+
+#define R_390_TLS_LDCALL	39
+
+#define R_390_TLS_GD32		40
+
+#define R_390_TLS_GD64		41
+
+#define R_390_TLS_GOTIE12	42
+
+#define R_390_TLS_GOTIE32	43
+
+#define R_390_TLS_GOTIE64	44
+
+#define R_390_TLS_LDM32		45
+
+#define R_390_TLS_LDM64		46
+
+#define R_390_TLS_IE32		47
+
+#define R_390_TLS_IE64		48
+
+#define R_390_TLS_IEENT		49
+
+#define R_390_TLS_LE32		50
+
+#define R_390_TLS_LE64		51
+
+#define R_390_TLS_LDO32		52
+
+#define R_390_TLS_LDO64		53
+
+#define R_390_TLS_DTPMOD	54
+#define R_390_TLS_DTPOFF	55
+#define R_390_TLS_TPOFF		56
+
+#define R_390_20		57
+#define R_390_GOT20		58
+#define R_390_GOTPLT20		59
+#define R_390_TLS_GOTIE20	60
+
+
+#define R_390_NUM		61
+
+
+
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+
+#define R_X86_64_NONE		0
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_GOT32		3
+#define R_X86_64_PLT32		4
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+#define R_X86_64_GOTPCREL	9
+
+#define R_X86_64_32		10
+#define R_X86_64_32S		11
+#define R_X86_64_16		12
+#define R_X86_64_PC16		13
+#define R_X86_64_8		14
+#define R_X86_64_PC8		15
+#define R_X86_64_DTPMOD64	16
+#define R_X86_64_DTPOFF64	17
+#define R_X86_64_TPOFF64	18
+#define R_X86_64_TLSGD		19
+
+#define R_X86_64_TLSLD		20
+
+#define R_X86_64_DTPOFF32	21
+#define R_X86_64_GOTTPOFF	22
+
+#define R_X86_64_TPOFF32	23
+#define R_X86_64_PC64		24
+#define R_X86_64_GOTOFF64	25
+#define R_X86_64_GOTPC32	26
+
+
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL   35
+
+#define R_X86_64_TLSDESC        36
+#define R_X86_64_IRELATIVE	37
+
+#define R_X86_64_NUM		38
+
+
+
+#define R_MN10300_NONE		0
+#define R_MN10300_32		1
+#define R_MN10300_16		2
+#define R_MN10300_8		3
+#define R_MN10300_PCREL32	4
+#define R_MN10300_PCREL16	5
+#define R_MN10300_PCREL8	6
+#define R_MN10300_GNU_VTINHERIT	7
+#define R_MN10300_GNU_VTENTRY	8
+#define R_MN10300_24		9
+#define R_MN10300_GOTPC32	10
+#define R_MN10300_GOTPC16	11
+#define R_MN10300_GOTOFF32	12
+#define R_MN10300_GOTOFF24	13
+#define R_MN10300_GOTOFF16	14
+#define R_MN10300_PLT32		15
+#define R_MN10300_PLT16		16
+#define R_MN10300_GOT32		17
+#define R_MN10300_GOT24		18
+#define R_MN10300_GOT16		19
+#define R_MN10300_COPY		20
+#define R_MN10300_GLOB_DAT	21
+#define R_MN10300_JMP_SLOT	22
+#define R_MN10300_RELATIVE	23
+
+#define R_MN10300_NUM		24
+
+
+
+#define R_M32R_NONE		0
+#define R_M32R_16		1
+#define R_M32R_32		2
+#define R_M32R_24		3
+#define R_M32R_10_PCREL		4
+#define R_M32R_18_PCREL		5
+#define R_M32R_26_PCREL		6
+#define R_M32R_HI16_ULO		7
+#define R_M32R_HI16_SLO		8
+#define R_M32R_LO16		9
+#define R_M32R_SDA16		10
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+
+#define R_M32R_16_RELA		33
+#define R_M32R_32_RELA		34
+#define R_M32R_24_RELA		35
+#define R_M32R_10_PCREL_RELA	36
+#define R_M32R_18_PCREL_RELA	37
+#define R_M32R_26_PCREL_RELA	38
+#define R_M32R_HI16_ULO_RELA	39
+#define R_M32R_HI16_SLO_RELA	40
+#define R_M32R_LO16_RELA	41
+#define R_M32R_SDA16_RELA	42
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45
+
+#define R_M32R_GOT24		48
+#define R_M32R_26_PLTREL	49
+#define R_M32R_COPY		50
+#define R_M32R_GLOB_DAT		51
+#define R_M32R_JMP_SLOT		52
+#define R_M32R_RELATIVE		53
+#define R_M32R_GOTOFF		54
+#define R_M32R_GOTPC24		55
+#define R_M32R_GOT16_HI_ULO	56
+
+#define R_M32R_GOT16_HI_SLO	57
+
+#define R_M32R_GOT16_LO		58
+#define R_M32R_GOTPC_HI_ULO	59
+
+#define R_M32R_GOTPC_HI_SLO	60
+
+#define R_M32R_GOTPC_LO		61
+
+#define R_M32R_GOTOFF_HI_ULO	62
+
+#define R_M32R_GOTOFF_HI_SLO	63
+
+#define R_M32R_GOTOFF_LO	64
+#define R_M32R_NUM		256
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/endian.h b/include/endian.h
new file mode 100644
index 00000000..bcf67662
--- /dev/null
+++ b/include/endian.h
@@ -0,0 +1,17 @@
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#include <bits/endian.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define BIG_ENDIAN __BIG_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+#endif
+
+#endif
diff --git a/include/errno.h b/include/errno.h
new file mode 100644
index 00000000..d9c2c9c7
--- /dev/null
+++ b/include/errno.h
@@ -0,0 +1,18 @@
+#ifndef	_ERRNO_H
+#define _ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/errno.h>
+
+extern int *__errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/fcntl.h b/include/fcntl.h
new file mode 100644
index 00000000..61a6cb55
--- /dev/null
+++ b/include/fcntl.h
@@ -0,0 +1,43 @@
+#ifndef	_FCNTL_H
+#define	_FCNTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_mode_t
+
+#include <bits/alltypes.h>
+
+#include <bits/fcntl.h>
+
+struct flock
+{
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+int creat(const char *, mode_t);
+int fcntl(int, int, ...);
+int open(const char *, int, ...);
+int openat(int, const char *, int, ...);
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/features.h b/include/features.h
new file mode 100644
index 00000000..851afb66
--- /dev/null
+++ b/include/features.h
@@ -0,0 +1 @@
+#warning "features.h is bogus"
diff --git a/include/fenv.h b/include/fenv.h
new file mode 100644
index 00000000..05de990c
--- /dev/null
+++ b/include/fenv.h
@@ -0,0 +1,28 @@
+#ifndef _FENV_H
+#define _FENV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/fenv.h>
+
+int feclearexcept(int);
+int fegetexceptflag(fexcept_t *, int);
+int feraiseexcept(int);
+int fesetexceptflag(const fexcept_t *, int);
+int fetestexcept(int);
+
+int fegetround(void);
+int fesetround(int);
+
+int fegetenv(fenv_t *);
+int feholdexcept(fenv_t *);
+int fesetenv(const fenv_t *);
+int feupdateenv(const fenv_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/float.h b/include/float.h
new file mode 100644
index 00000000..ef91f37d
--- /dev/null
+++ b/include/float.h
@@ -0,0 +1,34 @@
+#ifndef _FLOAT_H
+#define _FLOAT_H
+
+#define FLT_RADIX 2
+
+#define FLT_MIN 1.17549435e-38F
+#define FLT_MAX 3.40282347e+38F
+#define FLT_EPSILON 1.19209290e-07F
+
+#define FLT_MANT_DIG 24
+#define FLT_MIN_EXP (-125)
+#define FLT_MAX_EXP 128
+
+#define FLT_DIG 6
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_10_EXP 38
+
+#define DBL_MIN 2.2250738585072014e-308
+#define DBL_MAX 1.7976931348623157e+308
+#define DBL_EPSILON 2.2204460492503131e-16
+
+#define DBL_MANT_DIG 53
+#define DBL_MIN_EXP (-1021)
+#define DBL_MAX_EXP 1024
+
+#define DBL_DIG 15
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_10_EXP 308
+
+#include <bits/float.h>
+
+#define DECIMAL_DIG LDBL_DIG
+
+#endif
diff --git a/include/fnmatch.h b/include/fnmatch.h
new file mode 100644
index 00000000..b7aee504
--- /dev/null
+++ b/include/fnmatch.h
@@ -0,0 +1,25 @@
+#ifndef	_FNMATCH_H
+#define	_FNMATCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	FNM_PATHNAME 0x1
+#define	FNM_NOESCAPE 0x2
+#define	FNM_PERIOD   0x4
+
+#ifdef _GNU_SOURCE
+#define	FNM_CASEFOLD 0x10
+#endif
+
+#define	FNM_NOMATCH 1
+#define FNM_NOSYS   (-1)
+
+int fnmatch(const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ftw.h b/include/ftw.h
new file mode 100644
index 00000000..8d31c6d9
--- /dev/null
+++ b/include/ftw.h
@@ -0,0 +1,31 @@
+#ifndef _FTW_H
+#define	_FTW_H
+
+/* Normally we do not nest header includes. However useless bloat
+ * like ftw may be treated as a special case. Otherwise we would
+ * have to deal with duplicating all the stat.h mess. */
+#include <sys/stat.h>
+
+#define FTW_F   1
+#define FTW_D   2
+#define FTW_DNR 3
+#define FTW_NS  4
+#define FTW_SL  5
+#define FTW_DP  6
+#define FTW_SLN 7
+
+#define FTW_PHYS  1
+#define FTW_MOUNT 2
+#define FTW_CHDIR 4
+#define FTW_DEPTH 8
+
+struct FTW
+{
+	int base;
+	int level;
+};
+
+int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
+int nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int);
+
+#endif
diff --git a/include/getopt.h b/include/getopt.h
new file mode 100644
index 00000000..0de05aef
--- /dev/null
+++ b/include/getopt.h
@@ -0,0 +1,33 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+#ifdef _GNU_SOURCE
+struct option
+{
+	const char *name;
+	int has_arg;
+	int *flag;
+	int val;
+};
+
+int getopt_long(int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only(int, char *const *, const char *, const struct option *, int *);
+
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/glob.h b/include/glob.h
new file mode 100644
index 00000000..185912df
--- /dev/null
+++ b/include/glob.h
@@ -0,0 +1,41 @@
+#ifndef	_GLOB_H
+#define	_GLOB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct {
+	size_t gl_pathc;
+	char **gl_pathv;
+	size_t gl_offs;
+	int __dummy1;
+	void *__dummy2[5];
+} glob_t;
+
+int  glob(const char *, int, int (*)(const char *, int), glob_t *);
+void globfree(glob_t *);
+
+#define GLOB_ERR      0x01
+#define GLOB_MARK     0x02
+#define GLOB_NOSORT   0x04
+#define GLOB_DOOFFS   0x08
+#define GLOB_NOCHECK  0x10
+#define GLOB_APPEND   0x20
+#define GLOB_NOESCAPE 0x40
+#define	GLOB_PERIOD   0x80
+
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+#define GLOB_NOSYS   4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/grp.h b/include/grp.h
new file mode 100644
index 00000000..d4a3526a
--- /dev/null
+++ b/include/grp.h
@@ -0,0 +1,35 @@
+#ifndef	_GRP_H
+#define	_GRP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+struct group
+{
+	char *gr_name;
+	char *gr_passwd;
+	gid_t gr_gid;
+	char **gr_mem;
+};
+
+struct group  *getgrgid(gid_t);
+struct group  *getgrnam(const char *);
+
+int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
+int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
+
+struct group  *getgrent(void);
+void           endgrent(void);
+void           setgrent(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/iconv.h b/include/iconv.h
new file mode 100644
index 00000000..f2ccaf8c
--- /dev/null
+++ b/include/iconv.h
@@ -0,0 +1,22 @@
+#ifndef _ICONV_H
+#define _ICONV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef void *iconv_t;
+
+iconv_t iconv_open(const char *, const char *);
+size_t iconv(iconv_t, char **, size_t *, char **, size_t *);
+int iconv_close(iconv_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/inttypes.h b/include/inttypes.h
new file mode 100644
index 00000000..13ba6e0f
--- /dev/null
+++ b/include/inttypes.h
@@ -0,0 +1,227 @@
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define __NEED_wchar_t
+#include <bits/alltypes.h>
+
+typedef struct { intmax_t quot, rem; } imaxdiv_t;
+
+intmax_t imaxabs(intmax_t);
+imaxdiv_t imaxdiv(intmax_t, intmax_t);
+
+intmax_t strtoimax(const char *, char **, int);
+uintmax_t strtoumax(const char *, char **, int);
+
+intmax_t wcstoimax(const wchar_t *, wchar_t **, int);
+uintmax_t wcstoumax(const wchar_t *, wchar_t **, int);
+
+#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
+
+#define __PRI64  "ll"
+#define __PRIPTR "l"
+
+#define PRId8  "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 __PRI64 "d"
+
+#define PRIdLEAST8  "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 __PRI64 "d"
+
+#define PRIdFAST8  "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 __PRI64 "d"
+
+#define PRIi8  "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 __PRI64 "i"
+
+#define PRIiLEAST8  "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 __PRI64 "i"
+
+#define PRIiFAST8  "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 __PRI64 "i"
+
+#define PRIo8  "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 __PRI64 "o"
+
+#define PRIoLEAST8  "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 __PRI64 "o"
+
+#define PRIoFAST8  "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 __PRI64 "o"
+
+#define PRIu8  "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 __PRI64 "u"
+
+#define PRIuLEAST8  "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 __PRI64 "u"
+
+#define PRIuFAST8  "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 __PRI64 "u"
+
+#define PRIx8  "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 __PRI64 "x"
+
+#define PRIxLEAST8  "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 __PRI64 "x"
+
+#define PRIxFAST8  "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 __PRI64 "x"
+
+#define PRIX8  "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 __PRI64 "X"
+
+#define PRIXLEAST8  "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 __PRI64 "X"
+
+#define PRIXFAST8  "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 __PRI64 "X"
+
+#define PRIdMAX __PRI64 "d"
+#define PRIiMAX __PRI64 "i"
+#define PRIoMAX __PRI64 "o"
+#define PRIuMAX __PRI64 "u"
+#define PRIxMAX __PRI64 "x"
+#define PRIXMAX __PRI64 "X"
+
+#define PRIdPTR __PRIPTR "d"
+#define PRIiPTR __PRIPTR "i"
+#define PRIoPTR __PRIPTR "o"
+#define PRIuPTR __PRIPTR "u"
+#define PRIxPTR __PRIPTR "x"
+#define PRIXPTR __PRIPTR "X"
+
+#define SCNd8   "hhd"
+#define SCNd16  "hd"
+#define SCNd32  "d"
+#define SCNd64  __PRI64 "d"
+
+#define SCNdLEAST8  "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 __PRI64 "d"
+
+#define SCNdFAST8  "hhd"
+#define SCNdFAST16 __PRIPTR "d"
+#define SCNdFAST32 __PRIPTR "d"
+#define SCNdFAST64 __PRI64 "d"
+
+#define SCNi8   "hhi"
+#define SCNi16  "hi"
+#define SCNi32  "i"
+#define SCNi64  __PRI64 "i"
+
+#define SCNiLEAST8  "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 __PRI64 "i"
+
+#define SCNiFAST8  "hhi"
+#define SCNiFAST16 __PRIPTR "i"
+#define SCNiFAST32 __PRIPTR "i"
+#define SCNiFAST64 __PRI64 "i"
+
+#define SCNu8   "hhu"
+#define SCNu16  "hu"
+#define SCNu32  "u"
+#define SCNu64  __PRI64 "u"
+
+#define SCNuLEAST8  "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 __PRI64 "u"
+
+#define SCNuFAST8 "hhu"
+#define SCNuFAST16 __PRIPTR "u"
+#define SCNuFAST32 __PRIPTR "u"
+#define SCNuFAST64 __PRI64 "u"
+
+#define SCNo8   "hho"
+#define SCNo16  "ho"
+#define SCNo32  "o"
+#define SCNo64  __PRI64 "o"
+
+#define SCNoLEAST8  "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 __PRI64 "o"
+
+#define SCNoFAST8  "hho"
+#define SCNoFAST16 __PRIPTR "o"
+#define SCNoFAST32 __PRIPTR "o"
+#define SCNoFAST64 __PRI64 "o"
+
+#define SCNx8   "hhx"
+#define SCNx16  "hx"
+#define SCNx32  "x"
+#define SCNx64  __PRI64 "x"
+
+#define SCNxLEAST8  "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 __PRI64 "x"
+
+#define SCNxFAST8  "hhx"
+#define SCNxFAST16 __PRIPTR "x"
+#define SCNxFAST32 __PRIPTR "x"
+#define SCNxFAST64 __PRI64 "x"
+
+#define SCNdMAX __PRI64 "d"
+#define SCNiMAX __PRI64 "i"
+#define SCNoMAX __PRI64 "o"
+#define SCNuMAX __PRI64 "u"
+#define SCNxMAX __PRI64 "x"
+
+#define SCNdPTR __PRIPTR "d"
+#define SCNiPTR __PRIPTR "i"
+#define SCNoPTR __PRIPTR "o"
+#define SCNuPTR __PRIPTR "u"
+#define SCNxPTR __PRIPTR "x"
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/langinfo.h b/include/langinfo.h
new file mode 100644
index 00000000..4d9e0997
--- /dev/null
+++ b/include/langinfo.h
@@ -0,0 +1,85 @@
+#ifndef _LANGINFO_H
+#define _LANGINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_nl_item
+
+#include <bits/alltypes.h>
+
+#define ABDAY_1 0x20000
+#define ABDAY_2 0x20001
+#define ABDAY_3 0x20002
+#define ABDAY_4 0x20003
+#define ABDAY_5 0x20004
+#define ABDAY_6 0x20005
+#define ABDAY_7 0x20006
+
+#define DAY_1 0x20007
+#define DAY_2 0x20008
+#define DAY_3 0x20009
+#define DAY_4 0x2000A
+#define DAY_5 0x2000B
+#define DAY_6 0x2000C
+#define DAY_7 0x2000D
+
+#define ABMON_1 0x2000E
+#define ABMON_2 0x2000F
+#define ABMON_3 0x20010
+#define ABMON_4 0x20011
+#define ABMON_5 0x20012
+#define ABMON_6 0x20013
+#define ABMON_7 0x20014
+#define ABMON_8 0x20015
+#define ABMON_9 0x20016
+#define ABMON_10 0x20017
+#define ABMON_11 0x20018
+#define ABMON_12 0x20019
+
+#define MON_1 0x2001A
+#define MON_2 0x2001B
+#define MON_3 0x2001C
+#define MON_4 0x2001D
+#define MON_5 0x2001E
+#define MON_6 0x2001F
+#define MON_7 0x20020
+#define MON_8 0x20021
+#define MON_9 0x20022
+#define MON_10 0x20023
+#define MON_11 0x20024
+#define MON_12 0x20025
+
+#define AM_STR 0x20026
+#define PM_STR 0x20027
+
+#define D_T_FMT 0x20028
+#define D_FMT 0x20029
+#define T_FMT 0x2002A
+#define T_FMT_AMPM 0x2002B
+
+#define ERA 0x2002C
+#define ERA_D_FMT 0x2002E
+#define ALT_DIGITS 0x2002F
+#define ERA_D_T_FMT 0x20030
+#define ERA_T_FMT 0x20031
+
+#define CODESET 14
+
+#define CRNCYSTR 0x4000F
+
+#define RADIXCHAR 0x10000
+#define THOUSEP 0x10001
+#define YESEXPR 0x50000
+#define NOEXPR 0x50001
+#define YESSTR 0x50002
+#define NOSTR 0x50003
+
+char *nl_langinfo(nl_item);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libgen.h b/include/libgen.h
new file mode 100644
index 00000000..7c7fd9c6
--- /dev/null
+++ b/include/libgen.h
@@ -0,0 +1,15 @@
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *dirname(char *);
+char *basename(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libintl.h b/include/libintl.h
new file mode 100644
index 00000000..a2dada67
--- /dev/null
+++ b/include/libintl.h
@@ -0,0 +1,25 @@
+#ifndef _LIBINTL_H
+#define _LIBINTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __USE_GNU_GETTEXT 1
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 1 : -1)
+
+char *gettext(const char *);
+char *dgettext(const char *, const char *);
+char *dcgettext(const char *, const char *, int);
+char *ngettext(const char *, const char *, unsigned long);
+char *dngettext(const char *, const char *, const char *, unsigned long);
+char *dcngettext(const char *, const char *, const char *, unsigned long, int);
+char *textdomain(const char *);
+char *bindtextdomain (const char *, const char *);
+char *bind_textdomain_codeset(const char *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/limits.h b/include/limits.h
new file mode 100644
index 00000000..4499afbf
--- /dev/null
+++ b/include/limits.h
@@ -0,0 +1,101 @@
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+/* Most limits are system-specific */
+
+#include <bits/limits.h>
+
+/* Some universal constants... */
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+#define CHAR_MIN (-128)
+#define CHAR_MAX 127
+#define SSIZE_MAX LONG_MAX
+
+#define MB_LEN_MAX 4
+#define TZNAME_MAX 6
+#define TTY_NAME_MAX 20
+#define HOST_NAME_MAX 255
+
+/* Implementation choices... */
+
+#define PTHREAD_KEYS_MAX  1024
+#define PTHREAD_STACK_MIN (2*PAGE_SIZE)
+
+/* Arbitrary numbers... */
+
+#define BC_BASE_MAX 99
+#define BC_DIM_MAX 2048
+#define BC_SCALE_MAX 99
+#define BC_STRING_MAX 1000
+#define CHARCLASS_NAME_MAX 14
+#define COLL_WEIGHTS_MAX 2
+#define EXPR_NEST_MAX 32
+#define LINE_MAX 4096
+#define RE_DUP_MAX 255
+
+#define NL_ARGMAX 9
+#define NL_LANGMAX 32
+#define NL_MSGMAX 32767
+#define NL_NMAX (MB_LEN_MAX*4)
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+
+/* POSIX/SUS requirements follow. These numbers come directly
+ * from SUS and have nothing to do with the host system. */
+
+#define _POSIX_AIO_LISTIO_MAX   2
+#define _POSIX_AIO_MAX          1
+#define _POSIX_ARG_MAX          4096
+#define _POSIX_CHILD_MAX        25
+#define _POSIX_DELAYTIMER_MAX   32
+#define _POSIX_HOST_NAME_MAX    255
+#define _POSIX_LINK_MAX         8
+#define _POSIX_LOGIN_NAME_MAX   9
+#define _POSIX_MAX_CANON        255
+#define _POSIX_MAX_INPUT        255
+#define _POSIX_MQ_OPEN_MAX      8
+#define _POSIX_MQ_PRIO_MAX      32
+#define _POSIX_NAME_MAX         14
+#define _POSIX_NGROUPS_MAX      8
+#define _POSIX_OPEN_MAX         20
+#define _POSIX_PATH_MAX         256
+#define _POSIX_PIPE_BUF         512
+#define _POSIX_RE_DUP_MAX       255
+#define _POSIX_RTSIG_MAX        8
+#define _POSIX_SEM_NSEMS_MAX    256
+#define _POSIX_SEM_VALUE_MAX    32767
+#define _POSIX_SIGQUEUE_MAX     32
+#define _POSIX_SSIZE_MAX        32767
+#define _POSIX_STREAM_MAX       8
+#define _POSIX_SS_REPL_MAX      4
+#define _POSIX_SYMLINK_MAX      255
+#define _POSIX_SYMLOOP_MAX      8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX  128
+#define _POSIX_THREAD_THREADS_MAX 64
+#define _POSIX_TIMER_MAX        32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX   8
+#define _POSIX_TRACE_SYS_MAX    8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX     9
+#define _POSIX_TZNAME_MAX       6
+#define _POSIX2_BC_BASE_MAX     99
+#define _POSIX2_BC_DIM_MAX      2048
+#define _POSIX2_BC_SCALE_MAX    99
+#define _POSIX2_BC_STRING_MAX   1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX   32
+#define _POSIX2_LINE_MAX        2048
+#define _POSIX2_RE_DUP_MAX      255
+
+#define _XOPEN_IOV_MAX          16
+#define _XOPEN_NAME_MAX         255
+#define _XOPEN_PATH_MAX         1024
+
+#endif
diff --git a/include/linux/loop.h b/include/linux/loop.h
new file mode 100644
index 00000000..41aad407
--- /dev/null
+++ b/include/linux/loop.h
@@ -0,0 +1,69 @@
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+#include <stdint.h>
+
+#define LO_NAME_SIZE	64
+#define LO_KEY_SIZE	32
+
+enum {
+	LO_FLAGS_READ_ONLY	= 1,
+	LO_FLAGS_USE_AOPS	= 2,
+	LO_FLAGS_AUTOCLEAR	= 4,
+};
+
+struct loop_info {
+	int                lo_number;
+	long               lo_device;
+	unsigned long	   lo_inode;
+	long               lo_rdevice;
+	int		   lo_offset;
+	int		   lo_encrypt_type;
+	int		   lo_encrypt_key_size;
+	int		   lo_flags;
+	char		   lo_name[LO_NAME_SIZE];
+	unsigned char	   lo_encrypt_key[LO_KEY_SIZE];
+	unsigned long	   lo_init[2];
+	char		   reserved[4];
+};
+
+struct loop_info64 {
+	uint64_t	   lo_device;
+	uint64_t	   lo_inode;
+	uint64_t	   lo_rdevice;
+	uint64_t	   lo_offset;
+	uint64_t	   lo_sizelimit;
+	uint32_t	   lo_number;
+	uint32_t	   lo_encrypt_type;
+	uint32_t	   lo_encrypt_key_size;
+	uint32_t	   lo_flags;
+	uint8_t		   lo_file_name[LO_NAME_SIZE];
+	uint8_t		   lo_crypt_name[LO_NAME_SIZE];
+	uint8_t		   lo_encrypt_key[LO_KEY_SIZE];
+	uint64_t	   lo_init[2];
+};
+
+
+#define LO_CRYPT_NONE		0
+#define LO_CRYPT_XOR		1
+#define LO_CRYPT_DES		2
+#define LO_CRYPT_FISH2		3
+#define LO_CRYPT_BLOW		4
+#define LO_CRYPT_CAST128	5
+#define LO_CRYPT_IDEA		6
+#define LO_CRYPT_DUMMY		9
+#define LO_CRYPT_SKIPJACK	10
+#define LO_CRYPT_CRYPTOAPI	18
+#define MAX_LO_CRYPT		20
+
+
+#define LOOP_SET_FD		0x4C00
+#define LOOP_CLR_FD		0x4C01
+#define LOOP_SET_STATUS		0x4C02
+#define LOOP_GET_STATUS		0x4C03
+#define LOOP_SET_STATUS64	0x4C04
+#define LOOP_GET_STATUS64	0x4C05
+#define LOOP_CHANGE_FD		0x4C06
+#define LOOP_SET_CAPACITY	0x4C07
+
+#endif
diff --git a/include/linux/version.h b/include/linux/version.h
new file mode 100644
index 00000000..e6a89ef2
--- /dev/null
+++ b/include/linux/version.h
@@ -0,0 +1,2 @@
+#define LINUX_VERSION_CODE 132638
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/include/locale.h b/include/locale.h
new file mode 100644
index 00000000..70230237
--- /dev/null
+++ b/include/locale.h
@@ -0,0 +1,84 @@
+#ifndef	_LOCALE_H
+#define	_LOCALE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#define LC_CTYPE    0
+#define LC_NUMERIC  1
+#define LC_TIME     2
+#define LC_COLLATE  3
+#define LC_MONETARY 4
+#define LC_MESSAGES 5
+#define LC_ALL      6
+
+struct lconv {
+	char *decimal_point;
+	char *thousands_sep;
+	char *grouping;
+
+	char *int_curr_symbol;
+	char *currency_symbol;
+	char *mon_decimal_point;
+	char *mon_thousands_sep;
+	char *mon_grouping;
+	char *positive_sign;
+	char *negative_sign;
+	char int_frac_digits;
+	char frac_digits;
+	char p_cs_precedes;
+	char p_sep_by_space;
+	char n_cs_precedes;
+	char n_sep_by_space;
+	char p_sign_posn;
+	char n_sign_posn;
+	char int_p_cs_precedes;
+	char int_p_sep_by_space;
+	char int_n_cs_precedes;
+	char int_n_sep_by_space;
+	char int_p_sign_posn;
+	char int_n_sign_posn;
+};
+
+
+char *setlocale (int, const char *);
+struct lconv *localeconv(void);
+
+
+#if 1
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+#define LC_CTYPE_MASK    (1<<LC_CTYPE)
+#define LC_NUMERIC_MASK  (1<<LC_NUMERIC)
+#define LC_TIME_MASK     (1<<LC_TIME)
+#define LC_COLLATE_MASK  (1<<LC_COLLATE)
+#define LC_MONETARY_MASK (1<<LC_MONETARY)
+#define LC_MESSAGES_MASK (1<<LC_MESSAGES)
+#define LC_ALL_MASK      0x7fffffff
+
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char *, locale_t);
+locale_t uselocale(locale_t);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/malloc.h b/include/malloc.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/malloc.h
diff --git a/include/math.h b/include/math.h
new file mode 100644
index 00000000..cc9befb7
--- /dev/null
+++ b/include/math.h
@@ -0,0 +1,300 @@
+#ifndef _MATH_H
+#define _MATH_H
+
+#define __NEED___uint16_t
+#define __NEED___uint32_t
+#define __NEED___uint64_t
+#include <bits/alltypes.h>
+
+#define M_E             2.7182818284590452354   /* e */
+#define M_LOG2E         1.4426950408889634074   /* log_2 e */
+#define M_LOG10E        0.43429448190325182765  /* log_10 e */
+#define M_LN2           0.69314718055994530942  /* log_e 2 */
+#define M_LN10          2.30258509299404568402  /* log_e 10 */
+#define M_PI            3.14159265358979323846  /* pi */
+#define M_PI_2          1.57079632679489661923  /* pi/2 */
+#define M_PI_4          0.78539816339744830962  /* pi/4 */
+#define M_1_PI          0.31830988618379067154  /* 1/pi */
+#define M_2_PI          0.63661977236758134308  /* 2/pi */
+#define M_2_SQRTPI      1.12837916709551257390  /* 2/sqrt(pi) */
+#define M_SQRT2         1.41421356237309504880  /* sqrt(2) */
+#define M_SQRT1_2       0.70710678118654752440  /* 1/sqrt(2) */
+
+#define __MAKE_FLOAT(i) (((union { int __i; float __f; }){ .__i = i }).__f)
+
+#define NAN       __MAKE_FLOAT(0x7fc00000)
+#define INFINITY  __MAKE_FLOAT(0x7f800000)
+
+#define HUGE_VALF INFINITY
+#define HUGE_VAL  ((double)INFINITY)
+#define HUGE_VALL ((long double)INFINITY)
+
+#define MAXFLOAT  __MAKE_FLOAT(0x7f7fffff)
+
+#define MATH_ERRNO  1
+#define MATH_EXCEPT 2
+#define math_errhandling 2
+
+#define FP_ILOGBNAN (((unsigned)-1)>>1)
+#define FP_ILOGB0 (~FP_ILOGBNAN)
+
+#define FP_NAN       0
+#define FP_INFINITE  1
+#define FP_ZERO      2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL    4
+
+int __fpclassifyf(float);
+int __fpclassify(double);
+int __fpclassifyl(long double);
+
+#define fpclassify(x) ( \
+	sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \
+	sizeof(x) == sizeof(double) ? __fpclassify(x) : \
+	__fpclassifyl(x) )
+
+#define isinf(x)    (fpclassify(x) == FP_INFINITE)
+#define isnan(x)    (fpclassify(x) == FP_NAN)
+#define isnormal(x) (fpclassify(x) == FP_NORMAL)
+#define isfinite(x) (fpclassify(x) > FP_INFINITE)
+
+double      acos(double);
+float       acosf(float);
+long double acosl(long double);
+
+double      acosh(double);
+float       acoshf(float);
+long double acoshl(long double);
+
+double      asin(double);
+float       asinf(float);
+long double asinl(long double);
+
+double      asinh(double);
+float       asinhf(float);
+long double asinhl(long double);
+
+double      atan(double);
+float       atanf(float);
+long double atanl(long double);
+
+double      atan2(double, double);
+float       atan2f(float, float);
+long double atan2l(long double, long double);
+
+double      atanh(double);
+float       atanhf(float);
+long double atanhl(long double);
+
+double      cbrt(double);
+float       cbrtf(float);
+long double cbrtl(long double);
+
+double      ceil(double);
+float       ceilf(float);
+long double ceill(long double);
+
+double      copysign(double, double);
+float       copysignf(float, float);
+long double copysignl(long double, long double);
+
+double      cos(double);
+float       cosf(float);
+long double cosl(long double);
+
+double      cosh(double);
+float       coshf(float);
+long double coshl(long double);
+
+double      erf(double);
+float       erff(float);
+long double erfl(long double);
+
+double      erfc(double);
+float       erfcf(float);
+long double erfcl(long double);
+
+double      exp(double);
+float       expf(float);
+long double expl(long double);
+
+double      exp2(double);
+float       exp2f(float);
+long double exp2l(long double);
+
+double      expm1(double);
+float       expm1f(float);
+long double expm1l(long double);
+
+double      fabs(double);
+float       fabsf(float);
+long double fabsl(long double);
+
+double      fdim(double, double);
+float       fdimf(float, float);
+long double fdiml(long double, long double);
+
+double      floor(double);
+float       floorf(float);
+long double floorl(long double);
+
+double      fma(double, double, double);
+float       fmaf(float, float, float);
+long double fmal(long double, long double, long double);
+
+double      fmax(double, double);
+float       fmaxf(float, float);
+long double fmaxl(long double, long double);
+
+double      fmin(double, double);
+float       fminf(float, float);
+long double fminl(long double, long double);
+
+double      fmod(double, double);
+float       fmodf(float, float);
+long double fmodl(long double, long double);
+
+double      frexp(double, int *);
+float       frexpf(float value, int *);
+long double frexpl(long double value, int *);
+
+double      hypot(double, double);
+float       hypotf(float, float);
+long double hypotl(long double, long double);
+
+int         ilogb(double);
+int         ilogbf(float);
+int         ilogbl(long double);
+
+double      ldexp(double, int);
+float       ldexpf(float, int);
+long double ldexpl(long double, int);
+
+double      lgamma(double);
+float       lgammaf(float);
+long double lgammal(long double);
+
+long long   llrint(double);
+long long   llrintf(float);
+long long   llrintl(long double);
+
+long long   llround(double);
+long long   llroundf(float);
+long long   llroundl(long double);
+
+double      log(double);
+float       logf(float);
+long double logl(long double);
+
+double      log10(double);
+float       log10f(float);
+long double log10l(long double);
+
+double      log1p(double);
+float       log1pf(float);
+long double log1pl(long double);
+
+double      log2(double);
+float       log2f(float);
+long double log2l(long double);
+
+double      logb(double);
+float       logbf(float);
+long double logbl(long double);
+
+long        lrint(double);
+long        lrintf(float);
+long        lrintl(long double);
+
+long        lround(double);
+long        lroundf(float);
+long        lroundl(long double);
+
+double      modf(double, double *);
+float       modff(float, float *);
+long double modfl(long double, long double *);
+
+double      nan(const char *);
+float       nanf(const char *);
+long double nanl(const char *);
+
+double      nearbyint(double);
+float       nearbyintf(float);
+long double nearbyintl(long double);
+
+double      nextafter(double, double);
+float       nextafterf(float, float);
+long double nextafterl(long double, long double);
+
+double      nexttoward(double, long double);
+float       nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+
+double      pow(double, double);
+float       powf(float, float);
+long double powl(long double, long double);
+
+double      remainder(double, double);
+float       remainderf(float, float);
+long double remainderl(long double, long double);
+
+double      remquo(double, double, int *);
+float       remquof(float, float, int *);
+long double remquol(long double, long double, int *);
+
+double      rint(double);
+float       rintf(float);
+long double rintl(long double);
+
+double      round(double);
+float       roundf(float);
+long double roundl(long double);
+
+double      scalbln(double, long);
+float       scalblnf(float, long);
+long double scalblnl(long double, long);
+
+double      scalbn(double, int);
+float       scalbnf(float, int);
+long double scalbnl(long double, int);
+
+double      sin(double);
+float       sinf(float);
+long double sinl(long double);
+
+double      sinh(double);
+float       sinhf(float);
+long double sinhl(long double);
+
+double      sqrt(double);
+float       sqrtf(float);
+long double sqrtl(long double);
+
+double      tan(double);
+float       tanf(float);
+long double tanl(long double);
+
+double      tanh(double);
+float       tanhf(float);
+long double tanhl(long double);
+
+double      tgamma(double);
+float       tgammaf(float);
+long double tgammal(long double);
+
+double      trunc(double);
+float       truncf(float);
+long double truncl(long double);
+
+/* XSI stuff */
+double      j0(double);
+double      j1(double);
+double      jn(int, double);
+double      scalb(double, double);
+double      y0(double);
+double      y1(double);
+double      yn(int, double);
+
+extern int signgam;
+
+#endif
diff --git a/include/mntent.h b/include/mntent.h
new file mode 100644
index 00000000..c0fed7fc
--- /dev/null
+++ b/include/mntent.h
@@ -0,0 +1,43 @@
+#ifndef _MNTENT_H
+#define _MNTENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_FILE
+#include <bits/alltypes.h>
+
+#define MOUNTED "/etc/mtab"
+
+#define MNTTYPE_IGNORE	"ignore"
+#define MNTTYPE_NFS	"nfs"
+#define MNTTYPE_SWAP	"swap"
+#define MNTOPT_DEFAULTS	"defaults"
+#define MNTOPT_RO	"ro"
+#define MNTOPT_RW	"rw"
+#define MNTOPT_SUID	"suid"
+#define MNTOPT_NOSUID	"nosuid"
+#define MNTOPT_NOAUTO	"noauto"
+
+struct mntent
+{
+	char *mnt_fsname;
+	char *mnt_dir;
+	char *mnt_type;
+	char *mnt_opts;
+	int mnt_freq;
+	int mnt_passno;
+};
+
+FILE *setmntent(const char *, const char *);
+int endmntent(FILE *);
+struct mntent *getmntent(FILE *);
+int addmntent(FILE *, const struct mntent *);
+char *hasmntopt(const struct mntent *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/net/ethernet.h b/include/net/ethernet.h
new file mode 100644
index 00000000..a536502d
--- /dev/null
+++ b/include/net/ethernet.h
@@ -0,0 +1,47 @@
+#ifndef __NET_ETHERNET_H
+#define __NET_ETHERNET_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <netinet/if_ether.h>
+
+struct ether_addr {
+	uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+struct ether_header {
+	uint8_t  ether_dhost[ETH_ALEN];
+	uint8_t  ether_shost[ETH_ALEN];
+	uint16_t ether_type;
+};
+
+#define	ETHERTYPE_PUP		0x0200
+#define ETHERTYPE_SPRITE	0x0500
+#define	ETHERTYPE_IP		0x0800
+#define	ETHERTYPE_ARP		0x0806
+#define	ETHERTYPE_REVARP	0x8035
+#define ETHERTYPE_AT		0x809B
+#define ETHERTYPE_AARP		0x80F3
+#define	ETHERTYPE_VLAN		0x8100
+#define ETHERTYPE_IPX		0x8137
+#define	ETHERTYPE_IPV6		0x86dd
+#define ETHERTYPE_LOOPBACK	0x9000
+
+
+#define	ETHER_ADDR_LEN	ETH_ALEN
+#define	ETHER_TYPE_LEN	2
+#define	ETHER_CRC_LEN	4
+#define	ETHER_HDR_LEN	ETH_HLEN
+#define	ETHER_MIN_LEN	(ETH_ZLEN + ETHER_CRC_LEN)
+#define	ETHER_MAX_LEN	(ETH_FRAME_LEN + ETHER_CRC_LEN)
+
+#define	ETHER_IS_VALID_LEN(foo)	\
+	((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define	ETHERTYPE_TRAIL		0x1000
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERMTU	ETH_DATA_LEN
+#define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#endif
diff --git a/include/net/if.h b/include/net/if.h
new file mode 100644
index 00000000..2ae5f89e
--- /dev/null
+++ b/include/net/if.h
@@ -0,0 +1,122 @@
+#ifndef _NET_IF_H
+#define _NET_IF_H
+
+#define IF_NAMESIZE 16
+
+struct if_nameindex
+{
+	unsigned int if_index;
+	char *if_name;
+};
+
+unsigned int if_nametoindex (const char *);
+char *if_indextoname (unsigned int, char *);
+struct if_nameindex *if_nameindex (void);
+void if_freenameindex (struct if_nameindex *);
+
+
+
+
+#ifdef _GNU_SOURCE
+
+#include <sys/socket.h>
+
+#define IFF_UP	0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+
+struct ifaddr {
+	struct sockaddr ifa_addr;
+	union {
+		struct sockaddr	ifu_broadaddr;
+		struct sockaddr	ifu_dstaddr;
+	} ifa_ifu;
+	struct iface *ifa_ifp;
+	struct ifaddr *ifa_next;
+};
+
+#define ifa_broadaddr	ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr	ifa_ifu.ifu_dstaddr
+
+struct ifmap {
+	unsigned long int mem_start;
+	unsigned long int mem_end;
+	unsigned short int base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+#define IFHWADDRLEN	6
+#define IFNAMSIZ	IF_NAMESIZE
+
+struct ifreq {
+	union {
+		char ifrn_name[IFNAMSIZ];
+	} ifr_ifrn;
+	union {
+		struct sockaddr ifru_addr;
+		struct sockaddr ifru_dstaddr;
+		struct sockaddr ifru_broadaddr;
+		struct sockaddr ifru_netmask;
+		struct sockaddr ifru_hwaddr;
+		short int ifru_flags;
+		int ifru_ivalue;
+		int ifru_mtu;
+		struct ifmap ifru_map;
+		char ifru_slave[IFNAMSIZ];
+		char ifru_newname[IFNAMSIZ];
+		void *ifru_data;
+	} ifr_ifru;
+};
+
+#define ifr_name	ifr_ifrn.ifrn_name
+#define ifr_hwaddr	ifr_ifru.ifru_hwaddr
+#define ifr_addr	ifr_ifru.ifru_addr
+#define ifr_dstaddr	ifr_ifru.ifru_dstaddr
+#define ifr_broadaddr	ifr_ifru.ifru_broadaddr
+#define ifr_netmask	ifr_ifru.ifru_netmask
+#define ifr_flags	ifr_ifru.ifru_flags
+#define ifr_metric	ifr_ifru.ifru_ivalue
+#define ifr_mtu		ifr_ifru.ifru_mtu
+#define ifr_map		ifr_ifru.ifru_map
+#define ifr_slave	ifr_ifru.ifru_slave
+#define ifr_data	ifr_ifru.ifru_data
+#define ifr_ifindex	ifr_ifru.ifru_ivalue
+#define ifr_bandwidth	ifr_ifru.ifru_ivalue
+#define ifr_qlen	ifr_ifru.ifru_ivalue
+#define ifr_newname	ifr_ifru.ifru_newname
+#define _IOT_ifreq	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+#define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+#define _IOT_ifreq_int	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+struct ifconf {
+	int ifc_len;		
+	union {
+		void *ifcu_buf;
+		struct ifreq *ifcu_req;
+	} ifc_ifcu;
+};
+
+#define ifc_buf		ifc_ifcu.ifcu_buf
+#define ifc_req		ifc_ifcu.ifcu_req
+#define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0)
+
+#endif
+
+
+
+#endif
diff --git a/include/net/if_arp.h b/include/net/if_arp.h
new file mode 100644
index 00000000..bb5eadf1
--- /dev/null
+++ b/include/net/if_arp.h
@@ -0,0 +1,133 @@
+/* Nonstandard header */
+#ifndef _NET_IF_ARP_H
+#define _NET_IF_ARP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#define MAX_ADDR_LEN	7
+
+#define	ARPOP_REQUEST	1
+#define	ARPOP_REPLY	2
+#define	ARPOP_RREQUEST	3
+#define	ARPOP_RREPLY	4
+#define	ARPOP_InREQUEST	8
+#define	ARPOP_InREPLY	9
+#define	ARPOP_NAK	10
+
+struct arphdr {
+	uint16_t ar_hrd;
+	uint16_t ar_pro;
+	uint8_t ar_hln;
+	uint8_t ar_pln;
+	uint16_t ar_op;
+};
+
+
+#define ARPHRD_NETROM	0
+#define ARPHRD_ETHER 	1
+#define	ARPHRD_EETHER	2
+#define	ARPHRD_AX25	3
+#define	ARPHRD_PRONET	4
+#define	ARPHRD_CHAOS	5
+#define	ARPHRD_IEEE802	6
+#define	ARPHRD_ARCNET	7
+#define	ARPHRD_APPLETLK	8
+#define	ARPHRD_DLCI	15
+#define	ARPHRD_ATM	19
+#define	ARPHRD_METRICOM	23
+#define ARPHRD_IEEE1394	24
+#define ARPHRD_EUI64		27
+#define ARPHRD_INFINIBAND	32
+#define ARPHRD_SLIP	256
+#define ARPHRD_CSLIP	257
+#define ARPHRD_SLIP6	258
+#define ARPHRD_CSLIP6	259
+#define ARPHRD_RSRVD	260
+#define ARPHRD_ADAPT	264
+#define ARPHRD_ROSE	270
+#define ARPHRD_X25	271
+#define ARPHRD_HWX25	272
+#define ARPHRD_PPP	512
+#define ARPHRD_CISCO	513
+#define ARPHRD_HDLC	ARPHRD_CISCO
+#define ARPHRD_LAPB	516
+#define ARPHRD_DDCMP	517
+#define	ARPHRD_RAWHDLC	518
+
+#define ARPHRD_TUNNEL	768
+#define ARPHRD_TUNNEL6	769
+#define ARPHRD_FRAD	770
+#define ARPHRD_SKIP	771
+#define ARPHRD_LOOPBACK	772
+#define ARPHRD_LOCALTLK 773
+#define ARPHRD_FDDI	774
+#define ARPHRD_BIF	775
+#define ARPHRD_SIT	776
+#define ARPHRD_IPDDP	777
+#define ARPHRD_IPGRE	778
+#define ARPHRD_PIMREG	779
+#define ARPHRD_HIPPI	780
+#define ARPHRD_ASH	781
+#define ARPHRD_ECONET	782
+#define ARPHRD_IRDA	783
+#define ARPHRD_FCPP	784
+#define ARPHRD_FCAL	785
+#define ARPHRD_FCPL	786
+#define ARPHRD_FCFABRIC 787
+#define ARPHRD_IEEE802_TR 800
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_PHY 805
+
+#define ARPHRD_VOID	  0xFFFF
+#define ARPHRD_NONE	  0xFFFE
+
+struct arpreq {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+	char arp_dev[16];
+};
+
+struct arpreq_old {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+};
+
+#define ATF_COM		0x02
+#define	ATF_PERM	0x04
+#define	ATF_PUBL	0x08
+#define	ATF_USETRAILERS	0x10
+#define ATF_NETMASK     0x20
+#define ATF_DONTPUB	0x40
+#define ATF_MAGIC	0x80
+
+#define ARPD_UPDATE	0x01
+#define ARPD_LOOKUP	0x02
+#define ARPD_FLUSH	0x03
+
+struct arpd_request {
+	uint16_t req;
+	uint32_t ip;
+	uint32_t dev;
+	uint32_t stamp;
+	uint32_t updated;
+	uint8_t ha[MAX_ADDR_LEN];
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/net/route.h b/include/net/route.h
new file mode 100644
index 00000000..3aaab978
--- /dev/null
+++ b/include/net/route.h
@@ -0,0 +1,116 @@
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H
+
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+
+struct rtentry {
+	unsigned long int rt_pad1;
+	struct sockaddr rt_dst;
+	struct sockaddr rt_gateway;
+	struct sockaddr rt_genmask;
+	unsigned short int rt_flags;
+	short int rt_pad2;
+	unsigned long int rt_pad3;
+	unsigned char rt_tos;
+	unsigned char rt_class;
+	short int rt_pad4[sizeof(long)/2-1];
+	short int rt_metric;
+	char *rt_dev;
+	unsigned long int rt_mtu;
+	unsigned long int rt_window;
+	unsigned short int rt_irtt;
+};
+
+#define rt_mss	rt_mtu
+
+
+struct in6_rtmsg {
+	struct in6_addr rtmsg_dst;
+	struct in6_addr rtmsg_src;
+	struct in6_addr rtmsg_gateway;
+	uint32_t rtmsg_type;
+	uint16_t rtmsg_dst_len;
+	uint16_t rtmsg_src_len;
+	uint32_t rtmsg_metric;
+	unsigned long int rtmsg_info;
+	uint32_t rtmsg_flags;
+	int rtmsg_ifindex;
+};
+
+
+#define	RTF_UP		0x0001
+#define	RTF_GATEWAY	0x0002
+
+#define	RTF_HOST	0x0004
+#define RTF_REINSTATE	0x0008
+#define	RTF_DYNAMIC	0x0010
+#define	RTF_MODIFIED	0x0020
+#define RTF_MTU		0x0040
+#define RTF_MSS		RTF_MTU
+#define RTF_WINDOW	0x0080
+#define RTF_IRTT	0x0100
+#define RTF_REJECT	0x0200
+#define	RTF_STATIC	0x0400
+#define	RTF_XRESOLVE	0x0800
+#define RTF_NOFORWARD   0x1000
+#define RTF_THROW	0x2000
+#define RTF_NOPMTUDISC  0x4000
+
+#define RTF_DEFAULT	0x00010000
+#define RTF_ALLONLINK	0x00020000
+#define RTF_ADDRCONF	0x00040000
+
+#define RTF_LINKRT	0x00100000
+#define RTF_NONEXTHOP	0x00200000
+
+#define RTF_CACHE	0x01000000
+#define RTF_FLOW	0x02000000
+#define RTF_POLICY	0x04000000
+
+#define RTCF_VALVE	0x00200000
+#define RTCF_MASQ	0x00400000
+#define RTCF_NAT	0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG	0x02000000
+#define RTCF_DIRECTSRC	0x04000000
+
+#define RTF_LOCAL	0x80000000
+#define RTF_INTERFACE	0x40000000
+#define RTF_MULTICAST	0x20000000
+#define RTF_BROADCAST	0x10000000
+#define RTF_NAT		0x08000000
+
+#define RTF_ADDRCLASSMASK	0xF8000000
+#define RT_ADDRCLASS(flags)	((uint32_t) flags >> 23)
+
+#define RT_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags)	((flags & RTF_ADDRCLASSMASK) \
+				 == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC		0
+#define RT_CLASS_DEFAULT	253
+
+#define RT_CLASS_MAIN		254
+#define RT_CLASS_LOCAL		255
+#define RT_CLASS_MAX		255
+
+
+#define RTMSG_ACK		NLMSG_ACK
+#define RTMSG_OVERRUN		NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE		0x11
+#define RTMSG_DELDEVICE		0x12
+#define RTMSG_NEWROUTE		0x21
+#define RTMSG_DELROUTE		0x22
+#define RTMSG_NEWRULE		0x31
+#define RTMSG_DELRULE		0x32
+#define RTMSG_CONTROL		0x40
+
+#define RTMSG_AR_FAILED		0x51
+
+#endif
diff --git a/include/netdb.h b/include/netdb.h
new file mode 100644
index 00000000..5f1dd3f1
--- /dev/null
+++ b/include/netdb.h
@@ -0,0 +1,148 @@
+#ifndef	_NETDB_H
+#define	_NETDB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#endif
+
+#define __NEED_socklen_t
+#define __NEED_uint32_t
+
+#include <bits/alltypes.h>
+
+struct addrinfo
+{
+	int ai_flags;
+	int ai_family;
+	int ai_socktype;
+	int ai_protocol;
+	socklen_t ai_addrlen;
+	struct sockaddr *ai_addr;
+	char *ai_canonname;
+	struct addrinfo *ai_next;
+};
+
+#define IPPORT_RESERVED 1024
+
+#define AI_PASSIVE      0x01
+#define AI_CANONNAME    0x02
+#define AI_NUMERICHOST  0x04
+#define AI_V4MAPPED     0x08
+#define AI_ALL          0x10
+#define AI_ADDRCONFIG   0x20
+#define AI_NUMERICSERV  0x400
+
+
+#define NI_NUMERICHOST  0x01
+#define NI_NUMERICSERV  0x02
+#define NI_NOFQDN       0x04
+#define NI_NAMEREQD     0x08
+#define NI_DGRAM        0x10
+/*#define NI_NUMERICSCOPE */
+
+#define NI_MAXHOST 255
+#define NI_MAXSERV 32
+
+#define EAI_BADFLAGS   -1
+#define EAI_NONAME     -2
+#define EAI_AGAIN      -3
+#define EAI_FAIL       -4
+#define EAI_FAMILY     -6
+#define EAI_SOCKTYPE   -7
+#define EAI_SERVICE    -8
+#define EAI_MEMORY     -10
+#define EAI_SYSTEM     -11
+#define EAI_OVERFLOW   -12
+
+int getaddrinfo (const char *, const char *, const struct addrinfo *, struct addrinfo **);
+void freeaddrinfo (struct addrinfo *);
+int getnameinfo (const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, int);
+const char *gai_strerror(int);
+
+
+/* Legacy functions follow (marked OBsolete in SUS) */
+
+struct netent
+{
+	char *n_name;
+	char **n_aliases;
+	int n_addrtype;
+	uint32_t n_net;
+};
+
+struct hostent
+{
+	char *h_name;
+	char **h_aliases;
+	int h_addrtype;
+	int h_length;
+	char **h_addr_list;
+};
+#define h_addr h_addr_list[0]
+
+struct servent
+{
+	char *s_name;
+	char **s_aliases;
+	int s_port;
+	char *s_proto;
+};
+
+struct protoent
+{
+	char *p_name;
+	char **p_aliases;
+	int p_proto;
+};
+
+extern int h_errno;
+
+#define HOST_NOT_FOUND 1
+#define TRY_AGAIN      2
+#define NO_RECOVERY    3
+#define NO_DATA        4
+
+void sethostent (int);
+void endhostent (void);
+struct hostent *gethostent (void);
+struct hostent *gethostbyaddr (const void *, socklen_t, int);
+struct hostent *gethostbyname (const char *);
+
+void setnetent (int);
+void endnetent (void);
+struct netent *getnetent (void);
+struct netent *getnetbyaddr (uint32_t, int);
+struct netent *getnetbyname (const char *);
+
+void setservent (int);
+void endservent (void);
+struct servent *getservent (void);
+struct servent *getservbyname (const char *, const char *);
+struct servent *getservbyport (int, const char *);
+
+void setprotoent (int);
+void endprotoent (void);
+struct protoent *getprotoent (void);
+struct protoent *getprotobyname (const char *);
+struct protoent *getprotobynumber (int);
+
+#ifdef _GNU_SOURCE
+const char *hstrerror(int);
+int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
+int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent *gethostbyname2(const char *, int);
+int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);
+int getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **);
+int getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netinet/icmp6.h b/include/netinet/icmp6.h
new file mode 100644
index 00000000..01269e7d
--- /dev/null
+++ b/include/netinet/icmp6.h
@@ -0,0 +1,305 @@
+#ifndef _NETINET_ICMP6_H
+#define _NETINET_ICMP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#define ICMP6_FILTER 1
+
+#define ICMP6_FILTER_BLOCK		1
+#define ICMP6_FILTER_PASS		2
+#define ICMP6_FILTER_BLOCKOTHERS	3
+#define ICMP6_FILTER_PASSONLY		4
+
+struct icmp6_filter {
+	uint32_t icmp6_filt[8];
+};
+
+struct icmp6_hdr {
+	uint8_t     icmp6_type;
+	uint8_t     icmp6_code;
+	uint16_t    icmp6_cksum;
+	union {
+		uint32_t  icmp6_un_data32[1];
+		uint16_t  icmp6_un_data16[2];
+		uint8_t   icmp6_un_data8[4];
+	} icmp6_dataun;
+};
+
+#define icmp6_data32    icmp6_dataun.icmp6_un_data32
+#define icmp6_data16    icmp6_dataun.icmp6_un_data16
+#define icmp6_data8     icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr      icmp6_data32[0]
+#define icmp6_mtu       icmp6_data32[0]
+#define icmp6_id        icmp6_data16[0]
+#define icmp6_seq       icmp6_data16[1]
+#define icmp6_maxdelay  icmp6_data16[0]
+
+#define ICMP6_DST_UNREACH             1
+#define ICMP6_PACKET_TOO_BIG          2
+#define ICMP6_TIME_EXCEEDED           3
+#define ICMP6_PARAM_PROB              4
+
+#define ICMP6_INFOMSG_MASK  0x80
+
+#define ICMP6_ECHO_REQUEST          128
+#define ICMP6_ECHO_REPLY            129
+#define MLD_LISTENER_QUERY          130
+#define MLD_LISTENER_REPORT         131
+#define MLD_LISTENER_REDUCTION      132
+
+#define ICMP6_DST_UNREACH_NOROUTE     0
+#define ICMP6_DST_UNREACH_ADMIN       1
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_DST_UNREACH_ADDR        3
+#define ICMP6_DST_UNREACH_NOPORT      4
+
+#define ICMP6_TIME_EXCEED_TRANSIT     0
+#define ICMP6_TIME_EXCEED_REASSEMBLY  1
+
+#define ICMP6_PARAMPROB_HEADER        0
+#define ICMP6_PARAMPROB_NEXTHEADER    1
+#define ICMP6_PARAMPROB_OPTION        2
+
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+	memset (filterp, 0, sizeof (struct icmp6_filter));
+
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+	memset (filterp, 0xFF, sizeof (struct icmp6_filter));
+
+#define ND_ROUTER_SOLICIT           133
+#define ND_ROUTER_ADVERT            134
+#define ND_NEIGHBOR_SOLICIT         135
+#define ND_NEIGHBOR_ADVERT          136
+#define ND_REDIRECT                 137
+
+struct nd_router_solicit {
+	struct icmp6_hdr  nd_rs_hdr;
+};
+
+#define nd_rs_type               nd_rs_hdr.icmp6_type
+#define nd_rs_code               nd_rs_hdr.icmp6_code
+#define nd_rs_cksum              nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved           nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert {
+	struct icmp6_hdr  nd_ra_hdr;
+	uint32_t   nd_ra_reachable;
+	uint32_t   nd_ra_retransmit;
+};
+
+#define nd_ra_type               nd_ra_hdr.icmp6_type
+#define nd_ra_code               nd_ra_hdr.icmp6_code
+#define nd_ra_cksum              nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit        nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved     nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED       0x80
+#define ND_RA_FLAG_OTHER         0x40
+#define ND_RA_FLAG_HOME_AGENT    0x20
+#define nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit {
+	struct icmp6_hdr  nd_ns_hdr;
+	struct in6_addr   nd_ns_target;
+};
+
+#define nd_ns_type               nd_ns_hdr.icmp6_type
+#define nd_ns_code               nd_ns_hdr.icmp6_code
+#define nd_ns_cksum              nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved           nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert {
+	struct icmp6_hdr  nd_na_hdr;
+	struct in6_addr   nd_na_target;
+};
+
+#define nd_na_type               nd_na_hdr.icmp6_type
+#define nd_na_code               nd_na_hdr.icmp6_code
+#define nd_na_cksum              nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved     nd_na_hdr.icmp6_data32[0]
+#if     __BYTE_ORDER == __BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER        0x80000000
+#define ND_NA_FLAG_SOLICITED     0x40000000
+#define ND_NA_FLAG_OVERRIDE      0x20000000
+#else
+#define ND_NA_FLAG_ROUTER        0x00000080
+#define ND_NA_FLAG_SOLICITED     0x00000040
+#define ND_NA_FLAG_OVERRIDE      0x00000020
+#endif
+
+struct nd_redirect {
+	struct icmp6_hdr  nd_rd_hdr;
+	struct in6_addr   nd_rd_target;
+	struct in6_addr   nd_rd_dst;
+};
+
+#define nd_rd_type               nd_rd_hdr.icmp6_type
+#define nd_rd_code               nd_rd_hdr.icmp6_code
+#define nd_rd_cksum              nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved           nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr {
+	uint8_t  nd_opt_type;
+	uint8_t  nd_opt_len;
+};
+
+#define ND_OPT_SOURCE_LINKADDR		1
+#define ND_OPT_TARGET_LINKADDR		2
+#define ND_OPT_PREFIX_INFORMATION	3
+#define ND_OPT_REDIRECTED_HEADER	4
+#define ND_OPT_MTU			5
+#define ND_OPT_RTR_ADV_INTERVAL		7
+#define ND_OPT_HOME_AGENT_INFO		8
+
+struct nd_opt_prefix_info {
+	uint8_t   nd_opt_pi_type;
+	uint8_t   nd_opt_pi_len;
+	uint8_t   nd_opt_pi_prefix_len;
+	uint8_t   nd_opt_pi_flags_reserved;
+	uint32_t  nd_opt_pi_valid_time;
+	uint32_t  nd_opt_pi_preferred_time;
+	uint32_t  nd_opt_pi_reserved2;
+	struct in6_addr  nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK	0x80
+#define ND_OPT_PI_FLAG_AUTO	0x40
+#define ND_OPT_PI_FLAG_RADDR	0x20
+
+struct nd_opt_rd_hdr {
+	uint8_t   nd_opt_rh_type;
+	uint8_t   nd_opt_rh_len;
+	uint16_t  nd_opt_rh_reserved1;
+	uint32_t  nd_opt_rh_reserved2;
+};
+
+struct nd_opt_mtu {
+	uint8_t   nd_opt_mtu_type;
+	uint8_t   nd_opt_mtu_len;
+	uint16_t  nd_opt_mtu_reserved;
+	uint32_t  nd_opt_mtu_mtu;
+};
+
+struct mld_hdr {
+	struct icmp6_hdr    mld_icmp6_hdr;
+	struct in6_addr     mld_addr;
+};
+
+#define mld_type        mld_icmp6_hdr.icmp6_type
+#define mld_code        mld_icmp6_hdr.icmp6_code
+#define mld_cksum       mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay    mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved    mld_icmp6_hdr.icmp6_data16[1]
+
+#define ICMP6_ROUTER_RENUMBERING    138
+
+struct icmp6_router_renum {
+	struct icmp6_hdr    rr_hdr;
+	uint8_t             rr_segnum;
+	uint8_t             rr_flags;
+	uint16_t            rr_maxdelay;
+	uint32_t            rr_reserved;
+};
+
+#define rr_type		rr_hdr.icmp6_type
+#define rr_code         rr_hdr.icmp6_code
+#define rr_cksum        rr_hdr.icmp6_cksum
+#define rr_seqnum       rr_hdr.icmp6_data32[0]
+
+#define ICMP6_RR_FLAGS_TEST             0x80
+#define ICMP6_RR_FLAGS_REQRESULT        0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY       0x20
+#define ICMP6_RR_FLAGS_SPECSITE         0x10
+#define ICMP6_RR_FLAGS_PREVDONE         0x08
+
+struct rr_pco_match {
+	uint8_t             rpm_code;
+	uint8_t             rpm_len;
+	uint8_t             rpm_ordinal;
+	uint8_t             rpm_matchlen;
+	uint8_t             rpm_minlen;
+	uint8_t             rpm_maxlen;
+	uint16_t            rpm_reserved;
+	struct in6_addr     rpm_prefix;
+};
+
+#define RPM_PCO_ADD             1
+#define RPM_PCO_CHANGE          2
+#define RPM_PCO_SETGLOBAL       3
+
+struct rr_pco_use {
+	uint8_t             rpu_uselen;
+	uint8_t             rpu_keeplen;
+	uint8_t             rpu_ramask;
+	uint8_t             rpu_raflags;
+	uint32_t            rpu_vltime;
+	uint32_t            rpu_pltime;
+	uint32_t            rpu_flags;
+	struct in6_addr     rpu_prefix;
+};
+
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK  0x20
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO    0x10
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#else
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result {
+	uint16_t            rrr_flags;
+	uint8_t             rrr_ordinal;
+	uint8_t             rrr_matchedlen;
+	uint32_t            rrr_ifid;
+	struct in6_addr     rrr_prefix;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#else
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+struct nd_opt_adv_interval {
+	uint8_t   nd_opt_adv_interval_type;
+	uint8_t   nd_opt_adv_interval_len;
+	uint16_t  nd_opt_adv_interval_reserved;
+	uint32_t  nd_opt_adv_interval_ival;
+};
+
+struct nd_opt_home_agent_info {
+	uint8_t   nd_opt_home_agent_info_type;
+	uint8_t   nd_opt_home_agent_info_len;
+	uint16_t  nd_opt_home_agent_info_reserved;
+	uint16_t  nd_opt_home_agent_info_preference;
+	uint16_t  nd_opt_home_agent_info_lifetime;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h
new file mode 100644
index 00000000..65a838ac
--- /dev/null
+++ b/include/netinet/if_ether.h
@@ -0,0 +1,108 @@
+#ifndef _NETINET_IF_ETHER_H
+#define _NETINET_IF_ETHER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ETH_ALEN	6
+#define ETH_HLEN	14
+#define ETH_ZLEN	60
+#define ETH_DATA_LEN	1500
+#define ETH_FRAME_LEN	1514
+#define ETH_FCS_LEN	4
+
+#define ETH_P_LOOP	0x0060
+#define ETH_P_PUP	0x0200
+#define ETH_P_PUPAT	0x0201
+#define ETH_P_IP	0x0800
+#define ETH_P_X25	0x0805
+#define ETH_P_ARP	0x0806
+#define	ETH_P_BPQ	0x08FF
+#define ETH_P_IEEEPUP	0x0a00
+#define ETH_P_IEEEPUPAT	0x0a01
+#define ETH_P_DEC       0x6000
+#define ETH_P_DNA_DL    0x6001
+#define ETH_P_DNA_RC    0x6002
+#define ETH_P_DNA_RT    0x6003
+#define ETH_P_LAT       0x6004
+#define ETH_P_DIAG      0x6005
+#define ETH_P_CUST      0x6006
+#define ETH_P_SCA       0x6007
+#define ETH_P_TEB	0x6558
+#define ETH_P_RARP      0x8035
+#define ETH_P_ATALK	0x809B
+#define ETH_P_AARP	0x80F3
+#define ETH_P_8021Q	0x8100
+#define ETH_P_IPX	0x8137
+#define ETH_P_IPV6	0x86DD
+#define ETH_P_PAUSE	0x8808
+#define ETH_P_SLOW	0x8809
+#define ETH_P_WCCP	0x883E
+#define ETH_P_PPP_DISC	0x8863
+#define ETH_P_PPP_SES	0x8864
+#define ETH_P_MPLS_UC	0x8847
+#define ETH_P_MPLS_MC	0x8848
+#define ETH_P_ATMMPOA	0x884c
+#define ETH_P_ATMFATE	0x8884
+#define ETH_P_PAE	0x888E
+#define ETH_P_AOE	0x88A2
+#define ETH_P_TIPC	0x88CA
+#define ETH_P_FCOE	0x8906
+#define ETH_P_EDSA	0xDADA
+
+#define ETH_P_802_3	0x0001
+#define ETH_P_AX25	0x0002
+#define ETH_P_ALL	0x0003
+#define ETH_P_802_2	0x0004
+#define ETH_P_SNAP	0x0005
+#define ETH_P_DDCMP     0x0006
+#define ETH_P_WAN_PPP   0x0007
+#define ETH_P_PPP_MP    0x0008
+#define ETH_P_LOCALTALK 0x0009
+#define ETH_P_CAN	0x000C
+#define ETH_P_PPPTALK	0x0010
+#define ETH_P_TR_802_2	0x0011
+#define ETH_P_MOBITEX	0x0015
+#define ETH_P_CONTROL	0x0016
+#define ETH_P_IRDA	0x0017
+#define ETH_P_ECONET	0x0018
+#define ETH_P_HDLC	0x0019
+#define ETH_P_ARCNET	0x001A
+#define ETH_P_DSA	0x001B
+#define ETH_P_TRAILER	0x001C
+#define ETH_P_PHONET	0x00F5
+
+struct ethhdr {
+	uint8_t h_dest[ETH_ALEN];
+	uint8_t h_source[ETH_ALEN];
+	uint16_t h_proto;
+};
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+struct	ether_arp {
+	struct	arphdr ea_hdr;
+	uint8_t arp_sha[ETH_ALEN];
+	uint8_t arp_spa[4];
+	uint8_t arp_tha[ETH_ALEN];
+	uint8_t arp_tpa[4];
+};
+#define	arp_hrd	ea_hdr.ar_hrd
+#define	arp_pro	ea_hdr.ar_pro
+#define	arp_hln	ea_hdr.ar_hln
+#define	arp_pln	ea_hdr.ar_pln
+#define	arp_op	ea_hdr.ar_op
+
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+do { \
+	(enaddr)[0] = 0x01; \
+	(enaddr)[1] = 0x00; \
+	(enaddr)[2] = 0x5e; \
+	(enaddr)[3] = ((uint8_t *)ipaddr)[1] & 0x7f; \
+	(enaddr)[4] = ((uint8_t *)ipaddr)[2]; \
+	(enaddr)[5] = ((uint8_t *)ipaddr)[3]; \
+} while(0)
+
+
+#endif
diff --git a/include/netinet/in.h b/include/netinet/in.h
new file mode 100644
index 00000000..a641f6a6
--- /dev/null
+++ b/include/netinet/in.h
@@ -0,0 +1,158 @@
+#ifndef	_NETINET_IN_H
+#define	_NETINET_IN_H
+
+#define __NEED_in_addr_t
+#define __NEED_in_port_t
+#define __NEED_sa_family_t
+#define __NEED_struct_in_addr
+#define __NEED_uint8_t
+#define __NEED_uint16_t
+#define __NEED_uint32_t
+
+#include <bits/alltypes.h>
+
+struct sockaddr_in
+{
+	sa_family_t sin_family;
+	in_port_t sin_port;
+	struct in_addr sin_addr;
+	uint8_t sin_zero[8];
+};
+
+struct in6_addr
+{
+	union {
+		uint8_t __s6_addr[16];
+		uint32_t __s6_addr32[4];
+	} __in6_union;
+};
+#define s6_addr __in6_union.__s6_addr
+#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6
+{
+	sa_family_t     sin6_family;
+	in_port_t       sin6_port;
+	uint32_t        sin6_flowinfo;
+	struct in6_addr sin6_addr;
+	uint32_t        sin6_scope_id;
+};
+
+struct ipv6_mreq
+{
+	struct in6_addr ipv6mr_multiaddr;
+	unsigned        ipv6mr_interface;
+};
+
+#define INADDR_ANY        ((in_addr_t) 0x00000000)
+#define INADDR_BROADCAST  ((in_addr_t) 0xffffffff)
+#define INADDR_NONE       ((in_addr_t) 0xffffffff)
+#define INADDR_LOOPBACK   ((in_addr_t) 0x7f000001)
+
+#define IN6ADDR_ANY_INIT      { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+extern const struct in6_addr in6addr_any, in6addr_loopback;
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+#define IPPROTO_IP       0
+#define IPPROTO_ICMP     1
+#define IPPROTO_IGMP     2
+#define IPPROTO_IPIP     4
+#define IPPROTO_TCP      6
+#define IPPROTO_EGP      8
+#define IPPROTO_PUP      12
+#define IPPROTO_UDP      17
+#define IPPROTO_IDP      22
+#define IPPROTO_TP       29
+#define IPPROTO_IPV6     41
+#define IPPROTO_ROUTING  43
+#define IPPROTO_FRAGMENT 44
+#define IPPROTO_RSVP     46
+#define IPPROTO_GRE      47
+#define IPPROTO_ESP      50
+#define IPPROTO_AH       51
+#define IPPROTO_ICMPV6   58
+#define IPPROTO_NONE     59
+#define IPPROTO_DSTOPTS  60
+#define IPPROTO_MTP      92
+#define IPPROTO_ENCAP    98
+#define IPPROTO_PIM      103
+#define IPPROTO_COMP     108
+#define IPPROTO_RAW      255
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && \
+         ((uint8_t *) (a))[12] == 0 && ((uint8_t *) (a))[13] == 0 && \
+         ((uint8_t *) (a))[14] == 0 && ((uint8_t *) (a))[15] == 1 )
+
+#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0xc0)
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint8_t *) (a))[8] == 0 && ((uint8_t *) (a))[9] == 0 && \
+         ((uint8_t *) (a))[10] == 0xff && ((uint8_t *) (a))[11] == 0xff)
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0xe))
+
+#include <bits/in.h>
+
+#if 1 /* FIXME: namespace violation */
+#define	IN_CLASSA(a)		((((in_addr_t)(a)) & 0x80000000) == 0)
+#define	IN_CLASSA_NET		0xff000000
+#define	IN_CLASSA_NSHIFT	24
+#define	IN_CLASSA_HOST		(0xffffffff & ~IN_CLASSA_NET)
+#define	IN_CLASSA_MAX		128
+#define	IN_CLASSB(a)		((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
+#define	IN_CLASSB_NET		0xffff0000
+#define	IN_CLASSB_NSHIFT	16
+#define	IN_CLASSB_HOST		(0xffffffff & ~IN_CLASSB_NET)
+#define	IN_CLASSB_MAX		65536
+#define	IN_CLASSC(a)		((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
+#define	IN_CLASSC_NET		0xffffff00
+#define	IN_CLASSC_NSHIFT	8
+#define	IN_CLASSC_HOST		(0xffffffff & ~IN_CLASSC_NET)
+#define	IN_CLASSD(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
+#define	IN_MULTICAST(a)		IN_CLASSD(a)
+#define	IN_EXPERIMENTAL(a)	((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
+#define	IN_BADCLASS(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
+#endif
+
+#endif
diff --git a/include/netinet/ip.h b/include/netinet/ip.h
new file mode 100644
index 00000000..41187414
--- /dev/null
+++ b/include/netinet/ip.h
@@ -0,0 +1,186 @@
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct timestamp {
+	uint8_t len;
+	uint8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int flags:4;
+	unsigned int overflow:4;
+#else
+	unsigned int overflow:4;
+	unsigned int flags:4;
+#endif
+	uint32_t data[9];
+  };
+
+struct iphdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ihl:4;
+	unsigned int version:4;
+#else
+	unsigned int version:4;
+	unsigned int ihl:4;
+#endif
+	uint8_t tos;
+	uint16_t tot_len;
+	uint16_t id;
+	uint16_t frag_off;
+	uint8_t ttl;
+	uint8_t protocol;
+	uint16_t check;
+	uint32_t saddr;
+	uint32_t daddr;
+};
+
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ip_hl:4;
+	unsigned int ip_v:4;
+#else
+	unsigned int ip_v:4;
+	unsigned int ip_hl:4;
+#endif
+	uint8_t ip_tos;
+	uint16_t ip_len;
+	uint16_t ip_id;
+	uint16_t ip_off;
+	uint8_t ip_ttl;
+	uint8_t ip_p;
+	uint16_t ip_sum;
+	struct in_addr ip_src, ip_dst;
+};
+
+#define	IP_RF 0x8000
+#define	IP_DF 0x4000
+#define	IP_MF 0x2000
+#define	IP_OFFMASK 0x1fff
+
+struct ip_timestamp {
+	uint8_t ipt_code;
+	uint8_t ipt_len;
+	uint8_t ipt_ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ipt_flg:4;
+	unsigned int ipt_oflw:4;
+#else
+	unsigned int ipt_oflw:4;
+	unsigned int ipt_flg:4;
+#endif
+	uint32_t data[9];
+};
+
+#define	IPVERSION	4
+#define	IP_MAXPACKET	65535
+
+#define	IPTOS_ECN_MASK		0x03
+#define	IPTOS_ECN(x)		((x) & IPTOS_ECN_MASK)
+#define	IPTOS_ECN_NOT_ECT	0x00
+#define	IPTOS_ECN_ECT1		0x01
+#define	IPTOS_ECN_ECT0		0x02
+#define	IPTOS_ECN_CE		0x03
+
+#define	IPTOS_DSCP_MASK		0xfc
+#define	IPTOS_DSCP(x)		((x) & IPTOS_DSCP_MASK)
+#define	IPTOS_DSCP_AF11		0x28
+#define	IPTOS_DSCP_AF12		0x30
+#define	IPTOS_DSCP_AF13		0x38
+#define	IPTOS_DSCP_AF21		0x48
+#define	IPTOS_DSCP_AF22		0x50
+#define	IPTOS_DSCP_AF23		0x58
+#define	IPTOS_DSCP_AF31		0x68
+#define	IPTOS_DSCP_AF32		0x70
+#define	IPTOS_DSCP_AF33		0x78
+#define	IPTOS_DSCP_AF41		0x88
+#define	IPTOS_DSCP_AF42		0x90
+#define	IPTOS_DSCP_AF43		0x98
+#define	IPTOS_DSCP_EF		0xb8
+
+#define	IPTOS_TOS_MASK		0x1E
+#define	IPTOS_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+#define	IPTOS_LOWDELAY		0x10
+#define	IPTOS_THROUGHPUT	0x08
+#define	IPTOS_RELIABILITY	0x04
+#define	IPTOS_LOWCOST		0x02
+#define	IPTOS_MINCOST		IPTOS_LOWCOST
+
+#define	IPTOS_PREC_MASK			0xe0
+#define	IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define	IPTOS_PREC_NETCONTROL		0xe0
+#define	IPTOS_PREC_INTERNETCONTROL	0xc0
+#define	IPTOS_PREC_CRITIC_ECP		0xa0
+#define	IPTOS_PREC_FLASHOVERRIDE	0x80
+#define	IPTOS_PREC_FLASH		0x60
+#define	IPTOS_PREC_IMMEDIATE		0x40
+#define	IPTOS_PREC_PRIORITY		0x20
+#define	IPTOS_PREC_ROUTINE		0x00
+
+#define	IPOPT_COPY		0x80
+#define	IPOPT_CLASS_MASK	0x60
+#define	IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_COPIED(o)		((o) & IPOPT_COPY)
+#define	IPOPT_CLASS(o)		((o) & IPOPT_CLASS_MASK)
+#define	IPOPT_NUMBER(o)		((o) & IPOPT_NUMBER_MASK)
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_DEBMEAS		0x40
+#define	IPOPT_MEASUREMENT       IPOPT_DEBMEAS
+#define	IPOPT_RESERVED2		0x60
+
+#define	IPOPT_EOL		0
+#define	IPOPT_END		IPOPT_EOL
+#define	IPOPT_NOP		1
+#define	IPOPT_NOOP		IPOPT_NOP
+
+#define	IPOPT_RR		7
+#define	IPOPT_TS		68
+#define	IPOPT_TIMESTAMP		IPOPT_TS
+#define	IPOPT_SECURITY		130
+#define	IPOPT_SEC		IPOPT_SECURITY
+#define	IPOPT_LSRR		131
+#define	IPOPT_SATID		136
+#define	IPOPT_SID		IPOPT_SATID
+#define	IPOPT_SSRR		137
+#define	IPOPT_RA		148
+
+#define	IPOPT_OPTVAL		0
+#define	IPOPT_OLEN		1
+#define	IPOPT_OFFSET		2
+#define	IPOPT_MINOFF		4
+
+#define	MAX_IPOPTLEN		40
+
+#define	IPOPT_TS_TSONLY		0
+#define	IPOPT_TS_TSANDADDR	1
+#define	IPOPT_TS_PRESPEC	3
+
+#define	IPOPT_SECUR_UNCLASS	0x0000
+#define	IPOPT_SECUR_CONFID	0xf135
+#define	IPOPT_SECUR_EFTO	0x789a
+#define	IPOPT_SECUR_MMMM	0xbc4d
+#define	IPOPT_SECUR_RESTR	0xaf13
+#define	IPOPT_SECUR_SECRET	0xd788
+#define	IPOPT_SECUR_TOPSECRET	0x6bc5
+
+#define	MAXTTL		255
+#define	IPDEFTTL	64
+#define	IPFRAGTTL	60
+#define	IPTTLDEC	1
+
+#define	IP_MSS		576
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netinet/ip6.h b/include/netinet/ip6.h
new file mode 100644
index 00000000..a4347a53
--- /dev/null
+++ b/include/netinet/ip6.h
@@ -0,0 +1,142 @@
+#ifndef _NETINET_IP6_H
+#define _NETINET_IP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct ip6_hdr {
+	union {
+		struct ip6_hdrctl {
+			uint32_t ip6_un1_flow;
+			uint16_t ip6_un1_plen;
+			uint8_t  ip6_un1_nxt;
+			uint8_t  ip6_un1_hlim;
+		} ip6_un1;
+		uint8_t ip6_un2_vfc;
+	} ip6_ctlun;
+	struct in6_addr ip6_src;
+	struct in6_addr ip6_dst;
+};
+
+#define ip6_vfc   ip6_ctlun.ip6_un2_vfc
+#define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+struct ip6_ext {
+	uint8_t  ip6e_nxt;
+	uint8_t  ip6e_len;
+};
+
+struct ip6_hbh {
+	uint8_t  ip6h_nxt;
+	uint8_t  ip6h_len;
+};
+
+struct ip6_dest {
+	uint8_t  ip6d_nxt;
+	uint8_t  ip6d_len;
+};
+
+struct ip6_rthdr {
+	uint8_t  ip6r_nxt;
+	uint8_t  ip6r_len;
+	uint8_t  ip6r_type;
+	uint8_t  ip6r_segleft;
+};
+
+struct ip6_rthdr0 {
+	uint8_t  ip6r0_nxt;
+	uint8_t  ip6r0_len;
+	uint8_t  ip6r0_type;
+	uint8_t  ip6r0_segleft;
+	uint8_t  ip6r0_reserved;
+	uint8_t  ip6r0_slmap[3];
+	struct in6_addr ip6r0_addr[];
+};
+
+struct ip6_frag {
+	uint8_t   ip6f_nxt;
+	uint8_t   ip6f_reserved;
+	uint16_t  ip6f_offlg;
+	uint32_t  ip6f_ident;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6F_OFF_MASK       0xfff8
+#define IP6F_RESERVED_MASK  0x0006
+#define IP6F_MORE_FRAG      0x0001
+#else
+#define IP6F_OFF_MASK       0xf8ff
+#define IP6F_RESERVED_MASK  0x0600
+#define IP6F_MORE_FRAG      0x0100
+#endif
+
+struct ip6_opt {
+	uint8_t  ip6o_type;
+	uint8_t  ip6o_len;
+};
+
+#define IP6OPT_TYPE(o)		((o) & 0xc0)
+#define IP6OPT_TYPE_SKIP	0x00
+#define IP6OPT_TYPE_DISCARD	0x40
+#define IP6OPT_TYPE_FORCEICMP	0x80
+#define IP6OPT_TYPE_ICMP	0xc0
+#define IP6OPT_TYPE_MUTABLE	0x20
+
+#define IP6OPT_PAD1	0
+#define IP6OPT_PADN	1
+
+#define IP6OPT_JUMBO		0xc2
+#define IP6OPT_NSAP_ADDR	0xc3
+#define IP6OPT_TUNNEL_LIMIT	0x04
+#define IP6OPT_ROUTER_ALERT	0x05
+
+struct ip6_opt_jumbo {
+	uint8_t  ip6oj_type;
+	uint8_t  ip6oj_len;
+	uint8_t  ip6oj_jumbo_len[4];
+};
+#define IP6OPT_JUMBO_LEN	6
+
+struct ip6_opt_nsap {
+	uint8_t  ip6on_type;
+	uint8_t  ip6on_len;
+	uint8_t  ip6on_src_nsap_len;
+	uint8_t  ip6on_dst_nsap_len;
+};
+
+struct ip6_opt_tunnel {
+	uint8_t  ip6ot_type;
+	uint8_t  ip6ot_len;
+	uint8_t  ip6ot_encap_limit;
+};
+
+struct ip6_opt_router {
+	uint8_t  ip6or_type;
+	uint8_t  ip6or_len;
+	uint8_t  ip6or_value[2];
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0001
+#define IP6_ALERT_AN	0x0002
+#else
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0100
+#define IP6_ALERT_AN	0x0200
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netinet/ip_icmp.h b/include/netinet/ip_icmp.h
new file mode 100644
index 00000000..2f4a86dd
--- /dev/null
+++ b/include/netinet/ip_icmp.h
@@ -0,0 +1,192 @@
+#ifndef _NETINET_IP_ICMP_H
+#define _NETINET_IP_ICMP_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct icmphdr {
+	uint8_t type;
+	uint8_t code;
+	uint16_t checksum;
+	union {
+		struct {
+			uint16_t id;
+			uint16_t sequence;
+		} echo;
+		uint32_t gateway;
+		struct {
+			uint16_t __unused;
+			uint16_t mtu;
+		} frag;
+	} un;
+};
+
+#define ICMP_ECHOREPLY		0
+#define ICMP_DEST_UNREACH	3
+#define ICMP_SOURCE_QUENCH	4
+#define ICMP_REDIRECT		5
+#define ICMP_ECHO		8
+#define ICMP_TIME_EXCEEDED	11
+#define ICMP_PARAMETERPROB	12
+#define ICMP_TIMESTAMP		13
+#define ICMP_TIMESTAMPREPLY	14
+#define ICMP_INFO_REQUEST	15
+#define ICMP_INFO_REPLY		16
+#define ICMP_ADDRESS		17
+#define ICMP_ADDRESSREPLY	18
+#define NR_ICMP_TYPES		18
+
+
+#define ICMP_NET_UNREACH	0
+#define ICMP_HOST_UNREACH	1
+#define ICMP_PROT_UNREACH	2
+#define ICMP_PORT_UNREACH	3
+#define ICMP_FRAG_NEEDED	4
+#define ICMP_SR_FAILED		5
+#define ICMP_NET_UNKNOWN	6
+#define ICMP_HOST_UNKNOWN	7
+#define ICMP_HOST_ISOLATED	8
+#define ICMP_NET_ANO		9
+#define ICMP_HOST_ANO		10
+#define ICMP_NET_UNR_TOS	11
+#define ICMP_HOST_UNR_TOS	12
+#define ICMP_PKT_FILTERED	13
+#define ICMP_PREC_VIOLATION	14
+#define ICMP_PREC_CUTOFF	15
+#define NR_ICMP_UNREACH		15
+
+#define ICMP_REDIR_NET		0
+#define ICMP_REDIR_HOST		1
+#define ICMP_REDIR_NETTOS	2
+#define ICMP_REDIR_HOSTTOS	3
+
+#define ICMP_EXC_TTL		0
+#define ICMP_EXC_FRAGTIME	1
+
+
+struct icmp_ra_addr {
+	uint32_t ira_addr;
+	uint32_t ira_preference;
+};
+
+struct icmp {
+	uint8_t  icmp_type;
+	uint8_t  icmp_code;
+	uint16_t icmp_cksum;
+	union {
+		uint8_t ih_pptr;
+		struct in_addr ih_gwaddr;
+		struct ih_idseq {
+			uint16_t icd_id;
+			uint16_t icd_seq;
+		} ih_idseq;
+		uint32_t ih_void;
+
+		struct ih_pmtu {
+			uint16_t ipm_void;
+			uint16_t ipm_nextmtu;
+		} ih_pmtu;
+
+		struct ih_rtradv {
+			uint8_t irt_num_addrs;
+			uint8_t irt_wpa;
+			uint16_t irt_lifetime;
+		} ih_rtradv;
+	} icmp_hun;
+	union {
+		struct {
+			uint32_t its_otime;
+			uint32_t its_rtime;
+			uint32_t its_ttime;
+		} id_ts;
+		struct {
+			struct ip idi_ip;
+		} id_ip;
+		struct icmp_ra_addr id_radv;
+		uint32_t   id_mask;
+		uint8_t    id_data[1];
+	} icmp_dun;
+};
+
+#define	icmp_pptr	icmp_hun.ih_pptr
+#define	icmp_gwaddr	icmp_hun.ih_gwaddr
+#define	icmp_id		icmp_hun.ih_idseq.icd_id
+#define	icmp_seq	icmp_hun.ih_idseq.icd_seq
+#define	icmp_void	icmp_hun.ih_void
+#define	icmp_pmvoid	icmp_hun.ih_pmtu.ipm_void
+#define	icmp_nextmtu	icmp_hun.ih_pmtu.ipm_nextmtu
+#define	icmp_num_addrs	icmp_hun.ih_rtradv.irt_num_addrs
+#define	icmp_wpa	icmp_hun.ih_rtradv.irt_wpa
+#define	icmp_lifetime	icmp_hun.ih_rtradv.irt_lifetime
+#define	icmp_otime	icmp_dun.id_ts.its_otime
+#define	icmp_rtime	icmp_dun.id_ts.its_rtime
+#define	icmp_ttime	icmp_dun.id_ts.its_ttime
+#define	icmp_ip		icmp_dun.id_ip.idi_ip
+#define	icmp_radv	icmp_dun.id_radv
+#define	icmp_mask	icmp_dun.id_mask
+#define	icmp_data	icmp_dun.id_data
+
+#define	ICMP_MINLEN	8
+#define	ICMP_TSLEN	(8 + 3 * sizeof (n_time))
+#define	ICMP_MASKLEN	12
+#define	ICMP_ADVLENMIN	(8 + sizeof (struct ip) + 8)
+#define	ICMP_ADVLEN(p)	(8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define	ICMP_UNREACH		3
+#define	ICMP_SOURCEQUENCH	4
+#define	ICMP_ROUTERADVERT	9
+#define	ICMP_ROUTERSOLICIT	10
+#define	ICMP_TIMXCEED		11
+#define	ICMP_PARAMPROB		12
+#define	ICMP_TSTAMP		13
+#define	ICMP_TSTAMPREPLY	14
+#define	ICMP_IREQ		15
+#define	ICMP_IREQREPLY		16
+#define	ICMP_MASKREQ		17
+#define	ICMP_MASKREPLY		18
+#define	ICMP_MAXTYPE		18
+
+#define	ICMP_UNREACH_NET	        0
+#define	ICMP_UNREACH_HOST	        1
+#define	ICMP_UNREACH_PROTOCOL	        2
+#define	ICMP_UNREACH_PORT	        3
+#define	ICMP_UNREACH_NEEDFRAG	        4
+#define	ICMP_UNREACH_SRCFAIL	        5
+#define	ICMP_UNREACH_NET_UNKNOWN        6
+#define	ICMP_UNREACH_HOST_UNKNOWN       7
+#define	ICMP_UNREACH_ISOLATED	        8
+#define	ICMP_UNREACH_NET_PROHIB	        9
+#define	ICMP_UNREACH_HOST_PROHIB        10
+#define	ICMP_UNREACH_TOSNET	        11
+#define	ICMP_UNREACH_TOSHOST	        12
+#define	ICMP_UNREACH_FILTER_PROHIB      13
+#define	ICMP_UNREACH_HOST_PRECEDENCE    14
+#define	ICMP_UNREACH_PRECEDENCE_CUTOFF  15
+
+#define	ICMP_REDIRECT_NET	0
+#define	ICMP_REDIRECT_HOST	1
+#define	ICMP_REDIRECT_TOSNET	2
+#define	ICMP_REDIRECT_TOSHOST	3
+
+#define	ICMP_TIMXCEED_INTRANS	0
+#define	ICMP_TIMXCEED_REASS	1
+
+#define	ICMP_PARAMPROB_OPTABSENT 1
+
+#define	ICMP_INFOTYPE(type) \
+	((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+	(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+	(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+	(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+	(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h
new file mode 100644
index 00000000..ea32ca07
--- /dev/null
+++ b/include/netinet/tcp.h
@@ -0,0 +1,6 @@
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
+
+#include <bits/tcp.h>
+
+#endif
diff --git a/include/netinet/udp.h b/include/netinet/udp.h
new file mode 100644
index 00000000..15b91454
--- /dev/null
+++ b/include/netinet/udp.h
@@ -0,0 +1,35 @@
+#ifndef _NETINET_UDP_H
+#define _NETINET_UDP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+struct udphdr {
+	uint16_t source;
+	uint16_t dest;
+	uint16_t len;
+	uint16_t check;
+};
+
+#define uh_sport source
+#define uh_dport dest
+#define uh_ulen len
+#define uh_sum check
+
+#define UDP_CORK	1
+#define UDP_ENCAP	100
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1
+#define UDP_ENCAP_ESPINUDP	2
+#define UDP_ENCAP_L2TPINUDP	3
+
+#define SOL_UDP            17
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/nl_types.h b/include/nl_types.h
new file mode 100644
index 00000000..ca61efb6
--- /dev/null
+++ b/include/nl_types.h
@@ -0,0 +1,24 @@
+#ifndef _NL_TYPES_H
+#define _NL_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NL_SETD 1
+#define NL_CAT_LOCALE 1
+
+#define __NEED_nl_item
+#include <bits/alltypes.h>
+
+typedef long nl_catd;
+
+nl_catd catopen (const char *, int);
+char *catgets (nl_catd, int, int, const char *);
+int catclose (nl_catd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/paths.h b/include/paths.h
new file mode 100644
index 00000000..8a38ba7b
--- /dev/null
+++ b/include/paths.h
@@ -0,0 +1,40 @@
+#ifndef _PATHS_H_
+#define	_PATHS_H_
+
+#define	_PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define	_PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define	_PATH_BSHELL	"/bin/sh"
+#define	_PATH_CONSOLE	"/dev/console"
+#define	_PATH_CSHELL	"/bin/csh"
+#define	_PATH_DEVDB	"/var/run/dev.db"
+#define	_PATH_DEVNULL	"/dev/null"
+#define	_PATH_DRUM	"/dev/drum"
+#define	_PATH_GSHADOW	"/etc/gshadow"
+#define	_PATH_KLOG	"/proc/kmsg"
+#define	_PATH_KMEM	"/dev/kmem"
+#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define	_PATH_MAILDIR	"/var/mail"
+#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_MEM	"/dev/mem"
+#define	_PATH_MNTTAB	"/etc/fstab"
+#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_NOLOGIN	"/etc/nologin"
+#define	_PATH_PRESERVE	"/var/lib"
+#define	_PATH_RWHODIR	"/var/spool/rwho"
+#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
+#define	_PATH_SHADOW	"/etc/shadow"
+#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_TTY	"/dev/tty"
+#define	_PATH_UNIX	"/boot/vmlinux"
+#define _PATH_UTMP	"/var/run/utmp"
+#define	_PATH_VI	"/usr/bin/vi"
+#define _PATH_WTMP	"/var/log/wtmp"
+
+#define	_PATH_DEV	"/dev/"
+#define	_PATH_TMP	"/tmp/"
+#define	_PATH_VARDB	"/var/lib/misc/"
+#define	_PATH_VARRUN	"/var/run/"
+#define	_PATH_VARTMP	"/var/tmp/"
+
+#endif
diff --git a/include/poll.h b/include/poll.h
new file mode 100644
index 00000000..f868ab57
--- /dev/null
+++ b/include/poll.h
@@ -0,0 +1,35 @@
+#ifndef	_POLL_H
+#define	_POLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define POLLIN     0x001
+#define POLLPRI    0x002
+#define POLLOUT    0x004
+#define POLLERR    0x008
+#define POLLHUP    0x010
+#define POLLNVAL   0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#define POLLMSG    0x400
+
+typedef unsigned int nfds_t;
+
+struct pollfd
+{
+	int fd;
+	short events;
+	short revents;
+};
+
+int poll (struct pollfd *, nfds_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/pthread.h b/include/pthread.h
new file mode 100644
index 00000000..ce6273d2
--- /dev/null
+++ b/include/pthread.h
@@ -0,0 +1,216 @@
+#ifndef _PTHREAD_H
+#define _PTHREAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#define __NEED_pthread_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+struct sched_param;
+
+typedef int pthread_once_t, pthread_key_t, pthread_spinlock_t;
+typedef int pthread_mutexattr_t, pthread_condattr_t, pthread_barrierattr_t;
+
+typedef struct {
+	size_t __guardsize;
+	size_t __stacksize;
+	unsigned __detach : 1;
+	unsigned __pad : 31;
+	int __attr[6];
+} pthread_attr_t;
+
+typedef struct {
+	int __attr[2];
+} pthread_rwlockattr_t;
+
+typedef struct {
+	int __type;
+	int __lock;
+	pthread_t __owner;
+	int __pad2;
+	int __waiters;
+	int __pad;
+} pthread_mutex_t;
+
+typedef struct {
+	int __block;
+	int __pad[11];
+} pthread_cond_t;
+
+typedef struct {
+	int __wrlock;
+	int __readers;
+	int __waiters;
+	int __owner;
+	int __pad[4];
+} pthread_rwlock_t;
+
+typedef struct {
+	int __count;
+	int __limit;
+	int __left;
+	int __waiters;
+	int __barrier[1];
+} pthread_barrier_t;
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT 0
+#define PTHREAD_MUTEX_RECURSIVE 1
+#define PTHREAD_MUTEX_ERRORCHECK 2
+
+#define PTHREAD_MUTEX_STALLED 0
+#define PTHREAD_MUTEX_ROBUST 1
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+
+#define PTHREAD_MUTEX_INITIALIZER {0}
+#define PTHREAD_RWLOCK_INITIALIZER {0}
+#define PTHREAD_COND_INITIALIZER {0}
+#define PTHREAD_ONCE_INIT 0
+
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCELLED ((void *)-1)
+
+
+#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
+
+
+int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
+int pthread_detach(pthread_t);
+void pthread_exit(void *);
+int pthread_join(pthread_t, void **);
+
+pthread_t pthread_self(void);
+int pthread_equal(pthread_t, pthread_t);
+
+int pthread_setcancelstate(int, int *);
+int pthread_setcanceltype(int, int *);
+void pthread_testcancel(void);
+int pthread_cancel(pthread_t);
+
+int pthread_once(pthread_once_t *, void (*)(void));
+
+int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_mutex_trylock(pthread_mutex_t *);
+int pthread_mutex_destroy(pthread_mutex_t *);
+
+int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
+int pthread_cond_broadcast(pthread_cond_t *);
+int pthread_cond_signal(pthread_cond_t *);
+
+int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
+int pthread_rwlock_destroy(pthread_rwlock_t *);
+int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *, const struct timespec *);
+int pthread_rwlock_wrlock(pthread_rwlock_t *);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *, const struct timespec *);
+int pthread_rwlock_unlock(pthread_rwlock_t *);
+
+int pthread_spin_init(pthread_spinlock_t *, int);
+int pthread_spin_destroy(pthread_spinlock_t *);
+int pthread_spin_lock(pthread_spinlock_t *);
+int pthread_spin_trylock(pthread_spinlock_t *);
+int pthread_spin_unlock(pthread_spinlock_t *);
+
+int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *, unsigned);
+int pthread_barrier_destroy(pthread_barrier_t *);
+int pthread_barrier_wait(pthread_barrier_t *);
+
+int pthread_key_create(pthread_key_t *, void (*)(void *));
+int pthread_key_delete(pthread_key_t);
+void *pthread_getspecific(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void *);
+
+int pthread_attr_init(pthread_attr_t *);
+int pthread_attr_destroy(pthread_attr_t *);
+
+int pthread_attr_getguardsize(pthread_attr_t *, size_t *);
+int pthread_attr_setguardsize(pthread_attr_t *, size_t);
+int pthread_attr_getstacksize(pthread_attr_t *, size_t *);
+int pthread_attr_setstacksize(pthread_attr_t *, size_t);
+int pthread_attr_getdetachstate(pthread_attr_t *, int *);
+int pthread_attr_setdetachstate(pthread_attr_t *, int);
+int pthread_attr_getstack(pthread_attr_t *, void **, size_t *);
+int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
+int pthread_attr_getscope(pthread_attr_t *, int *);
+int pthread_attr_setscope(pthread_attr_t *, int);
+int pthread_attr_getschedpolicy(pthread_attr_t *, int *);
+int pthread_attr_setschedpolicy(pthread_attr_t *, int);
+int pthread_attr_getschedparam(pthread_attr_t *, struct sched_param *);
+int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *);
+int pthread_attr_getinheritsched(pthread_attr_t *, int *);
+int pthread_attr_setinheritsched(pthread_attr_t *, int);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *, int *);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *, int *);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *);
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t *, int *);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *);
+int pthread_mutexattr_init(pthread_mutexattr_t *);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *, int *);
+int pthread_barrierattr_init(pthread_barrierattr_t *);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+
+#include <bits/pthread.h>
+
+int __setjmp(void *);
+void __pthread_register_cancel(struct __ptcb *);
+void __pthread_unregister_cancel(struct __ptcb *);
+void __pthread_unwind_next(struct __ptcb *);
+
+#define pthread_cleanup_push(f, x) \
+do { struct __ptcb __cb; void (*__f)(void *) = (f); void *__x = (x); \
+if (__setjmp(__cb.__jb)) __f(__x), __pthread_unwind_next(&__cb); \
+__pthread_register_cancel(&__cb); {
+
+#define pthread_cleanup_pop(r) ; } \
+__pthread_unregister_cancel(&__cb); \
+if (r) __f(__x); } while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/pty.h b/include/pty.h
new file mode 100644
index 00000000..9444e5ec
--- /dev/null
+++ b/include/pty.h
@@ -0,0 +1,17 @@
+#ifndef	_PTY_H
+#define	_PTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int openpty(int *, int *, char *, const struct termios *, const struct winsize *);
+
+#ifdef __cplusplus
+extern }
+#endif
+
+#endif
diff --git a/include/pwd.h b/include/pwd.h
new file mode 100644
index 00000000..5abfbfd5
--- /dev/null
+++ b/include/pwd.h
@@ -0,0 +1,38 @@
+#ifndef _PWD_H
+#define _PWD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+struct passwd
+{
+	char *pw_name;
+	char *pw_passwd;
+	uid_t pw_uid;
+	gid_t pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell;
+};
+
+void setpwent (void);
+void endpwent (void);
+struct passwd *getpwent (void);
+
+struct passwd *getpwuid (uid_t);
+struct passwd *getpwnam (const char *);
+int getpwuid_r (uid_t, struct passwd *, char *, size_t, struct passwd **);
+int getpwnam_r (const char *, struct passwd *, char *, size_t, struct passwd **);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/regex.h b/include/regex.h
new file mode 100644
index 00000000..3673bfa7
--- /dev/null
+++ b/include/regex.h
@@ -0,0 +1,59 @@
+#ifndef _REGEX_H
+#define _REGEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef long regoff_t;
+
+typedef struct {
+	size_t re_nsub;
+	void *__opaque;
+} regex_t;
+
+typedef struct {
+	regoff_t rm_so;
+	regoff_t rm_eo;
+} regmatch_t;
+
+#define REG_EXTENDED    1
+#define REG_ICASE       2
+#define REG_NEWLINE     4
+#define REG_NOSUB       8
+
+#define REG_NOTBOL      1
+#define REG_NOTEOL      2
+
+#define REG_OK          0
+#define REG_NOMATCH     1
+#define REG_BADPAT      2
+#define REG_ECOLLATE    3
+#define REG_ECTYPE      4
+#define REG_EESCAPE     5
+#define REG_ESUBREG     6
+#define REG_EBRACK      7
+#define REG_EPAREN      8
+#define REG_EBRACE      9
+#define REG_BADBR       10
+#define REG_ERANGE      11
+#define REG_ESPACE      12
+#define REG_BADRPT      13
+
+#define REG_ENOSYS      -1
+
+int regcomp(regex_t *, const char *, int);
+int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
+void regfree(regex_t *);
+
+size_t regerror(int, const regex_t *, char *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/resolv.h b/include/resolv.h
new file mode 100644
index 00000000..3b77fc7b
--- /dev/null
+++ b/include/resolv.h
@@ -0,0 +1,143 @@
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <stdint.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNS			3
+#define MAXDFLSRCH		3
+#define MAXDNSRCH		6
+#define LOCALDOMAINPARTS	2
+
+#define RES_TIMEOUT		5
+#define MAXRESOLVSORT		10
+#define RES_MAXNDOTS		15
+#define RES_MAXRETRANS		30
+#define RES_MAXRETRY		5
+#define RES_DFLRETRY		2
+#define RES_MAXTIME		65535
+
+/* unused; purely for broken apps */
+typedef struct __res_state {
+	int retrans;
+	int retry;
+	unsigned long options;
+	int nscount;
+	struct sockaddr_in nsaddr_list[MAXNS];
+# define nsaddr	nsaddr_list[0]
+	unsigned short id;
+	char *dnsrch[MAXDNSRCH+1];
+	char defdname[256];
+	unsigned long pfcode;
+	unsigned ndots:4;
+	unsigned nsort:4;
+	unsigned ipv6_unavail:1;
+	unsigned unused:23;
+	struct {
+		struct in_addr addr;
+		uint32_t mask;
+	} sort_list[MAXRESOLVSORT];
+	void *qhook;
+	void *rhook;
+	int res_h_errno;
+	int _vcsock;
+	unsigned _flags;
+	union {
+		char pad[52];
+		struct {
+			uint16_t		nscount;
+			uint16_t		nsmap[MAXNS];
+			int			nssocks[MAXNS];
+			uint16_t		nscount6;
+			uint16_t		nsinit;
+			struct sockaddr_in6	*nsaddrs[MAXNS];
+			unsigned int		_initstamp[2];
+		} _ext;
+	} _u;
+} *res_state;
+
+#define	__RES	19991006
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF        "/etc/resolv.conf"
+#endif
+
+struct res_sym {
+	int number;
+	char *name;
+	char *humanname;
+};
+
+#define	RES_F_VC	0x00000001
+#define	RES_F_CONN	0x00000002
+#define RES_F_EDNS0ERR	0x00000004
+
+#define	RES_EXHAUSTIVE	0x00000001
+
+#define RES_INIT	0x00000001
+#define RES_DEBUG	0x00000002
+#define RES_AAONLY	0x00000004
+#define RES_USEVC	0x00000008
+#define RES_PRIMARY	0x00000010
+#define RES_IGNTC	0x00000020
+#define RES_RECURSE	0x00000040
+#define RES_DEFNAMES	0x00000080
+#define RES_STAYOPEN	0x00000100
+#define RES_DNSRCH	0x00000200
+#define	RES_INSECURE1	0x00000400
+#define	RES_INSECURE2	0x00000800
+#define	RES_NOALIASES	0x00001000
+#define	RES_USE_INET6	0x00002000
+#define RES_ROTATE	0x00004000
+#define	RES_NOCHECKNAME	0x00008000
+#define	RES_KEEPTSIG	0x00010000
+#define	RES_BLAST	0x00020000
+#define RES_USEBSTRING	0x00040000
+#define RES_NOIP6DOTINT	0x00080000
+#define RES_USE_EDNS0	0x00100000
+#define RES_SNGLKUP	0x00200000
+#define RES_SNGLKUPREOP	0x00400000
+#define RES_USE_DNSSEC	0x00800000
+
+#define RES_DEFAULT	(RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
+
+#define RES_PRF_STATS	0x00000001
+#define RES_PRF_UPDATE	0x00000002
+#define RES_PRF_CLASS   0x00000004
+#define RES_PRF_CMD	0x00000008
+#define RES_PRF_QUES	0x00000010
+#define RES_PRF_ANS	0x00000020
+#define RES_PRF_AUTH	0x00000040
+#define RES_PRF_ADD	0x00000080
+#define RES_PRF_HEAD1	0x00000100
+#define RES_PRF_HEAD2	0x00000200
+#define RES_PRF_TTLID	0x00000400
+#define RES_PRF_HEADX	0x00000800
+#define RES_PRF_QUERY	0x00001000
+#define RES_PRF_REPLY	0x00002000
+#define RES_PRF_INIT	0x00004000
+
+extern struct __res_state *__res_state(void);
+#define _res (*__res_state())
+
+struct rrec;
+
+int res_init(void);
+int res_query(const char *, int, int, unsigned char *, int);
+int res_querydomain(const char *, const char *, int, int, unsigned char *, int);
+int res_search(const char *, int, int, unsigned char *, int);
+int res_mkquery(int, const char *, int, int, char *, int, struct rrec *, char *, int);
+int res_send(const char *, int, char *, int);
+int dn_comp(unsigned char *, unsigned char *, int, unsigned char **, unsigned char *, unsigned char **);
+int dn_expand(unsigned char *, unsigned char *, unsigned char *, unsigned char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/sched.h b/include/sched.h
new file mode 100644
index 00000000..4d8bd3db
--- /dev/null
+++ b/include/sched.h
@@ -0,0 +1,37 @@
+#ifndef _SCHED_H
+#define _SCHED_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_struct_timespec
+#define __NEED_pid_t
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct sched_param {
+	int sched_priority;
+	int sched_ss_low_priority;
+	struct timespec sched_ss_repl_period;
+	struct timespec sched_ss_init_budget;
+	int sched_ss_max_repl;
+};
+
+int    sched_get_priority_max(int);
+int    sched_get_priority_min(int);
+int    sched_getparam(pid_t, struct sched_param *);
+int    sched_getscheduler(pid_t);
+int    sched_rr_get_interval(pid_t, struct timespec *);
+int    sched_setparam(pid_t, const struct sched_param *);
+int    sched_setscheduler(pid_t, int, const struct sched_param *);
+int     sched_yield(void);
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/search.h b/include/search.h
new file mode 100644
index 00000000..9254ed0c
--- /dev/null
+++ b/include/search.h
@@ -0,0 +1,6 @@
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+// FIXME!!!
+
+#endif
diff --git a/include/semaphore.h b/include/semaphore.h
new file mode 100644
index 00000000..5b68986d
--- /dev/null
+++ b/include/semaphore.h
@@ -0,0 +1,27 @@
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SEM_FAILED ((sem_t *)0)
+
+typedef struct {
+	long __val[4];
+} sem_t;
+
+int    sem_close(sem_t *);
+int    sem_destroy(sem_t *);
+int    sem_getvalue(sem_t *, int *);
+int    sem_init(sem_t *, int, unsigned);
+sem_t *sem_open(const char *, int, ...);
+int    sem_post(sem_t *);
+int    sem_timedwait(sem_t *, const struct timespec *);
+int    sem_trywait(sem_t *);
+int    sem_unlink(const char *);
+int    sem_wait(sem_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/setjmp.h b/include/setjmp.h
new file mode 100644
index 00000000..6288c846
--- /dev/null
+++ b/include/setjmp.h
@@ -0,0 +1,30 @@
+#ifndef	_SETJMP_H
+#define	_SETJMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/setjmp.h>
+typedef unsigned long sigjmp_buf[(1024+sizeof(jmp_buf))/sizeof(long)];
+
+#ifdef _GNU_SOURCE
+#define jmp_buf sigjmp_buf
+#endif
+
+int setjmp (jmp_buf);
+int _setjmp (jmp_buf);
+int sigsetjmp (sigjmp_buf, int);
+
+void longjmp (jmp_buf, int);
+void _longjmp (jmp_buf, int);
+void siglongjmp (sigjmp_buf, int);
+
+#define setjmp setjmp
+#define longjmp longjmp
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/shadow.h b/include/shadow.h
new file mode 100644
index 00000000..2b1be413
--- /dev/null
+++ b/include/shadow.h
@@ -0,0 +1,44 @@
+#ifndef _SHADOW_H
+#define _SHADOW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	__NEED_FILE
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define	SHADOW "/etc/shadow"
+
+struct spwd {
+	char *sp_namp;
+	char *sp_pwdp;
+	long sp_lstchg;
+	long sp_min;
+	long sp_max;
+	long sp_warn;
+	long sp_inact;
+	long sp_expire;
+	unsigned long sp_flag;
+};
+
+void setspent(void);
+void endspent(void);
+struct spwd *getspent(void);
+struct spwd *fgetspent(FILE *);
+struct spwd *sgetspent(const char *);
+int putspent(const struct spwd *, FILE *);
+
+struct spwd *getspnam(const char *);
+int getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);
+
+int lckpwdf(void);
+int ulckpwdf(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/signal.h b/include/signal.h
new file mode 100644
index 00000000..540236a5
--- /dev/null
+++ b/include/signal.h
@@ -0,0 +1,98 @@
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_uid_t
+#define __NEED_struct_timespec
+#define __NEED_pthread_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_sigset_t
+#define __NEED_siginfo_t
+
+#include <bits/alltypes.h>
+
+typedef int sig_atomic_t;
+
+struct sigaction
+{
+	union {
+		void (*sa_handler)(int);
+		void (*sa_sigaction)(int, siginfo_t *, void *);
+	} __sa_handler;
+	sigset_t sa_mask;
+	int sa_flags;
+	void (*__sa_restorer)(void);	
+};
+#define sa_handler   __sa_handler.sa_handler
+#define sa_sigaction __sa_handler.sa_sigaction
+
+typedef struct
+{
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+union sigval
+{
+	int sival_int;
+	void *sival_ptr;
+};
+
+#include <bits/signal.h>
+
+int __libc_current_sigrtmin(void);
+int __libc_current_sigrtmax(void);
+
+#define SIGRTMIN  (__libc_current_sigrtmin())
+#define SIGRTMAX  (__libc_current_sigrtmax())
+
+void (*signal(int, void (*)(int)))(int);
+void (*bsd_signal(int, void (*)(int)))(int);
+int kill(pid_t, int);
+int killpg(pid_t, int);
+int raise(int);
+int sigpause(int);
+
+int sigemptyset(sigset_t *);
+int sigfillset(sigset_t *);
+int sigaddset(sigset_t *, int);
+int sigdelset(sigset_t *, int);
+int sigismember(const sigset_t *, int);
+
+int sigprocmask(int, const sigset_t *, sigset_t *);
+int sigsuspend(const sigset_t *);
+int sigaction(int, const struct sigaction *, struct sigaction *);
+int sigpending(sigset_t *);
+int sigwait(const sigset_t *, int *);
+int sigwaitinfo(const sigset_t *, siginfo_t *);
+int sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *);
+int sigqueue(pid_t, int, const union sigval);
+
+int siginterrupt(int, int);
+
+int sigaltstack(const stack_t *, stack_t *);
+
+int sighold(int);
+int sigrelse(int);
+int sigignore(int);
+void (*sigset(int, void (*)(int)))(int);
+
+int pthread_sigmask(int, const sigset_t *, sigset_t *);
+int pthread_kill(pthread_t, int);
+
+#ifdef _GNU_SOURCE
+typedef int (*sighandler_t)(int);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/stdarg.h b/include/stdarg.h
new file mode 100644
index 00000000..cb18778b
--- /dev/null
+++ b/include/stdarg.h
@@ -0,0 +1,32 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_va_list
+
+#include <bits/alltypes.h>
+
+#define __VA_ALIGNED_SIZE(x) ((sizeof(x) + sizeof(int) - 1) & ~(sizeof(int) - 1))
+
+#define va_start(ap, last) ((ap) = (void *)(((char *)&(last)) + __VA_ALIGNED_SIZE(last)))
+#define va_end(ap) ((void)0)
+#define va_copy(dest, src) ((dest) = (src))
+
+#if 0
+#define va_arg(ap, type) \
+	( ((ap) = (va_list)((char *)(ap) + sizeof(type))), \
+	*(type *)(void *)((char *)(ap) - sizeof(type)) )
+#endif
+
+#define va_arg(ap, type) \
+	( ((ap) = (va_list)((char *)(ap) + __VA_ALIGNED_SIZE(type))), \
+	*(type *)(void *)((char *)(ap) - __VA_ALIGNED_SIZE(type)) )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/stdbool.h b/include/stdbool.h
new file mode 100644
index 00000000..3d8fbf2a
--- /dev/null
+++ b/include/stdbool.h
@@ -0,0 +1,13 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#define true 1
+#define false 0
+
+typedef _Bool bool;
+
+#endif
+
+#endif
diff --git a/include/stddef.h b/include/stddef.h
new file mode 100644
index 00000000..dbf5a4ae
--- /dev/null
+++ b/include/stddef.h
@@ -0,0 +1,19 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_ptrdiff_t
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
+
+#endif
diff --git a/include/stdint.h b/include/stdint.h
new file mode 100644
index 00000000..4d24fd2e
--- /dev/null
+++ b/include/stdint.h
@@ -0,0 +1,107 @@
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+
+#define __NEED_uint8_t
+#define __NEED_uint16_t
+#define __NEED_uint32_t
+#define __NEED_uint64_t
+
+#define __NEED_int_least8_t
+#define __NEED_int_least16_t
+#define __NEED_int_least32_t
+#define __NEED_int_least64_t
+
+#define __NEED_uint_least8_t
+#define __NEED_uint_least16_t
+#define __NEED_uint_least32_t
+#define __NEED_uint_least64_t
+
+#define __NEED_int_fast8_t
+#define __NEED_int_fast16_t
+#define __NEED_int_fast32_t
+#define __NEED_int_fast64_t
+
+#define __NEED_uint_fast8_t
+#define __NEED_uint_fast16_t
+#define __NEED_uint_fast32_t
+#define __NEED_uint_fast64_t
+
+#define __NEED_intptr_t
+#define __NEED_uintptr_t
+#define __NEED_intmax_t
+#define __NEED_uintmax_t
+
+#include <bits/alltypes.h>
+
+#if !defined __cplusplus || defined __STDC_LIMIT_MACROS
+
+#define INT8_MIN   (-1-0x7f)
+#define INT16_MIN  (-1-0x7fff)
+#define INT32_MIN  (-1-0x7fffffff)
+#define INT64_MIN  (-1-0x7fffffffffffffffLL)
+
+#define INT8_MAX   (0x7f)
+#define INT16_MAX  (0x7fff)
+#define INT32_MAX  (0x7fffffff)
+#define INT64_MAX  (0x7fffffffffffffffLL)
+
+#define UINT8_MAX  (0xff)
+#define UINT16_MAX (0xffff)
+#define UINT32_MAX (0xffffffff)
+#define UINT64_MAX (0xffffffffffffffffULL)
+
+#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
+
+#undef WCHAR_MIN
+#undef WCHAR_MAX
+#undef WINT_MIN
+#undef WINT_MAX
+#define WCHAR_MIN INT32_MIN
+#define WCHAR_MAX INT32_MAX
+#define WINT_MIN INT32_MIN
+#define WINT_MAX INT32_MAX
+
+#define INTMAX_MIN  INT64_MIN
+#define INTMAX_MAX  INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#include <bits/stdint.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) c ## LL
+
+#define UINT8_C(c)  c ## U
+#define UINT16_C(c) c ## U
+#define UINT32_C(c) c ## U
+#define UINT64_C(c) c ## ULL
+
+#define INTMAX_C(c)  c ## LL
+#define UINTMAX_C(c) c ## ULL
+
+#endif
+
+#endif
diff --git a/include/stdio.h b/include/stdio.h
new file mode 100644
index 00000000..b00436d9
--- /dev/null
+++ b/include/stdio.h
@@ -0,0 +1,144 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_FILE
+#define __NEED_va_list
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#undef EOF
+#define EOF (-1)
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+#include <bits/stdio.h>
+
+typedef union {
+	char __opaque[16];
+	double __align;
+} fpos_t;
+
+extern FILE *const stdin;
+extern FILE *const stdout;
+extern FILE *const stderr;
+
+#define stdin  (stdin)
+#define stdout (stdout)
+#define stderr (stderr)
+
+FILE *fopen(const char *, const char *);
+FILE *fdopen(int, const char *);
+FILE *freopen(const char *, const char *, FILE *);
+int fclose(FILE *);
+
+FILE *popen(const char *, const char *);
+int pclose(FILE *);
+
+int remove(const char *);
+int rename(const char *, const char *);
+
+int fileno(FILE *);
+int feof(FILE *);
+int ferror(FILE *);
+int fflush(FILE *);
+void clearerr(FILE *);
+
+int fseek(FILE *, long, int);
+int fseeko(FILE *, off_t, int);
+long ftell(FILE *);
+off_t ftello(FILE *);
+void rewind(FILE *);
+
+int fgetpos(FILE *, fpos_t *);
+int fsetpos(FILE *, const fpos_t *);
+
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+
+int fgetc(FILE *);
+int getc(FILE *);
+int getchar(void);
+int ungetc(int, FILE *);
+
+int fputc(int, FILE *);
+int putc(int, FILE *);
+int putchar(int);
+
+char *fgets(char *, int, FILE *);
+char *gets(char *);
+
+int fputs(const char *, FILE *);
+int puts(const char *);
+
+int printf(const char *, ...);
+int fprintf(FILE *, const char *, ...);
+int sprintf(char *, const char *, ...);
+int snprintf(char *, size_t, const char *, ...);
+
+int vprintf(const char *, va_list);
+int vfprintf(FILE *, const char *, va_list);
+int vsprintf(char *, const char *, va_list);
+int vsnprintf(char *, size_t, const char *, va_list);
+
+int dprintf(int, const char *, ...);
+int vdprintf(int, const char *, va_list);
+
+int scanf(const char *, ...);
+int fscanf(FILE *, const char *, ...);
+int sscanf(const char *, const char *, ...);
+int vscanf(const char *, va_list);
+int vfscanf(FILE *, const char *, va_list);
+int vsscanf(const char *, const char *, va_list);
+
+void perror(const char *);
+
+void flockfile(FILE *);
+int ftrylockfile(FILE *);
+void funlockfile(FILE *);
+int getc_unlocked(FILE *);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE *);
+int putchar_unlocked(int);
+
+int setvbuf(FILE *, char *, int, size_t);
+void setbuf(FILE *, char *);
+
+char *tmpnam(char *);
+char *tempnam(const char *, const char *);
+FILE *tmpfile(void);
+
+char *ctermid(char *);
+
+ssize_t getdelim(char **, size_t *, int, FILE *);
+ssize_t getline(char **, size_t *, FILE *);
+
+int renameat(int, const char *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/stdlib.h b/include/stdlib.h
new file mode 100644
index 00000000..6dbbc9cb
--- /dev/null
+++ b/include/stdlib.h
@@ -0,0 +1,129 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi (const char *);
+long atol (const char *);
+long long atoll (const char *);
+double atof (const char *);
+
+float strtof (const char *, char **);
+double strtod (const char *, char **);
+long double strtold (const char *, char **);
+
+long strtol (const char *, char **, int);
+unsigned long strtoul (const char *, char **, int);
+
+long long strtoll (const char *, char **, int);
+unsigned long long strtoull (const char *, char **, int);
+
+char *l64a (long);
+long a64l (const char *);
+
+long int random (void);
+void srandom (unsigned int);
+char *initstate (unsigned int, char *, size_t);
+char *setstate (char *);
+
+int rand (void);
+void srand (unsigned);
+int rand_r (unsigned *);
+
+double drand48 (void);
+double erand48 (unsigned short [3]);
+long int lrand48 (void);
+long int nrand48 (unsigned short [3]);
+long mrand48 (void);
+long jrand48 (unsigned short [3]);
+void srand48 (long);
+unsigned short *seed48 (unsigned short [3]);
+void lcong48 (unsigned short [7]);
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *valloc (size_t);
+int posix_memalign (void **, size_t, size_t);
+
+void abort (void);
+int atexit (void (*) (void));
+void exit (int);
+void _Exit (int);
+
+
+char *getenv (const char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+int unsetenv (const char *);
+
+
+char *mktemp (char *);
+int mkstemp (char *);
+
+int system (const char *);
+
+
+char *realpath (const char *, char *);
+
+void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+
+int abs (int);
+long labs (long);
+long long llabs (long long);
+
+typedef struct { int quot, rem; } div_t;
+extern div_t div (int, int);
+
+typedef struct { long quot, rem; } ldiv_t;
+ldiv_t ldiv (long, long);
+
+typedef struct { long long quot, rem; } lldiv_t;
+lldiv_t lldiv (long long, long long);
+
+
+int mblen (const char *, size_t);
+int mbtowc (wchar_t *, const char *, size_t);
+int wctomb (char *, wchar_t);
+size_t mbstowcs (wchar_t *, const char *, size_t);
+size_t wcstombs (char *, const wchar_t *, size_t);
+
+int getsubopt (char **, char *const *, char **);
+
+void setkey (const char *);
+
+int posix_openpt (int);
+int grantpt (int);
+int unlockpt (int);
+char *ptsname (int);
+
+#define MB_CUR_MAX 4
+
+#define RAND_MAX (0x7fffffff)
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+#include <bits/wexitstatus.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/string.h b/include/string.h
new file mode 100644
index 00000000..f189c082
--- /dev/null
+++ b/include/string.h
@@ -0,0 +1,72 @@
+#ifndef	_STRING_H
+#define	_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+void *memcpy (void *, const void *, size_t);
+void *memmove (void *, const void *, size_t);
+void *memccpy (void *, const void *, int, size_t);
+void *memset (void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memchr (const void *, int, size_t);
+
+char *strcpy (char *, const char *);
+char *strncpy (char *, const char *, size_t);
+
+char *strcat (char *, const char *);
+char *strncat (char *, const char *, size_t);
+
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+
+int strcoll (const char *, const char *);
+size_t strxfrm (char *, const char *, size_t);
+
+char *strdup (const char *);
+
+char *strchr (const char *, int);
+char *strrchr (const char *, int);
+
+size_t strcspn (const char *, const char *);
+size_t strspn (const char *, const char *);
+char *strpbrk (const char *, const char *);
+char *strstr (const char *, const char *);
+
+char *strtok (char *, const char *);
+char *strtok_r (char *, const char *, char **);
+
+size_t strlen (const char *);
+
+char *strerror (int);
+int strerror_r (int, char *, size_t);
+
+size_t strlcat (char *, const char *, size_t);
+size_t strlcpy (char *, const char *, size_t);
+
+char *stpcpy(char *, const char *);
+char *stpncpy(char *, const char *, size_t);
+size_t strnlen (const char *, size_t);
+
+#ifdef _GNU_SOURCE
+int strcasecmp (const char *, const char *);
+int strncasecmp (const char *, const char *, size_t);
+char *strchrnul(const char *, int);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/strings.h b/include/strings.h
new file mode 100644
index 00000000..059e3309
--- /dev/null
+++ b/include/strings.h
@@ -0,0 +1,36 @@
+#ifndef	_STRINGS_H
+#define	_STRINGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+
+int bcmp (const void *, const void *, size_t);
+void bcopy (const void *, void *, size_t);
+void bzero (void *, size_t);
+
+int ffs (int);
+
+char *index (const char *, int);
+char *rindex (const char *, int);
+
+int strcasecmp (const char *, const char *);
+int strncasecmp (const char *, const char *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/stropts.h b/include/stropts.h
new file mode 100644
index 00000000..80776ba6
--- /dev/null
+++ b/include/stropts.h
@@ -0,0 +1,16 @@
+#ifndef _STROPTS_H
+#define _STROPTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// FIXME
+
+int ioctl (int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/sys/epoll.h b/include/sys/epoll.h
new file mode 100644
index 00000000..3530a9ac
--- /dev/null
+++ b/include/sys/epoll.h
@@ -0,0 +1,61 @@
+#ifndef	_SYS_EPOLL_H
+#define	_SYS_EPOLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define EPOLL_CLOEXEC 02000000
+#define EPOLL_NONBLOCK 04000
+
+enum EPOLL_EVENTS { __EPOLL_DUMMY };
+#define EPOLLIN 0x001
+#define EPOLLPRI 0x002
+#define EPOLLOUT 0x004
+#define EPOLLRDNORM 0x040
+#define EPOLLRDBAND 0x080
+#define EPOLLWRNORM 0x100
+#define EPOLLWRBAND 0x200
+#define EPOLLMSG 0x400
+#define EPOLLERR 0x008
+#define EPOLLHUP 0x010
+#define EPOLLRDHUP 0x2000
+#define EPOLLONESHOT (1U<<30)
+#define EPOLLET (1U<<31)
+
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+
+typedef union epoll_data {
+	void *ptr;
+	int fd;
+	uint32_t u32;
+	uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event {
+	uint32_t events;
+	epoll_data_t data;
+} __attribute__ ((__packed__));
+
+
+int epoll_create(int);
+int epoll_create1(int);
+int epoll_ctl(int, int, int, struct epoll_event *);
+int epoll_wait(int, struct epoll_event *, int, int);
+int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sys/epoll.h */
diff --git a/include/sys/file.h b/include/sys/file.h
new file mode 100644
index 00000000..8b2eb01a
--- /dev/null
+++ b/include/sys/file.h
@@ -0,0 +1,21 @@
+#ifndef _SYS_FILE_H
+#define _SYS_FILE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define LOCK_SH	1
+#define LOCK_EX	2
+#define LOCK_NB	4
+#define LOCK_UN	8
+
+extern int flock(int, int);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h
new file mode 100644
index 00000000..d0415b3d
--- /dev/null
+++ b/include/sys/ioctl.h
@@ -0,0 +1,14 @@
+#ifndef	_SYS_IOCTL_H
+#define	_SYS_IOCTL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/ioctl.h>
+
+int ioctl (int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/ipc.h b/include/sys/ipc.h
new file mode 100644
index 00000000..9de9f3e7
--- /dev/null
+++ b/include/sys/ipc.h
@@ -0,0 +1,23 @@
+#ifndef _SYS_IPC_H
+#define _SYS_IPC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_key_t
+
+#include <bits/alltypes.h>
+
+#include <bits/ipc.h>
+
+key_t ftok (const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff --git a/include/sys/kd.h b/include/sys/kd.h
new file mode 100644
index 00000000..793fd59f
--- /dev/null
+++ b/include/sys/kd.h
@@ -0,0 +1,8 @@
+#ifndef _SYS_KD_H
+#define _SYS_KD_H
+
+#define _LINUX_TYPES_H
+#include <linux/kd.h>
+#undef _LINUX_TYPES_H
+
+#endif
diff --git a/include/sys/klog.h b/include/sys/klog.h
new file mode 100644
index 00000000..aa66684e
--- /dev/null
+++ b/include/sys/klog.h
@@ -0,0 +1,14 @@
+#ifndef	_SYS_KLOG_H
+#define	_SYS_KLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int klogctl (int, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/sys/mman.h b/include/sys/mman.h
new file mode 100644
index 00000000..6aede8bd
--- /dev/null
+++ b/include/sys/mman.h
@@ -0,0 +1,37 @@
+#ifndef	_SYS_MMAN_H
+#define	_SYS_MMAN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_mode_t
+#define __NEED_size_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+#include <bits/mman.h>
+
+void *mmap (void *, size_t, int, int, int, off_t);
+int munmap (void *, size_t);
+
+int mprotect (void *, size_t, int);
+int msync (void *, size_t, int);
+
+int posix_madvise (void *, size_t, int);
+
+int mlock (const void *, size_t);
+int munlock (const void *, size_t);
+int mlockall (int);
+int munlockall (void);
+
+/* linux extension */
+void *mremap (void *, size_t, size_t, int, ...);
+
+int shm_open (const char *, int, mode_t);
+int shm_unlink (const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/mount.h b/include/sys/mount.h
new file mode 100644
index 00000000..2c685f67
--- /dev/null
+++ b/include/sys/mount.h
@@ -0,0 +1,28 @@
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#define MS_RDONLY      1
+#define MS_NOSUID      2
+#define MS_NODEV       4
+#define MS_NOEXEC      8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT     32
+#define MS_MANDLOCK    64
+#define S_WRITE        128
+#define S_APPEND       256
+#define S_IMMUTABLE    512
+#define MS_NOATIME     1024
+#define MS_NODIRATIME  2048
+#define MS_BIND        4096
+#define MS_MOVE        8192
+#define MS_SILENT      32768
+
+#define MS_MGC_VAL 0xc0ed0000
+
+#define MNT_FORCE 1
+
+int mount(const char *, const char *, const char *, unsigned long, const void *);
+int umount(const char *);
+int umount2(const char *, int);
+
+#endif
diff --git a/include/sys/msg.h b/include/sys/msg.h
new file mode 100644
index 00000000..9fc42bcd
--- /dev/null
+++ b/include/sys/msg.h
@@ -0,0 +1,36 @@
+#ifndef _SYS_MSG_H
+#define _SYS_MSG_H
+
+#include <sys/ipc.h>
+
+#define __NEED_pid_t
+#define __NEED_key_t
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned long msgqnum_t;
+typedef unsigned long msglen_t;
+
+struct msqid_ds
+{
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msd_lrpid;
+};
+
+#define MSG_NOERROR 010000
+
+int msgctl (int, int, struct msqid_ds *);
+int msgget (key_t, int);
+int msgrcv (int, void *, size_t, long, int);
+int msgsnd (int, const void *, size_t, int);
+
+#endif
diff --git a/include/sys/param.h b/include/sys/param.h
new file mode 100644
index 00000000..ded4a16b
--- /dev/null
+++ b/include/sys/param.h
@@ -0,0 +1,15 @@
+#undef MAXSYMLINKS
+#define MAXSYMLINKS 20
+
+#undef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+
+#undef MAXNAMLEN
+#define MAXNAMLEN NAME_MAX
+
+#undef MAXPATHLEN
+#define MAXPATHLEN PATH_MAX
+
+#include <sys/resource.h>
+#include <endian.h>
+#include <limits.h>
diff --git a/include/sys/poll.h b/include/sys/poll.h
new file mode 100644
index 00000000..779ec774
--- /dev/null
+++ b/include/sys/poll.h
@@ -0,0 +1 @@
+#include <poll.h>
diff --git a/include/sys/prctl.h b/include/sys/prctl.h
new file mode 100644
index 00000000..cd34848a
--- /dev/null
+++ b/include/sys/prctl.h
@@ -0,0 +1,64 @@
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PR_SET_PDEATHSIG  1
+#define PR_GET_PDEATHSIG  2
+#define PR_GET_DUMPABLE   3
+#define PR_SET_DUMPABLE   4
+#define PR_GET_UNALIGN   5
+#define PR_SET_UNALIGN   6
+#define PR_UNALIGN_NOPRINT 1
+#define PR_UNALIGN_SIGBUS 2
+#define PR_GET_KEEPCAPS   7
+#define PR_SET_KEEPCAPS   8
+#define PR_GET_FPEMU  9
+#define PR_SET_FPEMU 10
+#define PR_FPEMU_NOPRINT 1
+#define PR_FPEMU_SIGFPE 2
+#define PR_GET_FPEXC 11
+#define PR_SET_FPEXC 12
+#define PR_FP_EXC_SW_ENABLE 0x80
+#define PR_FP_EXC_DIV  0x010000
+#define PR_FP_EXC_OVF  0x020000
+#define PR_FP_EXC_UND  0x040000
+#define PR_FP_EXC_RES  0x080000
+#define PR_FP_EXC_INV  0x100000
+#define PR_FP_EXC_DISABLED 0
+#define PR_FP_EXC_NONRECOV 1
+#define PR_FP_EXC_ASYNC 2
+#define PR_FP_EXC_PRECISE 3
+#define PR_GET_TIMING   13
+#define PR_SET_TIMING   14
+#define PR_TIMING_STATISTICAL  0
+#define PR_TIMING_TIMESTAMP    1
+#define PR_SET_NAME    15
+#define PR_GET_NAME    16
+#define PR_GET_ENDIAN 19
+#define PR_SET_ENDIAN 20
+#define PR_ENDIAN_BIG
+#define PR_ENDIAN_LITTLE
+#define PR_ENDIAN_PPC_LITTLE
+#define PR_GET_SECCOMP 21
+#define PR_SET_SECCOMP 22
+#define PR_CAPBSET_READ 23
+#define PR_CAPBSET_DROP 24
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+#define PR_TSC_ENABLE 1
+#define PR_TSC_SIGSEGV 2
+#define PR_GET_SECUREBITS 27
+#define PR_SET_SECUREBITS 28
+#define PR_SET_TIMERSLACK 29
+#define PR_GET_TIMERSLACK 30
+
+int prctl (int, ...);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif
diff --git a/include/sys/procfs.h b/include/sys/procfs.h
new file mode 100644
index 00000000..20b4847c
--- /dev/null
+++ b/include/sys/procfs.h
@@ -0,0 +1,81 @@
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+typedef unsigned long elf_greg_t;
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#if __WORDSIZE == 32
+typedef struct user_fpregs_struct elf_fpregset_t;
+typedef struct user_fpxregs_struct elf_fpxregset_t;
+#else
+typedef struct user_fpregs_struct elf_fpregset_t;
+#endif
+
+struct elf_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+};
+
+struct elf_prstatus {
+	struct elf_siginfo pr_info;
+	short int pr_cursig;
+	unsigned long int pr_sigpend;
+	unsigned long int pr_sighold;
+	pid_t pr_pid;
+	pid_t pr_ppid;
+	pid_t pr_pgrp;
+	pid_t pr_sid;
+	struct timeval pr_utime;
+	struct timeval pr_stime;
+	struct timeval pr_cutime;
+	struct timeval pr_cstime;
+	elf_gregset_t pr_reg;
+	int pr_fpvalid;
+};
+
+
+#define ELF_PRARGSZ 80
+
+struct elf_prpsinfo
+	{
+	char pr_state;
+	char pr_sname;
+	char pr_zomb;
+	char pr_nice;
+	unsigned long int pr_flag;
+#if __WORDSIZE == 32
+	unsigned short int pr_uid;
+	unsigned short int pr_gid;
+#else
+	unsigned int pr_uid;
+	unsigned int pr_gid;
+#endif
+	int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	char pr_fname[16];
+	char pr_psargs[ELF_PRARGSZ];
+};
+
+
+typedef void *psaddr_t;
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+typedef pid_t lwpid_t;
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/ptrace.h b/include/sys/ptrace.h
new file mode 100644
index 00000000..0459d1b6
--- /dev/null
+++ b/include/sys/ptrace.h
@@ -0,0 +1,77 @@
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PTRACE_TRACEME 0
+#define PT_TRACE_ME PTRACE_TRACEME
+
+#define PTRACE_PEEKTEXT 1
+#define PTRACE_PEEKDATA 2
+#define PTRACE_PEEKUSER 3
+#define PTRACE_POKETEXT 4
+#define PTRACE_POKEDATA 5
+#define PTRACE_POKEUSER 6
+#define PTRACE_CONT 7
+#define PTRACE_KILL 8
+#define PTRACE_SINGLESTEP 9
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_ATTACH 16
+#define PTRACE_DETACH 17
+#define PTRACE_GETFPXREGS 18
+#define PTRACE_SETFPXREGS 19
+#define PTRACE_SYSCALL 24
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+#define PTRACE_GETSIGINFO 0x4202
+#define PTRACE_SETSIGINFO 0x4203
+
+#define PT_READ_I PTRACE_PEEKTEXT
+#define PT_READ_D PTRACE_PEEKDATA
+#define PT_READ_U PTRACE_PEEKUSER
+#define PT_WRITE_I PTRACE_POKETEXT
+#define PT_WRITE_D PTRACE_POKEDATA
+#define PT_WRITE_U PTRACE_POKEUSER
+#define PT_CONTINUE PTRACE_CONT
+#define PT_KILL PTRACE_KILL
+#define PT_STEP PTRACE_SINGLESTEP
+#define PT_GETREGS PTRACE_GETREGS
+#define PT_SETREGS PTRACE_SETREGS
+#define PT_GETFPREGS PTRACE_GETFPREGS
+#define PT_SETFPREGS PTRACE_SETFPREGS
+#define PT_ATTACH PTRACE_ATTACH
+#define PT_DETACH PTRACE_DETACH
+#define PT_GETFPXREGS PTRACE_GETFPXREGS
+#define PT_SETFPXREGS PTRACE_SETFPXREGS
+#define PT_SYSCALL PTRACE_SYSCALL
+#define PT_SETOPTIONS PTRACE_SETOPTIONS
+#define PT_GETEVENTMSG PTRACE_GETEVENTMSG
+#define PT_GETSIGINFO PTRACE_GETSIGINFO
+#define PT_SETSIGINFO PTRACE_SETSIGINFO
+
+#define PTRACE_O_TRACESYSGOOD   0x00000001
+#define PTRACE_O_TRACEFORK      0x00000002
+#define PTRACE_O_TRACEVFORK     0x00000004
+#define PTRACE_O_TRACECLONE     0x00000008
+#define PTRACE_O_TRACEEXEC      0x00000010
+#define PTRACE_O_TRACEVFORKDONE 0x00000020
+#define PTRACE_O_TRACEEXIT      0x00000040
+#define PTRACE_O_MASK           0x0000007f
+
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+
+long int ptrace(int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/reboot.h b/include/sys/reboot.h
new file mode 100644
index 00000000..26cc3088
--- /dev/null
+++ b/include/sys/reboot.h
@@ -0,0 +1,18 @@
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_AUTOBOOT     0x01234567
+#define RB_HALT_SYSTEM  0xcdef0123
+#define RB_ENABLE_CAD   0x89abcdef
+#define RB_DISABLE_CAD  0
+#define RB_POWER_OFF    0x4321fedc
+
+int reboot(int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/reg.h b/include/sys/reg.h
new file mode 100644
index 00000000..ebf3fff4
--- /dev/null
+++ b/include/sys/reg.h
@@ -0,0 +1,9 @@
+#ifndef _SYS_USER_H
+#define _SYS_USER_H
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/reg.h>
+
+#endif
diff --git a/include/sys/resource.h b/include/sys/resource.h
new file mode 100644
index 00000000..99e383c4
--- /dev/null
+++ b/include/sys/resource.h
@@ -0,0 +1,74 @@
+#ifndef	_SYS_RESOURCE_H
+#define	_SYS_RESOURCE_H
+
+#define __NEED_id_t
+#define __NEED_time_t
+#define __NEED_struct_timeval
+#define __NEED_struct_rusage
+
+#include <bits/alltypes.h>
+
+typedef unsigned long long rlim_t;
+
+struct rlimit
+{
+	rlim_t rlim_cur;
+	rlim_t rlim_max;
+};
+
+struct rusage
+{
+	struct timeval ru_utime;
+	struct timeval ru_stime;
+	/* linux extentions, but useful */
+	long	ru_maxrss;
+	long	ru_ixrss;
+	long	ru_idrss;
+	long	ru_isrss;
+	long	ru_minflt;
+	long	ru_majflt;
+	long	ru_nswap;
+	long	ru_inblock;
+	long	ru_oublock;
+	long	ru_msgsnd;
+	long	ru_msgrcv;
+	long	ru_nsignals;
+	long	ru_nvcsw;
+	long	ru_nivcsw;
+	/* room for more... */
+	long    __reserved[16];
+};
+
+int getrlimit (int, struct rlimit *);
+int setrlimit (int, const struct rlimit *);
+int getrusage (int, struct rusage *);
+
+int getpriority (int, id_t);
+int setpriority (int, id_t, int);
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP    1
+#define PRIO_USER    2
+
+#define RUSAGE_SELF     0
+#define RUSAGE_CHILDREN 1
+
+#define RLIM_INFINITY (~0ULL)
+#define RLIM_SAVED_CUR RLIM_INFINITY
+#define RLIM_SAVED_MAX RLIM_INFINITY
+
+#define RLIMIT_CPU     0
+#define RLIMIT_FSIZE   1
+#define RLIMIT_DATA    2
+#define RLIMIT_STACK   3
+#define RLIMIT_CORE    4
+#define RLIMIT_RSS     5
+#define RLIMIT_NOFILE  7
+#define RLIMIT_AS      9
+#define RLIMIT_NPROC   6
+#define RLIMIT_MEMLOCK 8
+#define RLIMIT_LOCKS   10
+
+
+
+#endif
diff --git a/include/sys/select.h b/include/sys/select.h
new file mode 100644
index 00000000..c44eada4
--- /dev/null
+++ b/include/sys/select.h
@@ -0,0 +1,34 @@
+#ifndef _SYS_SELECT_H
+#define _SYS_SELECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define FD_SETSIZE 1024
+
+typedef struct
+{
+	unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
+} fd_set;
+
+#define FD_ZERO(s) do { int __i; unsigned long *__b=(s)->fds_bits; for(__i=sizeof (fd_set)/sizeof (long); __i; __i--) *__b++=0; } while(0)
+#define FD_SET(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] |= (1<<((d)%(8*sizeof(long)))))
+#define FD_CLR(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] &= ~(1<<((d)%(8*sizeof(long)))))
+#define FD_ISSET(d, s) ((s)->fds_bits[(d)/(8*sizeof(long))] & (1<<((d)%(8*sizeof(long)))))
+
+int select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+int pselect (int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/sem.h b/include/sys/sem.h
new file mode 100644
index 00000000..15d8b685
--- /dev/null
+++ b/include/sys/sem.h
@@ -0,0 +1,69 @@
+#ifndef _SYS_SEM_H
+#define _SYS_SEM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+
+#define SEM_UNDO	0x1000
+#define GETPID		11
+#define GETVAL		12
+#define GETALL		13
+#define GETNCNT		14
+#define GETZCNT		15
+#define SETVAL		16
+#define SETALL		17
+
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	long sem_otime;
+	unsigned long __unused1;
+	long sem_ctime;
+	unsigned long __unused2;
+	unsigned long sem_nsems;
+	unsigned long __unused3;
+	unsigned long __unused4;
+};
+
+#define _SEM_SEMUN_UNDEFINED 1
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct  seminfo {
+	int semmap;
+	int semmni;
+	int semmns;
+	int semmnu;
+	int semmsl;
+	int semopm;
+	int semume;
+	int semusz;
+	int semvmx;
+	int semaem;
+};
+
+struct sembuf {
+	unsigned short sem_num;
+	short sem_op;
+	short sem_flg;
+};
+
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf *, size_t);
+
+#ifdef _GNU_SOURCE
+#define __NEED_struct_timespec
+#include <bits/alltypes.h>
+int semtimedop(int, struct sembuf *, size_t, const struct timespec *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/shm.h b/include/sys/shm.h
new file mode 100644
index 00000000..6ebb9412
--- /dev/null
+++ b/include/sys/shm.h
@@ -0,0 +1,18 @@
+#ifndef _SYS_SHM_H
+#define _SYS_SHM_H
+
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+#include <bits/shm.h>
+
+void *shmat(int, const void *, int);
+int shmctl(int, int, struct shmid_ds *);
+int shmdt(const void *);
+int shmget(key_t, size_t, int);
+
+#endif
diff --git a/include/sys/signalfd.h b/include/sys/signalfd.h
new file mode 100644
index 00000000..895664bf
--- /dev/null
+++ b/include/sys/signalfd.h
@@ -0,0 +1,40 @@
+#ifndef _SYS_SIGNALFD_H
+#define _SYS_SIGNALFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+int signalfd(int, const sigset_t *, int);
+
+struct signalfd_siginfo {
+	uint32_t  ssi_signo;
+	int32_t   ssi_errno;
+	int32_t   ssi_code;
+	uint32_t  ssi_pid;
+	uint32_t  ssi_uid;
+	int32_t   ssi_fd;
+	uint32_t  ssi_tid;
+	uint32_t  ssi_band;
+	uint32_t  ssi_overrun;
+	uint32_t  ssi_trapno;
+	int32_t   ssi_status;
+	int32_t   ssi_int;
+	uintptr_t ssi_ptr;
+	uint64_t  ssi_utime;
+	uint64_t  ssi_stime;
+	uint64_t  ssi_addr;
+	uint8_t   pad[128-12*4-sizeof(void *)-3*8];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/sys/socket.h b/include/sys/socket.h
new file mode 100644
index 00000000..78c93056
--- /dev/null
+++ b/include/sys/socket.h
@@ -0,0 +1,64 @@
+#ifndef	_SYS_SOCKET_H
+#define	_SYS_SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+#include <bits/socket.h>
+
+struct sockaddr
+{
+	sa_family_t sa_family;
+	char sa_data[14];
+};
+
+struct sockaddr_storage
+{
+	sa_family_t ss_family;
+	long long __ss_align;
+	char __ss_padding[128 - sizeof(sa_family_t) - sizeof(long long)];
+};
+
+int socket (int, int, int);
+int socketpair (int, int, int, int [2]);
+
+int shutdown (int, int);
+
+int bind (int, const struct sockaddr *, socklen_t);
+int connect (int, const 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 *);
+
+ssize_t send (int, const void *, size_t, int);
+ssize_t recv (int, void *, size_t, int);
+ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, socklen_t *);
+ssize_t sendmsg (int, const struct msghdr *, int);
+ssize_t recvmsg (int, struct msghdr *, int);
+
+int getsockopt (int, int, int, void *, socklen_t *);
+int setsockopt (int, int, int, const void *, socklen_t);
+
+int sockatmark (int);
+
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/soundcard.h b/include/sys/soundcard.h
new file mode 100644
index 00000000..fade986f
--- /dev/null
+++ b/include/sys/soundcard.h
@@ -0,0 +1 @@
+#include <linux/soundcard.h>
diff --git a/include/sys/stat.h b/include/sys/stat.h
new file mode 100644
index 00000000..36575b0e
--- /dev/null
+++ b/include/sys/stat.h
@@ -0,0 +1,90 @@
+#ifndef	_SYS_STAT_H
+#define	_SYS_STAT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_dev_t
+#define __NEED_ino_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_time_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+
+#include <bits/alltypes.h>
+
+#include <bits/stat.h>
+
+#define S_IFMT  0170000
+
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFBLK 0060000
+#define S_IFREG 0100000
+#define S_IFIFO 0010000
+#define S_IFLNK 0120000
+#define S_IFSOCK 0140000
+
+#define S_TYPEISMQ(buf)  0
+#define S_TYPEISSEM(buf) 0
+#define S_TYPEISSHM(buf) 0
+#define S_TYPEISTMO(buf) 0
+
+#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
+#define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+
+#define S_IREAD  0400
+#define S_IWRITE 0200
+#define S_IEXEC  0100
+
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+
+
+int stat(const char *, struct stat *);
+int fstat(int, struct stat *);
+int lstat(const char *, struct stat *);
+int fstatat(int, const char *, struct stat *, int);
+int chmod(const char *, mode_t);
+int fchmod(int, mode_t);
+int fchmodat(int, const char *, mode_t, int);
+mode_t umask(mode_t);
+int mkdir(const char *, mode_t);
+int mknod(const char *, mode_t, dev_t);
+int mkfifo(const char *, mode_t);
+int mkdirat(int, const char *, mode_t);
+int mknodat(int, const char *, mode_t, dev_t);
+int mkfifoat(int, const char *, mode_t);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff --git a/include/sys/statfs.h b/include/sys/statfs.h
new file mode 100644
index 00000000..7eaa7e7c
--- /dev/null
+++ b/include/sys/statfs.h
@@ -0,0 +1,10 @@
+#ifndef	_SYS_STATFS_H
+#define	_SYS_STATFS_H
+
+#include <sys/statvfs.h>
+
+#define statfs statvfs
+#define fstatfs fstatvfs
+#define f_namelen f_namemax
+
+#endif
diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h
new file mode 100644
index 00000000..6479be6f
--- /dev/null
+++ b/include/sys/statvfs.h
@@ -0,0 +1,30 @@
+#ifndef	_SYS_STATVFS_H
+#define	_SYS_STATVFS_H
+
+
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+#include <bits/alltypes.h>
+
+#include <bits/statfs.h>
+
+int statvfs (const char *, struct statvfs *);
+int fstatvfs (int, struct statvfs *);
+
+#define ST_RDONLY 1
+#define ST_NOSUID 2
+
+#if 0
+#define ST_NODEV  4
+#define ST_NOEXEC 8
+#define ST_SYNCHRONOUS 16
+#define ST_MANDLOCK    64
+#define ST_WRITE       128
+#define ST_APPEND      256
+#define ST_IMMUTABLE   512
+#define ST_NOATIME     1024
+#define ST_NODIRATIME  2048
+#endif
+
+
+#endif
diff --git a/include/sys/stropts.h b/include/sys/stropts.h
new file mode 100644
index 00000000..5b5bc02f
--- /dev/null
+++ b/include/sys/stropts.h
@@ -0,0 +1 @@
+#include <stropts.h>
diff --git a/include/sys/swap.h b/include/sys/swap.h
new file mode 100644
index 00000000..c5824f1d
--- /dev/null
+++ b/include/sys/swap.h
@@ -0,0 +1,11 @@
+#ifndef _SYS_SWAP_H
+#define _SYS_SWAP_H
+
+#define	SWAP_FLAG_PREFER        0x8000
+#define	SWAP_FLAG_PRIO_MASK     0x7fff
+#define	SWAP_FLAG_PRIO_SHIFT    0
+
+int swapon (const char *, int);
+int swapoff (const char *);
+
+#endif
diff --git a/include/sys/sysctl.h b/include/sys/sysctl.h
new file mode 100644
index 00000000..af5ca8ba
--- /dev/null
+++ b/include/sys/sysctl.h
@@ -0,0 +1,9 @@
+#ifndef	_SYS_SYSCTL_H
+#define	_SYS_SYSCTL_H
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+int sysctl (int *, int, void *, size_t *, void *, size_t);
+
+#endif
diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h
new file mode 100644
index 00000000..ca52088a
--- /dev/null
+++ b/include/sys/sysinfo.h
@@ -0,0 +1,29 @@
+#ifndef _SYS_SYSINFO_H
+#define _SYS_SYSINFO_H
+
+/* ?? */
+#define SI_LOAD_SHIFT 16
+
+struct sysinfo {
+	unsigned long long uptime;
+	unsigned long loads[3];
+	unsigned long procs;
+	unsigned long long totalram;
+	unsigned long long freeram;
+	unsigned long long sharedram;
+	unsigned long long bufferram;
+	unsigned long long totalswap;
+	unsigned long long freeswap;
+	unsigned long long totalhigh;
+	unsigned long long freehigh;
+	unsigned long mem_unit;
+	char __reserved[256];
+};
+
+int sysinfo (struct sysinfo *);
+int get_nprocs_conf (void);
+int get_nprocs (void);
+long long get_phys_pages (void);
+long long get_avphys_pages (void);
+
+#endif
diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h
new file mode 100644
index 00000000..79eba3be
--- /dev/null
+++ b/include/sys/sysmacros.h
@@ -0,0 +1,6 @@
+#ifndef _SYSMACROS_H
+#define _SYSMACROS_H
+
+#include <bits/sysmacros.h>
+
+#endif
diff --git a/include/sys/time.h b/include/sys/time.h
new file mode 100644
index 00000000..9b3bfb99
--- /dev/null
+++ b/include/sys/time.h
@@ -0,0 +1,49 @@
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* All symbols from select.h except pselect are required anyway... */
+#include <sys/select.h>
+
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_timeval
+
+#include <bits/alltypes.h>
+
+
+
+int gettimeofday (struct timeval *, void *);
+
+/* extensions */
+int settimeofday (const struct timeval *, void *);
+int adjtime (const struct timeval *, struct timeval *);
+
+
+#define ITIMER_REAL    0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF    2
+
+struct itimerval
+{
+	struct timeval it_interval;
+	struct timeval it_value;
+};
+
+int getitimer (int, struct itimerval *);
+int setitimer (int, const struct itimerval *, struct itimerval *);
+int utimes (const char *, const struct timeval [2]);
+
+#ifdef _GNU_SOURCE
+struct timezone {
+	int tz_minuteswest;
+	int tz_dsttime;
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/times.h b/include/sys/times.h
new file mode 100644
index 00000000..aca743d3
--- /dev/null
+++ b/include/sys/times.h
@@ -0,0 +1,17 @@
+#ifndef	_SYS_TIMES_H
+#define	_SYS_TIMES_H
+
+#define __NEED_clock_t
+#include <bits/alltypes.h>
+
+struct tms
+{
+	clock_t tms_utime;
+	clock_t tms_stime;
+	clock_t tms_cutime;
+	clock_t tms_cstime;
+};
+
+clock_t times (struct tms *);
+
+#endif
diff --git a/include/sys/types.h b/include/sys/types.h
new file mode 100644
index 00000000..8be19e6b
--- /dev/null
+++ b/include/sys/types.h
@@ -0,0 +1,56 @@
+#ifndef	_SYS_TYPES_H
+#define	_SYS_TYPES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_loff_t
+#define __NEED_ino_t
+#define __NEED_dev_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_time_t
+#define __NEED_timer_t
+#define __NEED_clockid_t
+
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+
+#define __NEED_u_int8_t
+#define __NEED_u_int16_t
+#define __NEED_u_int32_t
+#define __NEED_u_int64_t
+
+#define __NEED_register_t
+
+#define __NEED_blkcnt_t
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+
+#define __NEED_id_t
+#define __NEED_key_t
+#define __NEED_clock_t
+#define __NEED_useconds_t
+#define __NEED_suseconds_t
+#define __NEED_blksize_t
+
+#include <bits/alltypes.h>
+
+#ifdef _GNU_SOURCE
+typedef unsigned long caddr_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
diff --git a/include/sys/ucontext.h b/include/sys/ucontext.h
new file mode 100644
index 00000000..5fdbd63d
--- /dev/null
+++ b/include/sys/ucontext.h
@@ -0,0 +1 @@
+#include <ucontext.h>
diff --git a/include/sys/uio.h b/include/sys/uio.h
new file mode 100644
index 00000000..7b068c0c
--- /dev/null
+++ b/include/sys/uio.h
@@ -0,0 +1,14 @@
+#ifndef _SYS_UIO_H
+#define _SYS_UIO_H
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+#include <bits/uio.h>
+
+ssize_t readv (int, const struct iovec *, int);
+ssize_t writev (int, const struct iovec *, int);
+
+#endif
diff --git a/include/sys/un.h b/include/sys/un.h
new file mode 100644
index 00000000..769dac6b
--- /dev/null
+++ b/include/sys/un.h
@@ -0,0 +1,13 @@
+#ifndef	_SYS_UN_H
+#define	_SYS_UN_H
+
+#define __NEED_sa_family_t
+#include <bits/alltypes.h>
+
+struct sockaddr_un
+{
+	sa_family_t sun_family;
+	char sun_path[108];
+};
+
+#endif
diff --git a/include/sys/user.h b/include/sys/user.h
new file mode 100644
index 00000000..24ac9400
--- /dev/null
+++ b/include/sys/user.h
@@ -0,0 +1,15 @@
+#ifndef _SYS_USER_H
+#define _SYS_USER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/user.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/sys/utsname.h b/include/sys/utsname.h
new file mode 100644
index 00000000..383e8251
--- /dev/null
+++ b/include/sys/utsname.h
@@ -0,0 +1,21 @@
+#ifndef	_SYS_UTSNAME_H
+#define	_SYS_UTSNAME_H
+
+struct utsname
+{
+	char sysname[65];
+	char nodename[65];
+	char release[65];
+	char version[65];
+	char machine[65];
+#ifdef _GNU_SOURCE
+	char domainname[65];
+#else
+	char __domainname[65];
+#endif
+};
+
+int uname (struct utsname *);
+
+
+#endif
diff --git a/include/sys/vfs.h b/include/sys/vfs.h
new file mode 100644
index 00000000..a899db27
--- /dev/null
+++ b/include/sys/vfs.h
@@ -0,0 +1 @@
+#include <sys/statfs.h>
diff --git a/include/sys/vt.h b/include/sys/vt.h
new file mode 100644
index 00000000..834abfbc
--- /dev/null
+++ b/include/sys/vt.h
@@ -0,0 +1 @@
+#include <linux/vt.h>
diff --git a/include/sys/wait.h b/include/sys/wait.h
new file mode 100644
index 00000000..a1851530
--- /dev/null
+++ b/include/sys/wait.h
@@ -0,0 +1,28 @@
+#ifndef	_SYS_WAIT_H
+#define	_SYS_WAIT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_pid_t
+#define __NEED_id_t
+#define __NEED_time_t
+#define __NEED_struct_timeval
+#define __NEED_siginfo_t
+#include <bits/alltypes.h>
+
+typedef int idtype_t;
+
+pid_t wait (int *);
+int waitid (idtype_t, id_t, siginfo_t *, int);
+pid_t waitpid (pid_t, int *, int );
+//pid_t wait3 (int *, int, struct rusage *);
+//pid_t wait4 (pid_t, int *, int, struct rusage *);
+
+#include <bits/wait.h>
+#include <bits/wexitstatus.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/syslog.h b/include/syslog.h
new file mode 100644
index 00000000..119c9bcb
--- /dev/null
+++ b/include/syslog.h
@@ -0,0 +1,54 @@
+#ifndef _SYS_SYSLOG_H
+#define _SYS_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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_MASK(p) (1<<(p))
+
+#define LOG_KERN     (0<<3)
+#define LOG_USER     (1<<3)
+#define LOG_MAIL     (2<<3)
+#define LOG_DAEMON   (3<<3)
+#define LOG_AUTH     (4<<3)
+#define LOG_SYSLOG   (5<<3)
+#define LOG_LPR      (6<<3)
+#define LOG_NEWS     (7<<3)
+#define LOG_UUCP     (8<<3)
+#define LOG_CRON     (9<<3)
+
+#define LOG_LOCAL0   (16<<3)
+#define LOG_LOCAL1   (17<<3)
+#define LOG_LOCAL2   (18<<3)
+#define LOG_LOCAL3   (19<<3)
+#define LOG_LOCAL4   (20<<3)
+#define LOG_LOCAL5   (21<<3)
+#define LOG_LOCAL6   (22<<3)
+#define LOG_LOCAL7   (23<<3)
+
+#define LOG_PID    0x01
+#define LOG_CONS   0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+
+void closelog (void);
+void openlog (const char *, int, int);
+int setlogmask (int);
+void syslog (int, const char *, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/tar.h b/include/tar.h
new file mode 100644
index 00000000..be589842
--- /dev/null
+++ b/include/tar.h
@@ -0,0 +1,33 @@
+#ifndef	_TAR_H
+#define	_TAR_H
+
+#define TSUID   04000
+#define TSGID   02000
+#define TSVTX   01000
+#define TUREAD  00400
+#define TUWRITE 00200
+#define TUEXEC  00100
+#define TGREAD  00040
+#define TGWRITE 00020
+#define TGEXEC  00010
+#define TOREAD  00004
+#define TOWRITE 00002
+#define TOEXEC  00001
+
+#define REGTYPE  '0'
+#define AREGTYPE '\0'
+#define LNKTYPE  '1'
+#define SYMTYPE  '2'
+#define CHRTYPE  '3'
+#define BLKTYPE  '4'
+#define DIRTYPE  '5'
+#define FIFOTYPE '6'
+#define CONTTYPE '7'
+
+#define TMAGIC "ustar"
+#define TMAGLEN 6
+
+#define TVERSION "00"
+#define TVERSLEN 2
+
+#endif
diff --git a/include/termios.h b/include/termios.h
new file mode 100644
index 00000000..4c465627
--- /dev/null
+++ b/include/termios.h
@@ -0,0 +1,39 @@
+#ifndef	_TERMIOS_H
+#define	_TERMIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <bits/termios.h>
+
+speed_t cfgetospeed (const struct termios *);
+speed_t cfgetispeed (const struct termios *);
+int cfsetospeed (struct termios *, speed_t);
+int cfsetispeed (struct termios *, speed_t);
+
+int tcgetattr (int, struct termios *);
+int tcsetattr (int, int, const struct termios *);
+
+int tcsendbreak (int, int);
+int tcdrain (int);
+int tcflush (int, int);
+int tcflow (int, int);
+
+pid_t tcgetsid (int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/time.h b/include/time.h
new file mode 100644
index 00000000..e6cfb73d
--- /dev/null
+++ b/include/time.h
@@ -0,0 +1,113 @@
+#ifndef	_TIME_H
+#define _TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_clock_t
+#define __NEED_clockid_t
+#define __NEED_timer_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+
+struct tm
+{
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+	long __tm_gmtoff;
+	const char *__tm_zone;
+};
+
+struct itimerspec
+{
+	struct timespec it_interval;
+	struct timespec it_value;
+};
+
+#define CLOCKS_PER_SEC 1000000UL
+
+#define CLOCK_REALTIME           0
+#define CLOCK_MONOTONIC          1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID  3
+
+#define TIMER_ABSTIME 1
+
+
+
+clock_t clock (void);
+time_t time (time_t *);
+double difftime (time_t, time_t);
+time_t mktime (struct tm *);
+size_t strftime (char *, size_t, const char *, const struct tm *);
+char *strptime (const char *, const char *, struct tm *);
+
+struct tm *gmtime (const time_t *);
+struct tm *gmtime_r (const time_t *, struct tm *);
+struct tm *localtime (const time_t *);
+struct tm *localtime_r (const time_t *, struct tm *);
+
+char *asctime (const struct tm *);
+char *asctime_r (const struct tm *, char *);
+char *ctime (const time_t *);
+char *ctime_r (const time_t *, char *);
+
+
+extern int daylight;
+extern long timezone;
+extern char *tzname[2];
+
+void tzset (void);
+
+
+
+int nanosleep (const struct timespec *, struct timespec *);
+
+
+int clock_getres (clockid_t, struct timespec *);
+int clock_gettime (clockid_t, struct timespec *);
+int clock_settime (clockid_t, const struct timespec *);
+
+int clock_nanosleep (clockid_t, int, const struct timespec *, struct timespec *);
+int clock_getcpuclockid (pid_t, clockid_t *);
+
+/* FIXME */
+struct sigevent;
+int timer_create (clockid_t, struct sigevent *, timer_t *);
+int timer_delete (timer_t);
+
+int timer_settime (timer_t, int, const struct itimerspec *, struct itimerspec *);
+int timer_gettime (timer_t, struct itimerspec *);
+int timer_getoverrun (timer_t);
+
+
+extern int getdate_err;
+extern struct tm *getdate (const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/ucontext.h b/include/ucontext.h
new file mode 100644
index 00000000..db335677
--- /dev/null
+++ b/include/ucontext.h
@@ -0,0 +1,38 @@
+#ifndef _UCONTEXT_H
+#define _UCONTEXT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <signal.h>
+
+struct __fpstate {
+	unsigned long __x[7];
+	unsigned char __y[80];
+	unsigned long __z;
+};
+
+typedef struct {
+	unsigned long __gregs[19];
+	void *__fpregs;
+	unsigned long __oldmask, __cr2;
+} mcontext_t;
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+	struct __fpstate __fpregs_mem;
+} ucontext_t;
+
+int  getcontext(ucontext_t *);
+void makecontext(ucontext_t *, void (*)(void), int, ...);
+int  setcontext(const ucontext_t *);
+int  swapcontext(ucontext_t *, const ucontext_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/ulimit.h b/include/ulimit.h
new file mode 100644
index 00000000..efdcd311
--- /dev/null
+++ b/include/ulimit.h
@@ -0,0 +1,17 @@
+#ifndef _ULIMIT_H
+#define _ULIMIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UL_GETFSIZE 1
+#define UL_SETFSIZE 2
+
+long ulimit (int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/unistd.h b/include/unistd.h
new file mode 100644
index 00000000..5ad0704b
--- /dev/null
+++ b/include/unistd.h
@@ -0,0 +1,464 @@
+#ifndef	_UNISTD_H
+#define	_UNISTD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_useconds_t
+#define __NEED_intptr_t
+
+#include <bits/alltypes.h>
+
+int pipe(int [2]);
+int close(int);
+int dup(int);
+int dup2(int, int);
+off_t lseek(int, off_t, int);
+int fsync(int);
+void sync(void);
+int fdatasync(int);
+
+ssize_t read(int, void *, size_t);
+ssize_t write(int, const void *, size_t);
+ssize_t pread(int, void *, size_t, off_t);
+ssize_t pwrite(int, const void *, size_t, off_t);
+
+#define F_ULOCK 0
+#define F_LOCK  1
+#define F_TLOCK 2
+#define F_TEST  3
+int lockf(int, int, off_t);
+
+int chown(const char *, uid_t, gid_t);
+int fchown(int, uid_t, gid_t);
+int lchown(const char *, uid_t, gid_t);
+int fchownat(int, const char *, uid_t, gid_t, int);
+
+int link(const char *, const char *);
+int linkat(int, const char *, int, const char *, int);
+int symlink(const char *, const char *);
+int symlinkat(const char *, int, const char *);
+int readlink(const char *, char *, size_t);
+int readlinkat(int, const char *, char *, size_t);
+int unlink(const char *);
+int unlinkat(int, const char *, int);
+int rmdir(const char *);
+int truncate(const char *, off_t);
+int ftruncate(int, off_t);
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+int access(const char *, int);
+int faccessat(int, const char *, int, int);
+
+int chdir(const char *);
+int fchdir(int);
+char *getcwd(char *, size_t);
+int chroot(const char *); /* dropped */
+
+unsigned alarm(unsigned);
+useconds_t ualarm(useconds_t, useconds_t);
+unsigned sleep(unsigned);
+int usleep(useconds_t);
+int pause(void);
+int nice(int);
+
+pid_t fork(void);
+pid_t vfork(void);
+int execve(const char *, char *const [], char *const []);
+int execv(const char *, char *const []);
+int execle(const char *, ...);
+int execl(const char *, ...);
+int execvp(const char *, char *const []);
+int execlp(const char *, ...);
+void _exit(int);
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t getpgrp(void);
+pid_t getpgid(pid_t);
+int setpgid(pid_t, pid_t);
+int setpgrp(void);
+pid_t setsid(void);
+pid_t getsid(pid_t);
+char *ttyname(int);
+int ttyname_r(int, char *, size_t);
+int isatty(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+int getgroups(int, gid_t []);
+int setuid(uid_t);
+int setreuid(uid_t, uid_t);
+int seteuid(uid_t);
+int setgid(gid_t);
+int setregid(gid_t, gid_t);
+int setegid(gid_t);
+
+char *getlogin(void);
+int getlogin_r(char *, size_t);
+long gethostid(void);
+int gethostname(char *, size_t);
+int sethostname(const char *, size_t);
+int getpagesize(void);
+char *ctermid(char *);
+
+int vhangup(void); /* dropped */
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+char *crypt(const char *, const char *);
+void encrypt(char *, int);
+
+void swab(const void *, void *, ssize_t);
+
+long pathconf(const char *, int);
+long fpathconf(int, int);
+long sysconf(int);
+size_t confstr(int, char *, size_t);
+
+#define _XOPEN_VERSION          700
+#define _XOPEN_UNIX             1
+#define _XOPEN_ENH_I18N         1
+
+#define _POSIX_VERSION          200809L
+#define _POSIX2_VERSION         _POSIX_VERSION
+
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_IPV6             _POSIX_VERSION
+#define _POSIX_JOB_CONTROL      1
+#define _POSIX_MAPPED_FILES     _POSIX_VERSION
+#define _POSIX_MEMLOCK          _POSIX_VERSION
+#define _POSIX_MEMLOCK_RANGE    _POSIX_VERSION
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION
+#define _POSIX_NO_TRUNC         1
+#define _POSIX_RAW_SOCKETS      _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
+#define _POSIX_REGEXP           1
+#define _POSIX_SAVED_IDS        1
+#define _POSIX_SHELL            1
+#define _POSIX_VDISABLE         0
+
+#define _POSIX_THREADS          _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_TIMERS           _POSIX_VERSION
+#define _POSIX_TIMEOUTS         _POSIX_VERSION
+#define _POSIX_MONOTONIC_CLOCK  _POSIX_VERSION
+#define _POSIX_CPUTIME          _POSIX_VERSION
+#define _POSIX_CLOCK_SELECTION  _POSIX_VERSION
+#define _POSIX_BARRIERS         _POSIX_VERSION
+#define _POSIX_SPIN_LOCKS       _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
+#define _POSIX_ASYNCHRONOUS_IO  _POSIX_VERSION
+#define _POSIX_SEMAPHORES       _POSIX_VERSION
+
+#define _POSIX2_C_BIND          _POSIX_VERSION
+
+#include <bits/posix.h>
+
+
+
+#define _PC_LINK_MAX	0
+#define _PC_MAX_CANON	1
+#define _PC_MAX_INPUT	2
+#define _PC_NAME_MAX	3
+#define _PC_PATH_MAX	4
+#define _PC_PIPE_BUF	5
+#define _PC_CHOWN_RESTRICTED	6
+#define _PC_NO_TRUNC	7
+#define _PC_VDISABLE	8
+#define _PC_SYNC_IO	9
+#define _PC_ASYNC_IO	10
+#define _PC_PRIO_IO	11
+#define _PC_SOCK_MAXBUF	12
+#define _PC_FILESIZEBITS	13
+#define _PC_REC_INCR_XFER_SIZE	14
+#define _PC_REC_MAX_XFER_SIZE	15
+#define _PC_REC_MIN_XFER_SIZE	16
+#define _PC_REC_XFER_ALIGN	17
+#define _PC_ALLOC_SIZE_MIN	18
+#define _PC_SYMLINK_MAX	19
+#define _PC_2_SYMLINKS	20
+
+#define _SC_ARG_MAX	0
+#define _SC_CHILD_MAX	1
+#define _SC_CLK_TCK	2
+#define _SC_NGROUPS_MAX	3
+#define _SC_OPEN_MAX	4
+#define _SC_STREAM_MAX	5
+#define _SC_TZNAME_MAX	6
+#define _SC_JOB_CONTROL	7
+#define _SC_SAVED_IDS	8
+#define _SC_REALTIME_SIGNALS	9
+#define _SC_PRIORITY_SCHEDULING	10
+#define _SC_TIMERS	11
+#define _SC_ASYNCHRONOUS_IO	12
+#define _SC_PRIORITIZED_IO	13
+#define _SC_SYNCHRONIZED_IO	14
+#define _SC_FSYNC	15
+#define _SC_MAPPED_FILES	16
+#define _SC_MEMLOCK	17
+#define _SC_MEMLOCK_RANGE	18
+#define _SC_MEMORY_PROTECTION	19
+#define _SC_MESSAGE_PASSING	20
+#define _SC_SEMAPHORES	21
+#define _SC_SHARED_MEMORY_OBJECTS	22
+#define _SC_AIO_LISTIO_MAX	23
+#define _SC_AIO_MAX	24
+#define _SC_AIO_PRIO_DELTA_MAX	25
+#define _SC_DELAYTIMER_MAX	26
+#define _SC_MQ_OPEN_MAX	27
+#define _SC_MQ_PRIO_MAX	28
+#define _SC_VERSION	29
+#define _SC_PAGE_SIZE	30
+#define _SC_PAGESIZE	30 /* !! */
+#define _SC_RTSIG_MAX	31
+#define _SC_SEM_NSEMS_MAX	32
+#define _SC_SEM_VALUE_MAX	33
+#define _SC_SIGQUEUE_MAX	34
+#define _SC_TIMER_MAX	35
+#define _SC_BC_BASE_MAX	36
+#define _SC_BC_DIM_MAX	37
+#define _SC_BC_SCALE_MAX	38
+#define _SC_BC_STRING_MAX	39
+#define _SC_COLL_WEIGHTS_MAX	40
+#define _SC_EQUIV_CLASS_MAX	41
+#define _SC_EXPR_NEST_MAX	42
+#define _SC_LINE_MAX	43
+#define _SC_RE_DUP_MAX	44
+#define _SC_CHARCLASS_NAME_MAX	45
+#define _SC_2_VERSION	46
+#define _SC_2_C_BIND	47
+#define _SC_2_C_DEV	48
+#define _SC_2_FORT_DEV	49
+#define _SC_2_FORT_RUN	50
+#define _SC_2_SW_DEV	51
+#define _SC_2_LOCALEDEF	52
+#define _SC_PII	53
+#define _SC_PII_XTI	54
+#define _SC_PII_SOCKET	55
+#define _SC_PII_INTERNET	56
+#define _SC_PII_OSI	57
+#define _SC_POLL	58
+#define _SC_SELECT	59
+#define _SC_UIO_MAXIOV	60 /* !! */
+#define _SC_IOV_MAX	60
+#define _SC_PII_INTERNET_STREAM	61
+#define _SC_PII_INTERNET_DGRAM	62
+#define _SC_PII_OSI_COTS	63
+#define _SC_PII_OSI_CLTS	64
+#define _SC_PII_OSI_M	65
+#define _SC_T_IOV_MAX	66
+#define _SC_THREADS	67
+#define _SC_THREAD_SAFE_FUNCTIONS	68
+#define _SC_GETGR_R_SIZE_MAX	69
+#define _SC_GETPW_R_SIZE_MAX	70
+#define _SC_LOGIN_NAME_MAX	71
+#define _SC_TTY_NAME_MAX	72
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS	73
+#define _SC_THREAD_KEYS_MAX	74
+#define _SC_THREAD_STACK_MIN	75
+#define _SC_THREAD_THREADS_MAX	76
+#define _SC_THREAD_ATTR_STACKADDR	77
+#define _SC_THREAD_ATTR_STACKSIZE	78
+#define _SC_THREAD_PRIORITY_SCHEDULING	79
+#define _SC_THREAD_PRIO_INHERIT	80
+#define _SC_THREAD_PRIO_PROTECT	81
+#define _SC_THREAD_PROCESS_SHARED	82
+#define _SC_NPROCESSORS_CONF	83
+#define _SC_NPROCESSORS_ONLN	84
+#define _SC_PHYS_PAGES	85
+#define _SC_AVPHYS_PAGES	86
+#define _SC_ATEXIT_MAX	87
+#define _SC_PASS_MAX	88
+#define _SC_XOPEN_VERSION	89
+#define _SC_XOPEN_XCU_VERSION	90
+#define _SC_XOPEN_UNIX	91
+#define _SC_XOPEN_CRYPT	92
+#define _SC_XOPEN_ENH_I18N	93
+#define _SC_XOPEN_SHM	94
+#define _SC_2_CHAR_TERM	95
+#define _SC_2_C_VERSION	96
+#define _SC_2_UPE	97
+#define _SC_XOPEN_XPG2	98
+#define _SC_XOPEN_XPG3	99
+#define _SC_XOPEN_XPG4	100
+#define _SC_CHAR_BIT	101
+#define _SC_CHAR_MAX	102
+#define _SC_CHAR_MIN	103
+#define _SC_INT_MAX	104
+#define _SC_INT_MIN	105
+#define _SC_LONG_BIT	106
+#define _SC_WORD_BIT	107
+#define _SC_MB_LEN_MAX	108
+#define _SC_NZERO	109
+#define _SC_SSIZE_MAX	110
+#define _SC_SCHAR_MAX	111
+#define _SC_SCHAR_MIN	112
+#define _SC_SHRT_MAX	113
+#define _SC_SHRT_MIN	114
+#define _SC_UCHAR_MAX	115
+#define _SC_UINT_MAX	116
+#define _SC_ULONG_MAX	117
+#define _SC_USHRT_MAX	118
+#define _SC_NL_ARGMAX	119
+#define _SC_NL_LANGMAX	120
+#define _SC_NL_MSGMAX	121
+#define _SC_NL_NMAX	122
+#define _SC_NL_SETMAX	123
+#define _SC_NL_TEXTMAX	124
+#define _SC_XBS5_ILP32_OFF32	125
+#define _SC_XBS5_ILP32_OFFBIG	126
+#define _SC_XBS5_LP64_OFF64	127
+#define _SC_XBS5_LPBIG_OFFBIG	128
+#define _SC_XOPEN_LEGACY	129
+#define _SC_XOPEN_REALTIME	130
+#define _SC_XOPEN_REALTIME_THREADS	131
+#define _SC_ADVISORY_INFO	132
+#define _SC_BARRIERS	133
+#define _SC_BASE	134
+#define _SC_C_LANG_SUPPORT	135
+#define _SC_C_LANG_SUPPORT_R	136
+#define _SC_CLOCK_SELECTION	137
+#define _SC_CPUTIME	138
+#define _SC_THREAD_CPUTIME	139
+#define _SC_DEVICE_IO	140
+#define _SC_DEVICE_SPECIFIC	141
+#define _SC_DEVICE_SPECIFIC_R	142
+#define _SC_FD_MGMT	143
+#define _SC_FIFO	144
+#define _SC_PIPE	145
+#define _SC_FILE_ATTRIBUTES	146
+#define _SC_FILE_LOCKING	147
+#define _SC_FILE_SYSTEM	148
+#define _SC_MONOTONIC_CLOCK	149
+#define _SC_MULTI_PROCESS	150
+#define _SC_SINGLE_PROCESS	151
+#define _SC_NETWORKING	152
+#define _SC_READER_WRITER_LOCKS	153
+#define _SC_SPIN_LOCKS	154
+#define _SC_REGEXP	155
+#define _SC_REGEX_VERSION	156
+#define _SC_SHELL	157
+#define _SC_SIGNALS	158
+#define _SC_SPAWN	159
+#define _SC_SPORADIC_SERVER	160
+#define _SC_THREAD_SPORADIC_SERVER	161
+#define _SC_SYSTEM_DATABASE	162
+#define _SC_SYSTEM_DATABASE_R	163
+#define _SC_TIMEOUTS	164
+#define _SC_TYPED_MEMORY_OBJECTS	165
+#define _SC_USER_GROUPS	166
+#define _SC_USER_GROUPS_R	167
+#define _SC_2_PBS	168
+#define _SC_2_PBS_ACCOUNTING	169
+#define _SC_2_PBS_LOCATE	170
+#define _SC_2_PBS_MESSAGE	171
+#define _SC_2_PBS_TRACK	172
+#define _SC_SYMLOOP_MAX	173
+#define _SC_STREAMS	174
+#define _SC_2_PBS_CHECKPOINT	175
+#define _SC_V6_ILP32_OFF32	176
+#define _SC_V6_ILP32_OFFBIG	177
+#define _SC_V6_LP64_OFF64	178
+#define _SC_V6_LPBIG_OFFBIG	179
+#define _SC_HOST_NAME_MAX	180
+#define _SC_TRACE	181
+#define _SC_TRACE_EVENT_FILTER	182
+#define _SC_TRACE_INHERIT	183
+#define _SC_TRACE_LOG	184
+
+#define _SC_IPV6	235
+#define _SC_RAW_SOCKETS	236
+#define _SC_V7_ILP32_OFF32	237
+#define _SC_V7_ILP32_OFFBIG	238
+#define _SC_V7_LP64_OFF64	239
+#define _SC_V7_LPBIG_OFFBIG	240
+#define _SC_SS_REPL_MAX	241
+#define _SC_TRACE_EVENT_NAME_MAX	242
+#define _SC_TRACE_NAME_MAX	243
+#define _SC_TRACE_SYS_MAX	244
+#define _SC_TRACE_USER_EVENT_MAX	245
+#define _SC_XOPEN_STREAMS	246
+#define _SC_THREAD_ROBUST_PRIO_INHERIT	247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT	248
+
+#define _CS_PATH	0
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS	1
+#define _CS_GNU_LIBC_VERSION	2
+#define _CS_GNU_LIBPTHREAD_VERSION	3
+#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS	4
+#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS	5
+
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS	1116
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS	1117
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS	1118
+#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS	1119
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS	1120
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS	1121
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS	1122
+#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS	1123
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS	1124
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS	1125
+#define _CS_POSIX_V6_LP64_OFF64_LIBS	1126
+#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS	1127
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS	1128
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS	1129
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS	1130
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS	1131
+#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS	1132
+#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS	1133
+#define _CS_POSIX_V7_ILP32_OFF32_LIBS	1134
+#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS	1135
+#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS	1136
+#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS	1137
+#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS	1138
+#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS	1139
+#define _CS_POSIX_V7_LP64_OFF64_CFLAGS	1140
+#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS	1141
+#define _CS_POSIX_V7_LP64_OFF64_LIBS	1142
+#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS	1143
+#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS	1144
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS	1145
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS	1146
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS	1147
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/utime.h b/include/utime.h
new file mode 100644
index 00000000..ec82e0f3
--- /dev/null
+++ b/include/utime.h
@@ -0,0 +1,24 @@
+#ifndef	_UTIME_H
+#define	_UTIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct utimbuf
+{
+	time_t actime;
+	time_t modtime;
+};
+
+int utime (const char *, const struct utimbuf *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/utmp.h b/include/utmp.h
new file mode 100644
index 00000000..f60ff883
--- /dev/null
+++ b/include/utmp.h
@@ -0,0 +1,23 @@
+#ifndef _UTMP_H
+#define _UTMP_H
+
+#include <utmpx.h>
+
+#define ut_time ut_tv.tv_sec
+#define ut_name ut_user
+#define ut_exit __ut_exit
+#define e_termination __e_termination
+#define e_exit __e_exit
+#define utmp utmpx
+#define endutent endutxent
+#define getutent getutxent
+#define setutent setutxent
+#define getutid getutxid
+#define getutline getutxline
+#define pututline pututxline
+#define utmpname(x) (-1)
+
+#define _PATH_UTMP "/dev/null"
+#define _PATH_WTMP "/dev/null"
+
+#endif
diff --git a/include/utmpx.h b/include/utmpx.h
new file mode 100644
index 00000000..9a2e3075
--- /dev/null
+++ b/include/utmpx.h
@@ -0,0 +1,52 @@
+#ifndef _UTMPX_H
+#define _UTMPX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_pid_t
+#define __NEED_time_t
+#define __NEED_struct_timeval
+
+#include <bits/alltypes.h>
+
+struct utmpx
+{
+	short ut_type;
+	pid_t ut_pid;
+	char ut_line[32];
+	char ut_id[4];
+	char ut_user[32];
+	char ut_host[256];
+	struct {
+		short __e_termination;
+		short __e_exit;
+	} __ut_exit;
+	long ut_session;
+	struct timeval ut_tv;
+	unsigned ut_addr_v6[4];
+	char __unused[20];
+};
+
+void          endutxent(void);
+struct utmpx *getutxent(void);
+struct utmpx *getutxid(const struct utmpx *);
+struct utmpx *getutxline(const struct utmpx *);
+struct utmpx *pututxline(const struct utmpx *);
+void          setutxent(void);
+
+#define EMPTY           0
+#define BOOT_TIME       2
+#define NEW_TIME        3
+#define OLD_TIME        4
+#define INIT_PROCESS    5
+#define LOGIN_PROCESS   6
+#define USER_PROCESS    7
+#define DEAD_PROCESS    8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/wchar.h b/include/wchar.h
new file mode 100644
index 00000000..3f325bff
--- /dev/null
+++ b/include/wchar.h
@@ -0,0 +1,152 @@
+#ifndef _WCHAR_H
+#define _WCHAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_FILE
+#define __NEED_va_list
+#define __NEED_size_t
+#define __NEED_wchar_t
+#define __NEED_wint_t
+#define __NEED_wctype_t
+
+#include <bits/alltypes.h>
+
+#undef NULL
+#define NULL ((void*)0)
+
+#undef WCHAR_MIN
+#undef WCHAR_MAX
+#define WCHAR_MIN (-1-0x7fffffff)
+#define WCHAR_MAX (0x7fffffff)
+
+#undef WEOF
+#define WEOF (-1)
+
+
+typedef struct
+{
+	unsigned __opaque1, __opaque2;
+} mbstate_t;
+
+wchar_t *wcscpy (wchar_t *, const wchar_t *);
+wchar_t *wcsncpy (wchar_t *, const wchar_t *, size_t);
+
+wchar_t *wcscat (wchar_t *, const wchar_t *);
+wchar_t *wcsncat (wchar_t *, const wchar_t *, size_t);
+
+int wcscmp (const wchar_t *, const wchar_t *);
+int wcsncmp (const wchar_t *, const wchar_t *, size_t);
+
+size_t wcsxfrm (wchar_t *, const wchar_t *, size_t n);
+
+wchar_t *wcschr (const wchar_t *, wchar_t);
+wchar_t *wcsrchr (const wchar_t *, wchar_t);
+
+size_t wcscspn (const wchar_t *, const wchar_t *);
+size_t wcsspn (const wchar_t *, const wchar_t *);
+wchar_t *wcspbrk (const wchar_t *, const wchar_t *);
+
+wchar_t *wcstok (wchar_t *, const wchar_t *, wchar_t **);
+
+size_t wcslen (const wchar_t *);
+
+wchar_t *wcsstr (const wchar_t *, const wchar_t *);
+wchar_t *wcswcs (const wchar_t *, const wchar_t *);
+
+wchar_t *wmemchr (const wchar_t *, wchar_t, size_t);
+int wmemcmp (const wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemcpy (wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemmove (wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemset (wchar_t *, wchar_t, size_t);
+
+wint_t btowc (int);
+int wctob (wint_t);
+
+int mbsinit (const mbstate_t *);
+size_t mbrtowc (wchar_t *, const char *, size_t, mbstate_t *);
+size_t wcrtomb (char *, wchar_t, mbstate_t *);
+
+size_t mbrlen (const char *, size_t, mbstate_t *);
+
+size_t mbsrtowcs (wchar_t *, const char **, size_t, mbstate_t *);
+size_t wcsrtombs (char *, const wchar_t **, size_t, mbstate_t *);
+
+int wcwidth (wchar_t);
+int wcswidth (const wchar_t *, size_t);
+
+float wcstof (const wchar_t *, wchar_t **);
+double wcstod (const wchar_t *, wchar_t **);
+long double wcstold (const wchar_t *, wchar_t **);
+
+long wcstol (const wchar_t *, wchar_t **, int);
+unsigned long wcstoul (const wchar_t *, wchar_t **, int);
+
+long long wcstoll (const wchar_t *, wchar_t **, int);
+unsigned long long wcstoull (const wchar_t *, wchar_t **, int);
+
+
+
+int fwide (FILE *, int);
+
+
+int wprintf (const wchar_t *, ...);
+int fwprintf (FILE *, const wchar_t *, ...);
+int swprintf (wchar_t *, const wchar_t *, ...);
+
+int vwprintf (const wchar_t *, va_list);
+int vfwprintf (FILE *, const wchar_t *, va_list);
+int vswprintf (wchar_t *, const wchar_t *, va_list);
+
+int wscanf (const wchar_t *, ...);
+int fwscanf (FILE *, const wchar_t *, ...);
+int swscanf (const wchar_t *, const wchar_t *, ...);
+
+int vwscanf (const wchar_t *, va_list);
+int vfwscanf (FILE *, const wchar_t *, va_list);
+int vswscanf (const wchar_t *, const wchar_t *, va_list);
+
+wint_t fgetwc (FILE *);
+wint_t getwc (FILE *);
+wint_t getwchar (void);
+
+wint_t fputwc (wchar_t, FILE *);
+wint_t putwc (wchar_t, FILE *);
+wint_t putwchar (wchar_t);
+
+wchar_t *fgetws (wchar_t *, int, FILE *);
+int fputws (const wchar_t *, FILE *);
+
+wint_t ungetwc (wint_t, FILE *);
+
+struct tm;
+size_t wcsftime (wchar_t *, size_t, const wchar_t *, const struct tm *);
+
+#undef iswdigit
+
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctype_t  wctype(const char *);
+
+#define iswdigit(a) ((unsigned)(a)-'0' < 10)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/wctype.h b/include/wctype.h
new file mode 100644
index 00000000..8b6c9d9d
--- /dev/null
+++ b/include/wctype.h
@@ -0,0 +1,44 @@
+#ifndef _WCTYPE_H
+#define _WCTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_wint_t
+#define __NEED_wctrans_t
+#define __NEED_wctype_t
+
+#include <bits/alltypes.h>
+
+#undef WEOF
+#define WEOF (-1)
+
+#undef iswdigit
+
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towctrans(wint_t, wctrans_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctrans_t wctrans(const char *);
+wctype_t  wctype(const char *);
+
+#define iswdigit(a) ((unsigned)((a)-L'0') < 10)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/wordexp.h b/include/wordexp.h
new file mode 100644
index 00000000..91995c44
--- /dev/null
+++ b/include/wordexp.h
@@ -0,0 +1,40 @@
+#ifndef	_WORDEXP_H
+#define	_WORDEXP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define WRDE_DOOFFS  1
+#define WRDE_APPEND  2
+#define WRDE_NOCMD   4
+#define WRDE_REUSE   8
+#define WRDE_SHOWERR 16
+#define WRDE_UNDEF   32
+
+typedef struct
+{
+	size_t we_wordc;
+	char **wc_wordv;
+	size_t we_offs;
+} wordexp_t;
+
+#define WRDE_NOSYS   -1
+#define WRDE_NOSPACE 1
+#define WRDE_BADCHAR 2
+#define WRDE_BADVAL  3
+#define WRDE_CMDSUB  4
+#define WRDE_SYNTAX  5
+
+int wordexp (const char *, wordexp_t *, int);
+void wordfree (wordexp_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
new file mode 100644
index 00000000..af7e4d3b
--- /dev/null
+++ b/src/conf/fpathconf.c
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+long fpathconf(int fd, int name)
+{
+	static const short values[] = {
+		[_PC_LINK_MAX] = _POSIX_LINK_MAX,
+		[_PC_MAX_CANON] = _POSIX_MAX_CANON,
+		[_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
+		[_PC_NAME_MAX] = NAME_MAX,
+		[_PC_PATH_MAX] = PATH_MAX,
+		[_PC_PIPE_BUF] = PIPE_BUF,
+		[_PC_CHOWN_RESTRICTED] = 1,
+		[_PC_NO_TRUNC] = 1,
+		[_PC_VDISABLE] = 0,
+		[_PC_SYNC_IO] = 0,
+		[_PC_ASYNC_IO] = 0,
+		[_PC_PRIO_IO] = 0,
+		[_PC_SOCK_MAXBUF] = -1,
+		[_PC_FILESIZEBITS] = sizeof(off_t),
+		[_PC_REC_INCR_XFER_SIZE] = PAGE_SIZE,
+		[_PC_REC_MAX_XFER_SIZE] = PAGE_SIZE,
+		[_PC_REC_MIN_XFER_SIZE] = PAGE_SIZE,
+		[_PC_REC_XFER_ALIGN] = PAGE_SIZE,
+		[_PC_ALLOC_SIZE_MIN] = PAGE_SIZE,
+		[_PC_SYMLINK_MAX] = SYMLINK_MAX,
+		[_PC_2_SYMLINKS] = 1
+	};
+	if (name > sizeof(values)/sizeof(values[0])) {
+		errno = EINVAL;
+		return -1;
+	}
+	return values[name];
+}
diff --git a/src/conf/pathconf.c b/src/conf/pathconf.c
new file mode 100644
index 00000000..01e19c59
--- /dev/null
+++ b/src/conf/pathconf.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+long pathconf(const char *path, int name)
+{
+	return fpathconf(-1, name);
+}
diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
new file mode 100644
index 00000000..cdaeb2a6
--- /dev/null
+++ b/src/conf/sysconf.c
@@ -0,0 +1,222 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+#define VER (-2)
+#define OFLOW (-3)
+
+long sysconf(int name)
+{
+	static const short values[] = {
+		[_SC_ARG_MAX] = OFLOW,
+		[_SC_CHILD_MAX] = -1,
+		[_SC_CLK_TCK] = 100,
+		[_SC_NGROUPS_MAX] = 32,
+		[_SC_OPEN_MAX] = 1024,
+		[_SC_STREAM_MAX] = -1,
+		[_SC_TZNAME_MAX] = TZNAME_MAX,
+		[_SC_JOB_CONTROL] = 1,
+		[_SC_SAVED_IDS] = 1,
+		[_SC_REALTIME_SIGNALS] = 1,
+		[_SC_PRIORITY_SCHEDULING] = -1,
+		[_SC_TIMERS] = VER,
+		[_SC_ASYNCHRONOUS_IO] = VER,
+		[_SC_PRIORITIZED_IO] = -1,
+		[_SC_SYNCHRONIZED_IO] = -1,
+		[_SC_FSYNC] = -1,
+		[_SC_MAPPED_FILES] = VER,
+		[_SC_MEMLOCK] = VER,
+		[_SC_MEMLOCK_RANGE] = VER,
+		[_SC_MEMORY_PROTECTION] = VER,
+		[_SC_MESSAGE_PASSING] = -1,
+		[_SC_SEMAPHORES] = VER,
+		[_SC_SHARED_MEMORY_OBJECTS] = -1,
+		[_SC_AIO_LISTIO_MAX] = -1,
+		[_SC_AIO_MAX] = -1,
+		[_SC_AIO_PRIO_DELTA_MAX] = 0, /* ?? */
+		[_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX,
+		[_SC_MQ_OPEN_MAX] = -1,
+		[_SC_MQ_PRIO_MAX] = _POSIX_MQ_PRIO_MAX,
+		[_SC_VERSION] = VER,
+		[_SC_PAGE_SIZE] = PAGE_SIZE,
+		[_SC_RTSIG_MAX] = 63, /* ?? */
+		[_SC_SEM_NSEMS_MAX] = _POSIX_SEM_NSEMS_MAX,
+		[_SC_SEM_VALUE_MAX] = _POSIX_SEM_VALUE_MAX,
+		[_SC_SIGQUEUE_MAX] = -1,
+		[_SC_TIMER_MAX] = -1,
+		[_SC_BC_BASE_MAX] = _POSIX2_BC_BASE_MAX,
+		[_SC_BC_DIM_MAX] = _POSIX2_BC_DIM_MAX,
+		[_SC_BC_SCALE_MAX] = _POSIX2_BC_SCALE_MAX,
+		[_SC_BC_STRING_MAX] = _POSIX2_BC_STRING_MAX,
+		[_SC_COLL_WEIGHTS_MAX] = COLL_WEIGHTS_MAX,
+		[_SC_EQUIV_CLASS_MAX] = -1, /* ?? */
+		[_SC_EXPR_NEST_MAX] = -1,
+		[_SC_LINE_MAX] = -1,
+		[_SC_RE_DUP_MAX] = RE_DUP_MAX,
+		[_SC_CHARCLASS_NAME_MAX] = -1, /* ?? */
+		[_SC_2_VERSION] = VER,
+		[_SC_2_C_BIND] = VER,
+		[_SC_2_C_DEV] = -1,
+		[_SC_2_FORT_DEV] = -1,
+		[_SC_2_FORT_RUN] = -1,
+		[_SC_2_SW_DEV] = -1,
+		[_SC_2_LOCALEDEF] = -1,
+		[_SC_PII] = -1, /* ????????? */
+		[_SC_PII_XTI] = -1,
+		[_SC_PII_SOCKET] = -1,
+		[_SC_PII_INTERNET] = -1,
+		[_SC_PII_OSI] = -1,
+		[_SC_POLL] = 1,
+		[_SC_SELECT] = 1,
+		[_SC_IOV_MAX] = IOV_MAX,
+		[_SC_PII_INTERNET_STREAM] = -1,
+		[_SC_PII_INTERNET_DGRAM] = -1,
+		[_SC_PII_OSI_COTS] = -1,
+		[_SC_PII_OSI_CLTS] = -1,
+		[_SC_PII_OSI_M] = -1,
+		[_SC_T_IOV_MAX] = -1,
+		[_SC_THREADS] = VER,
+		[_SC_THREAD_SAFE_FUNCTIONS] = VER,
+		[_SC_GETGR_R_SIZE_MAX] = -1,
+		[_SC_GETPW_R_SIZE_MAX] = -1,
+		[_SC_LOGIN_NAME_MAX] = 256,
+		[_SC_TTY_NAME_MAX] = TTY_NAME_MAX,
+		[_SC_THREAD_DESTRUCTOR_ITERATIONS] = _POSIX_THREAD_DESTRUCTOR_ITERATIONS,
+		[_SC_THREAD_KEYS_MAX] = -1,
+		[_SC_THREAD_STACK_MIN] = 2*PAGE_SIZE,
+		[_SC_THREAD_THREADS_MAX] = -1,
+		[_SC_THREAD_ATTR_STACKADDR] = -1,
+		[_SC_THREAD_ATTR_STACKSIZE] = VER,
+		[_SC_THREAD_PRIORITY_SCHEDULING] = -1,
+		[_SC_THREAD_PRIO_INHERIT] = -1,
+		[_SC_THREAD_PRIO_PROTECT] = -1,
+		[_SC_THREAD_PROCESS_SHARED] = VER,
+		[_SC_NPROCESSORS_CONF] = -1,
+		[_SC_NPROCESSORS_ONLN] = -1,
+		[_SC_PHYS_PAGES] = -1,
+		[_SC_AVPHYS_PAGES] = -1,
+		[_SC_ATEXIT_MAX] = -1,
+		[_SC_PASS_MAX] = -1,
+		[_SC_XOPEN_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_XCU_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_UNIX] = -1,
+		[_SC_XOPEN_CRYPT] = -1,
+		[_SC_XOPEN_ENH_I18N] = 1,
+		[_SC_XOPEN_SHM] = 1,
+		[_SC_2_CHAR_TERM] = -1,
+		[_SC_2_C_VERSION] = -1,
+		[_SC_2_UPE] = -1,
+		[_SC_XOPEN_XPG2] = -1,
+		[_SC_XOPEN_XPG3] = -1,
+		[_SC_XOPEN_XPG4] = -1,
+		[_SC_CHAR_BIT] = -1,
+		[_SC_CHAR_MAX] = -1,
+		[_SC_CHAR_MIN] = -1,
+		[_SC_INT_MAX] = -1,
+		[_SC_INT_MIN] = -1,
+		[_SC_LONG_BIT] = -1,
+		[_SC_WORD_BIT] = -1,
+		[_SC_MB_LEN_MAX] = -1,
+		[_SC_NZERO] = NZERO,
+		[_SC_SSIZE_MAX] = -1,
+		[_SC_SCHAR_MAX] = -1,
+		[_SC_SCHAR_MIN] = -1,
+		[_SC_SHRT_MAX] = -1,
+		[_SC_SHRT_MIN] = -1,
+		[_SC_UCHAR_MAX] = -1,
+		[_SC_UINT_MAX] = -1,
+		[_SC_ULONG_MAX] = -1,
+		[_SC_USHRT_MAX] = -1,
+		[_SC_NL_ARGMAX] = -1,
+		[_SC_NL_LANGMAX] = -1,
+		[_SC_NL_MSGMAX] = -1,
+		[_SC_NL_NMAX] = -1,
+		[_SC_NL_SETMAX] = -1,
+		[_SC_NL_TEXTMAX] = -1,
+		[_SC_XBS5_ILP32_OFF32] = -1,
+		[_SC_XBS5_ILP32_OFFBIG] = 2*(sizeof(long)==4)-1,
+		[_SC_XBS5_LP64_OFF64] = 2*(sizeof(long)==8)-1,
+		[_SC_XBS5_LPBIG_OFFBIG] = 2*(sizeof(long)>=8)-1,
+		[_SC_XOPEN_LEGACY] = -1,
+		[_SC_XOPEN_REALTIME] = -1,
+		[_SC_XOPEN_REALTIME_THREADS] = -1,
+		[_SC_ADVISORY_INFO] = -1,
+		[_SC_BARRIERS] = VER,
+		[_SC_BASE] = -1,
+		[_SC_C_LANG_SUPPORT] = -1,
+		[_SC_C_LANG_SUPPORT_R] = -1,
+		[_SC_CLOCK_SELECTION] = VER,
+		[_SC_CPUTIME] = VER,
+		[_SC_THREAD_CPUTIME] = -1,
+		[_SC_DEVICE_IO] = -1,
+		[_SC_DEVICE_SPECIFIC] = -1,
+		[_SC_DEVICE_SPECIFIC_R] = -1,
+		[_SC_FD_MGMT] = -1,
+		[_SC_FIFO] = -1,
+		[_SC_PIPE] = -1,
+		[_SC_FILE_ATTRIBUTES] = -1,
+		[_SC_FILE_LOCKING] = -1,
+		[_SC_FILE_SYSTEM] = -1,
+		[_SC_MONOTONIC_CLOCK] = VER,
+		[_SC_MULTI_PROCESS] = -1,
+		[_SC_SINGLE_PROCESS] = -1,
+		[_SC_NETWORKING] = -1,
+		[_SC_READER_WRITER_LOCKS] = VER,
+		[_SC_SPIN_LOCKS] = VER,
+		[_SC_REGEXP] = 1,
+		[_SC_REGEX_VERSION] = -1,
+		[_SC_SHELL] = 1,
+		[_SC_SIGNALS] = -1,
+		[_SC_SPAWN] = -1,
+		[_SC_SPORADIC_SERVER] = -1,
+		[_SC_THREAD_SPORADIC_SERVER] = -1,
+		[_SC_SYSTEM_DATABASE] = -1,
+		[_SC_SYSTEM_DATABASE_R] = -1,
+		[_SC_TIMEOUTS] = VER,
+		[_SC_TYPED_MEMORY_OBJECTS] = -1,
+		[_SC_USER_GROUPS] = -1,
+		[_SC_USER_GROUPS_R] = -1,
+		[_SC_2_PBS] = -1,
+		[_SC_2_PBS_ACCOUNTING] = -1,
+		[_SC_2_PBS_LOCATE] = -1,
+		[_SC_2_PBS_MESSAGE] = -1,
+		[_SC_2_PBS_TRACK] = -1,
+		[_SC_SYMLOOP_MAX] = SYMLOOP_MAX,
+		[_SC_STREAMS] = 0,
+		[_SC_2_PBS_CHECKPOINT] = -1,
+		[_SC_V6_ILP32_OFF32] = -1,
+		[_SC_V6_ILP32_OFFBIG] = 2*(sizeof(long)==4)-1,
+		[_SC_V6_LP64_OFF64] = 2*(sizeof(long)==8)-1,
+		[_SC_V6_LPBIG_OFFBIG] = 2*(sizeof(long)>=8)-1,
+		[_SC_HOST_NAME_MAX] = HOST_NAME_MAX,
+		[_SC_TRACE] = -1,
+		[_SC_TRACE_EVENT_FILTER] = -1,
+		[_SC_TRACE_INHERIT] = -1,
+		[_SC_TRACE_LOG] = -1,
+
+		[_SC_IPV6] = VER,
+		[_SC_RAW_SOCKETS] = VER,
+		[_SC_V7_ILP32_OFF32] = -1,
+		[_SC_V7_ILP32_OFFBIG] = 2*(sizeof(long)==4)-1,
+		[_SC_V7_LP64_OFF64] = 2*(sizeof(long)==8)-1,
+		[_SC_V7_LPBIG_OFFBIG] = 2*(sizeof(long)>=8)-1,
+		[_SC_SS_REPL_MAX] = -1,
+		[_SC_TRACE_EVENT_NAME_MAX] = -1,
+		[_SC_TRACE_NAME_MAX] = -1,
+		[_SC_TRACE_SYS_MAX] = -1,
+		[_SC_TRACE_USER_EVENT_MAX] = -1,
+		[_SC_XOPEN_STREAMS] = 0,
+		[_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
+		[_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
+	};
+	if (name > sizeof(values)/sizeof(values[0])) {
+		errno = EINVAL;
+		return -1;
+	} else if (values[name] == VER) {
+		return _POSIX_VERSION;
+	} else if (values[name] == OFLOW) {
+		return ARG_MAX;
+	} else {
+		return values[name];
+	}
+}
diff --git a/src/ctype/__ctype_get_mb_cur_max.c b/src/ctype/__ctype_get_mb_cur_max.c
new file mode 100644
index 00000000..42e4ee71
--- /dev/null
+++ b/src/ctype/__ctype_get_mb_cur_max.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+size_t __ctype_get_mb_cur_max()
+{
+	return 4;
+}
diff --git a/src/ctype/isalnum.c b/src/ctype/isalnum.c
new file mode 100644
index 00000000..e3d2cf0b
--- /dev/null
+++ b/src/ctype/isalnum.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isalnum(int c)
+{
+	return isalpha(c) || isdigit(c);
+}
diff --git a/src/ctype/isalpha.c b/src/ctype/isalpha.c
new file mode 100644
index 00000000..53e115c2
--- /dev/null
+++ b/src/ctype/isalpha.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef isalpha
+
+int isalpha(int c)
+{
+	return ((unsigned)c|32)-'a' < 26;
+}
diff --git a/src/ctype/isascii.c b/src/ctype/isascii.c
new file mode 100644
index 00000000..3af0a10d
--- /dev/null
+++ b/src/ctype/isascii.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isascii(int c)
+{
+	return !(c&~0x7f);
+}
diff --git a/src/ctype/isblank.c b/src/ctype/isblank.c
new file mode 100644
index 00000000..957400b2
--- /dev/null
+++ b/src/ctype/isblank.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isblank(int c)
+{
+	return (c == ' ' || c == '\t');
+}
diff --git a/src/ctype/iscntrl.c b/src/ctype/iscntrl.c
new file mode 100644
index 00000000..92ed7f0e
--- /dev/null
+++ b/src/ctype/iscntrl.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int iscntrl(int c)
+{
+	return (unsigned)c < 0x20 || c == 0x7f;
+}
diff --git a/src/ctype/isdigit.c b/src/ctype/isdigit.c
new file mode 100644
index 00000000..0bc82a6d
--- /dev/null
+++ b/src/ctype/isdigit.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef isdigit
+
+int isdigit(int c)
+{
+	return (unsigned)c-'0' < 10;
+}
diff --git a/src/ctype/isgraph.c b/src/ctype/isgraph.c
new file mode 100644
index 00000000..98979d1e
--- /dev/null
+++ b/src/ctype/isgraph.c
@@ -0,0 +1,4 @@
+int isgraph(int c)
+{
+	return (unsigned)c-0x21 < 0x5e;
+}
diff --git a/src/ctype/islower.c b/src/ctype/islower.c
new file mode 100644
index 00000000..d72fb212
--- /dev/null
+++ b/src/ctype/islower.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef islower
+
+int islower(int c)
+{
+	return (unsigned)c-'a' < 26;
+}
diff --git a/src/ctype/isprint.c b/src/ctype/isprint.c
new file mode 100644
index 00000000..504e66ed
--- /dev/null
+++ b/src/ctype/isprint.c
@@ -0,0 +1,4 @@
+int isprint(int c)
+{
+	return (unsigned)c-0x20 < 0x5f;
+}
diff --git a/src/ctype/ispunct.c b/src/ctype/ispunct.c
new file mode 100644
index 00000000..fc455352
--- /dev/null
+++ b/src/ctype/ispunct.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int ispunct(int c)
+{
+	return isgraph(c) && !isalnum(c);
+}
diff --git a/src/ctype/isspace.c b/src/ctype/isspace.c
new file mode 100644
index 00000000..8e535aa1
--- /dev/null
+++ b/src/ctype/isspace.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isspace(int c)
+{
+	return c == ' ' || (unsigned)c-'\t' < 5;
+}
diff --git a/src/ctype/isupper.c b/src/ctype/isupper.c
new file mode 100644
index 00000000..f09d88c5
--- /dev/null
+++ b/src/ctype/isupper.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef isupper
+
+int isupper(int c)
+{
+	return (unsigned)c-'A' < 26;
+}
diff --git a/src/ctype/iswalnum.c b/src/ctype/iswalnum.c
new file mode 100644
index 00000000..d3b56674
--- /dev/null
+++ b/src/ctype/iswalnum.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+#include <wctype.h>
+
+#undef iswalnum
+
+int iswalnum(wint_t wc)
+{
+	return (unsigned)wc-'0' < 10 || iswalpha(wc);
+}
diff --git a/src/ctype/iswalpha.c b/src/ctype/iswalpha.c
new file mode 100644
index 00000000..0f031eac
--- /dev/null
+++ b/src/ctype/iswalpha.c
@@ -0,0 +1,6 @@
+#include <wctype.h>
+
+int iswalpha(wint_t wc)
+{
+	return (32U|wc)-'a'<26;
+}
diff --git a/src/ctype/iswblank.c b/src/ctype/iswblank.c
new file mode 100644
index 00000000..bc6196f2
--- /dev/null
+++ b/src/ctype/iswblank.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+#include <wctype.h>
+#include <ctype.h>
+
+int iswblank(wint_t wc)
+{
+	return isblank(wc);
+}
diff --git a/src/ctype/iswcntrl.c b/src/ctype/iswcntrl.c
new file mode 100644
index 00000000..93942b08
--- /dev/null
+++ b/src/ctype/iswcntrl.c
@@ -0,0 +1,10 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int iswcntrl(wint_t wc)
+{
+	return (unsigned)wc < 32
+	    || (unsigned)(wc-0x7f) < 33
+	    || (unsigned)(wc-0x2028) < 2
+	    || (unsigned)(wc-0xfff9) < 3;
+}
diff --git a/src/ctype/iswctype.c b/src/ctype/iswctype.c
new file mode 100644
index 00000000..d917975b
--- /dev/null
+++ b/src/ctype/iswctype.c
@@ -0,0 +1,63 @@
+#include <wchar.h>
+#include <wctype.h>
+#include <string.h>
+
+#define WCTYPE_ALNUM  1
+#define WCTYPE_ALPHA  2
+#define WCTYPE_BLANK  3
+#define WCTYPE_CNTRL  4
+#define WCTYPE_DIGIT  5
+#define WCTYPE_GRAPH  6
+#define WCTYPE_LOWER  7
+#define WCTYPE_PRINT  8
+#define WCTYPE_PUNCT  9
+#define WCTYPE_SPACE  10
+#define WCTYPE_UPPER  11
+#define WCTYPE_XDIGIT 12
+
+int iswctype(wint_t wc, wctype_t type)
+{
+	switch (type) {
+	case WCTYPE_ALNUM:
+		return iswalnum(wc);
+	case WCTYPE_ALPHA:
+		return iswalpha(wc);
+	case WCTYPE_BLANK:
+		return iswblank(wc);
+	case WCTYPE_CNTRL:
+		return iswcntrl(wc);
+	case WCTYPE_DIGIT:
+		return iswdigit(wc);
+	case WCTYPE_GRAPH:
+		return iswgraph(wc);
+	case WCTYPE_LOWER:
+		return iswlower(wc);
+	case WCTYPE_PRINT:
+		return iswprint(wc);
+	case WCTYPE_PUNCT:
+		return iswpunct(wc);
+	case WCTYPE_SPACE:
+		return iswspace(wc);
+	case WCTYPE_UPPER:
+		return iswupper(wc);
+	case WCTYPE_XDIGIT:
+		return iswxdigit(wc);
+	}
+	return 0;
+}
+
+wctype_t wctype(const char *s)
+{
+	int i;
+	const char *p;
+	/* order must match! */
+	static const char names[] =
+		"alnum\0" "alpha\0" "blank\0"
+		"cntrl\0" "digit\0" "graph\0"
+		"lower\0" "print\0" "punct\0"
+		"space\0" "upper\0" "xdigit";
+	for (i=1, p=names; *p; i++, p+=6)
+		if (*s == *p && !strcmp(s, p))
+			return i;
+	return 0;
+}
diff --git a/src/ctype/iswdigit.c b/src/ctype/iswdigit.c
new file mode 100644
index 00000000..0487145f
--- /dev/null
+++ b/src/ctype/iswdigit.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+#include <wctype.h>
+
+#undef iswdigit
+
+int iswdigit(wint_t wc)
+{
+	return (unsigned)wc-'0' < 10;
+}
diff --git a/src/ctype/iswgraph.c b/src/ctype/iswgraph.c
new file mode 100644
index 00000000..fdc97853
--- /dev/null
+++ b/src/ctype/iswgraph.c
@@ -0,0 +1,7 @@
+#include <wctype.h>
+
+int iswgraph(wint_t wc)
+{
+	/* ISO C defines this function as: */
+	return !iswspace(wc) && iswprint(wc);
+}
diff --git a/src/ctype/iswlower.c b/src/ctype/iswlower.c
new file mode 100644
index 00000000..0a568e77
--- /dev/null
+++ b/src/ctype/iswlower.c
@@ -0,0 +1,6 @@
+#include <wctype.h>
+
+int iswlower(wint_t wc)
+{
+	return towupper(wc) != wc;
+}
diff --git a/src/ctype/iswprint.c b/src/ctype/iswprint.c
new file mode 100644
index 00000000..7717671a
--- /dev/null
+++ b/src/ctype/iswprint.c
@@ -0,0 +1,10 @@
+#include <wctype.h>
+
+int iswprint(wint_t wc)
+{
+	unsigned c = wc;
+	/* assume any non-control, non-illegal codepoint is printable */
+	if (c>0x10ffff || c-0xd800<0x800 || (c&0xfffe)==0xfffe || iswcntrl(c))
+		return 0;
+	return 1;
+}
diff --git a/src/ctype/iswpunct.c b/src/ctype/iswpunct.c
new file mode 100644
index 00000000..1414c30c
--- /dev/null
+++ b/src/ctype/iswpunct.c
@@ -0,0 +1,138 @@
+#include <wctype.h>
+#include <inttypes.h>
+
+/* The below data is derived from classes (P.|Sm) plus Pattern_Syntax */
+
+#define R(a,b) { (b), (b)-(a) }
+
+static const struct range {
+	uint32_t base:20;
+	uint32_t len:12;
+} ranges[] = {
+R(0x21, 0x2f),
+R(0x3a, 0x40),
+R(0x5b, 0x60),
+R(0x7b, 0x7e),
+R(0xa1, 0xa7),
+R(0xa9, 0xa9),
+R(0xab, 0xac),
+R(0xae, 0xae),
+R(0xb0, 0xb1),
+R(0xb6, 0xb7),
+R(0xbb, 0xbb),
+R(0xbf, 0xbf),
+R(0xd7, 0xd7),
+R(0xf7, 0xf7),
+R(0x37e, 0x37e),
+R(0x387, 0x387),
+R(0x3f6, 0x3f6),
+R(0x55a, 0x55f),
+R(0x589, 0x58a),
+R(0x5be, 0x5be),
+R(0x5c0, 0x5c0),
+R(0x5c3, 0x5c3),
+R(0x5c6, 0x5c6),
+R(0x5f3, 0x5f4),
+R(0x606, 0x60a),
+R(0x60c, 0x60d),
+R(0x61b, 0x61b),
+R(0x61e, 0x61f),
+R(0x66a, 0x66d),
+R(0x6d4, 0x6d4),
+R(0x700, 0x70d),
+R(0x7f7, 0x7f9),
+R(0x964, 0x965),
+R(0x970, 0x970),
+R(0xdf4, 0xdf4),
+R(0xe4f, 0xe4f),
+R(0xe5a, 0xe5b),
+R(0xf04, 0xf12),
+R(0xf3a, 0xf3d),
+R(0xf85, 0xf85),
+R(0xfd0, 0xfd4),
+R(0x104a, 0x104f),
+R(0x10fb, 0x10fb),
+R(0x1361, 0x1368),
+R(0x166d, 0x166e),
+R(0x1680, 0x1680),
+R(0x169b, 0x169c),
+R(0x16eb, 0x16ed),
+R(0x1735, 0x1736),
+R(0x17d4, 0x17d6),
+R(0x17d8, 0x17da),
+R(0x1800, 0x180a),
+R(0x180e, 0x180e),
+R(0x1944, 0x1945),
+R(0x19de, 0x19df),
+R(0x1a1e, 0x1a1f),
+R(0x1b5a, 0x1b60),
+R(0x1c3b, 0x1c3f),
+R(0x1c7e, 0x1c7f),
+R(0x2010, 0x2027),
+R(0x2030, 0x205e),
+R(0x207a, 0x207e),
+R(0x208a, 0x208e),
+R(0x2140, 0x2144),
+R(0x214b, 0x214b),
+R(0x2190, 0x245f),
+R(0x2500, 0x2775),
+R(0x2794, 0x2bff),
+R(0x2cf9, 0x2cfc),
+R(0x2cfe, 0x2cff),
+R(0x2e00, 0x2e7f),
+R(0x3001, 0x3003),
+R(0x3008, 0x3020),
+R(0x3030, 0x3030),
+R(0x303d, 0x303d),
+R(0x30a0, 0x30a0),
+R(0x30fb, 0x30fb),
+R(0xa60d, 0xa60f),
+R(0xa874, 0xa877),
+R(0xa8ce, 0xa8cf),
+R(0xa92e, 0xa92f),
+R(0xa95f, 0xa95f),
+R(0xfb29, 0xfb29),
+R(0xfd3e, 0xfd3f),
+R(0xfe10, 0xfe19),
+R(0xfe30, 0xfe52),
+R(0xfe54, 0xfe66),
+R(0xfe68, 0xfe68),
+R(0xfe6a, 0xfe6b),
+R(0xff01, 0xff03),
+R(0xff05, 0xff0f),
+R(0xff1a, 0xff20),
+R(0xff3b, 0xff3d),
+R(0xff3f, 0xff3f),
+R(0xff5b, 0xff65),
+R(0xffe2, 0xffe2),
+R(0xffe9, 0xffec),
+R(0x10100, 0x10101),
+R(0x1039f, 0x1039f),
+R(0x103d0, 0x103d0),
+R(0x1091f, 0x1091f),
+R(0x1093f, 0x1093f),
+R(0x10a50, 0x10a58),
+R(0x12470, 0x12473),
+R(0x1d6c1, 0x1d6c1),
+R(0x1d6db, 0x1d6db),
+R(0x1d6fb, 0x1d6fb),
+R(0x1d715, 0x1d715),
+R(0x1d735, 0x1d735),
+R(0x1d74f, 0x1d74f),
+R(0x1d76f, 0x1d76f),
+R(0x1d789, 0x1d789),
+R(0x1d7a9, 0x1d7a9),
+R(0x1d7c3, 0x1d7c3),
+};
+
+int iswpunct(wint_t wc)
+{
+	unsigned c = wc;
+	int a = 0;
+	int n = sizeof ranges / sizeof ranges[0];
+	do {
+		n >>= 1;
+		a += n+1 & (signed)(ranges[a+n].base-c)>>31;
+	} while (n);
+	return ranges[a].base-c <= ranges[a].len;
+}
diff --git a/src/ctype/iswspace.c b/src/ctype/iswspace.c
new file mode 100644
index 00000000..68a17437
--- /dev/null
+++ b/src/ctype/iswspace.c
@@ -0,0 +1,15 @@
+#include <wchar.h>
+#include <wctype.h>
+#include <ctype.h>
+
+int iswspace(wint_t wc)
+{
+	static const wchar_t spaces[] = {
+		' ', '\t', '\n', '\r', 11, 12,  0x0085,
+		0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
+		0x2006, 0x2008, 0x2009, 0x200a, 0x200b,
+		0x2028, 0x2029, 0x2050, 0x3000, 0
+	};
+	if (wcschr(spaces, wc)) return 1;
+	return 0;
+}
diff --git a/src/ctype/iswupper.c b/src/ctype/iswupper.c
new file mode 100644
index 00000000..eae59a75
--- /dev/null
+++ b/src/ctype/iswupper.c
@@ -0,0 +1,6 @@
+#include <wctype.h>
+
+int iswupper(wint_t wc)
+{
+	return towlower(wc) != wc;
+}
diff --git a/src/ctype/iswxdigit.c b/src/ctype/iswxdigit.c
new file mode 100644
index 00000000..229a469f
--- /dev/null
+++ b/src/ctype/iswxdigit.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int iswxdigit(wint_t wc)
+{
+	return (unsigned)(wc-'0') < 10 || (unsigned)((wc|32)-'a') < 6;
+}
diff --git a/src/ctype/isxdigit.c b/src/ctype/isxdigit.c
new file mode 100644
index 00000000..ae68a3dc
--- /dev/null
+++ b/src/ctype/isxdigit.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isxdigit(int c)
+{
+	return isdigit(c) || ((unsigned)c|32)-'a' < 6;
+}
diff --git a/src/ctype/toascii.c b/src/ctype/toascii.c
new file mode 100644
index 00000000..f0e48e8e
--- /dev/null
+++ b/src/ctype/toascii.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+
+/* nonsense function that should NEVER be used! */
+int toascii(int c)
+{
+	return c & 0x7f;
+}
diff --git a/src/ctype/tolower.c b/src/ctype/tolower.c
new file mode 100644
index 00000000..b56f3c50
--- /dev/null
+++ b/src/ctype/tolower.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+
+int tolower(int c)
+{
+	if (isupper(c)) return c | 32;
+	return c;
+}
diff --git a/src/ctype/toupper.c b/src/ctype/toupper.c
new file mode 100644
index 00000000..1799f030
--- /dev/null
+++ b/src/ctype/toupper.c
@@ -0,0 +1,7 @@
+#include <ctype.h>
+
+int toupper(int c)
+{
+	if (islower(c)) return c & 0x5f;
+	return c;
+}
diff --git a/src/ctype/towctrans.c b/src/ctype/towctrans.c
new file mode 100644
index 00000000..0b1eed04
--- /dev/null
+++ b/src/ctype/towctrans.c
@@ -0,0 +1,246 @@
+#include <wchar.h>
+#include <wctype.h>
+#include <stdio.h>
+
+#define CASEMAP(u1,u2,l) { (u1), (l)-(u1), (u2)-(u1)+1 }
+#define CASELACE(u1,u2) CASEMAP((u1),(u2),(u1)+1)
+
+static const struct {
+	unsigned short upper;
+	signed char lower;
+	unsigned char len;
+} casemaps[] = {
+	CASEMAP('A','Z','a'),
+	CASEMAP(0xc0,0xde,0xe0),
+
+	CASELACE(0x0100,0x012e),
+	CASELACE(0x0132,0x0136),
+	CASELACE(0x0139,0x0147),
+	CASELACE(0x014a,0x0176),
+	CASELACE(0x0179,0x017d),
+
+	CASELACE(0x370,0x372),
+	CASEMAP(0x391,0x3a1,0x3b1),
+	CASEMAP(0x3a3,0x3ab,0x3c3),
+	CASEMAP(0x400,0x40f,0x450),
+	CASEMAP(0x410,0x42f,0x430),
+
+	CASELACE(0x460,0x480),
+	CASELACE(0x48a,0x4be),
+	CASELACE(0x4c1,0x4cd),
+	CASELACE(0x4d0,0x50e),
+
+	CASEMAP(0x531,0x556,0x561),
+
+	CASELACE(0x01a0,0x01a4),
+	CASELACE(0x01b3,0x01b5),
+	CASELACE(0x01cd,0x01db),
+	CASELACE(0x01de,0x01ee),
+	CASELACE(0x01f8,0x021e),
+	CASELACE(0x0222,0x0232),
+	CASELACE(0x03d8,0x03ee),
+
+	CASELACE(0x1e00,0x1e94),
+	CASELACE(0x1ea0,0x1efe),
+
+	CASEMAP(0x1f08,0x1f0f,0x1f00),
+	CASEMAP(0x1f18,0x1f1d,0x1f10),
+	CASEMAP(0x1f28,0x1f2f,0x1f20),
+	CASEMAP(0x1f38,0x1f3f,0x1f30),
+	CASEMAP(0x1f48,0x1f4d,0x1f40),
+
+	CASEMAP(0x1f68,0x1f6f,0x1f60),
+	CASEMAP(0x1f88,0x1f8f,0x1f80),
+	CASEMAP(0x1f98,0x1f9f,0x1f90),
+	CASEMAP(0x1fa8,0x1faf,0x1fa0),
+	CASEMAP(0x1fb8,0x1fb9,0x1fb0),
+	CASEMAP(0x1fba,0x1fbb,0x1f70),
+	CASEMAP(0x1fc8,0x1fcb,0x1f72),
+	CASEMAP(0x1fd8,0x1fd9,0x1fd0),
+	CASEMAP(0x1fda,0x1fdb,0x1f76),
+	CASEMAP(0x1fe8,0x1fe9,0x1fe0),
+	CASEMAP(0x1fea,0x1feb,0x1f7a),
+	CASEMAP(0x1ff8,0x1ff9,0x1f78),
+	CASEMAP(0x1ffa,0x1ffb,0x1f7c),
+
+	CASELACE(0x246,0x24e),
+	CASELACE(0x510,0x512),
+	CASEMAP(0x2160,0x216f,0x2170),
+	CASEMAP(0x2c00,0x2c2e,0x2c30),
+	CASELACE(0x2c67,0x2c6b),
+	CASELACE(0x2c80,0x2ce2),
+
+	CASELACE(0xa722,0xa72e),
+	CASELACE(0xa732,0xa76e),
+	CASELACE(0xa779,0xa77b),
+	CASELACE(0xa77e,0xa786),
+
+	CASEMAP(0xff21,0xff3a,0xff41),
+	{ 0,0,0 }
+};
+
+static const unsigned short pairs[][2] = {
+	{ 'I',    0x0131 },
+	{ 'S',    0x017f },
+	{ 0x0130, 'i'    },
+	{ 0x0178, 0x00ff },
+	{ 0x0181, 0x0253 },
+	{ 0x0182, 0x0183 },
+	{ 0x0184, 0x0185 },
+	{ 0x0186, 0x0254 },
+	{ 0x0187, 0x0188 },
+	{ 0x0189, 0x0256 },
+	{ 0x018a, 0x0257 },
+	{ 0x018b, 0x018c },
+	{ 0x018e, 0x01dd },
+	{ 0x018f, 0x0259 },
+	{ 0x0190, 0x025b },
+	{ 0x0191, 0x0192 },
+	{ 0x0193, 0x0260 },
+	{ 0x0194, 0x0263 },
+	{ 0x0196, 0x0269 },
+	{ 0x0197, 0x0268 },
+	{ 0x0198, 0x0199 },
+	{ 0x019c, 0x026f },
+	{ 0x019d, 0x0272 },
+	{ 0x019f, 0x0275 },
+	{ 0x01a6, 0x0280 },
+	{ 0x01a7, 0x01a8 },
+	{ 0x01a9, 0x0283 },
+	{ 0x01ac, 0x01ad },
+	{ 0x01ae, 0x0288 },
+	{ 0x01af, 0x01b0 },
+	{ 0x01b1, 0x028a },
+	{ 0x01b2, 0x028b },
+	{ 0x01b7, 0x0292 },
+	{ 0x01b8, 0x01b9 },
+	{ 0x01bc, 0x01bd },
+	{ 0x01c4, 0x01c6 },
+	{ 0x01c4, 0x01c5 },
+	{ 0x01c5, 0x01c6 },
+	{ 0x01c7, 0x01c9 },
+	{ 0x01c7, 0x01c8 },
+	{ 0x01c8, 0x01c9 },
+	{ 0x01ca, 0x01cc },
+	{ 0x01ca, 0x01cb },
+	{ 0x01cb, 0x01cc },
+	{ 0x01f1, 0x01f3 },
+	{ 0x01f1, 0x01f2 },
+	{ 0x01f2, 0x01f3 },
+	{ 0x01f4, 0x01f5 },
+	{ 0x01f6, 0x0195 },
+	{ 0x01f7, 0x01bf },
+	{ 0x0220, 0x019e },
+	{ 0x0386, 0x03ac },
+	{ 0x0388, 0x03ad },
+	{ 0x0389, 0x03ae },
+	{ 0x038a, 0x03af },
+	{ 0x038c, 0x03cc },
+	{ 0x038e, 0x03cd },
+	{ 0x038f, 0x03ce },
+	{ 0x0399, 0x0345 },
+	{ 0x0399, 0x1fbe },
+	{ 0x03a3, 0x03c2 },
+	{ 0x03f7, 0x03f8 },
+	{ 0x03fa, 0x03fb },
+	{ 0x1e60, 0x1e9b },
+
+	{ 0x1f59, 0x1f51 },
+	{ 0x1f5b, 0x1f53 },
+	{ 0x1f5d, 0x1f55 },
+	{ 0x1f5f, 0x1f57 },
+	{ 0x1fbc, 0x1fb3 },
+	{ 0x1fcc, 0x1fc3 },
+	{ 0x1fec, 0x1fe5 },
+	{ 0x1ffc, 0x1ff3 },
+
+	{ 0x23a, 0x2c65 },
+	{ 0x23b, 0x23c },
+	{ 0x23d, 0x19a },
+	{ 0x23e, 0x2c66 },
+	{ 0x241, 0x242 },
+	{ 0x243, 0x180 },
+	{ 0x244, 0x289 },
+	{ 0x245, 0x28c },
+	{ 0x3f4, 0x3b8 },
+	{ 0x3f9, 0x3f2 },
+	{ 0x3fd, 0x37b },
+	{ 0x3fe, 0x37c },
+	{ 0x3ff, 0x37d },
+	{ 0x4c0, 0x4cf },
+
+	{ 0x2126, 0x3c9 },
+	{ 0x212a, 'k' },
+	{ 0x212b, 0xe5 },
+	{ 0x2132, 0x214e },
+	{ 0x2183, 0x2184 },
+	{ 0x2c60, 0x2c61 },
+	{ 0x2c62, 0x26b },
+	{ 0x2c63, 0x1d7d },
+	{ 0x2c64, 0x27d },
+	{ 0x2c6d, 0x251 },
+	{ 0x2c6e, 0x271 },
+	{ 0x2c6f, 0x250 },
+	{ 0x2c72, 0x2c73 },
+	{ 0x2c75, 0x2c76 },
+
+	{ 0xa77d, 0x1d79 },
+
+	/* bogus greek 'symbol' letters */
+	{ 0x376, 0x377 },
+	{ 0x39c, 0xb5 },
+	{ 0x392, 0x3d0 },
+	{ 0x398, 0x3d1 },
+	{ 0x3a6, 0x3d5 },
+	{ 0x3a0, 0x3d6 },
+	{ 0x39a, 0x3f0 },
+	{ 0x3a1, 0x3f1 },
+	{ 0x395, 0x3f5 },
+	{ 0x3cf, 0x3d7 },
+
+	{ 0,0 }
+};
+
+
+static wchar_t __towcase(wchar_t wc, int lower)
+{
+	int i;
+	int lmul = 2*lower-1;
+	int lmask = lower-1;
+	if ((unsigned)wc - 0x10400 < 0x50)
+		return wc + lmul*0x28;
+	/* no letters with case in these large ranges */
+	if (!iswalpha(wc)
+	 || (unsigned)wc - 0x0600 <= 0x0fff-0x0600
+	 || (unsigned)wc - 0x2e00 <= 0xa6ff-0x2e00
+	 || (unsigned)wc - 0xa800 <= 0xfeff-0xa800)
+		return wc;
+	/* special case because the diff between upper/lower is too big */
+	if ((unsigned)wc - 0x10a0 < 0x26 || (unsigned)wc - 0x2d00 < 0x26)
+		return wc + lmul*(0x2d00-0x10a0);
+	for (i=0; casemaps[i].len; i++) {
+		int base = casemaps[i].upper + (lmask & casemaps[i].lower);
+		if ((unsigned)wc-base < casemaps[i].len) {
+			if (casemaps[i].lower == 1)
+				return wc + lower - ((wc-casemaps[i].upper)&1);
+			return wc + lmul*casemaps[i].lower;
+		}
+	}
+	for (i=0; pairs[i][1-lower]; i++) {
+		if (pairs[i][1-lower] == wc)
+			return pairs[i][lower];
+	}
+	if ((unsigned)wc - 0x10428 + (lower<<5) + (lower<<3) < 0x28)
+		return wc - 0x28 + (lower<<10) + (lower<<6);
+	return wc;
+}
+
+wint_t towupper(wint_t wc)
+{
+	return __towcase(wc, 0);
+}
+
+wint_t towlower(wint_t wc)
+{
+	return __towcase(wc, 1);
+}
diff --git a/src/ctype/wcswidth.c b/src/ctype/wcswidth.c
new file mode 100644
index 00000000..5c8a5a4d
--- /dev/null
+++ b/src/ctype/wcswidth.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+int wcswidth(const wchar_t *wcs, size_t n)
+{
+	int l=0, k=0;
+	for (; n-- && *wcs && (k = wcwidth(*wcs)) >= 0; l+=k, wcs++);
+	return (k < 0) ? k : l;
+}
diff --git a/src/ctype/wctrans.c b/src/ctype/wctrans.c
new file mode 100644
index 00000000..03e9fd6a
--- /dev/null
+++ b/src/ctype/wctrans.c
@@ -0,0 +1,16 @@
+#include <wctype.h>
+#include <string.h>
+
+wctrans_t wctrans(const char *class)
+{
+	if (!strcmp(class, "toupper")) return 1;
+	if (!strcmp(class, "tolower")) return 2;
+	return 0;
+}
+
+wint_t towctrans(wint_t wc, wctrans_t trans)
+{
+	if (trans == 1) return towupper(wc);
+	if (trans == 2) return towlower(wc);
+	return wc;
+}
diff --git a/src/ctype/wcwidth.c b/src/ctype/wcwidth.c
new file mode 100644
index 00000000..ebc560a5
--- /dev/null
+++ b/src/ctype/wcwidth.c
@@ -0,0 +1,185 @@
+#include <inttypes.h>
+#include <wchar.h>
+
+#define R(a,b,w) { (b), (w)/2, (b)-(a) }
+
+static const struct range {
+	uint32_t base:20;
+	uint32_t width:1;
+	uint32_t len:11;
+} ranges[] = {
+	R(0x0300, 0x036F, 0),
+	R(0x0483, 0x0486, 0),
+	R(0x0488, 0x0489, 0),
+	R(0x0591, 0x05BD, 0),
+	R(0x05BF, 0x05BF, 0),
+	R(0x05C1, 0x05C2, 0),
+	R(0x05C4, 0x05C5, 0),
+	R(0x05C7, 0x05C7, 0),
+	R(0x0600, 0x0603, 0),
+	R(0x0610, 0x0615, 0),
+	R(0x064B, 0x065E, 0),
+	R(0x0670, 0x0670, 0),
+	R(0x06D6, 0x06E4, 0),
+	R(0x06E7, 0x06E8, 0),
+	R(0x06EA, 0x06ED, 0),
+	R(0x070F, 0x070F, 0),
+	R(0x0711, 0x0711, 0),
+	R(0x0730, 0x074A, 0),
+	R(0x07A6, 0x07B0, 0),
+	R(0x07EB, 0x07F3, 0),
+	R(0x0901, 0x0902, 0),
+	R(0x093C, 0x093C, 0),
+	R(0x0941, 0x0948, 0),
+	R(0x094D, 0x094D, 0),
+	R(0x0951, 0x0954, 0),
+	R(0x0962, 0x0963, 0),
+	R(0x0981, 0x0981, 0),
+	R(0x09BC, 0x09BC, 0),
+	R(0x09C1, 0x09C4, 0),
+	R(0x09CD, 0x09CD, 0),
+	R(0x09E2, 0x09E3, 0),
+	R(0x0A01, 0x0A02, 0),
+	R(0x0A3C, 0x0A3C, 0),
+	R(0x0A41, 0x0A42, 0),
+	R(0x0A47, 0x0A48, 0),
+	R(0x0A4B, 0x0A4D, 0),
+	R(0x0A70, 0x0A71, 0),
+	R(0x0A81, 0x0A82, 0),
+	R(0x0ABC, 0x0ABC, 0),
+	R(0x0AC1, 0x0AC5, 0),
+	R(0x0AC7, 0x0AC8, 0),
+	R(0x0ACD, 0x0ACD, 0),
+	R(0x0AE2, 0x0AE3, 0),
+	R(0x0B01, 0x0B01, 0),
+	R(0x0B3C, 0x0B3C, 0),
+	R(0x0B3F, 0x0B3F, 0),
+	R(0x0B41, 0x0B43, 0),
+	R(0x0B4D, 0x0B4D, 0),
+	R(0x0B56, 0x0B56, 0),
+	R(0x0B82, 0x0B82, 0),
+	R(0x0BC0, 0x0BC0, 0),
+	R(0x0BCD, 0x0BCD, 0),
+	R(0x0C3E, 0x0C40, 0),
+	R(0x0C46, 0x0C48, 0),
+	R(0x0C4A, 0x0C4D, 0),
+	R(0x0C55, 0x0C56, 0),
+	R(0x0CBC, 0x0CBC, 0),
+	R(0x0CBF, 0x0CBF, 0),
+	R(0x0CC6, 0x0CC6, 0),
+	R(0x0CCC, 0x0CCD, 0),
+	R(0x0CE2, 0x0CE3, 0),
+	R(0x0D41, 0x0D43, 0),
+	R(0x0D4D, 0x0D4D, 0),
+	R(0x0DCA, 0x0DCA, 0),
+	R(0x0DD2, 0x0DD4, 0),
+	R(0x0DD6, 0x0DD6, 0),
+	R(0x0E31, 0x0E31, 0),
+	R(0x0E34, 0x0E3A, 0),
+	R(0x0E47, 0x0E4E, 0),
+	R(0x0EB1, 0x0EB1, 0),
+	R(0x0EB4, 0x0EB9, 0),
+	R(0x0EBB, 0x0EBC, 0),
+	R(0x0EC8, 0x0ECD, 0),
+	R(0x0F18, 0x0F19, 0),
+	R(0x0F35, 0x0F35, 0),
+	R(0x0F37, 0x0F37, 0),
+	R(0x0F39, 0x0F39, 0),
+	R(0x0F71, 0x0F7E, 0),
+	R(0x0F80, 0x0F84, 0),
+	R(0x0F86, 0x0F87, 0),
+	R(0x0F90, 0x0F97, 0),
+	R(0x0F99, 0x0FBC, 0),
+	R(0x0FC6, 0x0FC6, 0),
+	R(0x102D, 0x1030, 0),
+	R(0x1032, 0x1032, 0),
+	R(0x1036, 0x1037, 0),
+	R(0x1039, 0x1039, 0),
+	R(0x1058, 0x1059, 0),
+	R(0x1100, 0x115F, 2),
+	R(0x1160, 0x11FF, 0),
+	R(0x135F, 0x135F, 0),
+	R(0x1712, 0x1714, 0),
+	R(0x1732, 0x1734, 0),
+	R(0x1752, 0x1753, 0),
+	R(0x1772, 0x1773, 0),
+	R(0x17B4, 0x17B5, 0),
+	R(0x17B7, 0x17BD, 0),
+	R(0x17C6, 0x17C6, 0),
+	R(0x17C9, 0x17D3, 0),
+	R(0x17DD, 0x17DD, 0),
+	R(0x180B, 0x180D, 0),
+	R(0x18A9, 0x18A9, 0),
+	R(0x1920, 0x1922, 0),
+	R(0x1927, 0x1928, 0),
+	R(0x1932, 0x1932, 0),
+	R(0x1939, 0x193B, 0),
+	R(0x1A17, 0x1A18, 0),
+	R(0x1B00, 0x1B03, 0),
+	R(0x1B34, 0x1B34, 0),
+	R(0x1B36, 0x1B3A, 0),
+	R(0x1B3C, 0x1B3C, 0),
+	R(0x1B42, 0x1B42, 0),
+	R(0x1B6B, 0x1B73, 0),
+	R(0x1DC0, 0x1DCA, 0),
+	R(0x1DFE, 0x1DFF, 0),
+	R(0x200B, 0x200F, 0),
+	R(0x202A, 0x202E, 0),
+	R(0x2060, 0x2063, 0),
+	R(0x206A, 0x206F, 0),
+	R(0x20D0, 0x20EF, 0),
+	R(0x2329, 0x232A, 2),
+	R(0x2E80, 0x3029, 2),
+	R(0x302A, 0x302F, 0),
+	R(0x3030, 0x303E, 2),
+	R(0x3099, 0x309A, 0),
+	R(0xA806, 0xA806, 0),
+	R(0xA80B, 0xA80B, 0),
+	R(0xA825, 0xA826, 0),
+	R(0xF900, 0xFAFF, 2),
+	R(0xFB1E, 0xFB1E, 0),
+	R(0xFE00, 0xFE0F, 0),
+	R(0xFE20, 0xFE23, 0),
+	R(0xFE30, 0xFE6F, 2),
+	R(0xFEFF, 0xFEFF, 0),
+	R(0xFF00, 0xFF60, 2),
+	R(0xFFE0, 0xFFE6, 2),
+	R(0x10A01, 0x10A03, 0),
+	R(0x10A05, 0x10A06, 0),
+	R(0x10A0C, 0x10A0F, 0),
+	R(0x10A38, 0x10A3A, 0),
+	R(0x10A3F, 0x10A3F, 0),
+	R(0x1D167, 0x1D169, 0),
+	R(0x1D173, 0x1D182, 0),
+	R(0x1D185, 0x1D18B, 0),
+	R(0x1D1AA, 0x1D1AD, 0),
+	R(0x1D242, 0x1D244, 0),
+	R(0xE0001, 0xE0001, 0),
+	R(0xE0020, 0xE007F, 0),
+	R(0xE0100, 0xE01EF, 0),
+};
+
+/* Note: because the len field is only 10 bits, we must special-case
+ * the two huge ranges of full width characters and exclude them
+ * from the binary search table. */
+
+int wcwidth(wchar_t wc)
+{
+	int a, n;
+	uint32_t c = wc;
+
+	if (c-0x20 < 0x5f) return 1;
+	if (!iswprint(c)) return wc ? -1 : 0;
+	if (c-0x20000 < 0x20000) return 2;
+
+	/* The following code is a branchless binary search. */
+	a = 0;
+	n = sizeof ranges / sizeof ranges[0];
+	do {
+		n >>= 1;
+		a += n+1 & (signed)(ranges[a+n].base-c)>>31;
+	} while (n);
+	if (ranges[a].base-c <= ranges[a].len)
+		return 2*ranges[a].width;
+	return 1 + (c-0x3040 < 0xd800-0x3040);
+}
diff --git a/src/dirent/__dirent.h b/src/dirent/__dirent.h
new file mode 100644
index 00000000..07b3ee68
--- /dev/null
+++ b/src/dirent/__dirent.h
@@ -0,0 +1,9 @@
+struct __DIR_s
+{
+	int lock;
+	int fd;
+	off_t tell;
+	int buf_pos;
+	int buf_end;
+	char buf[2048];
+};
diff --git a/src/dirent/__getdents.c b/src/dirent/__getdents.c
new file mode 100644
index 00000000..4195430b
--- /dev/null
+++ b/src/dirent/__getdents.c
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __getdents(int fd, struct dirent *buf, size_t len)
+{
+	return syscall3(__NR_getdents64, fd, (long)buf, len);
+}
+
+weak_alias(__getdents, getdents);
+
+LFS64(getdents);
diff --git a/src/dirent/alphasort.c b/src/dirent/alphasort.c
new file mode 100644
index 00000000..42050fb7
--- /dev/null
+++ b/src/dirent/alphasort.c
@@ -0,0 +1,10 @@
+#include <string.h>
+#include <dirent.h>
+#include "libc.h"
+
+int alphasort(const struct dirent **a, const struct dirent **b)
+{
+	return strcoll((*a)->d_name, (*b)->d_name);
+}
+
+LFS64(alphasort);
diff --git a/src/dirent/closedir.c b/src/dirent/closedir.c
new file mode 100644
index 00000000..81e9591c
--- /dev/null
+++ b/src/dirent/closedir.c
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+int closedir(DIR *dir)
+{
+	int ret = close(dir->fd);
+	free(dir);
+	return ret;
+}
diff --git a/src/dirent/dirfd.c b/src/dirent/dirfd.c
new file mode 100644
index 00000000..6c860073
--- /dev/null
+++ b/src/dirent/dirfd.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+int dirfd(DIR *d)
+{
+	return d->fd;
+}
diff --git a/src/dirent/fdopendir.c b/src/dirent/fdopendir.c
new file mode 100644
index 00000000..c4b8e61d
--- /dev/null
+++ b/src/dirent/fdopendir.c
@@ -0,0 +1,26 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include "__dirent.h"
+
+DIR *fdopendir(int fd)
+{
+	DIR *dir;
+	struct stat st;
+
+	if (fstat(fd, &st) < 0 || !S_ISDIR(st.st_mode)) {
+		errno = ENOTDIR;
+		return 0;
+	}
+	if (!(dir = calloc(1, sizeof *dir))) {
+		return 0;
+	}
+
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	dir->fd = fd;
+	return dir;
+}
diff --git a/src/dirent/opendir.c b/src/dirent/opendir.c
new file mode 100644
index 00000000..cefe6ce7
--- /dev/null
+++ b/src/dirent/opendir.c
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include "__dirent.h"
+
+DIR *opendir(const char *name)
+{
+	int fd;
+	DIR *dir;
+
+	if ((fd = open(name, O_RDONLY|O_DIRECTORY)) < 0)
+		return 0;
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	if (!(dir = calloc(1, sizeof *dir))) {
+		close(fd);
+		return 0;
+	}
+	dir->fd = fd;
+	return dir;
+}
diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c
new file mode 100644
index 00000000..1aeb25a5
--- /dev/null
+++ b/src/dirent/readdir.c
@@ -0,0 +1,32 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "__dirent.h"
+#include "syscall.h"
+#include "libc.h"
+
+int __getdents(int, struct dirent *, size_t);
+
+struct dirent *readdir(DIR *dir)
+{
+	struct dirent *de;
+	
+	if (dir->buf_pos >= dir->buf_end) {
+		int len = __getdents(dir->fd, (void *)dir->buf, sizeof dir->buf);
+		if (len < 0) {
+			dir->lock = 0;
+			return NULL;
+		} else if (len == 0) return 0;
+		dir->buf_end = len;
+		dir->buf_pos = 0;
+	}
+	de = (void *)(dir->buf + dir->buf_pos);
+	dir->buf_pos += de->d_reclen;
+	dir->tell = de->d_off;
+	return de;
+}
+
+LFS64(readdir);
diff --git a/src/dirent/readdir_r.c b/src/dirent/readdir_r.c
new file mode 100644
index 00000000..58f60325
--- /dev/null
+++ b/src/dirent/readdir_r.c
@@ -0,0 +1,30 @@
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "__dirent.h"
+#include "libc.h"
+
+int readdir_r(DIR *dir, struct dirent *buf, struct dirent **result)
+{
+	struct dirent *de;
+	int errno_save = errno;
+	int ret;
+	
+	LOCK(&dir->lock);
+	errno = 0;
+	de = readdir(dir);
+	if ((ret = errno)) {
+		UNLOCK(&dir->lock);
+		return ret;
+	}
+	errno = errno_save;
+	if (de) memcpy(buf, de, de->d_reclen);
+	else buf = NULL;
+
+	UNLOCK(&dir->lock);
+	*result = buf;
+	return 0;
+}
+
+LFS64_2(readdir_r, readdir64_r);
diff --git a/src/dirent/rewinddir.c b/src/dirent/rewinddir.c
new file mode 100644
index 00000000..c6138f7c
--- /dev/null
+++ b/src/dirent/rewinddir.c
@@ -0,0 +1,13 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+void rewinddir(DIR *dir)
+{
+	LOCK(&dir->lock);
+	lseek(dir->fd, 0, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	dir->tell = 0;
+	UNLOCK(&dir->lock);
+}
diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c
new file mode 100644
index 00000000..6a0a9993
--- /dev/null
+++ b/src/dirent/scandir.c
@@ -0,0 +1,50 @@
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stddef.h>
+#include <libc.h>
+
+int scandir(const char *path, struct dirent ***res,
+	int (*sel)(const struct dirent *),
+	int (*cmp)(const struct dirent **, const struct dirent **))
+{
+	DIR *d = opendir(path);
+	struct dirent *de, **names=0, **tmp;
+	size_t cnt=0, len=0, size;
+	int old_errno = errno;
+
+	if (!d) return -1;
+
+	while ((errno=0), (de = readdir(d))) {
+		if (sel && !sel(de)) continue;
+		if (cnt >= len) {
+			len = 2*len+1;
+			if (len > SIZE_MAX/sizeof *names) break;
+			tmp = realloc(names, len * sizeof *names);
+			if (!tmp) break;
+			names = tmp;
+		}
+		size = offsetof(struct dirent,d_name) + strlen(de->d_name) + 1;
+		names[cnt] = malloc(size);
+		if (!names[cnt]) break;
+		memcpy(names[cnt++], de, size);
+	}
+
+	closedir(d);
+
+	if (errno) {
+		old_errno = errno;
+		if (names) while (cnt-->0) free(names[cnt]);
+		free(names);
+		errno = old_errno;
+		return -1;
+	}
+
+	if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
+	*res = names;
+	return cnt;
+}
+
+LFS64(scandir);
diff --git a/src/dirent/seekdir.c b/src/dirent/seekdir.c
new file mode 100644
index 00000000..81a0e331
--- /dev/null
+++ b/src/dirent/seekdir.c
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+void seekdir(DIR *dir, long off)
+{
+	LOCK(&dir->lock);
+	dir->tell = lseek(dir->fd, off, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	UNLOCK(&dir->lock);
+}
diff --git a/src/dirent/telldir.c b/src/dirent/telldir.c
new file mode 100644
index 00000000..cf25acff
--- /dev/null
+++ b/src/dirent/telldir.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+long telldir(DIR *dir)
+{
+	return dir->tell;
+}
diff --git a/src/env/__environ.c b/src/env/__environ.c
new file mode 100644
index 00000000..d7bd5e50
--- /dev/null
+++ b/src/env/__environ.c
@@ -0,0 +1,7 @@
+#include "libc.h"
+
+#undef environ
+char **___environ = 0;
+weak_alias(___environ, __environ);
+weak_alias(___environ, _environ);
+weak_alias(___environ, environ);
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
new file mode 100644
index 00000000..70af77b5
--- /dev/null
+++ b/src/env/__libc_start_main.c
@@ -0,0 +1,26 @@
+#include "libc.h"
+
+/* Any use of __environ/environ will override this symbol. */
+char **__dummy_environ = (void *)-1;
+weak_alias(__dummy_environ, ___environ);
+
+int __libc_start_main(
+	int (*main)(int, char **, char **), int argc, char **argv,
+	int (*init)(int, char **, char **), void (*fini)(void),
+	void (*ldso_fini)(void))
+{
+	/* Save the environment if it may be used by libc/application */
+	char **envp = argv+argc+1;
+	if (___environ != (void *)-1) ___environ = envp;
+
+	/* Avoid writing 0 and triggering unnecessary COW */
+	if (ldso_fini) libc.ldso_fini = ldso_fini;
+	if (fini) libc.fini = fini;
+
+	/* Execute constructors (static) linked into the application */
+	if (init) init(argc, argv, envp);
+
+	/* Pass control to to application */
+	exit(main(argc, argv, envp));
+	return 0;
+}
diff --git a/src/env/clearenv.c b/src/env/clearenv.c
new file mode 100644
index 00000000..a2475ce7
--- /dev/null
+++ b/src/env/clearenv.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+extern char **__environ;
+
+int clearenv()
+{
+	__environ[0] = 0;
+	return 0;
+}
diff --git a/src/env/getenv.c b/src/env/getenv.c
new file mode 100644
index 00000000..00c1bce0
--- /dev/null
+++ b/src/env/getenv.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+char *getenv(const char *name)
+{
+	int i;
+	size_t l = strlen(name);
+	if (!__environ || !*name || strchr(name, '=')) return NULL;
+	for (i=0; __environ[i] && (strncmp(name, __environ[i], l)
+		|| __environ[i][l] != '='); i++);
+	if (__environ[i]) return __environ[i] + l+1;
+	return NULL;
+}
diff --git a/src/env/putenv.c b/src/env/putenv.c
new file mode 100644
index 00000000..181a4181
--- /dev/null
+++ b/src/env/putenv.c
@@ -0,0 +1,59 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+extern char **__environ;
+char **__env_map;
+
+int __putenv(char *s, int a)
+{
+	int i=0, j=0;
+	char *end = strchr(s, '=');
+	size_t l = end-s+1;
+	char **newenv = 0;
+	char **newmap = 0;
+	static char **oldenv;
+	
+	if (!end || l == 1) return -1;
+	for (; __environ[i] && memcmp(s, __environ[i], l); i++);
+	if (a) {
+		if (!__env_map) {
+			__env_map = calloc(2, sizeof(char *));
+			if (__env_map) __env_map[0] = s;
+		} else {
+			for (; __env_map[j] && __env_map[j] != __environ[i]; j++);
+			if (!__env_map[j]) {
+				newmap = realloc(__env_map, sizeof(char *)*(j+2));
+				if (newmap) {
+					__env_map = newmap;
+					__env_map[j] = s;
+					__env_map[j+1] = NULL;
+				}
+			} else {
+				free(__env_map[j]);
+			}
+		}
+	}
+	if (!__environ[i]) {
+		newenv = malloc(sizeof(char *)*(i+2));
+		if (!newenv) {
+			if (a && __env_map) __env_map[j] = 0;
+			return -1;
+		}
+		memcpy(newenv, __environ, sizeof(char *)*i);
+		newenv[i] = s;
+		newenv[i+1] = 0;
+		__environ = newenv;
+		free(oldenv);
+		oldenv = __environ;
+	}
+
+	__environ[i] = s;
+	return 0;
+}
+
+int putenv(char *s)
+{
+	return __putenv(s, 0);
+}
diff --git a/src/env/setenv.c b/src/env/setenv.c
new file mode 100644
index 00000000..03e165c8
--- /dev/null
+++ b/src/env/setenv.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int __putenv(char *s, int a);
+
+int setenv(const char *var, const char *value, int overwrite)
+{
+	char *s;
+	int l1, l2;
+
+	if (strchr(var, '=')) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (!overwrite && getenv(var)) return 0;
+
+	l1 = strlen(var);
+	l2 = strlen(value);
+	s = malloc(l1+l2+2);
+	memcpy(s, var, l1);
+	s[l1] = '=';
+	memcpy(s+l1+1, value, l2);
+	s[l1+l2+1] = 0;
+	if (__putenv(s, 1)) {
+		free(s);
+		errno = ENOMEM;
+		return -1;
+	}
+	return 0;
+}
diff --git a/src/env/unsetenv.c b/src/env/unsetenv.c
new file mode 100644
index 00000000..7493d970
--- /dev/null
+++ b/src/env/unsetenv.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+extern char **__environ;
+extern char **__env_map;
+
+int unsetenv(const char *name)
+{
+	int i, j;
+	size_t l = strlen(name);
+
+	if (!*name || strchr(name, '=')) {
+		errno = EINVAL;
+		return -1;
+	}
+again:
+	for (i=0; __environ[i] && (memcmp(name, __environ[i], l) || __environ[i][l] != '='); i++);
+	if (__environ[i]) {
+		if (__env_map) {
+			for (j=0; __env_map[j] && __env_map[j] != __environ[i]; j++);
+			free (__env_map[j]);
+			for (; __env_map[j]; j++)
+				__env_map[j] = __env_map[j+1];
+		}
+		for (; __environ[i]; i++)
+			__environ[i] = __environ[i+1];
+		goto again;
+	}
+	return 0;
+}
diff --git a/src/errno/__errno_location.c b/src/errno/__errno_location.c
new file mode 100644
index 00000000..0a220b63
--- /dev/null
+++ b/src/errno/__errno_location.c
@@ -0,0 +1,11 @@
+#include <errno.h>
+#include "libc.h"
+
+#undef errno
+int errno;
+
+int *__errno_location(void)
+{
+	if (libc.errno_location) return libc.errno_location();
+	return &errno;
+}
diff --git a/src/errno/__strerror.h b/src/errno/__strerror.h
new file mode 100644
index 00000000..00eaf938
--- /dev/null
+++ b/src/errno/__strerror.h
@@ -0,0 +1,101 @@
+/* This file is sorted such that 'errors' which represent exceptional
+ * conditions under which a correct program may fail come first, followed
+ * by messages that indicate an incorrect program or system failure. The
+ * macro E() along with double-inclusion is used to ensure that ordering
+ * of the strings remains synchronized. */
+
+E(EILSEQ,       "Illegal byte sequence")
+E(EDOM,         "Argument outside domain")
+E(ERANGE,       "Result not representable")
+
+E(ENOTTY,       "Not a tty")
+E(EACCES,       "Permission denied")
+E(EPERM,        "Operation not permitted")
+E(ENOENT,       "No such file or directory")
+E(ESRCH,        "No such process")
+E(EEXIST,       "File exists")
+
+E(EOVERFLOW,    "Value too large for defined data type")
+E(ENOSPC,       "No space left on device")
+E(ENOMEM,       "Out of memory")
+
+E(EBUSY,        "Device or resource busy")
+E(EINTR,        "Interrupted system call")
+E(EAGAIN,       "Operation would block")
+E(ESPIPE,       "Illegal seek")
+
+E(EXDEV,        "Cross-device link")
+E(EROFS,        "Read-only file system")
+E(ENOTEMPTY,    "Directory not empty")
+
+E(ECONNRESET,   "Connection reset by peer")
+E(ETIMEDOUT,    "Connection timed out")
+E(ECONNREFUSED, "Connection refused")
+E(EHOSTDOWN,    "Host is down")
+E(EHOSTUNREACH, "No route to host")
+E(EADDRINUSE,   "Address already in use")
+
+E(EPIPE,        "Broken pipe")
+E(EIO,          "I/O error")
+E(ENXIO,        "No such device or address")
+E(ENOTBLK,      "Block device required")
+E(ENODEV,       "No such device")
+E(ENOTDIR,      "Not a directory")
+E(EISDIR,       "Is a directory")
+E(ETXTBSY,      "Text file busy")
+E(ENOEXEC,      "Exec format error")
+
+E(EINVAL,       "Invalid argument")
+
+E(E2BIG,        "Argument list too long")
+E(ELOOP,        "Too many levels of symbolic links")
+E(ENAMETOOLONG, "Filename too long")
+E(ENFILE,       "File table overflow")
+E(EMFILE,       "Too many open files")
+E(EBADF,        "Bad file number")
+E(ECHILD,       "No child processes")
+E(EFAULT,       "Bad address")
+E(EFBIG,        "File too large")
+E(EMLINK,       "Too many links")
+E(ENOLCK,       "No record locks available")
+
+E(EDEADLK,      "Resource deadlock would occur")
+E(ENOSYS,       "Function not supported")
+E(ENOMSG,       "No message of desired type")
+E(EIDRM,        "Identifier removed")
+E(ENOSTR,       "Device not a stream")
+E(ENODATA,      "No data available")
+E(ETIME,        "Timer expired")
+E(ENOSR,        "Out of streams resources")
+E(ENOLINK,      "Link has been severed")
+E(EPROTO,       "Protocol error")
+E(EBADMSG,      "Not a data message")
+E(EBADFD,       "File descriptor in bad state")
+E(ENOTSOCK,     "Socket operation on non-socket")
+E(EDESTADDRREQ, "Destination address required")
+E(EMSGSIZE,     "Message too long")
+E(EPROTOTYPE,   "Protocol wrong type for socket")
+E(ENOPROTOOPT,  "Protocol not available")
+E(EPROTONOSUPPORT,"Protocol not supported")
+E(ESOCKTNOSUPPORT,"Socket type not supported")
+E(EOPNOTSUPP,   "Operation not supported on socket")
+E(EPFNOSUPPORT, "Protocol family not supported")
+E(EAFNOSUPPORT, "Address family not supported by protocol")
+E(EADDRNOTAVAIL,"Cannot assign requested address")
+E(ENETDOWN,     "Network is down")
+E(ENETUNREACH,  "Network is unreachable")
+E(ENETRESET,    "Network dropped connection because of reset")
+E(ECONNABORTED, "Software caused connection abort")
+E(ENOBUFS,      "No buffer space available")
+E(EISCONN,      "Socket is connected")
+E(ENOTCONN,     "Socket is not connected")
+E(ESHUTDOWN,    "Cannot send after socket shutdown")
+E(EALREADY,     "Operation already in progress")
+E(EINPROGRESS,  "Operation now in progress")
+E(ESTALE,       "Stale NFS file handle")
+E(EREMOTEIO,    "Remote I/O error")
+E(EDQUOT,       "Quota exceeded")
+E(ENOMEDIUM,    "No medium found")
+E(EMEDIUMTYPE,  "Wrong medium type")
+
+E(0,            "Invalid error number")
diff --git a/src/errno/strerror.c b/src/errno/strerror.c
new file mode 100644
index 00000000..b8fbc6db
--- /dev/null
+++ b/src/errno/strerror.c
@@ -0,0 +1,22 @@
+#include <errno.h>
+#include <string.h>
+
+#define E(a,b) a,
+static const unsigned char errid[] = {
+#include "__strerror.h"
+};
+
+#undef E
+#define E(a,b) b "\0"
+static const char errmsg[] =
+#include "__strerror.h"
+;
+
+char *strerror(int e)
+{
+	const char *s;
+	int i;
+	for (i=0; errid[i] && errid[i] != e; i++);
+	for (s=errmsg; i; s++, i--) for (; *s; s++);
+	return (char *)s;
+}
diff --git a/src/exit/_Exit.c b/src/exit/_Exit.c
new file mode 100644
index 00000000..8ef85a8f
--- /dev/null
+++ b/src/exit/_Exit.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#define SYSCALL_NORETURN
+#include "syscall.h"
+
+void _Exit(int ec)
+{
+	syscall1(__NR_exit_group, ec);
+	syscall1(__NR_exit, ec);
+}
diff --git a/src/exit/abort.c b/src/exit/abort.c
new file mode 100644
index 00000000..9a1c3d40
--- /dev/null
+++ b/src/exit/abort.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <signal.h>
+
+void abort(void)
+{
+	raise(SIGABRT);
+	for (;;);
+}
diff --git a/src/exit/assert.c b/src/exit/assert.c
new file mode 100644
index 00000000..e87442a7
--- /dev/null
+++ b/src/exit/assert.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+void __assert_fail(const char *expr, const char *file, int line, const char *func)
+{
+	fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
+	fflush(NULL);
+	abort();
+}
diff --git a/src/exit/atexit.c b/src/exit/atexit.c
new file mode 100644
index 00000000..49c060e6
--- /dev/null
+++ b/src/exit/atexit.c
@@ -0,0 +1,57 @@
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "libc.h"
+
+/* Ensure that at least 32 atexit handlers can be registered without malloc */
+#define COUNT 32
+
+static struct fl
+{
+	struct fl *next;
+	void (*f[COUNT])(void);
+} builtin, *head;
+
+static int run_atexit_functions(void)
+{
+	int i;
+	for (; head; head=head->next) {
+		for (i=COUNT-1; i>=0 && !head->f[i]; i--);
+		for (; i>=0; i--) head->f[i]();
+	}
+	return 0;
+}
+
+int (*const __funcs_on_exit)(void) = run_atexit_functions;
+
+int atexit(void (*func)(void))
+{
+	static int lock;
+	int i;
+
+	/* Hook for atexit extensions */
+	if (libc.atexit) return libc.atexit(func);
+
+	LOCK(&lock);
+
+	/* Defer initialization of head so it can be in BSS */
+	if (!head) head = &builtin;
+
+	/* If the current function list is full, add a new one */
+	if (head->f[COUNT-1]) {
+		struct fl *new_fl = calloc(sizeof(struct fl), 1);
+		if (!new_fl) {
+			UNLOCK(&lock);
+			return -1;
+		}
+		new_fl->next = head;
+		head = new_fl;
+	}
+
+	/* Append function to the list. */
+	for (i=0; i<COUNT && head->f[i]; i++);
+	head->f[i] = func;
+
+	UNLOCK(&lock);
+	return 0;
+}
diff --git a/src/exit/exit.c b/src/exit/exit.c
new file mode 100644
index 00000000..d0c1bfc1
--- /dev/null
+++ b/src/exit/exit.c
@@ -0,0 +1,28 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "libc.h"
+
+/* __overflow.c and atexit.c override these */
+static int (*const dummy)() = 0;
+weak_alias(dummy, __funcs_on_exit);
+weak_alias(dummy, __fflush_on_exit);
+
+void exit(int code)
+{
+	static int lock;
+
+	/* If more than one thread calls exit, hang until _Exit ends it all */
+	LOCK(&lock);
+
+	/* Only do atexit & stdio flush if they were actually used */
+	if (__funcs_on_exit) __funcs_on_exit();
+	if (__fflush_on_exit) __fflush_on_exit(0);
+
+	/* Destructor s**t is kept separate from atexit to avoid bloat */
+	if (libc.fini) libc.fini();
+	if (libc.ldso_fini) libc.ldso_fini();
+
+	_Exit(code);
+	for(;;);
+}
diff --git a/src/fcntl/creat.c b/src/fcntl/creat.c
new file mode 100644
index 00000000..be05faae
--- /dev/null
+++ b/src/fcntl/creat.c
@@ -0,0 +1,9 @@
+#include <fcntl.h>
+#include "libc.h"
+
+int creat(const char *filename, mode_t mode)
+{
+	return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
+
+LFS64(creat);
diff --git a/src/fcntl/fcntl.c b/src/fcntl/fcntl.c
new file mode 100644
index 00000000..464dbf00
--- /dev/null
+++ b/src/fcntl/fcntl.c
@@ -0,0 +1,22 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fcntl(int fd, int cmd, ...)
+{
+	int r;
+	long arg;
+	va_list ap;
+	va_start(ap, cmd);
+	arg = va_arg(ap, long);
+	va_end(ap);
+	if (cmd == F_SETFL) arg |= O_LARGEFILE;
+	if (cmd == F_SETLKW) CANCELPT_BEGIN;
+	r = __syscall_fcntl(fd, cmd, arg);
+	if (cmd == F_SETLKW) CANCELPT_END;
+	return r;
+}
+
+LFS64(fcntl);
diff --git a/src/fcntl/open.c b/src/fcntl/open.c
new file mode 100644
index 00000000..4c1a591d
--- /dev/null
+++ b/src/fcntl/open.c
@@ -0,0 +1,21 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+int open(const char *filename, int flags, ...)
+{
+	int r;
+	mode_t mode;
+	va_list ap;
+	va_start(ap, flags);
+	mode = va_arg(ap, mode_t);
+	va_end(ap);
+	CANCELPT_BEGIN;
+	r = __syscall_open(filename, flags, mode);
+	CANCELPT_END;
+	return r;
+}
+
+LFS64(open);
diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c
new file mode 100644
index 00000000..eefa0901
--- /dev/null
+++ b/src/fcntl/openat.c
@@ -0,0 +1,21 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+int openat(int fd, const char *filename, int flags, ...)
+{
+	int r;
+	mode_t mode;
+	va_list ap;
+	va_start(ap, flags);
+	mode = va_arg(ap, mode_t);
+	va_end(ap);
+	CANCELPT_BEGIN;
+	r = syscall4(__NR_openat, fd, (long)filename, flags|O_LARGEFILE, mode);
+	CANCELPT_END;
+	return r;
+}
+
+LFS64(openat);
diff --git a/src/internal/atomic.h b/src/internal/atomic.h
new file mode 100644
index 00000000..a15f8c2a
--- /dev/null
+++ b/src/internal/atomic.h
@@ -0,0 +1,110 @@
+#ifndef _INTERNAA_ATOMIC_H
+#define _INTERNAA_ATOMIC_H
+
+#include <stdint.h>
+
+static inline int a_ctz_64(uint64_t x)
+{
+	int r;
+	__asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; addl $32,%0\n1:"
+		: "=r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
+	return r;
+}
+
+
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__( "lock ; andl %1, (%0) ; lock ; andl %2, 4(%0)"
+		: : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) );
+}
+
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__( "lock ; orl %1, (%0) ; lock ; orl %2, 4(%0)"
+		: : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) );
+}
+
+static inline void a_store_l(volatile void *p, long x)
+{
+	__asm__( "movl %1, %0" : "=m"(*(long *)p) : "r"(x) : "memory" );
+}
+
+static inline void a_or_l(volatile void *p, long v)
+{
+	__asm__( "lock ; orl %1, %0"
+		: "=m"(*(long *)p) : "r"(v) );
+}
+
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	__asm__( "lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) );
+	return t;
+}
+
+static inline long a_cas_l(volatile void *p, long t, long s)
+{
+	__asm__( "lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) );
+	return t;
+}
+
+static inline void *a_swap_p(void *volatile *x, void *v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*(void **)x) : "0"(v) );
+	return v;
+}
+static inline long a_swap_l(volatile void *x, long v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*(long *)x) : "0"(v) );
+	return v;
+}
+
+static inline void a_or(volatile void *p, int v)
+{
+	__asm__( "lock ; orl %1, %0"
+		: "=m"(*(int *)p) : "r"(v) );
+}
+
+static inline void a_and(volatile void *p, int v)
+{
+	__asm__( "lock ; andl %1, %0"
+		: "=m"(*(int *)p) : "r"(v) );
+}
+
+static inline int a_swap(volatile int *x, int v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) );
+	return v;
+}
+
+#define a_xchg a_swap
+
+static inline int a_fetch_add(volatile int *x, int v)
+{
+	__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) );
+	return v;
+}
+
+static inline void a_inc(volatile int *x)
+{
+	__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) );
+}
+
+static inline void a_dec(volatile int *x)
+{
+	__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) );
+}
+
+static inline void a_store(volatile int *p, int x)
+{
+	__asm__( "movl %1, %0" : "=m"(*p) : "r"(x) : "memory" );
+}
+
+static inline void a_spin()
+{
+	__asm__ __volatile__( "pause" : : : "memory" );
+}
+
+
+#endif
diff --git a/src/internal/clone.h b/src/internal/clone.h
new file mode 100644
index 00000000..cc84aeb4
--- /dev/null
+++ b/src/internal/clone.h
@@ -0,0 +1,22 @@
+#define CLONE_VM      0x00000100
+#define CLONE_FS      0x00000200
+#define CLONE_FILES   0x00000400
+#define CLONE_SIGHAND 0x00000800
+#define CLONE_PTRACE  0x00002000
+#define CLONE_VFORK   0x00004000
+#define CLONE_PARENT  0x00008000
+#define CLONE_THREAD  0x00010000
+#define CLONE_NEWNS   0x00020000
+#define CLONE_SYSVSEM 0x00040000
+#define CLONE_SETTLS  0x00080000
+#define CLONE_PARENT_SETTID 0x00100000
+#define CLONE_CHILD_CLEARTID 0x00200000
+#define CLONE_DETACHED 0x00400000
+#define CLONE_UNTRACED 0x00800000
+#define CLONE_CHILD_SETTID 0x01000000
+#define CLONE_NEWUTS	0x04000000
+#define CLONE_NEWIPC	0x08000000
+#define CLONE_NEWUSER	0x10000000
+#define CLONE_NEWPID	0x20000000
+#define CLONE_NEWNET	0x40000000
+#define CLONE_IO	0x80000000
diff --git a/src/internal/futex.h b/src/internal/futex.h
new file mode 100644
index 00000000..c0453822
--- /dev/null
+++ b/src/internal/futex.h
@@ -0,0 +1,16 @@
+#ifndef _INTERNAL_FUTEX_H
+#define _INTERNAL_FUTEX_H
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_FD		2
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+
+int __futex(volatile int *, int, int, void *);
+
+#endif
diff --git a/src/internal/libc.c b/src/internal/libc.c
new file mode 100644
index 00000000..5e8e9d95
--- /dev/null
+++ b/src/internal/libc.c
@@ -0,0 +1,3 @@
+#include "libc.h"
+
+struct libc libc;
diff --git a/src/internal/libc.h b/src/internal/libc.h
new file mode 100644
index 00000000..e353f363
--- /dev/null
+++ b/src/internal/libc.h
@@ -0,0 +1,43 @@
+#ifndef LIBC_H
+#define LIBC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define libc __libc
+extern struct libc {
+	void (*lock)(volatile int *);
+	void (*cancelpt)(int);
+	int (*atexit)(void (*)(void));
+	void (*fini)(void);
+	void (*ldso_fini)(void);
+	int *(*errno_location)(void);
+	volatile int threads_minus_1;
+	int (*rsyscall)(int, long, long, long, long, long, long);
+	void (**tsd_keys)(void *);
+} libc;
+
+
+/* Designed to avoid any overhead in non-threaded processes */
+void __lock(volatile int *);
+#define LOCK(x) (libc.threads_minus_1 ? (__lock(x),1) : ((void)(x),1))
+#define UNLOCK(x) (*(x)=0)
+#define CANCELPT(x) (libc.cancelpt ? libc.cancelpt((x)),0 : (void)(x),0)
+#define CANCELPT_BEGIN CANCELPT(1)
+#define CANCELPT_END CANCELPT(0)
+
+extern char **__environ;
+#define environ __environ
+
+#undef weak_alias
+#define weak_alias(old, new) \
+	extern __typeof(old) new __attribute__((weak, alias(#old)))
+
+#undef LFS64_2
+//#define LFS64_2(x, y) weak_alias(x, y)
+#define LFS64_2(x, y) extern __typeof(x) y
+
+#undef LFS64
+#define LFS64(x) LFS64_2(x, x##64)
+
+#endif
diff --git a/src/internal/locale_impl.h b/src/internal/locale_impl.h
new file mode 100644
index 00000000..c268124f
--- /dev/null
+++ b/src/internal/locale_impl.h
@@ -0,0 +1,5 @@
+#include <locale.h>
+
+struct __locale {
+	int dummy;
+};
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
new file mode 100644
index 00000000..b7892103
--- /dev/null
+++ b/src/internal/pthread_impl.h
@@ -0,0 +1,68 @@
+#ifndef _PTHREAD_IMPL_H
+#define _PTHREAD_IMPL_H
+
+#include <pthread.h>
+#include <sched.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <setjmp.h>
+#include <string.h>
+#include <time.h>
+#include "libc.h"
+#include "syscall.h"
+#include "atomic.h"
+#include "futex.h"
+
+#define pthread __pthread
+
+struct pthread {
+	struct pthread *self, *join;
+	int errno_val;
+	pid_t tid, pid;
+	volatile int canceldisable, cancelasync, cancelpoint, cancel;
+	unsigned char *map_base;
+	size_t map_size;
+	void *start_arg;
+	void *(*start)(void *);
+	void *result;
+	jmp_buf exit_jmp_buf;
+	int detached;
+	int exitlock;
+	unsigned long tlsdesc[4];
+	struct __ptcb *cancelbuf;
+	void **tsd;
+	int tsd_used;
+	pthread_attr_t attr;
+	int *errno_ptr;
+};
+
+static inline struct pthread *__pthread_self()
+{
+	struct pthread *self;
+	__asm__ ("movl %%gs:0,%0" : "=r" (self) );
+	return self;
+}
+
+#define SIGCANCEL 32
+#define SIGSYSCALL 33
+#define SIGTIMER  32 /* ?? */
+
+int __set_thread_area(unsigned long *);
+int __set_pthread_self(void *);
+int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
+int __libc_sigprocmask(int, const sigset_t *, sigset_t *);
+void __lock(volatile int *);
+void __unmapself(void *, size_t);
+
+int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
+void __wait(volatile int *, volatile int *, int, int);
+void __wake(volatile int *, int, int);
+
+#define DEFAULT_STACK_SIZE (16384-PAGE_SIZE)
+#define DEFAULT_GUARD_SIZE PAGE_SIZE
+
+#endif
diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h
new file mode 100644
index 00000000..1e9159f6
--- /dev/null
+++ b/src/internal/stdio_impl.h
@@ -0,0 +1,100 @@
+#ifndef _STDIO_IMPL_H
+#define _STDIO_IMPL_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <math.h>
+#include <float.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define UNGET 4
+
+#define FLOCK(f) LOCK(&f->lock)
+#define FUNLOCK(f) UNLOCK(&f->lock)
+
+#define F_PERM 1
+#define F_NORD 4
+#define F_NOWR 8
+#define F_EOF 16
+#define F_ERR 32
+
+struct __FILE_s {
+	unsigned flags;
+	unsigned char *rpos, *rstop;
+	unsigned char *rend, *wend;
+	unsigned char *wpos, *wstop;
+	unsigned char *wbase;
+	unsigned char *dummy01[3];
+	unsigned char *buf;
+	size_t buf_size;
+	FILE *prev, *next;
+	int fd;
+	int pipe_pid;
+	long dummy2;
+	short dummy3;
+	char dummy4;
+	signed char lbf;
+	int lock;
+	int lockcount;
+	void *owner;
+	off_t off;
+	int (*flush)(FILE *);
+	void **wide_data; /* must be NULL */
+	size_t (*read)(FILE *, unsigned char *, size_t);
+	size_t (*write)(FILE *, const unsigned char *, size_t);
+	off_t (*seek)(FILE *, off_t, int);
+	int mode;
+	int (*close)(FILE *);
+};
+
+size_t __stdio_read(FILE *, unsigned char *, size_t);
+size_t __stdio_write(FILE *, const unsigned char *, size_t);
+off_t __stdio_seek(FILE *, off_t, int);
+int __stdio_close(FILE *);
+
+int __overflow(FILE *, int);
+int __oflow(FILE *);
+int __uflow(FILE *);
+int __underflow(FILE *);
+
+int __fseeko(FILE *, off_t, int);
+int __fseeko_unlocked(FILE *, off_t, int);
+off_t __ftello(FILE *);
+off_t __ftello_unlocked(FILE *);
+size_t __fwritex(const unsigned char *, size_t, FILE *);
+int __putc_unlocked(int, FILE *);
+
+FILE *__fdopen(int, const char *);
+
+extern struct ofl
+{
+	FILE *head;
+	int lock;
+} __ofl;
+
+#define OFLLOCK() LOCK(&__ofl.lock)
+#define OFLUNLOCK() UNLOCK(&__ofl.lock)
+#define ofl_head (__ofl.head)
+
+#define feof(f) ((f)->flags & F_EOF)
+#define ferror(f) ((f)->flags & F_ERR)
+
+/* Caller-allocated FILE * operations */
+FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
+int __fclose_ca(FILE *);
+
+#endif
diff --git a/src/internal/syscall.c b/src/internal/syscall.c
new file mode 100644
index 00000000..4f159e0b
--- /dev/null
+++ b/src/internal/syscall.c
@@ -0,0 +1,11 @@
+#include <errno.h>
+#include <unistd.h>
+
+long __syscall_ret(unsigned long r)
+{
+	if (r >= (unsigned long)-1 - 4096) {
+		errno = -(long)r;
+		return -1;
+	}
+	return (long)r;
+}
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
new file mode 100644
index 00000000..4b3c0a73
--- /dev/null
+++ b/src/internal/syscall.h
@@ -0,0 +1,469 @@
+#ifndef _SYSCALL_H
+#define _SYSCALL_H
+
+#define SYSCALL_LL(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+
+#define SYSCALL_SIGSET_SIZE 8
+
+#if defined(SYSCALL_STANDALONE)
+#include <errno.h>
+static inline long __syscall_ret(unsigned long r)
+{
+	if (r >= (unsigned long)-1 - 4096) {
+		errno = -(long)r;
+		return -1;
+	}
+	return (long)r;
+}
+#elif defined(SYSCALL_NORETURN)
+static inline long __syscall_ret(unsigned long r)
+{
+	for(;;);
+	return 0;
+}
+#elif defined(SYSCALL_RETURN_ERRNO)
+static inline long __syscall_ret(unsigned long r)
+{
+	return -r;
+}
+#else
+extern long __syscall_ret(unsigned long);
+#endif
+
+#define SYSCALL0 "int $128"
+
+#ifdef __PIC__
+#define SYSCALL "xchgl %%ebx,%2\n\t" SYSCALL0 "\n\txchgl %%ebx,%2"
+#define EBX "m"
+#else
+#define SYSCALL SYSCALL0
+#define EBX "b"
+#endif
+
+static inline long syscall0(long n)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL0 : "=a"(ret) : "a"(n) : "memory");
+	return __syscall_ret(ret);
+}
+
+static inline long syscall1(long n, long a1)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), EBX(a1) : "memory");
+	return __syscall_ret(ret);
+}
+
+static inline long syscall2(long n, long a1, long a2)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), EBX(a1), "c"(a2) : "memory");
+	return __syscall_ret(ret);
+}
+
+static inline long syscall3(long n, long a1, long a2, long a3)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), EBX(a1), "c"(a2), "d"(a3) : "memory");
+	return __syscall_ret(ret);
+}
+
+static inline long syscall4(long n, long a1, long a2, long a3, long a4)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), EBX(a1), "c"(a2), "d"(a3), "S"(a4) : "memory");
+	return __syscall_ret(ret);
+}
+
+static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
+{
+	unsigned long ret;
+	__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), EBX(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
+	return __syscall_ret(ret);
+}
+
+#ifdef __PIC__
+/* note: it's probably only safe to use this when a6 is on the stack */
+static inline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("xchgl %%ebx,%2 ; pushl %1 ; pushl %%ebp ; movl %%eax,%%ebp ; movl 4(%%esp),%%eax ; int $128 ; popl %%ebp ; popl %%ecx ; xchgl %%ebx,%2"
+		: "=a"(ret) : "g"(n), EBX(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "a"(a6) : "memory");
+	return __syscall_ret(ret);
+}
+#else
+static inline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("pushl %%ebp ; mov %1, %%ebp ; xchg %%ebp, %7 ; int $128 ; popl %%ebp"
+		: "=a"(ret) : "g"(n), EBX(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "a"(a6) : "memory");
+	return __syscall_ret(ret);
+}
+#endif
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76   /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86old		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_vm86		166
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl              172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64		180
+#define __NR_pwrite64		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188
+#define __NR_putpmsg		189
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_madvise1		219
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+/* 223 is unused */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#define __NR_mq_timedreceive	(__NR_mq_open+3)
+#define __NR_mq_notify		(__NR_mq_open+4)
+#define __NR_mq_getsetattr	(__NR_mq_open+5)
+#define __NR_kexec_load		283
+#define __NR_waitid		284
+/* #define __NR_sys_setaltroot	285 */
+#define __NR_add_key		286
+#define __NR_request_key	287
+#define __NR_keyctl		288
+#define __NR_ioprio_set		289
+#define __NR_ioprio_get		290
+#define __NR_inotify_init	291
+#define __NR_inotify_add_watch	292
+#define __NR_inotify_rm_watch	293
+#define __NR_migrate_pages	294
+#define __NR_openat		295
+#define __NR_mkdirat		296
+#define __NR_mknodat		297
+#define __NR_fchownat		298
+#define __NR_futimesat		299
+#define __NR_fstatat64		300
+#define __NR_unlinkat		301
+#define __NR_renameat		302
+#define __NR_linkat		303
+#define __NR_symlinkat		304
+#define __NR_readlinkat		305
+#define __NR_fchmodat		306
+#define __NR_faccessat		307
+#define __NR_pselect6		308
+#define __NR_ppoll		309
+#define __NR_unshare		310
+#define __NR_set_robust_list	311
+#define __NR_get_robust_list	312
+#define __NR_splice		313
+#define __NR_sync_file_range	314
+#define __NR_tee		315
+#define __NR_vmsplice		316
+#define __NR_move_pages		317
+#define __NR_getcpu		318
+#define __NR_epoll_pwait	319
+#define __NR_utimensat		320
+#define __NR_signalfd		321
+#define __NR_timerfd_create	322
+#define __NR_eventfd		323
+#define __NR_fallocate		324
+#define __NR_timerfd_settime	325
+#define __NR_timerfd_gettime	326
+#define __NR_signalfd4		327
+#define __NR_eventfd2		328
+#define __NR_epoll_create1	329
+#define __NR_dup3		330
+#define __NR_pipe2		331
+#define __NR_inotify_init1	332
+#define __NR_preadv		333
+#define __NR_pwritev		334
+
+
+#undef O_LARGEFILE
+#define O_LARGEFILE 0100000
+
+/* the following are needed for iso c functions to use */
+#define __syscall_open(filename, flags, mode) syscall3(__NR_open, (long)(filename), (flags)|O_LARGEFILE, (mode))
+#define __syscall_read(fd, buf, len)          syscall3(__NR_read, (fd), (long)(buf), (len))
+#define __syscall_write(fd, buf, len)         syscall3(__NR_write, (fd), (long)(buf), (len))
+#define __syscall_close(fd)                   syscall1(__NR_close, (fd))
+#define __syscall_fcntl(fd, cmd, arg)         syscall3(__NR_fcntl64, (fd), (cmd), (long)(arg))
+#define __syscall_dup2(old, new)              syscall2(__NR_dup2, (old), (new))
+#define __syscall_unlink(path)                syscall1(__NR_unlink, (long)(path))
+#define __syscall_getpid()                    syscall0(__NR_getpid)
+#define __syscall_kill(pid,sig)               syscall2(__NR_kill, (pid), (sig))
+#define __syscall_sigaction(sig,new,old)      syscall4(__NR_rt_sigaction, (sig), (long)(new), (long)(old), SYSCALL_SIGSET_SIZE)
+#define __syscall_ioctl(fd,ioc,arg)           syscall3(__NR_ioctl, (fd), (ioc), (long)(arg))
+#define __syscall_exit(code)                  syscall1(__NR_exit, code)
+
+#define __NEED_off_t
+#include <bits/alltypes.h>
+
+static inline off_t __syscall_lseek(int fd, off_t offset, int whence)
+{
+	off_t result;
+	return syscall5(__NR__llseek, fd, offset>>32, offset, (long)&result, whence) ? -1 : result;
+}
+
+#endif
diff --git a/src/internal/util.h b/src/internal/util.h
new file mode 100644
index 00000000..7c7c3a17
--- /dev/null
+++ b/src/internal/util.h
@@ -0,0 +1,5 @@
+#ifndef _INTERNAL_UTIL_H
+#define _INTERNAL_UTIL_H
+
+
+#endif
diff --git a/src/ipc/ftok.c b/src/ipc/ftok.c
new file mode 100644
index 00000000..cd6002ed
--- /dev/null
+++ b/src/ipc/ftok.c
@@ -0,0 +1,10 @@
+#include <sys/ipc.h>
+#include <sys/stat.h>
+
+key_t ftok(const char *path, int id)
+{
+	struct stat st;
+	if (stat(path, &st) < 0) return -1;
+
+	return ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 0xff) << 24));
+}
diff --git a/src/ipc/ipc.h b/src/ipc/ipc.h
new file mode 100644
index 00000000..9edd5ecf
--- /dev/null
+++ b/src/ipc/ipc.h
@@ -0,0 +1,13 @@
+#define IPCOP_semop      1
+#define IPCOP_semget     2
+#define IPCOP_semctl     3
+#define IPCOP_msgsnd    11
+#define IPCOP_msgrcv    12
+#define IPCOP_msgget    13
+#define IPCOP_msgctl    14
+#define IPCOP_shmat     21
+#define IPCOP_shmdt     22
+#define IPCOP_shmget    23
+#define IPCOP_shmctl    24
+
+#define IPC_MODERN   0x100
diff --git a/src/ipc/semctl.c b/src/ipc/semctl.c
new file mode 100644
index 00000000..7ada116b
--- /dev/null
+++ b/src/ipc/semctl.c
@@ -0,0 +1,18 @@
+#include <sys/sem.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semctl(int id, int num, int cmd, ...)
+{
+	long arg;
+	va_list ap;
+	va_start(ap, cmd);
+	arg = va_arg(ap, long);
+	va_end(ap);
+#ifdef __NR_semctl
+	return syscall4(__NR_semctl, id, num, cmd, arg);
+#else
+	return syscall5(__NR_ipc, IPCOP_semctl, id, num, cmd | 0x100, (long)&arg);
+#endif
+}
diff --git a/src/ipc/semget.c b/src/ipc/semget.c
new file mode 100644
index 00000000..2dcf6eac
--- /dev/null
+++ b/src/ipc/semget.c
@@ -0,0 +1,12 @@
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semget(key_t key, int n, int fl)
+{
+#ifdef __NR_semget
+	return syscall3(__NR_semget, key, n, fl);
+#else
+	return syscall4(__NR_ipc, IPCOP_semget, key, n, fl);
+#endif
+}
diff --git a/src/ipc/semop.c b/src/ipc/semop.c
new file mode 100644
index 00000000..48d8a654
--- /dev/null
+++ b/src/ipc/semop.c
@@ -0,0 +1,12 @@
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semop(int id, struct sembuf *buf, size_t n)
+{
+#ifdef __NR_semop
+	return syscall3(__NR_semop, id, (long)buf, n);
+#else
+	return syscall5(__NR_ipc, IPCOP_semop, id, n, 0, (long)buf);
+#endif
+}
diff --git a/src/ipc/shmat.c b/src/ipc/shmat.c
new file mode 100644
index 00000000..ff65b6a4
--- /dev/null
+++ b/src/ipc/shmat.c
@@ -0,0 +1,17 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#ifdef __NR_shmat
+void *shmat(int id, const void *addr, int flag)
+{
+	return syscall3(__NR_shmat, id, (long)addr, flag);
+}
+#else
+void *shmat(int id, const void *addr, int flag)
+{
+	unsigned long ret;
+	ret = syscall5(__NR_ipc, IPCOP_shmat, id, flag, (long)&addr, (long)addr);
+	return (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)addr;
+}
+#endif
diff --git a/src/ipc/shmctl.c b/src/ipc/shmctl.c
new file mode 100644
index 00000000..da357fa8
--- /dev/null
+++ b/src/ipc/shmctl.c
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmctl(int id, int cmd, struct shmid_ds *buf)
+{
+#ifdef __NR_shmctl
+	return syscall3(__NR_shmctl, id, cmd, (long)buf);
+#else
+	return syscall4(__NR_ipc, IPCOP_shmctl, id, cmd | IPC_MODERN, (long)buf);
+#endif
+}
diff --git a/src/ipc/shmdt.c b/src/ipc/shmdt.c
new file mode 100644
index 00000000..e04188f9
--- /dev/null
+++ b/src/ipc/shmdt.c
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmdt(const void *addr)
+{
+#ifdef __NR_shmdt
+	return syscall1(__NR_shmdt, (long)addr);
+#else
+	return syscall2(__NR_ipc, IPCOP_shmdt, (long)addr);
+#endif
+}
diff --git a/src/ipc/shmget.c b/src/ipc/shmget.c
new file mode 100644
index 00000000..86e254af
--- /dev/null
+++ b/src/ipc/shmget.c
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmget(key_t key, size_t size, int flag)
+{
+#ifdef __NR_shmget
+	return syscall3(__NR_shmget, key, size, flag);
+#else
+	return syscall4(__NR_ipc, IPCOP_shmget, key, size, flag);
+#endif
+}
diff --git a/src/linux/brk.c b/src/linux/brk.c
new file mode 100644
index 00000000..3c2982c6
--- /dev/null
+++ b/src/linux/brk.c
@@ -0,0 +1,6 @@
+#include "syscall.h"
+
+int brk(void *end)
+{
+	return -(syscall1(__NR_brk, (long)end) == -1);
+}
diff --git a/src/linux/chroot.c b/src/linux/chroot.c
new file mode 100644
index 00000000..b5af62dc
--- /dev/null
+++ b/src/linux/chroot.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int chroot(const char *path)
+{
+	return syscall1(__NR_chroot, (long)path);
+}
diff --git a/src/linux/daemon.c b/src/linux/daemon.c
new file mode 100644
index 00000000..632d1203
--- /dev/null
+++ b/src/linux/daemon.c
@@ -0,0 +1,31 @@
+#include <fcntl.h>
+#include <unistd.h>
+
+int daemon(int nochdir, int noclose)
+{
+	int fd;
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	if (setsid() < 0) return -1;
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	if (!nochdir) chdir("/");
+	if (!noclose && (fd = open("/dev/null", O_RDWR)) >= 0) {
+		dup2(fd, 0);
+		dup2(fd, 1);
+		dup2(fd, 2);
+		if (fd > 2) close(fd);
+	}
+
+	return 0;
+}
diff --git a/src/linux/epoll_create.c b/src/linux/epoll_create.c
new file mode 100644
index 00000000..c9dea8ce
--- /dev/null
+++ b/src/linux/epoll_create.c
@@ -0,0 +1,7 @@
+#include <sys/epoll.h>
+#include "syscall.h"
+
+int epoll_create(int size)
+{
+	return syscall1(__NR_epoll_create, size);
+}
diff --git a/src/linux/epoll_create1.c b/src/linux/epoll_create1.c
new file mode 100644
index 00000000..2e82e995
--- /dev/null
+++ b/src/linux/epoll_create1.c
@@ -0,0 +1,7 @@
+#include <sys/epoll.h>
+#include "syscall.h"
+
+int epoll_create1(int flags)
+{
+	return syscall1(__NR_epoll_create1, flags);
+}
diff --git a/src/linux/epoll_ctl.c b/src/linux/epoll_ctl.c
new file mode 100644
index 00000000..4214f407
--- /dev/null
+++ b/src/linux/epoll_ctl.c
@@ -0,0 +1,7 @@
+#include <sys/epoll.h>
+#include "syscall.h"
+
+int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
+{
+	return syscall4(__NR_epoll_ctl, fd, op, fd2, (long)ev);
+}
diff --git a/src/linux/epoll_pwait.c b/src/linux/epoll_pwait.c
new file mode 100644
index 00000000..5aaacba6
--- /dev/null
+++ b/src/linux/epoll_pwait.c
@@ -0,0 +1,7 @@
+#include <sys/epoll.h>
+#include "syscall.h"
+
+int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
+{
+	return syscall6(__NR_epoll_pwait, fd, (long)ev, cnt, to, (long)sigs, 8);
+}
diff --git a/src/linux/epoll_wait.c b/src/linux/epoll_wait.c
new file mode 100644
index 00000000..8a68ebdd
--- /dev/null
+++ b/src/linux/epoll_wait.c
@@ -0,0 +1,7 @@
+#include <sys/epoll.h>
+#include "syscall.h"
+
+int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
+{
+	return syscall4(__NR_epoll_wait, fd, (long)ev, cnt, to);
+}
diff --git a/src/linux/getdtablesize.c b/src/linux/getdtablesize.c
new file mode 100644
index 00000000..623a6af3
--- /dev/null
+++ b/src/linux/getdtablesize.c
@@ -0,0 +1,9 @@
+#include <limits.h>
+#include <sys/resource.h>
+
+int getdtablesize(void)
+{
+	struct rlimit rl;
+	getrlimit(RLIMIT_NOFILE, &rl);
+	return rl.rlim_max < INT_MAX ? rl.rlim_max : INT_MAX;
+}
diff --git a/src/linux/gethostid.c b/src/linux/gethostid.c
new file mode 100644
index 00000000..ea65611a
--- /dev/null
+++ b/src/linux/gethostid.c
@@ -0,0 +1,4 @@
+long gethostid()
+{
+	return 0;
+}
diff --git a/src/linux/getopt_long.c b/src/linux/getopt_long.c
new file mode 100644
index 00000000..d80cd1b6
--- /dev/null
+++ b/src/linux/getopt_long.c
@@ -0,0 +1,52 @@
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <getopt.h>
+#include <stdio.h>
+
+static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+	if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
+	if ((longonly && argv[optind][1]) ||
+		(argv[optind][1] == '-' && argv[optind][2]))
+	{
+		int i;
+		for (i=0; longopts[i].name; i++) {
+			const char *name = longopts[i].name;
+			char *opt = argv[optind]+1;
+			if (*opt == '-') opt++;
+			while (*name && *name++ == *opt++);
+			if (*name || (*opt && *opt != '=')) continue;
+			if (*opt == '=') {
+				if (!longopts[i].has_arg) continue;
+				optarg = opt+1;
+			} else {
+				if (longopts[i].has_arg == required_argument) {
+					if (!(optarg = argv[++optind]))
+						return ':';
+				} else optarg = NULL;
+			}
+			optind++;
+			if (idx) *idx = i;
+			if (longopts[i].flag) {
+				*longopts[i].flag = longopts[i].val;
+				return 0;
+			}
+			return longopts[i].val;
+		}
+		if (argv[optind][1] == '-') {
+			optind++;
+			return '?';
+		}
+	}
+	return getopt(argc, argv, optstring);
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
diff --git a/src/linux/getpagesize.c b/src/linux/getpagesize.c
new file mode 100644
index 00000000..5ede652b
--- /dev/null
+++ b/src/linux/getpagesize.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <limits.h>
+
+int getpagesize(void)
+{
+	return PAGE_SIZE;
+}
diff --git a/src/linux/getpass.c b/src/linux/getpass.c
new file mode 100644
index 00000000..d439a2a5
--- /dev/null
+++ b/src/linux/getpass.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+char *getpass(const char *prompt)
+{
+	int fd;
+	struct termios s, t;
+	ssize_t l;
+	static char password[128];
+
+	if ((fd = open("/dev/tty", O_RDONLY|O_NOCTTY)) < 0) fd = 0;
+
+	tcgetattr(fd, &t);
+	s = t;
+	t.c_lflag &= ~(ECHO|ISIG);
+	t.c_lflag |= ICANON;
+	t.c_iflag &= ~(INLCR|IGNCR);
+	t.c_iflag |= ICRNL;
+	tcsetattr(fd, TCSAFLUSH, &t);
+	tcdrain(fd);
+
+	fputs(prompt, stderr);
+	fflush(stderr);
+
+	l = read(fd, password, sizeof password);
+	if (l >= 0) {
+		if (l > 0 && password[l-1] == '\n') l--;
+		password[l] = 0;
+	}
+
+	tcsetattr(fd, TCSAFLUSH, &s);
+
+	if (fd > 2) close(fd);
+
+	return password;
+}
diff --git a/src/linux/initgroups.c b/src/linux/initgroups.c
new file mode 100644
index 00000000..ef9bc10a
--- /dev/null
+++ b/src/linux/initgroups.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include <grp.h>
+#include <limits.h>
+
+int getgrouplist(const char *, gid_t, gid_t *, int *);
+int setgroups(size_t, const gid_t *);
+
+int initgroups(const char *user, gid_t gid)
+{
+	gid_t groups[NGROUPS_MAX];
+	int count;
+	if (getgrouplist(user, gid, groups, &count) < 0) return -1;
+	return setgroups(count, groups);
+}
diff --git a/src/linux/klogctl.c b/src/linux/klogctl.c
new file mode 100644
index 00000000..6c288aff
--- /dev/null
+++ b/src/linux/klogctl.c
@@ -0,0 +1,7 @@
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int klogctl (int type, char *buf, int len)
+{
+	return syscall3(__NR_syslog, type, (long)buf, len);
+}
diff --git a/src/linux/mntent.c b/src/linux/mntent.c
new file mode 100644
index 00000000..e3735666
--- /dev/null
+++ b/src/linux/mntent.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <string.h>
+#include <mntent.h>
+
+FILE *setmntent(const char *name, const char *mode)
+{
+	return fopen(name, mode);
+}
+
+int endmntent(FILE *f)
+{
+	fclose(f);
+	return 1;
+}
+
+struct mntent *getmntent(FILE *f)
+{
+	static char linebuf[256];
+	static struct mntent mnt;
+	int cnt, n[8];
+
+	mnt.mnt_freq = 0;
+	mnt.mnt_passno = 0;
+
+	do {
+		fgets(linebuf, sizeof linebuf, f);
+		if (feof(f)) return NULL;
+		cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
+			n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
+			&mnt.mnt_freq, &mnt.mnt_passno);
+	} while (cnt >= 8 && linebuf[n[0]] != '#');
+
+	linebuf[n[1]] = 0;
+	linebuf[n[3]] = 0;
+	linebuf[n[5]] = 0;
+	linebuf[n[7]] = 0;
+
+	mnt.mnt_fsname = linebuf+n[0];
+	mnt.mnt_dir = linebuf+n[2];
+	mnt.mnt_type = linebuf+n[4];
+	mnt.mnt_opts = linebuf+n[6];
+
+	return &mnt;
+}
+
+int addmntent(FILE *f, const struct mntent *mnt)
+{
+	fseek(f, 0, SEEK_END);
+	return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n",
+		mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
+		mnt->mnt_freq, mnt->mnt_passno) < 0;
+}
+
+char *hasmntopt(const struct mntent *mnt, const char *opt)
+{
+	return strstr(mnt->mnt_opts, opt);
+}
diff --git a/src/linux/mount.c b/src/linux/mount.c
new file mode 100644
index 00000000..61299d48
--- /dev/null
+++ b/src/linux/mount.c
@@ -0,0 +1,8 @@
+#include <sys/mount.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data)
+{
+	return syscall5(__NR_mount, (long)special, (long)dir, (long)fstype, flags, (long)data);
+}
diff --git a/src/linux/prctl.c b/src/linux/prctl.c
new file mode 100644
index 00000000..d5516830
--- /dev/null
+++ b/src/linux/prctl.c
@@ -0,0 +1,13 @@
+#include <sys/prctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int prctl(int op, ...)
+{
+	unsigned long x[4];
+	int i;
+	va_list ap;
+	va_start(ap, op);
+	for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
+	return syscall5(__NR_prctl, op, x[0], x[1], x[2], x[3]);
+}
diff --git a/src/linux/reboot.c b/src/linux/reboot.c
new file mode 100644
index 00000000..68830d8e
--- /dev/null
+++ b/src/linux/reboot.c
@@ -0,0 +1,8 @@
+#include <sys/reboot.h>
+#include <errno.h>
+
+int reboot(int type)
+{
+	errno = ENOSYS;
+	return -1;
+}
diff --git a/src/linux/sbrk.c b/src/linux/sbrk.c
new file mode 100644
index 00000000..56f60d1b
--- /dev/null
+++ b/src/linux/sbrk.c
@@ -0,0 +1,7 @@
+#include <stddef.h>
+#include "syscall.h"
+
+void *sbrk(ptrdiff_t inc)
+{
+	return (void *)syscall1(__NR_brk, syscall1(__NR_brk, 0)+inc);
+}
diff --git a/src/linux/sendfile.c b/src/linux/sendfile.c
new file mode 100644
index 00000000..bfbc40ae
--- /dev/null
+++ b/src/linux/sendfile.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
+{
+	return syscall4(__NR_sendfile, out_fd, in_fd, (long)ofs, count);
+}
+
+LFS64(sendfile);
diff --git a/src/linux/setgroups.c b/src/linux/setgroups.c
new file mode 100644
index 00000000..2368aa0d
--- /dev/null
+++ b/src/linux/setgroups.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int setgroups(int count, const gid_t list[])
+{
+	/* this depends on our gid_t being 32bit */
+	return syscall2(__NR_setgroups32, count, (long)list);
+}
diff --git a/src/linux/sethostname.c b/src/linux/sethostname.c
new file mode 100644
index 00000000..f61e0cb4
--- /dev/null
+++ b/src/linux/sethostname.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int sethostname(const char *name, size_t len)
+{
+	return syscall2(__NR_sethostname, (long)name, len);
+}
diff --git a/src/linux/settimeofday.c b/src/linux/settimeofday.c
new file mode 100644
index 00000000..bd7e4104
--- /dev/null
+++ b/src/linux/settimeofday.c
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int settimeofday(const struct timeval *tv, void *tz)
+{
+	return syscall2(__NR_settimeofday, (long)tv, 0);
+}
diff --git a/src/linux/signalfd.c b/src/linux/signalfd.c
new file mode 100644
index 00000000..ecda263e
--- /dev/null
+++ b/src/linux/signalfd.c
@@ -0,0 +1,7 @@
+#include <sys/signalfd.h>
+#include "syscall.h"
+
+int signalfd(int fd, const sigset_t *sigs, int flags)
+{
+	return syscall3(__NR_signalfd, fd, (long)sigs, 8);
+}
diff --git a/src/linux/stime.c b/src/linux/stime.c
new file mode 100644
index 00000000..ec3ba821
--- /dev/null
+++ b/src/linux/stime.c
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+
+int stime(time_t *t)
+{
+	struct timeval tv = { .tv_sec = *t, .tv_usec = 0 };
+	return settimeofday(&tv, (void *)0);
+}
diff --git a/src/linux/swapoff.c b/src/linux/swapoff.c
new file mode 100644
index 00000000..f6fa794e
--- /dev/null
+++ b/src/linux/swapoff.c
@@ -0,0 +1,8 @@
+#include <sys/swap.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int swapoff(const char *path)
+{
+	return syscall1(__NR_swapoff, (long)path);
+}
diff --git a/src/linux/swapon.c b/src/linux/swapon.c
new file mode 100644
index 00000000..13d2876b
--- /dev/null
+++ b/src/linux/swapon.c
@@ -0,0 +1,8 @@
+#include <sys/swap.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int swapon(const char *path, int flags)
+{
+	return syscall2(__NR_swapon, (long)path, flags);
+}
diff --git a/src/linux/sysinfo.c b/src/linux/sysinfo.c
new file mode 100644
index 00000000..98669472
--- /dev/null
+++ b/src/linux/sysinfo.c
@@ -0,0 +1,9 @@
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+struct sysinfo;
+
+int sysinfo(struct sysinfo *info)
+{
+	return syscall1(__NR_sysinfo, (long)info);
+}
diff --git a/src/linux/umount.c b/src/linux/umount.c
new file mode 100644
index 00000000..c35f994d
--- /dev/null
+++ b/src/linux/umount.c
@@ -0,0 +1,8 @@
+#include <sys/mount.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int umount(const char *special)
+{
+	return syscall1(__NR_umount, (long)special);
+}
diff --git a/src/linux/umount2.c b/src/linux/umount2.c
new file mode 100644
index 00000000..cab93fd0
--- /dev/null
+++ b/src/linux/umount2.c
@@ -0,0 +1,8 @@
+#include <sys/mount.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int umount2(const char *special, int flags)
+{
+	return syscall2(__NR_umount2, (long)special, flags);
+}
diff --git a/src/linux/utimes.c b/src/linux/utimes.c
new file mode 100644
index 00000000..99a3b2b8
--- /dev/null
+++ b/src/linux/utimes.c
@@ -0,0 +1,13 @@
+#include <sys/time.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+int utimes(const char *path, const struct timeval times[2])
+{
+	long ktimes[2];
+	if (times) {
+		ktimes[0] = times[0].tv_sec;
+		ktimes[1] = times[1].tv_sec;
+	}
+	return syscall2(__NR_utime, (long)path, times ? (long)ktimes : 0);
+}
diff --git a/src/linux/wait3.c b/src/linux/wait3.c
new file mode 100644
index 00000000..dd63707c
--- /dev/null
+++ b/src/linux/wait3.c
@@ -0,0 +1,11 @@
+#include <sys/wait.h>
+#include <sys/resource.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+pid_t wait4(pid_t, int *, int, struct rusage *);
+
+pid_t wait3(int *status, int options, struct rusage *usage)
+{
+	return wait4(-1, status, options, usage);
+}
diff --git a/src/linux/wait4.c b/src/linux/wait4.c
new file mode 100644
index 00000000..dda942d3
--- /dev/null
+++ b/src/linux/wait4.c
@@ -0,0 +1,19 @@
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <string.h>
+#define SYSCALL_STANDALONE
+#include "syscall.h"
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage)
+{
+	pid_t ret = syscall4(__NR_wait4, pid, (long)status, options, (long)usage);
+	/* Fixup kernel time_t... */
+	if (usage) {
+		long kusage[4];
+		memcpy(kusage, usage, sizeof kusage);
+		memmove((struct timeval *)usage + 2, (long *)usage + 4, sizeof *usage - 2*sizeof(struct timeval));
+		usage->ru_utime = (struct timeval){ kusage[0], kusage[1] };
+		usage->ru_stime = (struct timeval){ kusage[2], kusage[3] };
+	}
+	return ret;
+}
diff --git a/src/locale/catclose.c b/src/locale/catclose.c
new file mode 100644
index 00000000..02cd3e5c
--- /dev/null
+++ b/src/locale/catclose.c
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+int catclose (nl_catd catd)
+{
+	return 0;
+}
diff --git a/src/locale/catgets.c b/src/locale/catgets.c
new file mode 100644
index 00000000..bbee8986
--- /dev/null
+++ b/src/locale/catgets.c
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+char *catgets (nl_catd catd, int set_id, int msg_id, const char *s)
+{
+	return (char *)s;
+}
diff --git a/src/locale/catopen.c b/src/locale/catopen.c
new file mode 100644
index 00000000..4423c4d9
--- /dev/null
+++ b/src/locale/catopen.c
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+nl_catd catopen (const char *name, int oflag)
+{
+	return (nl_catd)-1;
+}
diff --git a/src/locale/duplocale.c b/src/locale/duplocale.c
new file mode 100644
index 00000000..dd445d46
--- /dev/null
+++ b/src/locale/duplocale.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+
+locale_t duplocale(locale_t old)
+{
+	locale_t new;
+	new = calloc(1, sizeof *new);
+	if (new) memcpy(new, old, sizeof *new);
+	return new;
+}
diff --git a/src/locale/freelocale.c b/src/locale/freelocale.c
new file mode 100644
index 00000000..4e089f22
--- /dev/null
+++ b/src/locale/freelocale.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include "locale_impl.h"
+
+void freelocale(locale_t l)
+{
+	free(l);
+}
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
new file mode 100644
index 00000000..4e46c7e4
--- /dev/null
+++ b/src/locale/iconv.c
@@ -0,0 +1,568 @@
+#include <iconv.h>
+#include <errno.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+
+#define UTF_32BE    000
+#define UTF_16LE    001
+#define UTF_16BE    002
+#define UTF_32LE    003
+#define UCS2BE      004
+#define UCS2LE      005
+#define WCHAR_T     007
+
+#define US_ASCII    021
+#define UTF_8       022
+#define LATIN_9     024
+#define TIS_620     025
+#define JIS_0201    026
+
+#define EUC         031
+#define EUC_TW      032
+#define SHIFT_JIS   033
+#define BIG5        034
+#define GBK         035
+
+/* FIXME: these are not implemented yet
+ * EUC:   A1-FE A1-FE
+ * GBK:   81-FE 40-7E,80-FE
+ * Big5:  A1-FE 40-7E,A1-FE
+ */
+
+/* Definitions of charmaps. Each charmap consists of:
+ * 1. Empty-string-terminated list of null-terminated aliases.
+ * 2. Special type code or bits per character.
+ * 3. Number of elided entries (128 for specials).
+ * 4. Character table (size determined by fields 2 and 3). */
+
+static const unsigned char charmaps[] =
+"utf8\0\0\022\x80"
+"wchart\0\0\007\x80"
+
+"ucs2\0ucs2be\0\0\004\x80"
+"ucs2le\0\0\005\x80"
+
+"utf16\0utf16be\0\0\002\x80"
+"utf16le\0\0\001\x80"
+
+"ucs4\0ucs4be\0utf32\0utf32be\0\0\000\x80"
+"ucs4le\0utf32le\0\0\003\x80"
+
+"ascii\0iso646\0usascii\0\0\021\x80"
+"latin1\0iso88591\0\0\x09\x80"
+"latin9\0iso885915\0\0\024\x80"
+"tis620\0iso885911\0\0\025\x80"
+"jis0201\0\0\026\x80"
+
+"iso88592\0\0\x0a\x21"
+"\x04\x61\x1b\x14\x29\x3d\x69\x75\x0a\x2a"
+"\x60\x79\x45\x56\x5e\xad\xf4\xb5\x17\x2c"
+"\x05\x6d\x2b\x14\x2d\x3e\x6d\x75\x2c\x2e"
+"\x61\x7d\x55\x96\x5e\xdd\xfa\xc5\x17\x55"
+"\xc1\x08\x23\x10\x31\x39\x19\x74\x0c\x43"
+"\xc9\x60\xb4\x8c\x46\xcd\x38\xe3\x10\x44"
+"\x43\x1d\x35\x0d\x35\x50\x59\x73\x0d\x56"
+"\x6e\x69\x03\x17\x37\xdd\x88\xf5\x4d\x55"
+"\xe1\x88\x33\x10\x39\x3a\x1d\x74\x4e\x43"
+"\xe9\x64\xb4\xce\x46\xed\xb8\xf3\x50\x44"
+"\x44\x21\x35\x0f\x3d\x51\xd9\x73\x4f\x56"
+"\x6f\xe9\x13\x17\x3f\xfd\x8c\x95\x2d"
+
+"iso88593\0\0\x0a\x21"
+"\x26\x61\x3b\x0a\x29\x00\x90\x74\x0a\x2a"
+"\x30\x79\xe5\x11\x4d\xad\x00\xb0\x17\x2c"
+"\x27\xc9\x32\x0b\x2d\xb5\x94\x74\x0b\x2e"
+"\x31\x7d\xf5\x51\x4d\xbd\x00\xc0\x17\x30"
+"\xc1\x08\x03\x00\x31\x0a\x21\x74\x0c\x32"
+"\xc9\x28\xb3\x0c\x33\xcd\x38\xf3\x0c\x00"
+"\xd1\x48\x33\x0d\x35\x20\x59\x73\x0d\x47"
+"\xd9\x68\xb3\x0d\x37\x6c\x71\xf5\x0d\x38"
+"\xe1\x88\x03\x00\x39\x0b\x25\x74\x0e\x3a"
+"\xe9\xa8\xb3\x0e\x3b\xed\xb8\xf3\x0e\x00"
+"\xf1\xc8\x33\x0f\x3d\x21\xd9\x73\x4f\x47"
+"\xf9\xe8\xb3\x0f\x3f\x6d\x75\x95\x2d"
+
+"iso88594\0\0\x0a\x21"
+"\x04\xe1\x64\x15\x29\x28\xed\x74\x0a\x2a"
+"\x60\x49\x24\x92\x59\xad\xf4\xf5\x0a\x2c"
+"\x05\x6d\x7b\x15\x2d\x29\xf1\x74\x2c\x2e"
+"\x61\x4d\x34\xd2\x59\x4a\xf9\xb5\x14\x40"
+"\xc1\x08\x33\x0c\x31\xc5\x18\xe3\x12\x43"
+"\xc9\x60\xb4\x8c\x45\xcd\x38\xa3\x12\x44"
+"\x45\x31\x65\x13\x35\xd5\x58\x73\x0d\x36"
+"\x72\x69\xb3\x0d\x37\x68\xa9\xf5\x4d\x40"
+"\xe1\x88\x33\x0e\x39\xe5\x98\xf3\x52\x43"
+"\xe9\x64\xb4\xce\x45\xed\xb8\xb3\x52\x44"
+"\x46\x35\x75\x13\x3d\xf5\xd8\x73\x0f\x3e"
+"\x73\xe9\xb3\x0f\x3f\x69\xad\x95\x2d"
+
+"iso88595\0\0\x0e\x21"
+"\x01\x84\x00\x31\x40\x10\x10\x05\x84\x01"
+"\x71\x40\x20\x10\x09\x84\x02\xb1\x40\x30"
+"\x10\xad\x80\x03\xf1\x40\x40\x10\x11\x84"
+"\x04\x31\x41\x50\x10\x15\x84\x05\x71\x41"
+"\x60\x10\x19\x84\x06\xb1\x41\x70\x10\x1d"
+"\x84\x07\xf1\x41\x80\x10\x21\x84\x08\x31"
+"\x42\x90\x10\x25\x84\x09\x71\x42\xa0\x10"
+"\x29\x84\x0a\xb1\x42\xb0\x10\x2d\x84\x0b"
+"\xf1\x42\xc0\x10\x31\x84\x0c\x31\x43\xd0"
+"\x10\x35\x84\x0d\x71\x43\xe0\x10\x39\x84"
+"\x0e\xb1\x43\xf0\x10\x3d\x84\x0f\xf1\x43"
+"\x00\x11\x41\x84\x10\x31\x44\x10\x11\x45"
+"\x84\x11\x71\x44\x20\x11\x49\x84\x12\xb1"
+"\x44\x30\x11\x4d\x84\x13\xf1\x44\x58\x84"
+"\x51\x84\x14\x31\x45\x50\x11\x55\x84\x15"
+"\x71\x45\x60\x11\x59\x84\x16\xb1\x45\x70"
+"\x11\xa7\x80\x17\xf1\x45\x00"
+
+"iso88596\0\0\x0b\x21"
+"\x00\x00\x00\x00\x48\x01\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x18\xdc\x0a\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\xc0\x86\x01\x00\x00"
+"\x00\x7c\x18\x00\x21\x16\xf1\x88\x49\x5c"
+"\x62\x13\x9f\x18\xc5\x29\x56\xf1\x8a\x59"
+"\xdc\x62\x17\xbf\x18\xc6\x31\x96\xf1\x8c"
+"\x69\x5c\x63\x1b\xdf\x18\xc7\x39\xd6\x31"
+"\x00\x00\x00\x00\x00\x00\x00\xc8\x41\x16"
+"\xf2\x90\x89\x5c\x64\x23\x1f\x19\xc9\x49"
+"\x56\xf2\x92\x99\xdc\x64\x27\x3f\x19\xca"
+"\x51\x96\x32\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00"
+
+"iso88597\0\0\x0e\x21"
+"\x18\x60\x06\x38\x0a\xb0\x82\xaf\xa0\x29"
+"\x70\x0a\xa0\x02\xa9\x80\xde\xb0\x0a\xb0"
+"\x02\xad\x00\x00\x50\x01\xc2\x02\xb1\x80"
+"\x2c\x30\x0b\x10\x0e\x85\x83\xe1\x70\x0b"
+"\x20\x0e\x89\x83\xe2\xb0\x0b\x30\x0e\xbd"
+"\x80\xe3\xf0\x38\x40\x0e\x91\x83\xe4\x30"
+"\x39\x50\x0e\x95\x83\xe5\x70\x39\x60\x0e"
+"\x99\x83\xe6\xb0\x39\x70\x0e\x9d\x83\xe7"
+"\xf0\x39\x80\x0e\xa1\x03\x00\x30\x3a\x90"
+"\x0e\xa5\x83\xe9\x70\x3a\xa0\x0e\xa9\x83"
+"\xea\xb0\x3a\xb0\x0e\xad\x83\xeb\xf0\x3a"
+"\xc0\x0e\xb1\x83\xec\x30\x3b\xd0\x0e\xb5"
+"\x83\xed\x70\x3b\xe0\x0e\xb9\x83\xee\xb0"
+"\x3b\xf0\x0e\xbd\x83\xef\xf0\x3b\x00\x0f"
+"\xc1\x83\xf0\x30\x3c\x10\x0f\xc5\x83\xf1"
+"\x70\x3c\x20\x0f\xc9\x83\xf2\xb0\x3c\x30"
+"\x0f\xcd\x83\xf3\x00\x00\x00"
+
+"iso88598\0\0\x0e\x21"
+"\x00\x80\x28\x30\x0a\x90\x02\xa5\x80\x29"
+"\x70\x0a\xa0\x02\xa9\xc0\x35\xb0\x0a\xb0"
+"\x02\xad\x80\x2b\xf0\x0a\xc0\x02\xb1\x80"
+"\x2c\x30\x0b\xd0\x02\xb5\x80\x2d\x70\x0b"
+"\xe0\x02\xb9\xc0\x3d\xb0\x0b\xf0\x02\xbd"
+"\x80\x2f\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x70\x01"
+"\x42\x17\xd1\x85\x74\x31\x5d\x50\x17\xd5"
+"\x85\x75\x71\x5d\x60\x17\xd9\x85\x76\xb1"
+"\x5d\x70\x17\xdd\x85\x77\xf1\x5d\x80\x17"
+"\xe1\x85\x78\x31\x5e\x90\x17\xe5\x85\x79"
+"\x71\x5e\xa0\x17\xe9\x85\x7a\x01\x00\x00"
+"\x00\x0e\xe0\x03\x08\x00\x00"
+
+"iso88599\0\0\x09\x50"
+"\x1e\xa3\x49\x9b\x46\xad\x9a\xb5\x6b\xd8"
+"\xb2\x69\xdb\xc6\x0d\xa6\xd7\x6f\xe0\xc2"
+"\x89\x1b\x47\xae\x9c\xb9\x73\xe8\xd2\xa9"
+"\x5b\xc7\xae\x9d\xbb\x77\x1f\xe3\xc9\x9b"
+"\x47\xaf\x9e\xbd\x7b\xf8\xf2\xe9\xdb\xc7"
+"\x2f\xe6\xd7\x7f"
+
+"iso885910\0\0\x0e\x21"
+"\x04\x81\x44\x20\x12\xa8\x04\x28\x81\x4d"
+"\x70\x0a\xec\x04\x10\x01\x58\x60\x16\xf4"
+"\x05\xad\x80\x5a\xa0\x14\xc0\x02\x05\xc1"
+"\x44\x30\x12\xac\x04\x29\xc1\x4d\x70\x0b"
+"\xf0\x04\x11\x41\x58\x70\x16\xf8\x05\x15"
+"\xe0\x5a\xb0\x14\x00\x04\xc1\x80\x30\x30"
+"\x0c\x10\x03\xc5\x80\x31\xe0\x12\x30\x04"
+"\xc9\x00\x46\xb0\x0c\x58\x04\xcd\x80\x33"
+"\xf0\x0c\x40\x03\x45\x01\x53\x30\x0d\x50"
+"\x03\xd5\x80\x35\x80\x16\x60\x03\x72\x81"
+"\x36\xb0\x0d\x70\x03\xdd\x80\x37\xf0\x0d"
+"\x04\x04\xe1\x80\x38\x30\x0e\x90\x03\xe5"
+"\x80\x39\xf0\x12\x34\x04\xe9\x40\x46\xb0"
+"\x0e\x5c\x04\xed\x80\x3b\xf0\x0e\xc0\x03"
+"\x46\x41\x53\x30\x0f\xd0\x03\xf5\x80\x3d"
+"\x90\x16\xe0\x03\x73\x81\x3e\xb0\x0f\xf0"
+"\x03\xfd\x80\x3f\x80\x13\x00"
+
+"iso885913\0\0\x0e\x21"
+"\x1d\xa0\x28\x30\x0a\x90\x02\x1e\xa0\x29"
+"\x70\x0a\x60\x03\xa9\x80\x55\xb0\x0a\xb0"
+"\x02\xad\x80\x2b\x60\x0c\xc0\x02\xb1\x80"
+"\x2c\x30\x0b\x70\x80\xb5\x80\x2d\x70\x0b"
+"\xe0\x03\xb9\xc0\x55\xb0\x0b\xf0\x02\xbd"
+"\x80\x2f\x60\x0e\x10\x04\x2e\x01\x40\x60"
+"\x10\x10\x03\xc5\x00\x46\x20\x11\x30\x04"
+"\xc9\x40\x5e\x60\x11\x88\x04\x36\x81\x4a"
+"\xb0\x13\x80\x05\x43\x41\x51\x30\x0d\x30"
+"\x05\xd5\x80\x35\x70\x0d\xc8\x05\x41\x81"
+"\x56\xa0\x16\x70\x03\x7b\x41\x5f\xf0\x0d"
+"\x14\x04\x2f\x41\x40\x70\x10\x90\x03\xe5"
+"\x40\x46\x30\x11\x34\x04\xe9\x80\x5e\x70"
+"\x11\x8c\x04\x37\xc1\x4a\xc0\x13\x84\x05"
+"\x44\x81\x51\x30\x0f\x34\x05\xf5\x80\x3d"
+"\x70\x0f\xcc\x05\x42\xc1\x56\xb0\x16\xf0"
+"\x03\x7c\x81\x5f\x90\x01\x02"
+
+"iso885914\0\0\x0d\x21"
+"\x02\x7e\xc0\x8f\x02\x85\xb0\x10\x14\xfc"
+"\x29\x00\xf4\xa9\x40\xd0\x2f\x78\x79\xdf"
+"\x0a\x5c\x01\x5e\xf0\xf0\x1f\x1e\x24\x84"
+"\x04\x20\x1f\xe4\x6d\x81\x95\x0f\xf4\x57"
+"\x7e\xd0\x83\xf9\x79\x4f\xe8\x0b\x7d\x98"
+"\x07\x06\xc1\x40\x18\x0c\x03\x62\x50\x0c"
+"\x8c\xc1\x31\x40\x06\xc9\x40\x19\x2c\x03"
+"\x66\xd0\x0c\x9c\xc1\x33\xa0\x0b\xd1\x40"
+"\x1a\x4c\x03\x6a\x50\x0d\xac\x81\x9a\xc7"
+"\x06\xd9\x40\x1b\x6c\x03\x6e\xd0\x0d\xec"
+"\xc2\x37\x00\x07\xe1\x40\x1c\x8c\x03\x72"
+"\x50\x0e\xcc\xc1\x39\x40\x07\xe9\x40\x1d"
+"\xac\x03\x76\xd0\x0e\xdc\xc1\x3b\xa8\x0b"
+"\xf1\x40\x1e\xcc\x03\x7a\x50\x0f\xec\xc1"
+"\x9a\xc7\x07\xf9\x40\x1f\xec\x03\x7e\xd0"
+"\x0f\xee\xc2\x3f\x00"
+
+"iso885916\0\0\x0e\x21"
+"\x04\x41\x41\x10\x14\xb0\x82\x1e\x20\x58"
+"\x70\x0a\x84\x05\xa9\x00\x86\xb0\x0a\xe4"
+"\x05\xad\x80\x5e\xb0\x17\xc0\x02\xb1\x00"
+"\x43\x20\x14\xf4\x05\x1d\xa0\x2d\x70\x0b"
+"\xf8\x05\x0d\x41\x86\xb0\x0b\x48\x05\x53"
+"\x01\x5e\xc0\x17\x00\x03\xc1\x80\x30\x20"
+"\x10\x10\x03\x06\x81\x31\x70\x0c\x20\x03"
+"\xc9\x80\x32\xb0\x0c\x30\x03\xcd\x80\x33"
+"\xf0\x0c\x40\x04\x43\x81\x34\x30\x0d\x50"
+"\x03\x50\x81\x35\xa0\x15\xc0\x05\xd9\x80"
+"\x36\xb0\x0d\x70\x03\x18\x81\x86\xf0\x0d"
+"\x80\x03\xe1\x80\x38\x30\x10\x90\x03\x07"
+"\x81\x39\x70\x0e\xa0\x03\xe9\x80\x3a\xb0"
+"\x0e\xb0\x03\xed\x80\x3b\xf0\x0e\x44\x04"
+"\x44\x81\x3c\x30\x0f\xd0\x03\x51\x81\x3d"
+"\xb0\x15\xc4\x05\xf9\x80\x3e\xb0\x0f\xf0"
+"\x03\x19\xc1\x86\xf0\x0f\x00"
+
+"windows1252\0\0\x0e\x00"
+"\xac\x20\x00\xa0\x01\x4a\x06\x1e\xa0\x09"
+"\x08\x02\x86\x80\xc6\x02\x0c\x08\x16\xe4"
+"\x80\x52\x01\x00\xd0\x17\x00\x00\x00\x00"
+"\x06\x98\x01\x72\x80\x1d\xa0\x08\x38\x01"
+"\x52\x80\xdc\x82\x48\x18\x16\xe8\x80\x53"
+"\x01\x00\xe0\x17\xe0\x05\xa0\x40\x28\x20"
+"\x0a\x8c\x02\xa4\x40\x29\x60\x0a\x9c\x02"
+"\xa8\x40\x2a\xa0\x0a\xac\x02\xac\x40\x2b"
+"\xe0\x0a\xbc\x02\xb0\x40\x2c\x20\x0b\xcc"
+"\x02\xb4\x40\x2d\x60\x0b\xdc\x02\xb8\x40"
+"\x2e\xa0\x0b\xec\x02\xbc\x40\x2f\xe0\x0b"
+"\xfc\x02\xc0\x40\x30\x20\x0c\x0c\x03\xc4"
+"\x40\x31\x60\x0c\x1c\x03\xc8\x40\x32\xa0"
+"\x0c\x2c\x03\xcc\x40\x33\xe0\x0c\x3c\x03"
+"\xd0\x40\x34\x20\x0d\x4c\x03\xd4\x40\x35"
+"\x60\x0d\x5c\x03\xd8\x40\x36\xa0\x0d\x6c"
+"\x03\xdc\x40\x37\xe0\x0d\x7c\x03\xe0\x40"
+"\x38\x20\x0e\x8c\x03\xe4\x40\x39\x60\x0e"
+"\x9c\x03\xe8\x40\x3a\xa0\x0e\xac\x03\xec"
+"\x40\x3b\xe0\x0e\xbc\x03\xf0\x40\x3c\x20"
+"\x0f\xcc\x03\xf4\x40\x3d\x60\x0f\xdc\x03"
+"\xf8\x40\x3e\xa0\x0f\xec\x03\xfc\x40\x3f"
+"\xe0\x0f\xfc\x03"
+;
+
+
+
+static int fuzzycmp(const char *a, const char *b)
+{
+	for (; *a && *b; a++, b++) {
+		while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;
+		if ((*a|32U) != *b) return 1;
+	}
+	return *a != *b;
+}
+
+static int find_charmap(const char *name)
+{
+	const unsigned char *s;
+	for (s=charmaps; *s; ) {
+		if (!fuzzycmp(name, s)) {
+			for (; *s; s+=strlen(s)+1);
+			return s+1-charmaps;
+		}
+		s += strlen(s)+1;
+		if (!*s) s += ((128-s[2])*s[1]+7)/8 + 3;
+	}
+	return -1;
+}
+
+iconv_t iconv_open(const char *to, const char *from)
+{
+	int f, t;
+
+	if ((t = find_charmap(to)) < 0 || (f = find_charmap(from)) < 0) {
+		errno = EINVAL;
+		return (iconv_t)-1;
+	}
+
+	return (void *)(f<<16 | t);
+}
+
+int iconv_close(iconv_t cd)
+{
+	return 0;
+}
+
+static unsigned get_16(const unsigned char *s, int e)
+{
+	e &= 1;
+	return s[e]<<8 | s[1-e];
+}
+
+static void put_16(unsigned char *s, unsigned c, int e)
+{
+	e &= 1;
+	s[e] = c>>8;
+	s[1-e] = c;
+}
+
+static unsigned get_32(const unsigned char *s, int e)
+{
+	return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
+}
+
+static void put_32(unsigned char *s, unsigned c, int e)
+{
+	s[e^0] = c>>24;
+	s[e^1] = c>>16;
+	s[e^2] = c>>8;
+	s[e^3] = c;
+}
+
+
+
+#define GET_MAPPING(m, i, n) ( (1<<(n))-1 & ( \
+	(m)[(i)*(n)/8] >> ((n)%8*(i)%8) | \
+	(m)[(i)*(n)/8+1] << 8-((n)%8*(i)%8) | \
+	(m)[(i)*(n)/8+2] << 16-((n)%8*(i)%8)     ) )
+
+static unsigned get_mapping(const unsigned char *m, unsigned c, unsigned n)
+{
+	switch (n) {
+	default:
+	case 9:  return m[c*9/8]>>c%8 | m[c*9/8+1]<<8-c%8 & (1<<n)-1;
+	case 10: return m[c*10/8]>>2*c%8 | m[c*10/8+1]<<8-2*c%8 & (1<<n)-1;
+	case 11: return GET_MAPPING(m, c, 11);
+	case 13: return GET_MAPPING(m, c, 13);
+	case 14: return GET_MAPPING(m, c, 14);
+	}
+}
+
+/* Adapt as needed */
+#define mbrtowc_utf8 mbrtowc
+#define wctomb_utf8 wctomb
+
+#include <stdio.h>
+size_t iconv(iconv_t cd0, char **in, size_t *inb, char **out, size_t *outb)
+{
+	size_t x=0;
+	unsigned long cd = (unsigned long)cd0;
+	unsigned to = cd & 0xffff;
+	unsigned from = cd >> 16;
+	const unsigned char *map = charmaps+from+2;
+	const unsigned char *tomap = charmaps+to+2;
+	mbstate_t st = {0};
+	wchar_t wc;
+	unsigned c, d;
+	size_t k, l;
+	int err;
+	unsigned elide = map[-1] + 128;
+	unsigned toelide = tomap[-1] + 128;
+	unsigned char type = map[-2];
+	unsigned char totype = tomap[-2];
+
+	if (!in || !*in || !*inb) return 0;
+
+	for (; *inb; *in+=l, *inb-=l) {
+		c = *(unsigned char *)*in;
+		l = 1;
+		if (type < 8 || c >= 0x80) switch (type) {
+		case UTF_8:
+			l = mbrtowc_utf8(&wc, *in, *inb, &st);
+			if (!l) l++;
+			else if (l == (size_t)-1) goto ilseq;
+			else if (l == (size_t)-2) goto starved;
+			c = wc;
+			break;
+		case LATIN_9:
+			if ((unsigned)c - 0xa4 <= 0xbe - 0xa4) {
+				static const unsigned char map[] = {
+					0, 0x60, 0, 0x61, 0, 0, 0, 0, 0, 0, 0,
+					0, 0, 0, 0, 0x7d, 0, 0, 0, 0x7e, 0, 0, 0,
+					0x52, 0x53, 0x78
+				};
+				if (c == 0xa4) c = 0x20ac;
+				else if (map[c-0xa5]) c = 0x100 | map[c-0xa5];
+			}
+			break;
+		case TIS_620:
+			if (c >= 0xa1) c += 0x0e01-0xa1;
+			break;
+		case JIS_0201:
+			if (c >= 0xa1)
+				if (c <= 0xdf) c += 0xff61-0xa1;
+				else goto ilseq;
+			break;
+		case 9: case 10: case 11: case 13: case 14:
+			if (c < elide) break;
+			c = get_mapping(map, c-elide, type);
+			if (!c) {
+		case US_ASCII:
+				goto ilseq;
+			}
+			break;
+		case WCHAR_T:
+			l = sizeof(wchar_t);
+			if (*inb < l) goto starved;
+			c = *(wchar_t *)*in;
+			if (0) {
+		case UTF_32BE:
+		case UTF_32LE:
+			l = 4;
+			if (*inb < 4) goto starved;
+			c = get_32(*in, type);
+			}
+			if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;
+			break;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16BE:
+		case UTF_16LE:
+			l = 2;
+			if (*inb < 2) goto starved;
+			c = get_16(*in, type);
+			if ((unsigned)(c-0xdc00) < 0x400) goto ilseq;
+			if ((unsigned)(c-0xd800) < 0x400) {
+				if (type-UCS2BE < 2U) goto ilseq;
+				l = 4;
+				if (*inb < 4) goto starved;
+				d = get_16(*in + 2, from);
+				if ((unsigned)(c-0xdc00) >= 0x400) goto ilseq;
+				c = ((c-0xd800)<<10) | (d-0xdc00);
+			}
+			break;
+		}
+
+		switch (totype) {
+		case WCHAR_T:
+			if (*outb < sizeof(wchar_t)) goto toobig;
+			*(wchar_t *)*out = c;
+			*out += sizeof(wchar_t);
+			*outb -= sizeof(wchar_t);
+			break;
+		case UTF_8:
+			if (*outb < 4) {
+				char tmp[4];
+				k = wctomb_utf8(tmp, c);
+				if (*outb < k) goto toobig;
+				memcpy(*out, tmp, k);
+			} else k = wctomb_utf8(*out, c);
+			*out += k;
+			*outb -= k;
+			break;
+		case TIS_620:
+			if (c-0xe01u <= 0xff-0xa1)
+				c -= 0xe01-0xa1;
+			else if (c >= 0xa1)
+				goto ascii;
+			goto revout;
+		case JIS_0201:
+			if (c-0xff61u <= 0xdf-0xa1)
+				c -= 0xff61-0xa1;
+			else if (c >= 0xa1)
+				goto ascii;
+			goto revout;
+		case LATIN_9:
+			if (c == 0x20ac) {
+				c=0xa4;
+			} else if (c-0x150u<=0x12 && (1<<c-0x150 & 0x3000c)) {
+				static const unsigned char map[] =
+					{ 0xa6,0xa8,0xbc,0xbd };
+				c = map[c&3];
+			} else if (c-0x178u<=0x7 && (1<<c-0x178 & 0x61)) {
+				static const unsigned char map[] =
+					{ 0xbe,0,0,0,0,0xb4,0xb8 };
+				c = map[c&7];
+			} else if (c>0x100 ||
+				c-0xa5u<=0xbeu-0xa5
+				&& (1<<c-0xa5 & 0x388800a))
+		case US_ASCII: ascii:
+			if (c > 0x7f) x++, c='*';
+		case 9: case 10: case 11: case 13: case 14:
+			if (*outb < 1) goto toobig;
+			if (c < toelide) {
+			revout:
+				*(*out)++ = c;
+				*outb -= 1;
+				break;
+			}
+			for (d=0; d<256-toelide; d++) {
+				if (c == get_mapping(tomap, d, totype)) {
+					c = d + toelide;
+					goto revout;
+				}
+			}
+			x++;
+			c = '*';
+			goto revout;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16BE:
+		case UTF_16LE:
+			if (c < 0x10000) {
+				if (*outb < 2) goto toobig;
+				put_16(*out, c, totype);
+				*out += 2;
+				*outb -= 2;
+				break;
+			}
+			if (type-UCS2BE < 2U) goto ilseq;
+			if (*outb < 4) goto toobig;
+			put_16(*out, (c>>10)|0xd800, totype);
+			put_16(*out + 2, (c&0x3ff)|0xdc00, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		case UTF_32BE:
+		case UTF_32LE:
+			if (*outb < 4) goto toobig;
+			put_32(*out, c, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		}
+	}
+	return x;
+ilseq:
+	err = EILSEQ;
+	x = -1;
+	goto end;
+toobig:
+	err = E2BIG;
+	goto end;
+starved:
+	err = EINVAL;
+end:
+	errno = err;
+	return x;
+}
diff --git a/src/locale/intl.c b/src/locale/intl.c
new file mode 100644
index 00000000..964f7da1
--- /dev/null
+++ b/src/locale/intl.c
@@ -0,0 +1,67 @@
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+
+char *gettext(const char *msgid)
+{
+	return (char *) msgid;
+}
+
+char *dgettext(const char *domainname, const char *msgid)
+{
+	return (char *) msgid;
+}
+
+char *dcgettext(const char *domainname, const char *msgid, int category)
+{
+	return (char *) msgid;
+}
+
+char *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+char *dngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+char *textdomain(const char *domainname)
+{
+	static const char default_str[] = "messages";
+
+	if (domainname && *domainname && strcmp(domainname, default_str)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	return (char *) default_str;
+}
+
+char *bindtextdomain(const char *domainname, const char *dirname)
+{
+	static const char dir[] = "/";
+
+	if (!domainname || !*domainname
+		|| (dirname && ((dirname[0] != '/') || dirname[1]))
+		) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	return (char *) dir;
+}
+
+char *bind_textdomain_codeset(const char *domainname, const char *codeset)
+{
+	if (!domainname || !*domainname || (codeset && strcasecmp(codeset, "UTF-8"))) {
+		errno = EINVAL;
+	}
+	return NULL;
+}
diff --git a/src/locale/isalnum_l.c b/src/locale/isalnum_l.c
new file mode 100644
index 00000000..b8a6eef3
--- /dev/null
+++ b/src/locale/isalnum_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isalnum_l(int c, locale_t l)
+{
+	return isalnum(c);
+}
diff --git a/src/locale/isalpha_l.c b/src/locale/isalpha_l.c
new file mode 100644
index 00000000..2e1205c6
--- /dev/null
+++ b/src/locale/isalpha_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isalpha_l(int c, locale_t l)
+{
+	return isalpha(c);
+}
diff --git a/src/locale/isblank_l.c b/src/locale/isblank_l.c
new file mode 100644
index 00000000..27479aa1
--- /dev/null
+++ b/src/locale/isblank_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isblank_l(int c, locale_t l)
+{
+	return isblank(c);
+}
diff --git a/src/locale/iscntrl_l.c b/src/locale/iscntrl_l.c
new file mode 100644
index 00000000..ca596fa9
--- /dev/null
+++ b/src/locale/iscntrl_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int iscntrl_l(int c, locale_t l)
+{
+	return iscntrl(c);
+}
diff --git a/src/locale/isdigit_l.c b/src/locale/isdigit_l.c
new file mode 100644
index 00000000..c8ae7bd3
--- /dev/null
+++ b/src/locale/isdigit_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isdigit_l(int c, locale_t l)
+{
+	return isdigit(c);
+}
diff --git a/src/locale/isgraph_l.c b/src/locale/isgraph_l.c
new file mode 100644
index 00000000..713a86e6
--- /dev/null
+++ b/src/locale/isgraph_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isgraph_l(int c, locale_t l)
+{
+	return isgraph(c);
+}
diff --git a/src/locale/islower_l.c b/src/locale/islower_l.c
new file mode 100644
index 00000000..25ec97a1
--- /dev/null
+++ b/src/locale/islower_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int islower_l(int c, locale_t l)
+{
+	return islower(c);
+}
diff --git a/src/locale/isprint_l.c b/src/locale/isprint_l.c
new file mode 100644
index 00000000..79ef3514
--- /dev/null
+++ b/src/locale/isprint_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isprint_l(int c, locale_t l)
+{
+	return isprint(c);
+}
diff --git a/src/locale/ispunct_l.c b/src/locale/ispunct_l.c
new file mode 100644
index 00000000..1c0bd046
--- /dev/null
+++ b/src/locale/ispunct_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int ispunct_l(int c, locale_t l)
+{
+	return ispunct(c);
+}
diff --git a/src/locale/isspace_l.c b/src/locale/isspace_l.c
new file mode 100644
index 00000000..e1a0efed
--- /dev/null
+++ b/src/locale/isspace_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isspace_l(int c, locale_t l)
+{
+	return isspace(c);
+}
diff --git a/src/locale/isupper_l.c b/src/locale/isupper_l.c
new file mode 100644
index 00000000..11ba7036
--- /dev/null
+++ b/src/locale/isupper_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isupper_l(int c, locale_t l)
+{
+	return isupper(c);
+}
diff --git a/src/locale/isxdigit_l.c b/src/locale/isxdigit_l.c
new file mode 100644
index 00000000..68649d09
--- /dev/null
+++ b/src/locale/isxdigit_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int isxdigit_l(int c, locale_t l)
+{
+	return isxdigit(c);
+}
diff --git a/src/locale/langinfo.c b/src/locale/langinfo.c
new file mode 100644
index 00000000..f7f56012
--- /dev/null
+++ b/src/locale/langinfo.c
@@ -0,0 +1,58 @@
+#include <locale.h>
+#include <langinfo.h>
+
+static const char c_time[] =
+	"Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0"
+	"Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0"
+	"Thursday\0" "Friday\0" "Saturday\0"
+	"Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0"
+	"Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0"
+	"January\0"   "February\0" "March\0"    "April\0"
+	"May\0"       "June\0"     "July\0"     "August\0"
+	"September\0" "October\0"  "November\0" "December\0"
+	"AM\0" "PM\0"
+	"%a %b %e %T %Y\0"
+	"%m/%d/%y\0"
+	"%H:%M:%S\0"
+	"%I:%M:%S %p\0"
+	"\0"
+	"%m/%d/%y\0"
+	"0123456789"
+	"%a %b %e %T %Y\0"
+	"%H:%M:%S";
+
+static const char c_messages[] = "^[yY]\0" "^[nN]";
+static const char c_numeric[] = ".\0" "";
+
+const char *__langinfo(nl_item item)
+{
+	int cat = item >> 16;
+	int idx = item & 65535;
+	const char *str;
+
+	if (item == CODESET) return "UTF-8";
+	
+	switch (cat) {
+	case LC_NUMERIC:
+		if (idx > 1) return NULL;
+		str = c_numeric;
+		break;
+	case LC_TIME:
+		if (idx > 0x31) return NULL;
+		str = c_time;
+		break;
+	case LC_MONETARY:
+		if (idx > 0) return NULL;
+		str = "";
+		break;
+	case LC_MESSAGES:
+		if (idx > 1) return NULL;
+		str = c_messages;
+		break;
+	default:
+		return NULL;
+	}
+
+	for (; idx; idx--, str++) for (; *str; str++);
+	return str;
+}
diff --git a/src/locale/localeconv.c b/src/locale/localeconv.c
new file mode 100644
index 00000000..d79d1c07
--- /dev/null
+++ b/src/locale/localeconv.c
@@ -0,0 +1,22 @@
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct lconv *localeconv(void)
+{
+	static struct lconv *posix_lconv;
+	if (posix_lconv) return posix_lconv;
+	posix_lconv = malloc(sizeof *posix_lconv);
+	memset(posix_lconv, -1, sizeof *posix_lconv);
+	posix_lconv->decimal_point = ".";
+	posix_lconv->thousands_sep = "";
+	posix_lconv->grouping = "\xff";
+	posix_lconv->int_curr_symbol = ""; //"\xc2\xa4";
+	posix_lconv->currency_symbol = "";
+	posix_lconv->mon_decimal_point = "";
+	posix_lconv->mon_thousands_sep = "";
+	posix_lconv->mon_grouping = "\xff";
+	posix_lconv->positive_sign = ""; // "+";
+	posix_lconv->negative_sign = ""; // "-";
+	return posix_lconv;
+}
diff --git a/src/locale/newlocale.c b/src/locale/newlocale.c
new file mode 100644
index 00000000..986e796f
--- /dev/null
+++ b/src/locale/newlocale.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+
+locale_t newlocale(int mask, const char *name, locale_t base)
+{
+	if (*name && strcmp(name, "C") && strcmp(name, "POSIX"))
+		return 0;
+	if (!base) base = calloc(1, sizeof *base);
+	return base;
+}
diff --git a/src/locale/nl_langinfo.c b/src/locale/nl_langinfo.c
new file mode 100644
index 00000000..bb3a2c46
--- /dev/null
+++ b/src/locale/nl_langinfo.c
@@ -0,0 +1,13 @@
+#include <langinfo.h>
+
+// FIXME: other items
+
+char *nl_langinfo(nl_item item)
+{
+	switch (item) {
+	case CODESET:
+		return "UTF-8";
+	default:
+		return "";
+	}
+}
diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c
new file mode 100644
index 00000000..28f29b80
--- /dev/null
+++ b/src/locale/setlocale.c
@@ -0,0 +1,9 @@
+#include <locale.h>
+
+char *setlocale(int category, const char *locale)
+{
+	/* Note: plain "C" would be better, but puts some broken
+	 * software into legacy 8-bit-codepage mode, ignoring
+	 * the standard library's multibyte encoding */
+	return "C.UTF-8";
+}
diff --git a/src/locale/strcoll.c b/src/locale/strcoll.c
new file mode 100644
index 00000000..30bccd62
--- /dev/null
+++ b/src/locale/strcoll.c
@@ -0,0 +1,6 @@
+#include <string.h>
+
+int strcoll(const char *l, const char *r)
+{
+	return strcmp(l, r);
+}
diff --git a/src/locale/strxfrm.c b/src/locale/strxfrm.c
new file mode 100644
index 00000000..8f123399
--- /dev/null
+++ b/src/locale/strxfrm.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+/* collate only by code points */
+size_t strxfrm(char *dest, const char *src, size_t n)
+{
+	size_t l = strlen(src);
+	if (n > l) strcpy(dest, src);
+	return l;
+}
diff --git a/src/locale/tmp b/src/locale/tmp
new file mode 100644
index 00000000..aa71779f
--- /dev/null
+++ b/src/locale/tmp
@@ -0,0 +1,390 @@
+"iso88591\0\x08\x80"
+"iso88592\0\x0a\x21"
+"\x04\x61\x1b\x14\x29\x3d\x69\x75\x0a\x2a"
+"\x60\x79\x45\x56\x5e\xad\xf4\xb5\x17\x2c"
+"\x05\x6d\x2b\x14\x2d\x3e\x6d\x75\x2c\x2e"
+"\x61\x7d\x55\x96\x5e\xdd\xfa\xc5\x17\x55"
+"\xc1\x08\x23\x10\x31\x39\x19\x74\x0c\x43"
+"\xc9\x60\xb4\x8c\x46\xcd\x38\xe3\x10\x44"
+"\x43\x1d\x35\x0d\x35\x50\x59\x73\x0d\x56"
+"\x6e\x69\x03\x17\x37\xdd\x88\xf5\x4d\x55"
+"\xe1\x88\x33\x10\x39\x3a\x1d\x74\x4e\x43"
+"\xe9\x64\xb4\xce\x46\xed\xb8\xf3\x50\x44"
+"\x44\x21\x35\x0f\x3d\x51\xd9\x73\x4f\x56"
+"\x6f\xe9\x13\x17\x3f\xfd\x8c\x95\x2d"
+"iso88593\0\x0a0x21"
+"\x26\x61\x3b\x0a\x29\x00\x90\x74\x0a\x2a"
+"\x30\x79\xe5\x11\x4d\xad\x00\xb0\x17\x2c"
+"\x27\xc9\x32\x0b\x2d\xb5\x94\x74\x0b\x2e"
+"\x31\x7d\xf5\x51\x4d\xbd\x00\xc0\x17\x30"
+"\xc1\x08\x03\x00\x31\x0a\x21\x74\x0c\x32"
+"\xc9\x28\xb3\x0c\x33\xcd\x38\xf3\x0c\x00"
+"\xd1\x48\x33\x0d\x35\x20\x59\x73\x0d\x47"
+"\xd9\x68\xb3\x0d\x37\x6c\x71\xf5\x0d\x38"
+"\xe1\x88\x03\x00\x39\x0b\x25\x74\x0e\x3a"
+"\xe9\xa8\xb3\x0e\x3b\xed\xb8\xf3\x0e\x00"
+"\xf1\xc8\x33\x0f\x3d\x21\xd9\x73\x4f\x47"
+"\xf9\xe8\xb3\x0f\x3f\x6d\x75\x95\x2d"
+"iso88594\0\x0a\x21"
+"\x04\xe1\x64\x15\x29\x28\xed\x74\x0a\x2a"
+"\x60\x49\x24\x92\x59\xad\xf4\xf5\x0a\x2c"
+"\x05\x6d\x7b\x15\x2d\x29\xf1\x74\x2c\x2e"
+"\x61\x4d\x34\xd2\x59\x4a\xf9\xb5\x14\x40"
+"\xc1\x08\x33\x0c\x31\xc5\x18\xe3\x12\x43"
+"\xc9\x60\xb4\x8c\x45\xcd\x38\xa3\x12\x44"
+"\x45\x31\x65\x13\x35\xd5\x58\x73\x0d\x36"
+"\x72\x69\xb3\x0d\x37\x68\xa9\xf5\x4d\x40"
+"\xe1\x88\x33\x0e\x39\xe5\x98\xf3\x52\x43"
+"\xe9\x64\xb4\xce\x45\xed\xb8\xb3\x52\x44"
+"\x46\x35\x75\x13\x3d\xf5\xd8\x73\x0f\x3e"
+"\x73\xe9\xb3\x0f\x3f\x69\xad\x95\x2d"
+"iso88595\0\x0d\x21"
+"\x01\x84\x00\x30\x40\x10\x10\x05\x84\x01"
+"\x70\x40\x20\x10\x09\x84\x02\xb0\x40\x30"
+"\x10\xad\x80\x03\xf0\x40\x40\x10\x11\x84"
+"\x04\x30\x41\x50\x10\x15\x84\x05\x70\x41"
+"\x60\x10\x19\x84\x06\xb0\x41\x70\x10\x1d"
+"\x84\x07\xf0\x41\x80\x10\x21\x84\x08\x30"
+"\x42\x90\x10\x25\x84\x09\x70\x42\xa0\x10"
+"\x29\x84\x0a\xb0\x42\xb0\x10\x2d\x84\x0b"
+"\xf0\x42\xc0\x10\x31\x84\x0c\x30\x43\xd0"
+"\x10\x35\x84\x0d\x70\x43\xe0\x10\x39\x84"
+"\x0e\xb0\x43\xf0\x10\x3d\x84\x0f\xf0\x43"
+"\x00\x11\x41\x84\x10\x30\x44\x10\x11\x45"
+"\x84\x11\x70\x44\x20\x11\x49\x84\x12\xb0"
+"\x44\x30\x11\x4d\x84\x13\xf0\x44\x58\x84"
+"\x51\x84\x14\x30\x45\x50\x11\x55\x84\x15"
+"\x70\x45\x60\x11\x59\x84\x16\xb0\x45\x70"
+"\x11\xa7\x80\x17\xf0\x45\x00"
+"iso88596\0\x0b\x21"
+"\x00\x00\x00\x00\x48\x01\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x18\xdc\x0a\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\xc0\x86\x00\x00\x00"
+"\x00\x7c\x18\x00\x21\x16\xf1\x88\x48\x5c"
+"\x62\x13\x9c\x18\xc5\x29\x56\xf1\x8a\x58"
+"\xdc\x62\x17\xbc\x18\xc6\x31\x96\xf1\x8c"
+"\x68\x5c\x63\x1b\xdc\x18\xc7\x39\xd6\x31"
+"\x00\x00\x00\x00\x00\x00\x00\xc8\x41\x16"
+"\xf2\x90\x88\x5c\x64\x23\x1c\x19\xc9\x49"
+"\x56\xf2\x92\x98\xdc\x64\x27\x3c\x19\xca"
+"\x51\x96\x32\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00"
+"iso88597\0\x0d\x21"
+"\x18\x60\x06\x30\x0a\xb0\x82\xaf\xa0\x29"
+"\x70\x0a\xa0\x02\xa9\x80\xde\xb0\x0a\xb0"
+"\x02\xad\x00\x00\x50\x01\xc0\x02\xb1\x80"
+"\x2c\x30\x0b\x10\x0e\x85\x83\xe1\x70\x0b"
+"\x20\x0e\x89\x83\xe2\xb0\x0b\x30\x0e\xbd"
+"\x80\xe3\xf0\x38\x40\x0e\x91\x83\xe4\x30"
+"\x39\x50\x0e\x95\x83\xe5\x70\x39\x60\x0e"
+"\x99\x83\xe6\xb0\x39\x70\x0e\x9d\x83\xe7"
+"\xf0\x39\x80\x0e\xa1\x03\x00\x30\x3a\x90"
+"\x0e\xa5\x83\xe9\x70\x3a\xa0\x0e\xa9\x83"
+"\xea\xb0\x3a\xb0\x0e\xad\x83\xeb\xf0\x3a"
+"\xc0\x0e\xb1\x83\xec\x30\x3b\xd0\x0e\xb5"
+"\x83\xed\x70\x3b\xe0\x0e\xb9\x83\xee\xb0"
+"\x3b\xf0\x0e\xbd\x83\xef\xf0\x3b\x00\x0f"
+"\xc1\x83\xf0\x30\x3c\x10\x0f\xc5\x83\xf1"
+"\x70\x3c\x20\x0f\xc9\x83\xf2\xb0\x3c\x30"
+"\x0f\xcd\x83\xf3\x00\x00\x00"
+"iso88598\0\x0d\x21"
+"\x00\x80\x28\x30\x0a\x90\x02\xa5\x80\x29"
+"\x70\x0a\xa0\x02\xa9\xc0\x35\xb0\x0a\xb0"
+"\x02\xad\x80\x2b\xf0\x0a\xc0\x02\xb1\x80"
+"\x2c\x30\x0b\xd0\x02\xb5\x80\x2d\x70\x0b"
+"\xe0\x02\xb9\xc0\x3d\xb0\x0b\xf0\x02\xbd"
+"\x80\x2f\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+"\x00\x00\x00\x00\x00\x00\x00\x00\x70\x01"
+"\x40\x17\xd1\x85\x74\x30\x5d\x50\x17\xd5"
+"\x85\x75\x70\x5d\x60\x17\xd9\x85\x76\xb0"
+"\x5d\x70\x17\xdd\x85\x77\xf0\x5d\x80\x17"
+"\xe1\x85\x78\x30\x5e\x90\x17\xe5\x85\x79"
+"\x70\x5e\xa0\x17\xe9\x85\x7a\x00\x00\x00"
+"\x00\x0e\xe0\x03\x00\x00\x00"
+"iso88599\0\x09\x50"
+"\x1e\xa3\x49\x9b\x46\xad\x9a\xb5\x6b\xd8"
+"\xb2\x69\xdb\xc6\x0d\xa6\xd7\x6f\xe0\xc2"
+"\x89\x1b\x47\xae\x9c\xb9\x73\xe8\xd2\xa9"
+"\x5b\xc7\xae\x9d\xbb\x77\x1f\xe3\xc9\x9b"
+"\x47\xaf\x9e\xbd\x7b\xf8\xf2\xe9\xdb\xc7"
+"\x2f\xe6\xd7\x7f"
+"iso885910\0\x0d\x21"
+"\x04\x81\x44\x20\x12\xa8\x04\x28\x81\x4d"
+"\x70\x0a\xec\x04\x10\x01\x58\x60\x16\xf4"
+"\x05\xad\x80\x5a\xa0\x14\xc0\x02\x05\xc1"
+"\x44\x30\x12\xac\x04\x29\xc1\x4d\x70\x0b"
+"\xf0\x04\x11\x41\x58\x70\x16\xf8\x05\x15"
+"\xe0\x5a\xb0\x14\x00\x04\xc1\x80\x30\x30"
+"\x0c\x10\x03\xc5\x80\x31\xe0\x12\x30\x04"
+"\xc9\x00\x46\xb0\x0c\x58\x04\xcd\x80\x33"
+"\xf0\x0c\x40\x03\x45\x01\x53\x30\x0d\x50"
+"\x03\xd5\x80\x35\x80\x16\x60\x03\x72\x81"
+"\x36\xb0\x0d\x70\x03\xdd\x80\x37\xf0\x0d"
+"\x04\x04\xe1\x80\x38\x30\x0e\x90\x03\xe5"
+"\x80\x39\xf0\x12\x34\x04\xe9\x40\x46\xb0"
+"\x0e\x5c\x04\xed\x80\x3b\xf0\x0e\xc0\x03"
+"\x46\x41\x53\x30\x0f\xd0\x03\xf5\x80\x3d"
+"\x90\x16\xe0\x03\x73\x81\x3e\xb0\x0f\xf0"
+"\x03\xfd\x80\x3f\x80\x13\x00"
+"iso885913\0\x0d\x21"
+"\x1d\xa0\x28\x30\x0a\x90\x02\x1e\xa0\x29"
+"\x70\x0a\x60\x03\xa9\x80\x55\xb0\x0a\xb0"
+"\x02\xad\x80\x2b\x60\x0c\xc0\x02\xb1\x80"
+"\x2c\x30\x0b\x70\x80\xb5\x80\x2d\x70\x0b"
+"\xe0\x03\xb9\xc0\x55\xb0\x0b\xf0\x02\xbd"
+"\x80\x2f\x60\x0e\x10\x04\x2e\x01\x40\x60"
+"\x10\x10\x03\xc5\x00\x46\x20\x11\x30\x04"
+"\xc9\x40\x5e\x60\x11\x88\x04\x36\x81\x4a"
+"\xb0\x13\x80\x05\x43\x41\x51\x30\x0d\x30"
+"\x05\xd5\x80\x35\x70\x0d\xc8\x05\x41\x81"
+"\x56\xa0\x16\x70\x03\x7b\x41\x5f\xf0\x0d"
+"\x14\x04\x2f\x41\x40\x70\x10\x90\x03\xe5"
+"\x40\x46\x30\x11\x34\x04\xe9\x80\x5e\x70"
+"\x11\x8c\x04\x37\xc1\x4a\xc0\x13\x84\x05"
+"\x44\x81\x51\x30\x0f\x34\x05\xf5\x80\x3d"
+"\x70\x0f\xcc\x05\x42\xc1\x56\xb0\x16\xf0"
+"\x03\x7c\x81\x5f\x90\x01\x00"
+"iso885914\0\x0c\x21"
+"\x02\x7e\xc0\x8c\x02\x85\xb0\x10\x14\xfc"
+"\x29\x00\xf4\xa9\x40\xd0\x2c\x78\x79\xd0"
+"\x0a\x5c\x01\x5e\xf0\xf0\x1f\x1e\x24\x84"
+"\x04\x20\x10\xe4\x6c\x81\x95\x08\xf4\x57"
+"\x7e\xd0\x80\xf9\x79\x40\xe8\x0a\x7d\x98"
+"\x00\x06\xc1\x40\x18\x0c\x03\x62\x50\x0c"
+"\x8c\xc1\x31\x40\x06\xc9\x40\x19\x2c\x03"
+"\x66\xd0\x0c\x9c\xc1\x33\xa0\x0b\xd1\x40"
+"\x1a\x4c\x03\x6a\x50\x0d\xac\x81\x9a\xc0"
+"\x06\xd9\x40\x1b\x6c\x03\x6e\xd0\x0d\xec"
+"\xc2\x37\x00\x07\xe1\x40\x1c\x8c\x03\x72"
+"\x50\x0e\xcc\xc1\x39\x40\x07\xe9\x40\x1d"
+"\xac\x03\x76\xd0\x0e\xdc\xc1\x3b\xa8\x0b"
+"\xf1\x40\x1e\xcc\x03\x7a\x50\x0f\xec\xc1"
+"\x9a\xc0\x07\xf9\x40\x1f\xec\x03\x7e\xd0"
+"\x0f\xee\xc2\x3f\x00"
+"iso885916\0\x0d\x21"
+"\x04\x41\x41\x10\x14\xb0\x82\x1e\x20\x58"
+"\x70\x0a\x84\x05\xa9\x00\x86\xb0\x0a\xe4"
+"\x05\xad\x80\x5e\xb0\x17\xc0\x02\xb1\x00"
+"\x43\x20\x14\xf4\x05\x1d\xa0\x2d\x70\x0b"
+"\xf8\x05\x0d\x41\x86\xb0\x0b\x48\x05\x53"
+"\x01\x5e\xc0\x17\x00\x03\xc1\x80\x30\x20"
+"\x10\x10\x03\x06\x81\x31\x70\x0c\x20\x03"
+"\xc9\x80\x32\xb0\x0c\x30\x03\xcd\x80\x33"
+"\xf0\x0c\x40\x04\x43\x81\x34\x30\x0d\x50"
+"\x03\x50\x81\x35\xa0\x15\xc0\x05\xd9\x80"
+"\x36\xb0\x0d\x70\x03\x18\x81\x86\xf0\x0d"
+"\x80\x03\xe1\x80\x38\x30\x10\x90\x03\x07"
+"\x81\x39\x70\x0e\xa0\x03\xe9\x80\x3a\xb0"
+"\x0e\xb0\x03\xed\x80\x3b\xf0\x0e\x44\x04"
+"\x44\x81\x3c\x30\x0f\xd0\x03\x51\x81\x3d"
+"\xb0\x15\xc4\x05\xf9\x80\x3e\xb0\x0f\xf0"
+"\x03\x19\xc1\x86\xf0\x0f\x00"
+;
+
+
+'i','s','o','8','8','5','9','1',0,
+8,128,
+'i','s','o','8','8','5','9','2',0,
+10, 33,
+0x04, 0x61, 0x1b, 0x14, 0x29, 0x3d, 0x69, 0x75, 0x0a, 0x2a,
+0x60, 0x79, 0x45, 0x56, 0x5e, 0xad, 0xf4, 0xb5, 0x17, 0x2c,
+0x05, 0x6d, 0x2b, 0x14, 0x2d, 0x3e, 0x6d, 0x75, 0x2c, 0x2e,
+0x61, 0x7d, 0x55, 0x96, 0x5e, 0xdd, 0xfa, 0xc5, 0x17, 0x55,
+0xc1, 0x08, 0x23, 0x10, 0x31, 0x39, 0x19, 0x74, 0x0c, 0x43,
+0xc9, 0x60, 0xb4, 0x8c, 0x46, 0xcd, 0x38, 0xe3, 0x10, 0x44,
+0x43, 0x1d, 0x35, 0x0d, 0x35, 0x50, 0x59, 0x73, 0x0d, 0x56,
+0x6e, 0x69, 0x03, 0x17, 0x37, 0xdd, 0x88, 0xf5, 0x4d, 0x55,
+0xe1, 0x88, 0x33, 0x10, 0x39, 0x3a, 0x1d, 0x74, 0x4e, 0x43,
+0xe9, 0x64, 0xb4, 0xce, 0x46, 0xed, 0xb8, 0xf3, 0x50, 0x44,
+0x44, 0x21, 0x35, 0x0f, 0x3d, 0x51, 0xd9, 0x73, 0x4f, 0x56,
+0x6f, 0xe9, 0x13, 0x17, 0x3f, 0xfd, 0x8c, 0x95, 0x2d,
+'i','s','o','8','8','5','9','3',0,
+10, 33,
+0x26, 0x61, 0x3b, 0x0a, 0x29, 0x00, 0x90, 0x74, 0x0a, 0x2a,
+0x30, 0x79, 0xe5, 0x11, 0x4d, 0xad, 0x00, 0xb0, 0x17, 0x2c,
+0x27, 0xc9, 0x32, 0x0b, 0x2d, 0xb5, 0x94, 0x74, 0x0b, 0x2e,
+0x31, 0x7d, 0xf5, 0x51, 0x4d, 0xbd, 0x00, 0xc0, 0x17, 0x30,
+0xc1, 0x08, 0x03, 0x00, 0x31, 0x0a, 0x21, 0x74, 0x0c, 0x32,
+0xc9, 0x28, 0xb3, 0x0c, 0x33, 0xcd, 0x38, 0xf3, 0x0c, 0x00,
+0xd1, 0x48, 0x33, 0x0d, 0x35, 0x20, 0x59, 0x73, 0x0d, 0x47,
+0xd9, 0x68, 0xb3, 0x0d, 0x37, 0x6c, 0x71, 0xf5, 0x0d, 0x38,
+0xe1, 0x88, 0x03, 0x00, 0x39, 0x0b, 0x25, 0x74, 0x0e, 0x3a,
+0xe9, 0xa8, 0xb3, 0x0e, 0x3b, 0xed, 0xb8, 0xf3, 0x0e, 0x00,
+0xf1, 0xc8, 0x33, 0x0f, 0x3d, 0x21, 0xd9, 0x73, 0x4f, 0x47,
+0xf9, 0xe8, 0xb3, 0x0f, 0x3f, 0x6d, 0x75, 0x95, 0x2d,
+'i','s','o','8','8','5','9','4',0,
+10, 33,
+0x04, 0xe1, 0x64, 0x15, 0x29, 0x28, 0xed, 0x74, 0x0a, 0x2a,
+0x60, 0x49, 0x24, 0x92, 0x59, 0xad, 0xf4, 0xf5, 0x0a, 0x2c,
+0x05, 0x6d, 0x7b, 0x15, 0x2d, 0x29, 0xf1, 0x74, 0x2c, 0x2e,
+0x61, 0x4d, 0x34, 0xd2, 0x59, 0x4a, 0xf9, 0xb5, 0x14, 0x40,
+0xc1, 0x08, 0x33, 0x0c, 0x31, 0xc5, 0x18, 0xe3, 0x12, 0x43,
+0xc9, 0x60, 0xb4, 0x8c, 0x45, 0xcd, 0x38, 0xa3, 0x12, 0x44,
+0x45, 0x31, 0x65, 0x13, 0x35, 0xd5, 0x58, 0x73, 0x0d, 0x36,
+0x72, 0x69, 0xb3, 0x0d, 0x37, 0x68, 0xa9, 0xf5, 0x4d, 0x40,
+0xe1, 0x88, 0x33, 0x0e, 0x39, 0xe5, 0x98, 0xf3, 0x52, 0x43,
+0xe9, 0x64, 0xb4, 0xce, 0x45, 0xed, 0xb8, 0xb3, 0x52, 0x44,
+0x46, 0x35, 0x75, 0x13, 0x3d, 0xf5, 0xd8, 0x73, 0x0f, 0x3e,
+0x73, 0xe9, 0xb3, 0x0f, 0x3f, 0x69, 0xad, 0x95, 0x2d,
+'i','s','o','8','8','5','9','5',0,
+14, 33,
+0x01, 0x84, 0x00, 0x30, 0x40, 0x10, 0x10, 0x05, 0x84, 0x01,
+0x70, 0x40, 0x20, 0x10, 0x09, 0x84, 0x02, 0xb0, 0x40, 0x30,
+0x10, 0xad, 0x80, 0x03, 0xf0, 0x40, 0x40, 0x10, 0x11, 0x84,
+0x04, 0x30, 0x41, 0x50, 0x10, 0x15, 0x84, 0x05, 0x70, 0x41,
+0x60, 0x10, 0x19, 0x84, 0x06, 0xb0, 0x41, 0x70, 0x10, 0x1d,
+0x84, 0x07, 0xf0, 0x41, 0x80, 0x10, 0x21, 0x84, 0x08, 0x30,
+0x42, 0x90, 0x10, 0x25, 0x84, 0x09, 0x70, 0x42, 0xa0, 0x10,
+0x29, 0x84, 0x0a, 0xb0, 0x42, 0xb0, 0x10, 0x2d, 0x84, 0x0b,
+0xf0, 0x42, 0xc0, 0x10, 0x31, 0x84, 0x0c, 0x30, 0x43, 0xd0,
+0x10, 0x35, 0x84, 0x0d, 0x70, 0x43, 0xe0, 0x10, 0x39, 0x84,
+0x0e, 0xb0, 0x43, 0xf0, 0x10, 0x3d, 0x84, 0x0f, 0xf0, 0x43,
+0x00, 0x11, 0x41, 0x84, 0x10, 0x30, 0x44, 0x10, 0x11, 0x45,
+0x84, 0x11, 0x70, 0x44, 0x20, 0x11, 0x49, 0x84, 0x12, 0xb0,
+0x44, 0x30, 0x11, 0x4d, 0x84, 0x13, 0xf0, 0x44, 0x58, 0x84,
+0x51, 0x84, 0x14, 0x30, 0x45, 0x50, 0x11, 0x55, 0x84, 0x15,
+0x70, 0x45, 0x60, 0x11, 0x59, 0x84, 0x16, 0xb0, 0x45, 0x70,
+0x11, 0xa7, 0x80, 0x17, 0xf0, 0x45, 0x00,
+'i','s','o','8','8','5','9','6',0,
+11, 33,
+0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xdc, 0x0a, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x86, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0x18, 0x00, 0x21, 0x16, 0xf1, 0x88, 0x48, 0x5c,
+0x62, 0x13, 0x9c, 0x18, 0xc5, 0x29, 0x56, 0xf1, 0x8a, 0x58,
+0xdc, 0x62, 0x17, 0xbc, 0x18, 0xc6, 0x31, 0x96, 0xf1, 0x8c,
+0x68, 0x5c, 0x63, 0x1b, 0xdc, 0x18, 0xc7, 0x39, 0xd6, 0x31,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x41, 0x16,
+0xf2, 0x90, 0x88, 0x5c, 0x64, 0x23, 0x1c, 0x19, 0xc9, 0x49,
+0x56, 0xf2, 0x92, 0x98, 0xdc, 0x64, 0x27, 0x3c, 0x19, 0xca,
+0x51, 0x96, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00,
+'i','s','o','8','8','5','9','7',0,
+14, 33,
+0x18, 0x60, 0x06, 0x30, 0x0a, 0xb0, 0x82, 0xaf, 0xa0, 0x29,
+0x70, 0x0a, 0xa0, 0x02, 0xa9, 0x80, 0xde, 0xb0, 0x0a, 0xb0,
+0x02, 0xad, 0x00, 0x00, 0x50, 0x01, 0xc0, 0x02, 0xb1, 0x80,
+0x2c, 0x30, 0x0b, 0x10, 0x0e, 0x85, 0x83, 0xe1, 0x70, 0x0b,
+0x20, 0x0e, 0x89, 0x83, 0xe2, 0xb0, 0x0b, 0x30, 0x0e, 0xbd,
+0x80, 0xe3, 0xf0, 0x38, 0x40, 0x0e, 0x91, 0x83, 0xe4, 0x30,
+0x39, 0x50, 0x0e, 0x95, 0x83, 0xe5, 0x70, 0x39, 0x60, 0x0e,
+0x99, 0x83, 0xe6, 0xb0, 0x39, 0x70, 0x0e, 0x9d, 0x83, 0xe7,
+0xf0, 0x39, 0x80, 0x0e, 0xa1, 0x03, 0x00, 0x30, 0x3a, 0x90,
+0x0e, 0xa5, 0x83, 0xe9, 0x70, 0x3a, 0xa0, 0x0e, 0xa9, 0x83,
+0xea, 0xb0, 0x3a, 0xb0, 0x0e, 0xad, 0x83, 0xeb, 0xf0, 0x3a,
+0xc0, 0x0e, 0xb1, 0x83, 0xec, 0x30, 0x3b, 0xd0, 0x0e, 0xb5,
+0x83, 0xed, 0x70, 0x3b, 0xe0, 0x0e, 0xb9, 0x83, 0xee, 0xb0,
+0x3b, 0xf0, 0x0e, 0xbd, 0x83, 0xef, 0xf0, 0x3b, 0x00, 0x0f,
+0xc1, 0x83, 0xf0, 0x30, 0x3c, 0x10, 0x0f, 0xc5, 0x83, 0xf1,
+0x70, 0x3c, 0x20, 0x0f, 0xc9, 0x83, 0xf2, 0xb0, 0x3c, 0x30,
+0x0f, 0xcd, 0x83, 0xf3, 0x00, 0x00, 0x00,
+'i','s','o','8','8','5','9','8',0,
+14, 33,
+0x00, 0x80, 0x28, 0x30, 0x0a, 0x90, 0x02, 0xa5, 0x80, 0x29,
+0x70, 0x0a, 0xa0, 0x02, 0xa9, 0xc0, 0x35, 0xb0, 0x0a, 0xb0,
+0x02, 0xad, 0x80, 0x2b, 0xf0, 0x0a, 0xc0, 0x02, 0xb1, 0x80,
+0x2c, 0x30, 0x0b, 0xd0, 0x02, 0xb5, 0x80, 0x2d, 0x70, 0x0b,
+0xe0, 0x02, 0xb9, 0xc0, 0x3d, 0xb0, 0x0b, 0xf0, 0x02, 0xbd,
+0x80, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01,
+0x40, 0x17, 0xd1, 0x85, 0x74, 0x30, 0x5d, 0x50, 0x17, 0xd5,
+0x85, 0x75, 0x70, 0x5d, 0x60, 0x17, 0xd9, 0x85, 0x76, 0xb0,
+0x5d, 0x70, 0x17, 0xdd, 0x85, 0x77, 0xf0, 0x5d, 0x80, 0x17,
+0xe1, 0x85, 0x78, 0x30, 0x5e, 0x90, 0x17, 0xe5, 0x85, 0x79,
+0x70, 0x5e, 0xa0, 0x17, 0xe9, 0x85, 0x7a, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0xe0, 0x03, 0x00, 0x00, 0x00,
+'i','s','o','8','8','5','9','9',0,
+9, 80,
+0x1e, 0xa3, 0x49, 0x9b, 0x46, 0xad, 0x9a, 0xb5, 0x6b, 0xd8,
+0xb2, 0x69, 0xdb, 0xc6, 0x0d, 0xa6, 0xd7, 0x6f, 0xe0, 0xc2,
+0x89, 0x1b, 0x47, 0xae, 0x9c, 0xb9, 0x73, 0xe8, 0xd2, 0xa9,
+0x5b, 0xc7, 0xae, 0x9d, 0xbb, 0x77, 0x1f, 0xe3, 0xc9, 0x9b,
+0x47, 0xaf, 0x9e, 0xbd, 0x7b, 0xf8, 0xf2, 0xe9, 0xdb, 0xc7,
+0x2f, 0xe6, 0xd7, 0x7f,
+'i','s','o','8','8','5','9','1','0',0,
+14, 33,
+0x04, 0x81, 0x44, 0x20, 0x12, 0xa8, 0x04, 0x28, 0x81, 0x4d,
+0x70, 0x0a, 0xec, 0x04, 0x10, 0x01, 0x58, 0x60, 0x16, 0xf4,
+0x05, 0xad, 0x80, 0x5a, 0xa0, 0x14, 0xc0, 0x02, 0x05, 0xc1,
+0x44, 0x30, 0x12, 0xac, 0x04, 0x29, 0xc1, 0x4d, 0x70, 0x0b,
+0xf0, 0x04, 0x11, 0x41, 0x58, 0x70, 0x16, 0xf8, 0x05, 0x15,
+0xe0, 0x5a, 0xb0, 0x14, 0x00, 0x04, 0xc1, 0x80, 0x30, 0x30,
+0x0c, 0x10, 0x03, 0xc5, 0x80, 0x31, 0xe0, 0x12, 0x30, 0x04,
+0xc9, 0x00, 0x46, 0xb0, 0x0c, 0x58, 0x04, 0xcd, 0x80, 0x33,
+0xf0, 0x0c, 0x40, 0x03, 0x45, 0x01, 0x53, 0x30, 0x0d, 0x50,
+0x03, 0xd5, 0x80, 0x35, 0x80, 0x16, 0x60, 0x03, 0x72, 0x81,
+0x36, 0xb0, 0x0d, 0x70, 0x03, 0xdd, 0x80, 0x37, 0xf0, 0x0d,
+0x04, 0x04, 0xe1, 0x80, 0x38, 0x30, 0x0e, 0x90, 0x03, 0xe5,
+0x80, 0x39, 0xf0, 0x12, 0x34, 0x04, 0xe9, 0x40, 0x46, 0xb0,
+0x0e, 0x5c, 0x04, 0xed, 0x80, 0x3b, 0xf0, 0x0e, 0xc0, 0x03,
+0x46, 0x41, 0x53, 0x30, 0x0f, 0xd0, 0x03, 0xf5, 0x80, 0x3d,
+0x90, 0x16, 0xe0, 0x03, 0x73, 0x81, 0x3e, 0xb0, 0x0f, 0xf0,
+0x03, 0xfd, 0x80, 0x3f, 0x80, 0x13, 0x00,
+'i','s','o','8','8','5','9','1','3',0,
+14, 33,
+0x1d, 0xa0, 0x28, 0x30, 0x0a, 0x90, 0x02, 0x1e, 0xa0, 0x29,
+0x70, 0x0a, 0x60, 0x03, 0xa9, 0x80, 0x55, 0xb0, 0x0a, 0xb0,
+0x02, 0xad, 0x80, 0x2b, 0x60, 0x0c, 0xc0, 0x02, 0xb1, 0x80,
+0x2c, 0x30, 0x0b, 0x70, 0x80, 0xb5, 0x80, 0x2d, 0x70, 0x0b,
+0xe0, 0x03, 0xb9, 0xc0, 0x55, 0xb0, 0x0b, 0xf0, 0x02, 0xbd,
+0x80, 0x2f, 0x60, 0x0e, 0x10, 0x04, 0x2e, 0x01, 0x40, 0x60,
+0x10, 0x10, 0x03, 0xc5, 0x00, 0x46, 0x20, 0x11, 0x30, 0x04,
+0xc9, 0x40, 0x5e, 0x60, 0x11, 0x88, 0x04, 0x36, 0x81, 0x4a,
+0xb0, 0x13, 0x80, 0x05, 0x43, 0x41, 0x51, 0x30, 0x0d, 0x30,
+0x05, 0xd5, 0x80, 0x35, 0x70, 0x0d, 0xc8, 0x05, 0x41, 0x81,
+0x56, 0xa0, 0x16, 0x70, 0x03, 0x7b, 0x41, 0x5f, 0xf0, 0x0d,
+0x14, 0x04, 0x2f, 0x41, 0x40, 0x70, 0x10, 0x90, 0x03, 0xe5,
+0x40, 0x46, 0x30, 0x11, 0x34, 0x04, 0xe9, 0x80, 0x5e, 0x70,
+0x11, 0x8c, 0x04, 0x37, 0xc1, 0x4a, 0xc0, 0x13, 0x84, 0x05,
+0x44, 0x81, 0x51, 0x30, 0x0f, 0x34, 0x05, 0xf5, 0x80, 0x3d,
+0x70, 0x0f, 0xcc, 0x05, 0x42, 0xc1, 0x56, 0xb0, 0x16, 0xf0,
+0x03, 0x7c, 0x81, 0x5f, 0x90, 0x01, 0x00,
+'i','s','o','8','8','5','9','1','4',0,
+13, 33,
+0x02, 0x7e, 0xc0, 0x8c, 0x02, 0x85, 0xb0, 0x10, 0x14, 0xfc,
+0x29, 0x00, 0xf4, 0xa9, 0x40, 0xd0, 0x2c, 0x78, 0x79, 0xd0,
+0x0a, 0x5c, 0x01, 0x5e, 0xf0, 0xf0, 0x1f, 0x1e, 0x24, 0x84,
+0x04, 0x20, 0x10, 0xe4, 0x6c, 0x81, 0x95, 0x08, 0xf4, 0x57,
+0x7e, 0xd0, 0x80, 0xf9, 0x79, 0x40, 0xe8, 0x0a, 0x7d, 0x98,
+0x00, 0x06, 0xc1, 0x40, 0x18, 0x0c, 0x03, 0x62, 0x50, 0x0c,
+0x8c, 0xc1, 0x31, 0x40, 0x06, 0xc9, 0x40, 0x19, 0x2c, 0x03,
+0x66, 0xd0, 0x0c, 0x9c, 0xc1, 0x33, 0xa0, 0x0b, 0xd1, 0x40,
+0x1a, 0x4c, 0x03, 0x6a, 0x50, 0x0d, 0xac, 0x81, 0x9a, 0xc0,
+0x06, 0xd9, 0x40, 0x1b, 0x6c, 0x03, 0x6e, 0xd0, 0x0d, 0xec,
+0xc2, 0x37, 0x00, 0x07, 0xe1, 0x40, 0x1c, 0x8c, 0x03, 0x72,
+0x50, 0x0e, 0xcc, 0xc1, 0x39, 0x40, 0x07, 0xe9, 0x40, 0x1d,
+0xac, 0x03, 0x76, 0xd0, 0x0e, 0xdc, 0xc1, 0x3b, 0xa8, 0x0b,
+0xf1, 0x40, 0x1e, 0xcc, 0x03, 0x7a, 0x50, 0x0f, 0xec, 0xc1,
+0x9a, 0xc0, 0x07, 0xf9, 0x40, 0x1f, 0xec, 0x03, 0x7e, 0xd0,
+0x0f, 0xee, 0xc2, 0x3f, 0x00,
+'i','s','o','8','8','5','9','1','6',0,
+14, 33,
+0x04, 0x41, 0x41, 0x10, 0x14, 0xb0, 0x82, 0x1e, 0x20, 0x58,
+0x70, 0x0a, 0x84, 0x05, 0xa9, 0x00, 0x86, 0xb0, 0x0a, 0xe4,
+0x05, 0xad, 0x80, 0x5e, 0xb0, 0x17, 0xc0, 0x02, 0xb1, 0x00,
+0x43, 0x20, 0x14, 0xf4, 0x05, 0x1d, 0xa0, 0x2d, 0x70, 0x0b,
+0xf8, 0x05, 0x0d, 0x41, 0x86, 0xb0, 0x0b, 0x48, 0x05, 0x53,
+0x01, 0x5e, 0xc0, 0x17, 0x00, 0x03, 0xc1, 0x80, 0x30, 0x20,
+0x10, 0x10, 0x03, 0x06, 0x81, 0x31, 0x70, 0x0c, 0x20, 0x03,
+0xc9, 0x80, 0x32, 0xb0, 0x0c, 0x30, 0x03, 0xcd, 0x80, 0x33,
+0xf0, 0x0c, 0x40, 0x04, 0x43, 0x81, 0x34, 0x30, 0x0d, 0x50,
+0x03, 0x50, 0x81, 0x35, 0xa0, 0x15, 0xc0, 0x05, 0xd9, 0x80,
+0x36, 0xb0, 0x0d, 0x70, 0x03, 0x18, 0x81, 0x86, 0xf0, 0x0d,
+0x80, 0x03, 0xe1, 0x80, 0x38, 0x30, 0x10, 0x90, 0x03, 0x07,
+0x81, 0x39, 0x70, 0x0e, 0xa0, 0x03, 0xe9, 0x80, 0x3a, 0xb0,
+0x0e, 0xb0, 0x03, 0xed, 0x80, 0x3b, 0xf0, 0x0e, 0x44, 0x04,
+0x44, 0x81, 0x3c, 0x30, 0x0f, 0xd0, 0x03, 0x51, 0x81, 0x3d,
+0xb0, 0x15, 0xc4, 0x05, 0xf9, 0x80, 0x3e, 0xb0, 0x0f, 0xf0,
+0x03, 0x19, 0xc1, 0x86, 0xf0, 0x0f, 0x00,
diff --git a/src/locale/tolower_l.c b/src/locale/tolower_l.c
new file mode 100644
index 00000000..ba277919
--- /dev/null
+++ b/src/locale/tolower_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int tolower_l(int c, locale_t l)
+{
+	return tolower(c);
+}
diff --git a/src/locale/toupper_l.c b/src/locale/toupper_l.c
new file mode 100644
index 00000000..73f2f39b
--- /dev/null
+++ b/src/locale/toupper_l.c
@@ -0,0 +1,6 @@
+#include <ctype.h>
+
+int toupper_l(int c, locale_t l)
+{
+	return toupper(c);
+}
diff --git a/src/locale/wcscoll.c b/src/locale/wcscoll.c
new file mode 100644
index 00000000..cdbce1c2
--- /dev/null
+++ b/src/locale/wcscoll.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+/* FIXME: stub */
+int wcscoll(const wchar_t *l, const wchar_t *r)
+{
+	return wcscmp(l, r);
+}
diff --git a/src/locale/wcsxfrm.c b/src/locale/wcsxfrm.c
new file mode 100644
index 00000000..5f76e5a7
--- /dev/null
+++ b/src/locale/wcsxfrm.c
@@ -0,0 +1,12 @@
+#include <wchar.h>
+
+/* collate only by code points */
+size_t wcsxfrm(wchar_t *dest, const wchar_t *src, size_t n)
+{
+	size_t l = wcslen(src);
+	if (l >= n) {
+		wmemcpy(dest, src, n-1);
+		dest[n-1] = 0;
+	} else wcscpy(dest, src);
+	return l;
+}
diff --git a/src/malloc/DESIGN b/src/malloc/DESIGN
new file mode 100644
index 00000000..58b0523f
--- /dev/null
+++ b/src/malloc/DESIGN
@@ -0,0 +1,22 @@
+
+
+In principle, this memory allocator is roughly equivalent to Doug
+Lea's dlmalloc with fine-grained locking.
+
+
+
+malloc:
+
+Uses a freelist binned by chunk size, with a bitmap to optimize
+searching for the smallest non-empty bin which can satisfy an
+allocation. If no free chunks are available, it creates a new chunk of
+the requested size and attempts to merge it with any existing free
+chunk immediately below the newly created chunk.
+
+Whether the chunk was obtained from a bin or newly created, it's
+likely to be larger than the requested allocation. malloc always
+finishes its work by passing the new chunk to realloc, which will
+split it into two chunks and free the tail portion.
+
+
+
diff --git a/src/malloc/__brk.c b/src/malloc/__brk.c
new file mode 100644
index 00000000..e3b3af31
--- /dev/null
+++ b/src/malloc/__brk.c
@@ -0,0 +1,7 @@
+#include <stdint.h>
+#include "syscall.h"
+
+uintptr_t __brk(uintptr_t newbrk)
+{
+	return syscall1(__NR_brk, newbrk);
+}
diff --git a/src/malloc/__simple_malloc.c b/src/malloc/__simple_malloc.c
new file mode 100644
index 00000000..49b74c8e
--- /dev/null
+++ b/src/malloc/__simple_malloc.c
@@ -0,0 +1,44 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+uintptr_t __brk(uintptr_t);
+
+#define ALIGN 16
+
+void *__simple_malloc(size_t n)
+{
+	static uintptr_t cur, brk;
+	uintptr_t base, new;
+	static int lock;
+	size_t align=1;
+
+	if (n < SIZE_MAX - ALIGN)
+		while (align<n && align<ALIGN)
+			align += align;
+	n = n + align - 1 & -align;
+
+	LOCK(&lock);
+	if (!cur) cur = brk = __brk(0)+16;
+	if (n > SIZE_MAX - brk) goto fail;
+
+	base = cur + align-1 & -align;
+	if (base+n > brk) {
+		new = base+n + PAGE_SIZE-1 & -PAGE_SIZE;
+		if (__brk(new) != new) goto fail;
+		brk = new;
+	}
+	cur = base+n;
+	UNLOCK(&lock);
+
+	return (void *)base;
+
+fail:
+	UNLOCK(&lock);
+	errno = ENOMEM;
+	return 0;
+}
+
+weak_alias(__simple_malloc, malloc);
diff --git a/src/malloc/calloc.c b/src/malloc/calloc.c
new file mode 100644
index 00000000..9d574562
--- /dev/null
+++ b/src/malloc/calloc.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+void *calloc(size_t m, size_t n)
+{
+	void *p;
+	size_t *z;
+	if (n && m > (size_t)-1/n) {
+		errno = ENOMEM;
+		return 0;
+	}
+	n *= m;
+	p = malloc(n);
+	if (!p) return 0;
+	/* Only do this for non-mmapped chunks */
+	if (((size_t *)p)[-1] & 7) {
+		/* Only write words that are not already zero */
+		m = (n + sizeof *z - 1)/sizeof *z;
+		for (z=p; m; m--, z++) if (*z) *z=0;
+	}
+	return p;
+}
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
new file mode 100644
index 00000000..d9a30fe4
--- /dev/null
+++ b/src/malloc/malloc.c
@@ -0,0 +1,515 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "atomic.h"
+#include "pthread_impl.h"
+
+uintptr_t __brk(uintptr_t);
+void *__mmap(void *, size_t, int, int, int, off_t);
+int __munmap(void *, size_t);
+void *__mremap(void *, size_t, size_t, int, ...);
+int __madvise(void *, size_t, int);
+
+struct chunk {
+	size_t data[1];
+	struct chunk *next;
+	struct chunk *prev;
+};
+
+struct bin {
+	int lock[2];
+	struct chunk *head;
+	struct chunk *tail;
+};
+
+static struct {
+	uintptr_t brk;
+	size_t *heap;
+	uint64_t binmap;
+	struct bin bins[64];
+	int brk_lock[2];
+	int free_lock[2];
+} mal;
+
+
+#define SIZE_ALIGN (4*sizeof(size_t))
+#define SIZE_MASK (-SIZE_ALIGN)
+#define OVERHEAD (2*sizeof(size_t))
+#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
+#define DONTCARE 16
+#define RECLAIM 163840
+
+#define CHUNK_SIZE(c) ((c)->data[0] & SIZE_MASK)
+#define CHUNK_PSIZE(c) ((c)->data[-1] & SIZE_MASK)
+#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
+#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
+#define MEM_TO_CHUNK(p) (struct chunk *)((size_t *)p - 1)
+#define CHUNK_TO_MEM(c) (void *)((c)->data+1)
+#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
+
+#define C_INUSE  ((size_t)1)
+#define C_FLAGS  ((size_t)3)
+#define C_SIZE   SIZE_MASK
+
+#define IS_MMAPPED(c) !((c)->data[0] & (C_INUSE))
+
+
+/* Synchronization tools */
+
+static void lock(volatile int *lk)
+{
+	if (!libc.threads_minus_1) return;
+	while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
+}
+
+static void unlock(volatile int *lk)
+{
+	if (!libc.threads_minus_1) return;
+	a_store(lk, 0);
+	if (lk[1]) __wake(lk, 1, 1);
+}
+
+static void lock_bin(int i)
+{
+	if (libc.threads_minus_1)
+		lock(mal.bins[i].lock);
+	if (!mal.bins[i].head)
+		mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
+}
+
+static void unlock_bin(int i)
+{
+	if (!libc.threads_minus_1) return;
+	unlock(mal.bins[i].lock);
+}
+
+static int first_set(uint64_t x)
+{
+#if 1
+	return a_ctz_64(x);
+#else
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
+		}
+		return debruijn32[(y&-y)*0x076be629 >> 27];
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+#endif
+}
+
+static int bin_index(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	if (x > 0x1c00) return 63;
+	return ((union { float v; uint32_t r; }){ x }.r>>21) - 496;
+}
+
+static int bin_index_up(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	return ((union { float v; uint32_t r; }){ x }.r+0x1fffff>>21) - 496;
+}
+
+#if 0
+void __dump_heap(int x)
+{
+	struct chunk *c;
+	int i;
+	for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
+		fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
+			c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
+			c->data[0] & 15,
+			NEXT_CHUNK(c)->data[-1] & 15);
+	for (i=0; i<64; i++) {
+		if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
+			fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
+			if (!(mal.binmap & 1ULL<<i))
+				fprintf(stderr, "missing from binmap!\n");
+		} else if (mal.binmap & 1ULL<<i)
+			fprintf(stderr, "binmap wrongly contains %d!\n", i);
+	}
+}
+#endif
+
+static struct chunk *expand_heap(size_t n)
+{
+	struct chunk *w;
+	uintptr_t new;
+
+	lock(mal.brk_lock);
+
+	if (n > SIZE_MAX - mal.brk - 2*PAGE_SIZE) goto fail;
+	new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE;
+	n = new - mal.brk;
+
+	if (__brk(new) != new) goto fail;
+
+	w = MEM_TO_CHUNK(new);
+	w->data[-1] = n | C_INUSE;
+	w->data[0] = 0 | C_INUSE;
+
+	w = MEM_TO_CHUNK(mal.brk);
+	w->data[0] = n | C_INUSE;
+	mal.brk = new;
+	
+	unlock(mal.brk_lock);
+
+	return w;
+fail:
+	unlock(mal.brk_lock);
+	return 0;
+}
+
+static int init_malloc()
+{
+	static int init, waiters;
+	int state;
+	struct chunk *c;
+
+	if (init == 2) return 0;
+
+	while ((state=a_swap(&init, 1)) == 1)
+		__wait(&init, &waiters, 1, 1);
+	if (state) {
+		a_store(&init, 2);
+		return 0;
+	}
+
+	mal.brk = __brk(0) + 2*SIZE_ALIGN-1 & -SIZE_ALIGN;
+
+	c = expand_heap(1);
+
+	if (!c) {
+		a_store(&init, 0);
+		if (waiters) __wake(&init, 1, 1);
+		return -1;
+	}
+
+	mal.heap = (void *)c;
+	c->data[-1] = 0 | C_INUSE;
+	free(CHUNK_TO_MEM(c));
+
+	a_store(&init, 2);
+	if (waiters) __wake(&init, -1, 1);
+	return 0;
+}
+
+static int adjust_size(size_t *n)
+{
+	/* Result of pointer difference must fit in ptrdiff_t. */
+	if (*n > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
+		errno = ENOMEM;
+		return -1;
+	}
+	*n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
+	return 0;
+}
+
+static void unbin(struct chunk *c, int i)
+{
+	if (c->prev == c->next)
+		a_and_64(&mal.binmap, ~(1ULL<<i));
+	c->prev->next = c->next;
+	c->next->prev = c->prev;
+	c->data[0] |= C_INUSE;
+	NEXT_CHUNK(c)->data[-1] |= C_INUSE;
+}
+
+static int alloc_fwd(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->data[0]) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->data[0] == k) {
+			unbin(c, i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+static int alloc_rev(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->data[-1]) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->data[-1] == k) {
+			unbin(PREV_CHUNK(c), i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+
+/* pretrim - trims a chunk _prior_ to removing it from its bin.
+ * Must be called with i as the ideal bin for size n, j the bin
+ * for the _free_ chunk self, and bin j locked. */
+static int pretrim(struct chunk *self, size_t n, int i, int j)
+{
+	size_t n1;
+	struct chunk *next, *split;
+
+	/* We cannot pretrim if it would require re-binning. */
+	if (j < 40) return 0;
+	if (j < i+3) {
+		if (j != 63) return 0;
+		n1 = CHUNK_SIZE(self);
+		if (n1-n <= MMAP_THRESHOLD) return 0;
+	} else {
+		n1 = CHUNK_SIZE(self);
+	}
+	if (bin_index(n1-n) != j) return 0;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->prev = self->prev;
+	split->next = self->next;
+	split->prev->next = split;
+	split->next->prev = split;
+	split->data[-1] = n | C_INUSE;
+	split->data[0] = n1-n;
+	next->data[-1] = n1-n;
+	self->data[0] = n | C_INUSE;
+	return 1;
+}
+
+static void trim(struct chunk *self, size_t n)
+{
+	size_t n1 = CHUNK_SIZE(self);
+	struct chunk *next, *split;
+
+	if (n >= n1 - DONTCARE) return;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->data[-1] = n | C_INUSE;
+	split->data[0] = n1-n | C_INUSE;
+	next->data[-1] = n1-n | C_INUSE;
+	self->data[0] = n | C_INUSE;
+
+	free(CHUNK_TO_MEM(split));
+}
+
+void *malloc(size_t n)
+{
+	struct chunk *c;
+	int i, j;
+
+	if (!n || adjust_size(&n) < 0) return 0;
+
+	if (n > MMAP_THRESHOLD) {
+		size_t len = n + PAGE_SIZE - 1 & -PAGE_SIZE;
+		char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+		if (base == (void *)-1) return 0;
+		c = (void *)(base + SIZE_ALIGN - sizeof(size_t));
+		c->data[0] = len - (SIZE_ALIGN - sizeof(size_t));
+		c->data[-1] = SIZE_ALIGN - sizeof(size_t);
+		return CHUNK_TO_MEM(c);
+	}
+
+	i = bin_index_up(n);
+	for (;;) {
+		uint64_t mask = mal.binmap & -(1ULL<<i);
+		if (!mask) {
+			init_malloc();
+			c = expand_heap(n);
+			if (!c) return 0;
+			if (alloc_rev(c)) {
+				struct chunk *x = c;
+				c = PREV_CHUNK(c);
+				NEXT_CHUNK(x)->data[-1] = c->data[0] =
+					x->data[0] + CHUNK_SIZE(c);
+			}
+			break;
+		}
+		j = first_set(mask);
+		lock_bin(j);
+		c = mal.bins[j].head;
+		if (c != BIN_TO_CHUNK(j) && j == bin_index(c->data[0])) {
+			if (!pretrim(c, n, i, j)) unbin(c, j);
+			unlock_bin(j);
+			break;
+		}
+		unlock_bin(j);
+	}
+
+	/* Now patch up in case we over-allocated */
+	trim(c, n);
+
+	return CHUNK_TO_MEM(c);
+}
+
+void *realloc(void *p, size_t n)
+{
+	struct chunk *self, *next;
+	size_t n0, n1;
+	void *new;
+
+	if (!p) return malloc(n);
+	else if (!n) return free(p), (void *)0;
+
+	if (adjust_size(&n) < 0) return 0;
+
+	self = MEM_TO_CHUNK(p);
+	n1 = n0 = CHUNK_SIZE(self);
+
+	if (IS_MMAPPED(self)) {
+		size_t extra = self->data[-1];
+		char *base = (char *)self - extra;
+		size_t oldlen = n0 + extra;
+		size_t newlen = n + extra;
+		if (newlen < PAGE_SIZE && (new = malloc(n))) {
+			memcpy(new, p, n-OVERHEAD);
+			free(p);
+			return new;
+		}
+		newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
+		if (oldlen == newlen) return p;
+		base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
+		if (base == (void *)-1)
+			return newlen < oldlen ? p : 0;
+		self = (void *)(base + extra);
+		self->data[0] = newlen - extra;
+		return CHUNK_TO_MEM(self);
+	}
+
+	next = NEXT_CHUNK(self);
+
+	/* Merge adjacent chunks if we need more space. This is not
+	 * a waste of time even if we fail to get enough space, because our
+	 * subsequent call to free would otherwise have to do the merge. */
+	if (n > n1 && alloc_fwd(next)) {
+		n1 += CHUNK_SIZE(next);
+		next = NEXT_CHUNK(next);
+	}
+	/* FIXME: find what's wrong here and reenable it..? */
+	if (0 && n > n1 && alloc_rev(self)) {
+		self = PREV_CHUNK(self);
+		n1 += CHUNK_SIZE(self);
+	}
+	self->data[0] = n1 | C_INUSE;
+	next->data[-1] = n1 | C_INUSE;
+
+	/* If we got enough space, split off the excess and return */
+	if (n <= n1) {
+		//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
+		trim(self, n);
+		return CHUNK_TO_MEM(self);
+	}
+
+	/* As a last resort, allocate a new chunk and copy to it. */
+	new = malloc(n-OVERHEAD);
+	if (!new) return 0;
+	memcpy(new, p, n0-OVERHEAD);
+	free(CHUNK_TO_MEM(self));
+	return new;
+}
+
+void free(void *p)
+{
+	struct chunk *self = MEM_TO_CHUNK(p);
+	struct chunk *next;
+	size_t final_size, new_size, size;
+	int reclaim=0;
+	int i;
+
+	if (!p) return;
+
+	if (IS_MMAPPED(self)) {
+		size_t extra = self->data[-1];
+		char *base = (char *)self - extra;
+		size_t len = CHUNK_SIZE(self) + extra;
+		__munmap(base, len);
+		return;
+	}
+
+	final_size = new_size = CHUNK_SIZE(self);
+	next = NEXT_CHUNK(self);
+
+	for (;;) {
+		/* Replace middle of large chunks with fresh zero pages */
+		if (reclaim && (self->data[-1] & next->data[0] & C_INUSE)) {
+			uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
+			uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
+#if 1
+			__madvise((void *)a, b-a, MADV_DONTNEED);
+#else
+			__mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
+				MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+#endif
+		}
+
+		if (self->data[-1] & next->data[0] & C_INUSE) {
+			self->data[0] = final_size | C_INUSE;
+			next->data[-1] = final_size | C_INUSE;
+			i = bin_index(final_size);
+			lock_bin(i);
+			lock(mal.free_lock);
+			if (self->data[-1] & next->data[0] & C_INUSE)
+				break;
+			unlock(mal.free_lock);
+			unlock_bin(i);
+		}
+
+		if (alloc_rev(self)) {
+			self = PREV_CHUNK(self);
+			size = CHUNK_SIZE(self);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+		}
+
+		if (alloc_fwd(next)) {
+			size = CHUNK_SIZE(next);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+			next = NEXT_CHUNK(next);
+		}
+	}
+
+	self->data[0] = final_size;
+	next->data[-1] = final_size;
+	unlock(mal.free_lock);
+
+	self->next = BIN_TO_CHUNK(i);
+	self->prev = mal.bins[i].tail;
+	self->next->prev = self;
+	self->prev->next = self;
+
+	if (!(mal.binmap & 1ULL<<i))
+		a_or_64(&mal.binmap, 1ULL<<i);
+
+	unlock_bin(i);
+}
diff --git a/src/malloc/memalign.c b/src/malloc/memalign.c
new file mode 100644
index 00000000..61f456e4
--- /dev/null
+++ b/src/malloc/memalign.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <errno.h>
+
+void *memalign(size_t align, size_t len)
+{
+	void *mem;
+	int ret;
+	if ((ret = posix_memalign(&mem, align, len))) {
+		errno = ret;
+		return 0;
+	}
+	return mem;
+}
diff --git a/src/malloc/posix_memalign.c b/src/malloc/posix_memalign.c
new file mode 100644
index 00000000..ef86260d
--- /dev/null
+++ b/src/malloc/posix_memalign.c
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+
+/* This function should work with most dlmalloc-like chunk bookkeeping
+ * systems, but it's only guaranteed to work with the native implementation
+ * used in this library. */
+
+int posix_memalign(void **res, size_t align, size_t len)
+{
+	unsigned char *mem, *new, *end;
+	size_t header, footer;
+
+	if ((align & -align) != align) return EINVAL;
+	if (len > SIZE_MAX - align) return ENOMEM;
+
+	if (align <= 4*sizeof(size_t)) {
+		if (!(mem = malloc(len)))
+			return errno;
+		*res = mem;
+		return 0;
+	}
+
+	if (!(mem = malloc(len + align-1)))
+		return errno;
+
+	header = ((size_t *)mem)[-1];
+	end = mem + (header & -8);
+	footer = ((size_t *)end)[-2];
+	new = (void *)((uintptr_t)mem + align-1 & -align);
+
+	if (!(header & 7)) {
+		((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
+		((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
+		*res = new;
+		return 0;
+	}
+
+	((size_t *)mem)[-1] = header&7 | new-mem;
+	((size_t *)new)[-2] = footer&7 | new-mem;
+	((size_t *)new)[-1] = header&7 | end-new;
+	((size_t *)end)[-2] = footer&7 | end-new;
+
+	if (new != mem) free(mem);
+	*res = new;
+	return 0;
+}
diff --git a/src/math/__fpclassify.c b/src/math/__fpclassify.c
new file mode 100644
index 00000000..16051100
--- /dev/null
+++ b/src/math/__fpclassify.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include <math.h>
+
+int __fpclassify(double __x)
+{
+	union {
+		double __d;
+		__uint64_t __i;
+	} __y = { __x };
+	int __ee = __y.__i>>52 & 0x7ff;
+	if (!__ee) return __y.__i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (__ee==0x7ff) return __y.__i<<12 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
diff --git a/src/math/__fpclassifyf.c b/src/math/__fpclassifyf.c
new file mode 100644
index 00000000..bf59d0d4
--- /dev/null
+++ b/src/math/__fpclassifyf.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include <math.h>
+
+int __fpclassifyf(float __x)
+{
+	union {
+		float __f;
+		__uint32_t __i;
+	} __y = { __x };
+	int __ee = __y.__i>>23 & 0xff;
+	if (!__ee) return __y.__i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (__ee==0xff) return __y.__i<<9 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
diff --git a/src/math/__fpclassifyl.c b/src/math/__fpclassifyl.c
new file mode 100644
index 00000000..4f93bef1
--- /dev/null
+++ b/src/math/__fpclassifyl.c
@@ -0,0 +1,16 @@
+#include <stdint.h>
+#include <math.h>
+
+/* FIXME: move this to arch-specific file */
+int __fpclassifyl(long double __x)
+{
+	union {
+		long double __ld;
+		__uint16_t __hw[5];
+		__uint64_t __m;
+	} __y = { __x };
+	int __ee = __y.__hw[4]&0x7fff;
+	if (!__ee) return __y.__m ? FP_SUBNORMAL : FP_ZERO;
+	if (__ee==0x7fff) return __y.__m ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
diff --git a/src/math/e_acos.c b/src/math/e_acos.c
new file mode 100644
index 00000000..e0236391
--- /dev/null
+++ b/src/math/e_acos.c
@@ -0,0 +1,99 @@
+/* @(#)e_acos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* acos(x)
+ * Method :                  
+ *      acos(x)  = pi/2 - asin(x)
+ *      acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ *      acos(x) = pi/2 - (x + x*x^2*R(x^2))     (see asin.c)
+ * For x>0.5
+ *      acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ *              = 2asin(sqrt((1-x)/2))  
+ *              = 2s + 2s*z*R(z)        ...z=(1-x)/2, s=sqrt(z)
+ *              = 2f + (2c + 2s*z*R(z))
+ *     where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ *     for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ *      acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ *              = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ *      if x is NaN, return x itself;
+ *      if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one=  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+pio2_hi =  1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo =  6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+double
+acos(double x)
+{
+        double z,p,q,r,w,s,c,df;
+        int32_t hx,ix;
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x3ff00000) {    /* |x| >= 1 */
+            uint32_t lx;
+            GET_LOW_WORD(lx,x);
+            if(((ix-0x3ff00000)|lx)==0) {       /* |x|==1 */
+                if(hx>0) return 0.0;            /* acos(1) = 0  */
+                else return pi+2.0*pio2_lo;     /* acos(-1)= pi */
+            }
+            return (x-x)/(x-x);         /* acos(|x|>1) is NaN */
+        }
+        if(ix<0x3fe00000) {     /* |x| < 0.5 */
+            if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+            z = x*x;
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            r = p/q;
+            return pio2_hi - (x - (pio2_lo-x*r));
+        } else  if (hx<0) {             /* x < -0.5 */
+            z = (one+x)*0.5;
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            s = sqrt(z);
+            r = p/q;
+            w = r*s-pio2_lo;
+            return pi - 2.0*(s+w);
+        } else {                        /* x > 0.5 */
+            z = (one-x)*0.5;
+            s = sqrt(z);
+            df = s;
+            SET_LOW_WORD(df,0);
+            c  = (z-df*df)/(s+df);
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            r = p/q;
+            w = r*s+c;
+            return 2.0*(df+w);
+        }
+}
diff --git a/src/math/e_acosf.c b/src/math/e_acosf.c
new file mode 100644
index 00000000..4c59781b
--- /dev/null
+++ b/src/math/e_acosf.c
@@ -0,0 +1,77 @@
+/* e_acosf.c -- float version of e_acos.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one =  1.0000000000e+00, /* 0x3F800000 */
+pi =  3.1415925026e+00, /* 0x40490fda */
+pio2_hi =  1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo =  7.5497894159e-08, /* 0x33a22168 */
+pS0 =  1.6666667163e-01, /* 0x3e2aaaab */
+pS1 = -3.2556581497e-01, /* 0xbea6b090 */
+pS2 =  2.0121252537e-01, /* 0x3e4e0aa8 */
+pS3 = -4.0055535734e-02, /* 0xbd241146 */
+pS4 =  7.9153501429e-04, /* 0x3a4f7f04 */
+pS5 =  3.4793309169e-05, /* 0x3811ef08 */
+qS1 = -2.4033949375e+00, /* 0xc019d139 */
+qS2 =  2.0209457874e+00, /* 0x4001572d */
+qS3 = -6.8828397989e-01, /* 0xbf303361 */
+qS4 =  7.7038154006e-02; /* 0x3d9dc62e */
+
+float
+acosf(float x)
+{
+        float z,p,q,r,w,s,c,df;
+        int32_t hx,ix;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix==0x3f800000) {            /* |x|==1 */
+            if(hx>0) return 0.0;        /* acos(1) = 0  */
+            else return pi+(float)2.0*pio2_lo;  /* acos(-1)= pi */
+        } else if(ix>0x3f800000) {      /* |x| >= 1 */
+            return (x-x)/(x-x);         /* acos(|x|>1) is NaN */
+        }
+        if(ix<0x3f000000) {     /* |x| < 0.5 */
+            if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+            z = x*x;
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            r = p/q;
+            return pio2_hi - (x - (pio2_lo-x*r));
+        } else  if (hx<0) {             /* x < -0.5 */
+            z = (one+x)*(float)0.5;
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            s = sqrtf(z);
+            r = p/q;
+            w = r*s-pio2_lo;
+            return pi - (float)2.0*(s+w);
+        } else {                        /* x > 0.5 */
+            int32_t idf;
+            z = (one-x)*(float)0.5;
+            s = sqrtf(z);
+            df = s;
+            GET_FLOAT_WORD(idf,df);
+            SET_FLOAT_WORD(df,idf&0xfffff000);
+            c  = (z-df*df)/(s+df);
+            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+            r = p/q;
+            w = r*s+c;
+            return (float)2.0*(df+w);
+        }
+}
diff --git a/src/math/e_acosh.c b/src/math/e_acosh.c
new file mode 100644
index 00000000..8b454e75
--- /dev/null
+++ b/src/math/e_acosh.c
@@ -0,0 +1,59 @@
+
+/* @(#)e_acosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* acosh(x)
+ * Method :
+ *      Based on 
+ *              acosh(x) = log [ x + sqrt(x*x-1) ]
+ *      we have
+ *              acosh(x) := log(x)+ln2, if x is large; else
+ *              acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ *              acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ *      acosh(x) is NaN with signal if x<1.
+ *      acosh(NaN) is NaN without signal.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one     = 1.0,
+ln2     = 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
+
+double
+acosh(double x)
+{
+        double t;
+        int32_t hx;
+        uint32_t lx;
+        EXTRACT_WORDS(hx,lx,x);
+        if(hx<0x3ff00000) {             /* x < 1 */
+            return (x-x)/(x-x);
+        } else if(hx >=0x41b00000) {    /* x > 2**28 */
+            if(hx >=0x7ff00000) {       /* x is inf of NaN */
+                return x+x;
+            } else 
+                return log(x)+ln2;    /* acosh(huge)=log(2x) */
+        } else if(((hx-0x3ff00000)|lx)==0) {
+            return 0.0;                 /* acosh(1) = 0 */
+        } else if (hx > 0x40000000) {   /* 2**28 > x > 2 */
+            t=x*x;
+            return log(2.0*x-one/(x+sqrt(t-one)));
+        } else {                        /* 1<x<2 */
+            t = x-one;
+            return log1p(t+sqrt(2.0*t+t*t));
+        }
+}
diff --git a/src/math/e_acoshf.c b/src/math/e_acoshf.c
new file mode 100644
index 00000000..b7f1df69
--- /dev/null
+++ b/src/math/e_acoshf.c
@@ -0,0 +1,45 @@
+/* e_acoshf.c -- float version of e_acosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one     = 1.0,
+ln2     = 6.9314718246e-01;  /* 0x3f317218 */
+
+float
+acoshf(float x)
+{
+        float t;
+        int32_t hx;
+        GET_FLOAT_WORD(hx,x);
+        if(hx<0x3f800000) {             /* x < 1 */
+            return (x-x)/(x-x);
+        } else if(hx >=0x4d800000) {    /* x > 2**28 */
+            if(hx >=0x7f800000) {       /* x is inf of NaN */
+                return x+x;
+            } else
+                return logf(x)+ln2;     /* acosh(huge)=log(2x) */
+        } else if (hx==0x3f800000) {
+            return 0.0;                 /* acosh(1) = 0 */
+        } else if (hx > 0x40000000) {   /* 2**28 > x > 2 */
+            t=x*x;
+            return logf((float)2.0*x-one/(x+sqrtf(t-one)));
+        } else {                        /* 1<x<2 */
+            t = x-one;
+            return log1pf(t+sqrtf((float)2.0*t+t*t));
+        }
+}
diff --git a/src/math/e_asin.c b/src/math/e_asin.c
new file mode 100644
index 00000000..4bf162a1
--- /dev/null
+++ b/src/math/e_asin.c
@@ -0,0 +1,109 @@
+
+/* @(#)e_asin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* asin(x)
+ * Method :                  
+ *      Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ *      we approximate asin(x) on [0,0.5] by
+ *              asin(x) = x + x*x^2*R(x^2)
+ *      where
+ *              R(x^2) is a rational approximation of (asin(x)-x)/x^3 
+ *      and its remez error is bounded by
+ *              |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ *      For x in [0.5,1]
+ *              asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ *      Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ *      then for x>0.98
+ *              asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *                      = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ *      For x<=0.98, let pio4_hi = pio2_hi/2, then
+ *              f = hi part of s;
+ *              c = sqrt(z) - f = (z-f*f)/(s+f)         ...f+c=sqrt(z)
+ *      and
+ *              asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *                      = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ *                      = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ *      if x is NaN, return x itself;
+ *      if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+huge =  1.000e+300,
+pio2_hi =  1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo =  6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi =  7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+        /* coefficient for R(x^2) */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+double
+asin(double x)
+{
+        double t=0.0,w,p,q,c,r,s;
+        int32_t hx,ix;
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>= 0x3ff00000) {           /* |x|>= 1 */
+            uint32_t lx;
+            GET_LOW_WORD(lx,x);
+            if(((ix-0x3ff00000)|lx)==0)
+                    /* asin(1)=+-pi/2 with inexact */
+                return x*pio2_hi+x*pio2_lo;     
+            return (x-x)/(x-x);         /* asin(|x|>1) is NaN */   
+        } else if (ix<0x3fe00000) {     /* |x|<0.5 */
+            if(ix<0x3e400000) {         /* if |x| < 2**-27 */
+                if(huge+x>one) return x;/* return x with inexact if x!=0*/
+            } else 
+                t = x*x;
+                p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+                q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+                w = p/q;
+                return x+x*w;
+        }
+        /* 1> |x|>= 0.5 */
+        w = one-fabs(x);
+        t = w*0.5;
+        p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+        q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+        s = sqrt(t);
+        if(ix>=0x3FEF3333) {    /* if |x| > 0.975 */
+            w = p/q;
+            t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
+        } else {
+            w  = s;
+            SET_LOW_WORD(w,0);
+            c  = (t-w*w)/(s+w);
+            r  = p/q;
+            p  = 2.0*s*r-(pio2_lo-2.0*c);
+            q  = pio4_hi-2.0*w;
+            t  = pio4_hi-(p-q);
+        }    
+        if(hx>0) return t; else return -t;    
+}
diff --git a/src/math/e_asinf.c b/src/math/e_asinf.c
new file mode 100644
index 00000000..9c693970
--- /dev/null
+++ b/src/math/e_asinf.c
@@ -0,0 +1,80 @@
+/* e_asinf.c -- float version of e_asin.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one =  1.0000000000e+00, /* 0x3F800000 */
+huge =  1.000e+30,
+pio2_hi =  1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo =  7.5497894159e-08, /* 0x33a22168 */
+pio4_hi =  7.8539818525e-01, /* 0x3f490fdb */
+	/* coefficient for R(x^2) */
+pS0 =  1.6666667163e-01, /* 0x3e2aaaab */
+pS1 = -3.2556581497e-01, /* 0xbea6b090 */
+pS2 =  2.0121252537e-01, /* 0x3e4e0aa8 */
+pS3 = -4.0055535734e-02, /* 0xbd241146 */
+pS4 =  7.9153501429e-04, /* 0x3a4f7f04 */
+pS5 =  3.4793309169e-05, /* 0x3811ef08 */
+qS1 = -2.4033949375e+00, /* 0xc019d139 */
+qS2 =  2.0209457874e+00, /* 0x4001572d */
+qS3 = -6.8828397989e-01, /* 0xbf303361 */
+qS4 =  7.7038154006e-02; /* 0x3d9dc62e */
+
+float
+asinf(float x)
+{
+	float t=0.0,w,p,q,c,r,s;
+	int32_t hx,ix;
+	GET_FLOAT_WORD(hx,x);
+	ix = hx&0x7fffffff;
+	if(ix==0x3f800000) {
+		/* asin(1)=+-pi/2 with inexact */
+	    return x*pio2_hi+x*pio2_lo;
+	} else if(ix> 0x3f800000) {	/* |x|>= 1 */
+	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */
+	} else if (ix<0x3f000000) {	/* |x|<0.5 */
+	    if(ix<0x32000000) {		/* if |x| < 2**-27 */
+		if(huge+x>one) return x;/* return x with inexact if x!=0*/
+	    } else
+		t = x*x;
+		p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+		q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+		w = p/q;
+		return x+x*w;
+	}
+	/* 1> |x|>= 0.5 */
+	w = one-fabsf(x);
+	t = w*(float)0.5;
+	p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+	q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+	s = sqrtf(t);
+	if(ix>=0x3F79999A) { 	/* if |x| > 0.975 */
+	    w = p/q;
+	    t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo);
+	} else {
+	    int32_t iw;
+	    w  = s;
+	    GET_FLOAT_WORD(iw,w);
+	    SET_FLOAT_WORD(w,iw&0xfffff000);
+	    c  = (t-w*w)/(s+w);
+	    r  = p/q;
+	    p  = (float)2.0*s*r-(pio2_lo-(float)2.0*c);
+	    q  = pio4_hi-(float)2.0*w;
+	    t  = pio4_hi-(p-q);
+	}
+	if(hx>0) return t; else return -t;
+}
diff --git a/src/math/e_atan2.c b/src/math/e_atan2.c
new file mode 100644
index 00000000..dd021164
--- /dev/null
+++ b/src/math/e_atan2.c
@@ -0,0 +1,120 @@
+
+/* @(#)e_atan2.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* atan2(y,x)
+ * Method :
+ *      1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *      2. Reduce x to positive by (if x and y are unexceptional): 
+ *              ARG (x+iy) = arctan(y/x)           ... if x > 0,
+ *              ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
+ *
+ * Special cases:
+ *
+ *      ATAN2((anything), NaN ) is NaN;
+ *      ATAN2(NAN , (anything) ) is NaN;
+ *      ATAN2(+-0, +(anything but NaN)) is +-0  ;
+ *      ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ *      ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ *      ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ *      ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ *      ATAN2(+-INF,+INF ) is +-pi/4 ;
+ *      ATAN2(+-INF,-INF ) is +-3pi/4;
+ *      ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+tiny  = 1.0e-300,
+zero  = 0.0,
+pi_o_4  = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
+pi_o_2  = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
+pi      = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo   = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+double
+atan2(double y, double x)
+{
+        double z;
+        int32_t k,m,hx,hy,ix,iy;
+        uint32_t lx,ly;
+
+        EXTRACT_WORDS(hx,lx,x);
+        ix = hx&0x7fffffff;
+        EXTRACT_WORDS(hy,ly,y);
+        iy = hy&0x7fffffff;
+        if(((ix|((lx|-lx)>>31))>0x7ff00000)||
+           ((iy|((ly|-ly)>>31))>0x7ff00000))    /* x or y is NaN */
+           return x+y;
+        if(((hx-0x3ff00000)|lx)==0) return atan(y);   /* x=1.0 */
+        m = ((hy>>31)&1)|((hx>>30)&2);  /* 2*sign(x)+sign(y) */
+
+    /* when y = 0 */
+        if((iy|ly)==0) {
+            switch(m) {
+                case 0: 
+                case 1: return y;       /* atan(+-0,+anything)=+-0 */
+                case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
+                case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+            }
+        }
+    /* when x = 0 */
+        if((ix|lx)==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
+            
+    /* when x is INF */
+        if(ix==0x7ff00000) {
+            if(iy==0x7ff00000) {
+                switch(m) {
+                    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
+                    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+                    case 2: return  3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+                    case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+                }
+            } else {
+                switch(m) {
+                    case 0: return  zero  ;     /* atan(+...,+INF) */
+                    case 1: return -zero  ;     /* atan(-...,+INF) */
+                    case 2: return  pi+tiny  ;  /* atan(+...,-INF) */
+                    case 3: return -pi-tiny  ;  /* atan(-...,-INF) */
+                }
+            }
+        }
+    /* when y is INF */
+        if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* compute y/x */
+        k = (iy-ix)>>20;
+        if(k > 60) z=pi_o_2+0.5*pi_lo;  /* |y/x| >  2**60 */
+        else if(hx<0&&k<-60) z=0.0;     /* |y|/x < -2**60 */
+        else z=atan(fabs(y/x));         /* safe to do y/x */
+        switch (m) {
+            case 0: return       z  ;   /* atan(+,+) */
+            case 1: {
+                      uint32_t zh;
+                      GET_HIGH_WORD(zh,z);
+                      SET_HIGH_WORD(z,zh ^ 0x80000000);
+                    }
+                    return       z  ;   /* atan(-,+) */
+            case 2: return  pi-(z-pi_lo);/* atan(+,-) */
+            default: /* case 3 */
+                    return  (z-pi_lo)-pi;/* atan(-,-) */
+        }
+}
diff --git a/src/math/e_atan2f.c b/src/math/e_atan2f.c
new file mode 100644
index 00000000..535e10a0
--- /dev/null
+++ b/src/math/e_atan2f.c
@@ -0,0 +1,93 @@
+/* e_atan2f.c -- float version of e_atan2.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+tiny  = 1.0e-30,
+zero  = 0.0,
+pi_o_4  = 7.8539818525e-01, /* 0x3f490fdb */
+pi_o_2  = 1.5707963705e+00, /* 0x3fc90fdb */
+pi      = 3.1415927410e+00, /* 0x40490fdb */
+pi_lo   = -8.7422776573e-08; /* 0xb3bbbd2e */
+
+float
+atan2f(float y, float x)
+{
+        float z;
+        int32_t k,m,hx,hy,ix,iy;
+
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        GET_FLOAT_WORD(hy,y);
+        iy = hy&0x7fffffff;
+        if((ix>0x7f800000)||
+           (iy>0x7f800000))     /* x or y is NaN */
+           return x+y;
+        if(hx==0x3f800000) return atanf(y);   /* x=1.0 */
+        m = ((hy>>31)&1)|((hx>>30)&2);  /* 2*sign(x)+sign(y) */
+
+    /* when y = 0 */
+        if(iy==0) {
+            switch(m) {
+                case 0:
+                case 1: return y;       /* atan(+-0,+anything)=+-0 */
+                case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
+                case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+            }
+        }
+    /* when x = 0 */
+        if(ix==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* when x is INF */
+        if(ix==0x7f800000) {
+            if(iy==0x7f800000) {
+                switch(m) {
+                    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
+                    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+                    case 2: return  (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+                    case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+                }
+            } else {
+                switch(m) {
+                    case 0: return  zero  ;     /* atan(+...,+INF) */
+                    case 1: return -zero  ;     /* atan(-...,+INF) */
+                    case 2: return  pi+tiny  ;  /* atan(+...,-INF) */
+                    case 3: return -pi-tiny  ;  /* atan(-...,-INF) */
+                }
+            }
+        }
+    /* when y is INF */
+        if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* compute y/x */
+        k = (iy-ix)>>23;
+        if(k > 60) z=pi_o_2+(float)0.5*pi_lo;   /* |y/x| >  2**60 */
+        else if(hx<0&&k<-60) z=0.0;     /* |y|/x < -2**60 */
+        else z=atanf(fabsf(y/x));       /* safe to do y/x */
+        switch (m) {
+            case 0: return       z  ;   /* atan(+,+) */
+            case 1: {
+                      uint32_t zh;
+                      GET_FLOAT_WORD(zh,z);
+                      SET_FLOAT_WORD(z,zh ^ 0x80000000);
+                    }
+                    return       z  ;   /* atan(-,+) */
+            case 2: return  pi-(z-pi_lo);/* atan(+,-) */
+            default: /* case 3 */
+                    return  (z-pi_lo)-pi;/* atan(-,-) */
+        }
+}
diff --git a/src/math/e_atanh.c b/src/math/e_atanh.c
new file mode 100644
index 00000000..45f1c966
--- /dev/null
+++ b/src/math/e_atanh.c
@@ -0,0 +1,59 @@
+
+/* @(#)e_atanh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* atanh(x)
+ * Method :
+ *    1.Reduced x to positive by atanh(-x) = -atanh(x)
+ *    2.For x>=0.5
+ *                  1              2x                          x
+ *      atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ *                  2             1 - x                      1 - x
+ *      
+ *      For x<0.5
+ *      atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ *      atanh(x) is NaN if |x| > 1 with signal;
+ *      atanh(NaN) is that NaN with no signal;
+ *      atanh(+-1) is +-INF with signal.
+ *
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one = 1.0, huge = 1e300;
+static const double zero = 0.0;
+
+double
+atanh(double x)
+{
+        double t;
+        int32_t hx,ix;
+        uint32_t lx;
+        EXTRACT_WORDS(hx,lx,x);
+        ix = hx&0x7fffffff;
+        if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
+            return (x-x)/(x-x);
+        if(ix==0x3ff00000) 
+            return x/zero;
+        if(ix<0x3e300000&&(huge+x)>zero) return x;      /* x<2**-28 */
+        SET_HIGH_WORD(x,ix);
+        if(ix<0x3fe00000) {             /* x < 0.5 */
+            t = x+x;
+            t = 0.5*log1p(t+t*x/(one-x));
+        } else 
+            t = 0.5*log1p((x+x)/(one-x));
+        if(hx>=0) return t; else return -t;
+}
diff --git a/src/math/e_atanhf.c b/src/math/e_atanhf.c
new file mode 100644
index 00000000..7356cfc9
--- /dev/null
+++ b/src/math/e_atanhf.c
@@ -0,0 +1,42 @@
+/* e_atanhf.c -- float version of e_atanh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one = 1.0, huge = 1e30;
+
+static const float zero = 0.0;
+
+float
+atanhf(float x)
+{
+        float t;
+        int32_t hx,ix;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if (ix>0x3f800000)              /* |x|>1 */
+            return (x-x)/(x-x);
+        if(ix==0x3f800000)
+            return x/zero;
+        if(ix<0x31800000&&(huge+x)>zero) return x;      /* x<2**-28 */
+        SET_FLOAT_WORD(x,ix);
+        if(ix<0x3f000000) {             /* x < 0.5 */
+            t = x+x;
+            t = (float)0.5*log1pf(t+t*x/(one-x));
+        } else
+            t = (float)0.5*log1pf((x+x)/(one-x));
+        if(hx>=0) return t; else return -t;
+}
diff --git a/src/math/e_cosh.c b/src/math/e_cosh.c
new file mode 100644
index 00000000..ad425bd3
--- /dev/null
+++ b/src/math/e_cosh.c
@@ -0,0 +1,82 @@
+
+/* @(#)e_cosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* cosh(x)
+ * Method : 
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ *      1. Replace x by |x| (cosh(x) = cosh(-x)). 
+ *      2. 
+ *                                                      [ exp(x) - 1 ]^2 
+ *          0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
+ *                                                         2*exp(x)
+ *
+ *                                                exp(x) +  1/exp(x)
+ *          ln2/2    <= x <= 22     :  cosh(x) := -------------------
+ *                                                        2
+ *          22       <= x <= lnovft :  cosh(x) := exp(x)/2 
+ *          lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
+ *          ln2ovft  <  x           :  cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ *      cosh(x) is |x| if x is +INF, -INF, or NaN.
+ *      only cosh(0)=1 is exact for finite x.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one = 1.0, half=0.5, huge = 1.0e300;
+
+double
+cosh(double x)
+{
+        double t,w;
+        int32_t ix;
+        uint32_t lx;
+
+    /* High word of |x|. */
+        GET_HIGH_WORD(ix,x);
+        ix &= 0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7ff00000) return x*x;  
+
+    /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+        if(ix<0x3fd62e43) {
+            t = expm1(fabs(x));
+            w = one+t;
+            if (ix<0x3c800000) return w;        /* cosh(tiny) = 1 */
+            return one+(t*t)/(w+w);
+        }
+
+    /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+        if (ix < 0x40360000) {
+                t = exp(fabs(x));
+                return half*t+half/t;
+        }
+
+    /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+        if (ix < 0x40862E42)  return half*exp(fabs(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+        GET_LOW_WORD(lx,x);
+        if (ix<0x408633CE ||
+              ((ix==0x408633ce)&&(lx<=(uint32_t)0x8fb9f87d))) {
+            w = exp(half*fabs(x));
+            t = half*w;
+            return t*w;
+        }
+
+    /* |x| > overflowthresold, cosh(x) overflow */
+        return huge*huge;
+}
diff --git a/src/math/e_coshf.c b/src/math/e_coshf.c
new file mode 100644
index 00000000..6db10885
--- /dev/null
+++ b/src/math/e_coshf.c
@@ -0,0 +1,59 @@
+/* e_coshf.c -- float version of e_cosh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one = 1.0, half=0.5, huge = 1.0e30;
+
+float
+coshf(float x)
+{
+        float t,w;
+        int32_t ix;
+
+        GET_FLOAT_WORD(ix,x);
+        ix &= 0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7f800000) return x*x;
+
+    /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+        if(ix<0x3eb17218) {
+            t = expm1f(fabsf(x));
+            w = one+t;
+            if (ix<0x24000000) return w;        /* cosh(tiny) = 1 */
+            return one+(t*t)/(w+w);
+        }
+
+    /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+        if (ix < 0x41b00000) {
+                t = expf(fabsf(x));
+                return half*t+half/t;
+        }
+
+    /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+        if (ix < 0x42b17180)  return half*expf(fabsf(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+        if (ix<=0x42b2d4fc) {
+            w = expf(half*fabsf(x));
+            t = half*w;
+            return t*w;
+        }
+
+    /* |x| > overflowthresold, cosh(x) overflow */
+        return huge*huge;
+}
diff --git a/src/math/e_exp.c b/src/math/e_exp.c
new file mode 100644
index 00000000..66107b95
--- /dev/null
+++ b/src/math/e_exp.c
@@ -0,0 +1,155 @@
+
+/* @(#)e_exp.c 1.6 04/04/22 */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ *      Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2.  
+ *
+ *      Here r will be represented as r = hi-lo for better 
+ *      accuracy.
+ *
+ *   2. Approximation of exp(r) by a special rational function on
+ *      the interval [0,0.34658]:
+ *      Write
+ *          R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ *      We use a special Remes algorithm on [0,0.34658] to generate 
+ *      a polynomial of degree 5 to approximate R. The maximum error 
+ *      of this polynomial approximation is bounded by 2**-59. In
+ *      other words,
+ *          R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ *      (where z=r*r, and the values of P1 to P5 are listed below)
+ *      and
+ *          |                  5          |     -59
+ *          | 2.0+P1*z+...+P5*z   -  R(z) | <= 2 
+ *          |                             |
+ *      The computation of exp(r) thus becomes
+ *                             2*r
+ *              exp(r) = 1 + -------
+ *                            R - r
+ *                                 r*R1(r)      
+ *                     = 1 + r + ----------- (for better accuracy)
+ *                                2 - R1(r)
+ *      where
+ *                               2       4             10
+ *              R1(r) = r - (P1*r  + P2*r  + ... + P5*r   ).
+ *      
+ *   3. Scale back to obtain exp(x):
+ *      From step 1, we have
+ *         exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ *      exp(INF) is INF, exp(NaN) is NaN;
+ *      exp(-INF) is 0, and
+ *      for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *      For IEEE double 
+ *          if x >  7.09782712893383973096e+02 then exp(x) overflow
+ *          if x < -7.45133219101941108420e+02 then exp(x) underflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one     = 1.0,
+halF[2] = {0.5,-0.5,},
+huge    = 1.0e+300,
+twom1000= 9.33263618503218878990e-302,     /* 2**-1000=0x01700000,0*/
+o_threshold=  7.09782712893383973096e+02,  /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02,  /* 0xc0874910, 0xD52D3051 */
+ln2HI[2]   ={ 6.93147180369123816490e-01,  /* 0x3fe62e42, 0xfee00000 */
+             -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2]   ={ 1.90821492927058770002e-10,  /* 0x3dea39ef, 0x35793c76 */
+             -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 =  1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+
+double
+exp(double x) /* default IEEE double exp */
+{
+        double y,hi=0.0,lo=0.0,c,t;
+        int32_t k=0,xsb;
+        uint32_t hx;
+
+        GET_HIGH_WORD(hx,x);
+        xsb = (hx>>31)&1;               /* sign bit of x */
+        hx &= 0x7fffffff;               /* high word of |x| */
+
+    /* filter out non-finite argument */
+        if(hx >= 0x40862E42) {                  /* if |x|>=709.78... */
+            if(hx>=0x7ff00000) {
+                uint32_t lx;
+                GET_LOW_WORD(lx,x);
+                if(((hx&0xfffff)|lx)!=0)
+                     return x+x;                /* NaN */
+                else return (xsb==0)? x:0.0;    /* exp(+-inf)={inf,0} */
+            }
+            if(x > o_threshold) return huge*huge; /* overflow */
+            if(x < u_threshold) return twom1000*twom1000; /* underflow */
+        }
+
+    /* argument reduction */
+        if(hx > 0x3fd62e42) {           /* if  |x| > 0.5 ln2 */ 
+            if(hx < 0x3FF0A2B2) {       /* and |x| < 1.5 ln2 */
+                hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+            } else {
+                k  = (int)(invln2*x+halF[xsb]);
+                t  = k;
+                hi = x - t*ln2HI[0];    /* t*ln2HI is exact here */
+                lo = t*ln2LO[0];
+            }
+            x  = hi - lo;
+        } 
+        else if(hx < 0x3e300000)  {     /* when |x|<2**-28 */
+            if(huge+x>one) return one+x;/* trigger inexact */
+        }
+        else k = 0;
+
+    /* x is now in primary range */
+        t  = x*x;
+        c  = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+        if(k==0)        return one-((x*c)/(c-2.0)-x); 
+        else            y = one-((lo-(x*c)/(2.0-c))-hi);
+        if(k >= -1021) {
+            uint32_t hy;
+            GET_HIGH_WORD(hy,y);
+            SET_HIGH_WORD(y,hy+(k<<20));        /* add k to y's exponent */
+            return y;
+        } else {
+            uint32_t hy;
+            GET_HIGH_WORD(hy,y);
+            SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */
+            return y*twom1000;
+        }
+}
diff --git a/src/math/e_expf.c b/src/math/e_expf.c
new file mode 100644
index 00000000..99818edc
--- /dev/null
+++ b/src/math/e_expf.c
@@ -0,0 +1,91 @@
+/* e_expf.c -- float version of e_exp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one     = 1.0,
+halF[2] = {0.5,-0.5,},
+huge    = 1.0e+30,
+twom100 = 7.8886090522e-31,      /* 2**-100=0x0d800000 */
+o_threshold=  8.8721679688e+01,  /* 0x42b17180 */
+u_threshold= -1.0397208405e+02,  /* 0xc2cff1b5 */
+ln2HI[2]   ={ 6.9313812256e-01,         /* 0x3f317180 */
+             -6.9313812256e-01,},       /* 0xbf317180 */
+ln2LO[2]   ={ 9.0580006145e-06,         /* 0x3717f7d1 */
+             -9.0580006145e-06,},       /* 0xb717f7d1 */
+invln2 =  1.4426950216e+00,             /* 0x3fb8aa3b */
+P1   =  1.6666667163e-01, /* 0x3e2aaaab */
+P2   = -2.7777778450e-03, /* 0xbb360b61 */
+P3   =  6.6137559770e-05, /* 0x388ab355 */
+P4   = -1.6533901999e-06, /* 0xb5ddea0e */
+P5   =  4.1381369442e-08; /* 0x3331bb4c */
+
+float
+expf(float x) /* default IEEE double exp */
+{
+        float y,hi=0.0,lo=0.0,c,t;
+        int32_t k=0,xsb;
+        uint32_t hx;
+
+        GET_FLOAT_WORD(hx,x);
+        xsb = (hx>>31)&1;               /* sign bit of x */
+        hx &= 0x7fffffff;               /* high word of |x| */
+
+    /* filter out non-finite argument */
+        if(hx >= 0x42b17218) {                  /* if |x|>=88.721... */
+            if(hx>0x7f800000)
+                 return x+x;                    /* NaN */
+            if(hx==0x7f800000)
+                return (xsb==0)? x:0.0;         /* exp(+-inf)={inf,0} */
+            if(x > o_threshold) return huge*huge; /* overflow */
+            if(x < u_threshold) return twom100*twom100; /* underflow */
+        }
+
+    /* argument reduction */
+        if(hx > 0x3eb17218) {           /* if  |x| > 0.5 ln2 */
+            if(hx < 0x3F851592) {       /* and |x| < 1.5 ln2 */
+                hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+            } else {
+                k  = invln2*x+halF[xsb];
+                t  = k;
+                hi = x - t*ln2HI[0];    /* t*ln2HI is exact here */
+                lo = t*ln2LO[0];
+            }
+            x  = hi - lo;
+        }
+        else if(hx < 0x31800000)  {     /* when |x|<2**-28 */
+            if(huge+x>one) return one+x;/* trigger inexact */
+        }
+        else k = 0;
+
+    /* x is now in primary range */
+        t  = x*x;
+        c  = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+        if(k==0)        return one-((x*c)/(c-(float)2.0)-x);
+        else            y = one-((lo-(x*c)/((float)2.0-c))-hi);
+        if(k >= -125) {
+            uint32_t hy;
+            GET_FLOAT_WORD(hy,y);
+            SET_FLOAT_WORD(y,hy+(k<<23));       /* add k to y's exponent */
+            return y;
+        } else {
+            uint32_t hy;
+            GET_FLOAT_WORD(hy,y);
+            SET_FLOAT_WORD(y,hy+((k+100)<<23)); /* add k to y's exponent */
+            return y*twom100;
+        }
+}
diff --git a/src/math/e_fmod.c b/src/math/e_fmod.c
new file mode 100644
index 00000000..99afe489
--- /dev/null
+++ b/src/math/e_fmod.c
@@ -0,0 +1,129 @@
+
+/* @(#)e_fmod.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+
+double
+fmod(double x, double y)
+{
+        int32_t n,hx,hy,hz,ix,iy,sx,i;
+        uint32_t lx,ly,lz;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hy,ly,y);
+        sx = hx&0x80000000;             /* sign of x */
+        hx ^=sx;                /* |x| */
+        hy &= 0x7fffffff;       /* |y| */
+
+    /* purge off exception values */
+        if((hy|ly)==0||(hx>=0x7ff00000)||       /* y=0,or x not finite */
+          ((hy|((ly|-ly)>>31))>0x7ff00000))     /* or y is NaN */
+            return (x*y)/(x*y);
+        if(hx<=hy) {
+            if((hx<hy)||(lx<ly)) return x;      /* |x|<|y| return x */
+            if(lx==ly) 
+                return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
+        }
+
+    /* determine ix = ilogb(x) */
+        if(hx<0x00100000) {     /* subnormal x */
+            if(hx==0) {
+                for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+            } else {
+                for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+            }
+        } else ix = (hx>>20)-1023;
+
+    /* determine iy = ilogb(y) */
+        if(hy<0x00100000) {     /* subnormal y */
+            if(hy==0) {
+                for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+            } else {
+                for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+            }
+        } else iy = (hy>>20)-1023;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+        if(ix >= -1022) 
+            hx = 0x00100000|(0x000fffff&hx);
+        else {          /* subnormal x, shift x to normal */
+            n = -1022-ix;
+            if(n<=31) {
+                hx = (hx<<n)|(lx>>(32-n));
+                lx <<= n;
+            } else {
+                hx = lx<<(n-32);
+                lx = 0;
+            }
+        }
+        if(iy >= -1022) 
+            hy = 0x00100000|(0x000fffff&hy);
+        else {          /* subnormal y, shift y to normal */
+            n = -1022-iy;
+            if(n<=31) {
+                hy = (hy<<n)|(ly>>(32-n));
+                ly <<= n;
+            } else {
+                hy = ly<<(n-32);
+                ly = 0;
+            }
+        }
+
+    /* fix point fmod */
+        n = ix - iy;
+        while(n--) {
+            hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+            if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+            else {
+                if((hz|lz)==0)          /* return sign(x)*0 */
+                    return Zero[(uint32_t)sx>>31];
+                hx = hz+hz+(lz>>31); lx = lz+lz;
+            }
+        }
+        hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+        if(hz>=0) {hx=hz;lx=lz;}
+
+    /* convert back to floating value and restore the sign */
+        if((hx|lx)==0)                  /* return sign(x)*0 */
+            return Zero[(uint32_t)sx>>31];
+        while(hx<0x00100000) {          /* normalize x */
+            hx = hx+hx+(lx>>31); lx = lx+lx;
+            iy -= 1;
+        }
+        if(iy>= -1022) {        /* normalize output */
+            hx = ((hx-0x00100000)|((iy+1023)<<20));
+            INSERT_WORDS(x,hx|sx,lx);
+        } else {                /* subnormal output */
+            n = -1022 - iy;
+            if(n<=20) {
+                lx = (lx>>n)|((uint32_t)hx<<(32-n));
+                hx >>= n;
+            } else if (n<=31) {
+                lx = (hx<<(32-n))|(lx>>n); hx = sx;
+            } else {
+                lx = hx>>(n-32); hx = sx;
+            }
+            INSERT_WORDS(x,hx|sx,lx);
+            x *= one;           /* create necessary signal */
+        }
+        return x;               /* exact output */
+}
diff --git a/src/math/e_fmodf.c b/src/math/e_fmodf.c
new file mode 100644
index 00000000..fe86cb04
--- /dev/null
+++ b/src/math/e_fmodf.c
@@ -0,0 +1,101 @@
+/* e_fmodf.c -- float version of e_fmod.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * fmodf(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one = 1.0, Zero[] = {0.0, -0.0,};
+
+float
+fmodf(float x, float y)
+{
+        int32_t n,hx,hy,hz,ix,iy,sx,i;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hy,y);
+        sx = hx&0x80000000;             /* sign of x */
+        hx ^=sx;                /* |x| */
+        hy &= 0x7fffffff;       /* |y| */
+
+    /* purge off exception values */
+        if(hy==0||(hx>=0x7f800000)||            /* y=0,or x not finite */
+           (hy>0x7f800000))                     /* or y is NaN */
+            return (x*y)/(x*y);
+        if(hx<hy) return x;                     /* |x|<|y| return x */
+        if(hx==hy)
+            return Zero[(uint32_t)sx>>31];     /* |x|=|y| return x*0*/
+
+    /* determine ix = ilogb(x) */
+        if(hx<0x00800000) {     /* subnormal x */
+            for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
+        } else ix = (hx>>23)-127;
+
+    /* determine iy = ilogb(y) */
+        if(hy<0x00800000) {     /* subnormal y */
+            for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
+        } else iy = (hy>>23)-127;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+        if(ix >= -126)
+            hx = 0x00800000|(0x007fffff&hx);
+        else {          /* subnormal x, shift x to normal */
+            n = -126-ix;
+            hx = hx<<n;
+        }
+        if(iy >= -126)
+            hy = 0x00800000|(0x007fffff&hy);
+        else {          /* subnormal y, shift y to normal */
+            n = -126-iy;
+            hy = hy<<n;
+        }
+
+    /* fix point fmod */
+        n = ix - iy;
+        while(n--) {
+            hz=hx-hy;
+            if(hz<0){hx = hx+hx;}
+            else {
+                if(hz==0)               /* return sign(x)*0 */
+                    return Zero[(uint32_t)sx>>31];
+                hx = hz+hz;
+            }
+        }
+        hz=hx-hy;
+        if(hz>=0) {hx=hz;}
+
+    /* convert back to floating value and restore the sign */
+        if(hx==0)                       /* return sign(x)*0 */
+            return Zero[(uint32_t)sx>>31];
+        while(hx<0x00800000) {          /* normalize x */
+            hx = hx+hx;
+            iy -= 1;
+        }
+        if(iy>= -126) {         /* normalize output */
+            hx = ((hx-0x00800000)|((iy+127)<<23));
+            SET_FLOAT_WORD(x,hx|sx);
+        } else {                /* subnormal output */
+            n = -126 - iy;
+            hx >>= n;
+            SET_FLOAT_WORD(x,hx|sx);
+            x *= one;           /* create necessary signal */
+        }
+        return x;               /* exact output */
+}
diff --git a/src/math/e_hypot.c b/src/math/e_hypot.c
new file mode 100644
index 00000000..e925adc3
--- /dev/null
+++ b/src/math/e_hypot.c
@@ -0,0 +1,121 @@
+
+/* @(#)e_hypot.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* hypot(x,y)
+ *
+ * Method :                  
+ *      If (assume round-to-nearest) z=x*x+y*y 
+ *      has error less than sqrt(2)/2 ulp, than 
+ *      sqrt(z) has error less than 1 ulp (exercise).
+ *
+ *      So, compute sqrt(x*x+y*y) with some care as 
+ *      follows to get the error below 1 ulp:
+ *
+ *      Assume x>y>0;
+ *      (if possible, set rounding to round-to-nearest)
+ *      1. if x > 2y  use
+ *              x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ *      where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ *      2. if x <= 2y use
+ *              t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ *      where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, 
+ *      y1= y with lower 32 bits chopped, y2 = y-y1.
+ *              
+ *      NOTE: scaling may be necessary if some argument is too 
+ *            large or too tiny
+ *
+ * Special cases:
+ *      hypot(x,y) is INF if x or y is +INF or -INF; else
+ *      hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ *      hypot(x,y) returns sqrt(x^2+y^2) with error less 
+ *      than 1 ulps (units in the last place) 
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+hypot(double x, double y)
+{
+        double a=x,b=y,t1,t2,y1,y2,w;
+        int32_t j,k,ha,hb;
+
+        GET_HIGH_WORD(ha,x);
+        ha &= 0x7fffffff;
+        GET_HIGH_WORD(hb,y);
+        hb &= 0x7fffffff;
+        if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+        SET_HIGH_WORD(a,ha);    /* a <- |a| */
+        SET_HIGH_WORD(b,hb);    /* b <- |b| */
+        if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
+        k=0;
+        if(ha > 0x5f300000) {   /* a>2**500 */
+           if(ha >= 0x7ff00000) {       /* Inf or NaN */
+               uint32_t low;
+               w = a+b;                 /* for sNaN */
+               GET_LOW_WORD(low,a);
+               if(((ha&0xfffff)|low)==0) w = a;
+               GET_LOW_WORD(low,b);
+               if(((hb^0x7ff00000)|low)==0) w = b;
+               return w;
+           }
+           /* scale a and b by 2**-600 */
+           ha -= 0x25800000; hb -= 0x25800000;  k += 600;
+           SET_HIGH_WORD(a,ha);
+           SET_HIGH_WORD(b,hb);
+        }
+        if(hb < 0x20b00000) {   /* b < 2**-500 */
+            if(hb <= 0x000fffff) {      /* subnormal b or 0 */
+                uint32_t low;
+                GET_LOW_WORD(low,b);
+                if((hb|low)==0) return a;
+                t1=0;
+                SET_HIGH_WORD(t1,0x7fd00000);   /* t1=2^1022 */
+                b *= t1;
+                a *= t1;
+                k -= 1022;
+            } else {            /* scale a and b by 2^600 */
+                ha += 0x25800000;       /* a *= 2^600 */
+                hb += 0x25800000;       /* b *= 2^600 */
+                k -= 600;
+                SET_HIGH_WORD(a,ha);
+                SET_HIGH_WORD(b,hb);
+            }
+        }
+    /* medium size a and b */
+        w = a-b;
+        if (w>b) {
+            t1 = 0;
+            SET_HIGH_WORD(t1,ha);
+            t2 = a-t1;
+            w  = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+        } else {
+            a  = a+a;
+            y1 = 0;
+            SET_HIGH_WORD(y1,hb);
+            y2 = b - y1;
+            t1 = 0;
+            SET_HIGH_WORD(t1,ha+0x00100000);
+            t2 = a - t1;
+            w  = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+        }
+        if(k!=0) {
+            uint32_t high;
+            t1 = 1.0;
+            GET_HIGH_WORD(high,t1);
+            SET_HIGH_WORD(t1,high+(k<<20));
+            return t1*w;
+        } else return w;
+}
diff --git a/src/math/e_hypotf.c b/src/math/e_hypotf.c
new file mode 100644
index 00000000..13773554
--- /dev/null
+++ b/src/math/e_hypotf.c
@@ -0,0 +1,79 @@
+/* e_hypotf.c -- float version of e_hypot.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+hypotf(float x, float y)
+{
+        float a=x,b=y,t1,t2,y1,y2,w;
+        int32_t j,k,ha,hb;
+
+        GET_FLOAT_WORD(ha,x);
+        ha &= 0x7fffffff;
+        GET_FLOAT_WORD(hb,y);
+        hb &= 0x7fffffff;
+        if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+        SET_FLOAT_WORD(a,ha);   /* a <- |a| */
+        SET_FLOAT_WORD(b,hb);   /* b <- |b| */
+        if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
+        k=0;
+        if(ha > 0x58800000) {   /* a>2**50 */
+           if(ha >= 0x7f800000) {       /* Inf or NaN */
+               w = a+b;                 /* for sNaN */
+               if(ha == 0x7f800000) w = a;
+               if(hb == 0x7f800000) w = b;
+               return w;
+           }
+           /* scale a and b by 2**-68 */
+           ha -= 0x22000000; hb -= 0x22000000;  k += 68;
+           SET_FLOAT_WORD(a,ha);
+           SET_FLOAT_WORD(b,hb);
+        }
+        if(hb < 0x26800000) {   /* b < 2**-50 */
+            if(hb <= 0x007fffff) {      /* subnormal b or 0 */
+                if(hb==0) return a;
+                SET_FLOAT_WORD(t1,0x7e800000);  /* t1=2^126 */
+                b *= t1;
+                a *= t1;
+                k -= 126;
+            } else {            /* scale a and b by 2^68 */
+                ha += 0x22000000;       /* a *= 2^68 */
+                hb += 0x22000000;       /* b *= 2^68 */
+                k -= 68;
+                SET_FLOAT_WORD(a,ha);
+                SET_FLOAT_WORD(b,hb);
+            }
+        }
+    /* medium size a and b */
+        w = a-b;
+        if (w>b) {
+            SET_FLOAT_WORD(t1,ha&0xfffff000);
+            t2 = a-t1;
+            w  = sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+        } else {
+            a  = a+a;
+            SET_FLOAT_WORD(y1,hb&0xfffff000);
+            y2 = b - y1;
+            SET_FLOAT_WORD(t1,ha+0x00800000);
+            t2 = a - t1;
+            w  = sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+        }
+        if(k!=0) {
+            SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
+            return t1*w;
+        } else return w;
+}
diff --git a/src/math/e_log.c b/src/math/e_log.c
new file mode 100644
index 00000000..9eb0e444
--- /dev/null
+++ b/src/math/e_log.c
@@ -0,0 +1,131 @@
+
+/* @(#)e_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* log(x)
+ * Return the logrithm of x
+ *
+ * Method :                  
+ *   1. Argument Reduction: find k and f such that 
+ *                      x = 2^k * (1+f), 
+ *         where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *   2. Approximation of log(1+f).
+ *      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *               = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *               = 2s + s*R
+ *      We use a special Reme algorithm on [0,0.1716] to generate 
+ *      a polynomial of degree 14 to approximate R The maximum error 
+ *      of this polynomial approximation is bounded by 2**-58.45. In
+ *      other words,
+ *                      2      4      6      8      10      12      14
+ *          R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
+ *      (the values of Lg1 to Lg7 are listed in the program)
+ *      and
+ *          |      2          14          |     -58.45
+ *          | Lg1*s +...+Lg7*s    -  R(z) | <= 2 
+ *          |                             |
+ *      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ *      In order to guarantee error in log below 1ulp, we compute log
+ *      by
+ *              log(1+f) = f - s*(f - R)        (if f is not too large)
+ *              log(1+f) = f - (hfsq - s*(hfsq+R)).     (better accuracy)
+ *      
+ *      3. Finally,  log(x) = k*ln2 + log(1+f).  
+ *                          = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ *         Here ln2 is split into two floating point number: 
+ *                      ln2_hi + ln2_lo,
+ *         where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ *      log(x) is NaN with signal if x < 0 (including -INF) ; 
+ *      log(+INF) is +INF; log(0) is -INF with signal;
+ *      log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+ln2_hi  =  6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo  =  1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+two54   =  1.80143985094819840000e+16,  /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+static const double zero   =  0.0;
+
+double
+log(double x)
+{
+        double hfsq,f,s,z,R,w,t1,t2,dk;
+        int32_t k,hx,i,j;
+        uint32_t lx;
+
+        EXTRACT_WORDS(hx,lx,x);
+
+        k=0;
+        if (hx < 0x00100000) {                  /* x < 2**-1022  */
+            if (((hx&0x7fffffff)|lx)==0) 
+                return -two54/zero;             /* log(+-0)=-inf */
+            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
+            k -= 54; x *= two54; /* subnormal number, scale up x */
+            GET_HIGH_WORD(hx,x);
+        } 
+        if (hx >= 0x7ff00000) return x+x;
+        k += (hx>>20)-1023;
+        hx &= 0x000fffff;
+        i = (hx+0x95f64)&0x100000;
+        SET_HIGH_WORD(x,hx|(i^0x3ff00000));     /* normalize x or x/2 */
+        k += (i>>20);
+        f = x-1.0;
+        if((0x000fffff&(2+hx))<3) {     /* |f| < 2**-20 */
+            if(f==zero) { if(k==0) return zero;  else {dk=(double)k;
+                                 return dk*ln2_hi+dk*ln2_lo;} }
+            R = f*f*(0.5-0.33333333333333333*f);
+            if(k==0) return f-R; else {dk=(double)k;
+                     return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+        }
+        s = f/(2.0+f); 
+        dk = (double)k;
+        z = s*s;
+        i = hx-0x6147a;
+        w = z*z;
+        j = 0x6b851-hx;
+        t1= w*(Lg2+w*(Lg4+w*Lg6)); 
+        t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); 
+        i |= j;
+        R = t2+t1;
+        if(i>0) {
+            hfsq=0.5*f*f;
+            if(k==0) return f-(hfsq-s*(hfsq+R)); else
+                     return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+        } else {
+            if(k==0) return f-s*(f-R); else
+                     return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+        }
+}
diff --git a/src/math/e_log10.c b/src/math/e_log10.c
new file mode 100644
index 00000000..3be179f7
--- /dev/null
+++ b/src/math/e_log10.c
@@ -0,0 +1,83 @@
+
+/* @(#)e_log10.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* log10(x)
+ * Return the base 10 logarithm of x
+ * 
+ * Method :
+ *      Let log10_2hi = leading 40 bits of log10(2) and
+ *          log10_2lo = log10(2) - log10_2hi,
+ *          ivln10   = 1/log(10) rounded.
+ *      Then
+ *              n = ilogb(x), 
+ *              if(n<0)  n = n+1;
+ *              x = scalbn(x,-n);
+ *              log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+ *
+ * Note 1:
+ *      To guarantee log10(10**n)=n, where 10**n is normal, the rounding 
+ *      mode must set to Round-to-Nearest.
+ * Note 2:
+ *      [1/log(10)] rounded to 53 bits has error  .198   ulps;
+ *      log10 is monotonic at all binary break points.
+ *
+ * Special cases:
+ *      log10(x) is NaN with signal if x < 0; 
+ *      log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ *      log10(NaN) is that NaN with no signal;
+ *      log10(10**N) = N  for N=0,1,...,22.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+two54      =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln10     =  4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
+log10_2hi  =  3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo  =  3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
+
+static const double zero   =  0.0;
+
+double
+log10(double x)
+{
+        double y,z;
+        int32_t i,k,hx;
+        uint32_t lx;
+
+        EXTRACT_WORDS(hx,lx,x);
+
+        k=0;
+        if (hx < 0x00100000) {                  /* x < 2**-1022  */
+            if (((hx&0x7fffffff)|lx)==0)
+                return -two54/zero;             /* log(+-0)=-inf */
+            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
+            k -= 54; x *= two54; /* subnormal number, scale up x */
+            GET_HIGH_WORD(hx,x);
+        }
+        if (hx >= 0x7ff00000) return x+x;
+        k += (hx>>20)-1023;
+        i  = ((uint32_t)k&0x80000000)>>31;
+        hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+        y  = (double)(k+i);
+        SET_HIGH_WORD(x,hx);
+        z  = y*log10_2lo + ivln10*log(x);
+        return  z+y*log10_2hi;
+}
diff --git a/src/math/e_log10f.c b/src/math/e_log10f.c
new file mode 100644
index 00000000..8fc5c5ca
--- /dev/null
+++ b/src/math/e_log10f.c
@@ -0,0 +1,51 @@
+/* e_log10f.c -- float version of e_log10.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+two25      =  3.3554432000e+07, /* 0x4c000000 */
+ivln10     =  4.3429449201e-01, /* 0x3ede5bd9 */
+log10_2hi  =  3.0102920532e-01, /* 0x3e9a2080 */
+log10_2lo  =  7.9034151668e-07; /* 0x355427db */
+
+static const float zero   =  0.0;
+
+float
+log10f(float x)
+{
+        float y,z;
+        int32_t i,k,hx;
+
+        GET_FLOAT_WORD(hx,x);
+
+        k=0;
+        if (hx < 0x00800000) {                  /* x < 2**-126  */
+            if ((hx&0x7fffffff)==0)
+                return -two25/zero;             /* log(+-0)=-inf */
+            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
+            k -= 25; x *= two25; /* subnormal number, scale up x */
+            GET_FLOAT_WORD(hx,x);
+        }
+        if (hx >= 0x7f800000) return x+x;
+        k += (hx>>23)-127;
+        i  = ((uint32_t)k&0x80000000)>>31;
+        hx = (hx&0x007fffff)|((0x7f-i)<<23);
+        y  = (float)(k+i);
+        SET_FLOAT_WORD(x,hx);
+        z  = y*log10_2lo + ivln10*logf(x);
+        return  z+y*log10_2hi;
+}
diff --git a/src/math/e_logf.c b/src/math/e_logf.c
new file mode 100644
index 00000000..46a8b8ce
--- /dev/null
+++ b/src/math/e_logf.c
@@ -0,0 +1,81 @@
+/* e_logf.c -- float version of e_log.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+ln2_hi =   6.9313812256e-01,    /* 0x3f317180 */
+ln2_lo =   9.0580006145e-06,    /* 0x3717f7d1 */
+two25 =    3.355443200e+07,     /* 0x4c000000 */
+Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lg3 = 2.8571429849e-01, /* 3E924925 */
+Lg4 = 2.2222198546e-01, /* 3E638E29 */
+Lg5 = 1.8183572590e-01, /* 3E3A3325 */
+Lg6 = 1.5313838422e-01, /* 3E1CD04F */
+Lg7 = 1.4798198640e-01; /* 3E178897 */
+
+static const float zero   =  0.0;
+
+float
+logf(float x)
+{
+        float hfsq,f,s,z,R,w,t1,t2,dk;
+        int32_t k,ix,i,j;
+
+        GET_FLOAT_WORD(ix,x);
+
+        k=0;
+        if (ix < 0x00800000) {                  /* x < 2**-126  */
+            if ((ix&0x7fffffff)==0)
+                return -two25/zero;             /* log(+-0)=-inf */
+            if (ix<0) return (x-x)/zero;        /* log(-#) = NaN */
+            k -= 25; x *= two25; /* subnormal number, scale up x */
+            GET_FLOAT_WORD(ix,x);
+        }
+        if (ix >= 0x7f800000) return x+x;
+        k += (ix>>23)-127;
+        ix &= 0x007fffff;
+        i = (ix+(0x95f64<<3))&0x800000;
+        SET_FLOAT_WORD(x,ix|(i^0x3f800000));    /* normalize x or x/2 */
+        k += (i>>23);
+        f = x-(float)1.0;
+        if((0x007fffff&(15+ix))<16) {   /* |f| < 2**-20 */
+            if(f==zero) { if(k==0) return zero;  else {dk=(float)k;
+                                 return dk*ln2_hi+dk*ln2_lo;} }
+            R = f*f*((float)0.5-(float)0.33333333333333333*f);
+            if(k==0) return f-R; else {dk=(float)k;
+                     return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+        }
+        s = f/((float)2.0+f);
+        dk = (float)k;
+        z = s*s;
+        i = ix-(0x6147a<<3);
+        w = z*z;
+        j = (0x6b851<<3)-ix;
+        t1= w*(Lg2+w*(Lg4+w*Lg6));
+        t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+        i |= j;
+        R = t2+t1;
+        if(i>0) {
+            hfsq=(float)0.5*f*f;
+            if(k==0) return f-(hfsq-s*(hfsq+R)); else
+                     return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+        } else {
+            if(k==0) return f-s*(f-R); else
+                     return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+        }
+}
diff --git a/src/math/e_pow.c b/src/math/e_pow.c
new file mode 100644
index 00000000..aad24287
--- /dev/null
+++ b/src/math/e_pow.c
@@ -0,0 +1,300 @@
+/* @(#)e_pow.c 1.5 04/04/22 SMI */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* pow(x,y) return x**y
+ *
+ *                    n
+ * Method:  Let x =  2   * (1+f)
+ *      1. Compute and return log2(x) in two pieces:
+ *              log2(x) = w1 + w2,
+ *         where w1 has 53-24 = 29 bit trailing zeros.
+ *      2. Perform y*log2(x) = n+y' by simulating muti-precision 
+ *         arithmetic, where |y'|<=0.5.
+ *      3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ *      1.  (anything) ** 0  is 1
+ *      2.  (anything) ** 1  is itself
+ *      3.  (anything) ** NAN is NAN
+ *      4.  NAN ** (anything except 0) is NAN
+ *      5.  +-(|x| > 1) **  +INF is +INF
+ *      6.  +-(|x| > 1) **  -INF is +0
+ *      7.  +-(|x| < 1) **  +INF is +0
+ *      8.  +-(|x| < 1) **  -INF is +INF
+ *      9.  +-1         ** +-INF is NAN
+ *      10. +0 ** (+anything except 0, NAN)               is +0
+ *      11. -0 ** (+anything except 0, NAN, odd integer)  is +0
+ *      12. +0 ** (-anything except 0, NAN)               is +INF
+ *      13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
+ *      14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ *      15. +INF ** (+anything except 0,NAN) is +INF
+ *      16. +INF ** (-anything except 0,NAN) is +0
+ *      17. -INF ** (anything)  = -0 ** (-anything)
+ *      18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ *      19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ *      pow(x,y) returns x**y nearly rounded. In particular
+ *                      pow(integer,integer)
+ *      always returns the correct integer provided it is 
+ *      representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero    =  0.0,
+one     =  1.0,
+two     =  2.0,
+two53   =  9007199254740992.0,  /* 0x43400000, 0x00000000 */
+huge    =  1.0e300,
+tiny    =  1.0e-300,
+        /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1  =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2  =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3  =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4  =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5  =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6  =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2  =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h  =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l  = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt =  8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp    =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h  =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l  = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2    =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+double
+pow(double x, double y)
+{
+        double z,ax,z_h,z_l,p_h,p_l;
+        double y1,t1,t2,r,s,t,u,v,w;
+        int32_t i,j,k,yisint,n;
+        int32_t hx,hy,ix,iy;
+        uint32_t lx,ly;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hy,ly,y);
+        ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
+
+    /* y==zero: x**0 = 1 */
+        if((iy|ly)==0) return one;      
+
+    /* +-NaN return x+y */
+        if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+           iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) 
+                return x+y;     
+
+    /* determine if y is an odd int when x < 0
+     * yisint = 0       ... y is not an integer
+     * yisint = 1       ... y is an odd int
+     * yisint = 2       ... y is an even int
+     */
+        yisint  = 0;
+        if(hx<0) {      
+            if(iy>=0x43400000) yisint = 2; /* even integer y */
+            else if(iy>=0x3ff00000) {
+                k = (iy>>20)-0x3ff;        /* exponent */
+                if(k>20) {
+                    j = ly>>(52-k);
+                    if((j<<(52-k))==ly) yisint = 2-(j&1);
+                } else if(ly==0) {
+                    j = iy>>(20-k);
+                    if((j<<(20-k))==iy) yisint = 2-(j&1);
+                }
+            }           
+        } 
+
+    /* special value of y */
+        if(ly==0) {     
+            if (iy==0x7ff00000) {       /* y is +-inf */
+                if(((ix-0x3ff00000)|lx)==0)
+                    return  y - y;      /* inf**+-1 is NaN */
+                else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+                    return (hy>=0)? y: zero;
+                else                    /* (|x|<1)**-,+inf = inf,0 */
+                    return (hy<0)?-y: zero;
+            } 
+            if(iy==0x3ff00000) {        /* y is  +-1 */
+                if(hy<0) return one/x; else return x;
+            }
+            if(hy==0x40000000) return x*x; /* y is  2 */
+            if(hy==0x3fe00000) {        /* y is  0.5 */
+                if(hx>=0)       /* x >= +0 */
+                return sqrt(x); 
+            }
+        }
+
+        ax   = fabs(x);
+    /* special value of x */
+        if(lx==0) {
+            if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+                z = ax;                 /*x is +-0,+-inf,+-1*/
+                if(hy<0) z = one/z;     /* z = (1/|x|) */
+                if(hx<0) {
+                    if(((ix-0x3ff00000)|yisint)==0) {
+                        z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+                    } else if(yisint==1) 
+                        z = -z;         /* (x<0)**odd = -(|x|**odd) */
+                }
+                return z;
+            }
+        }
+    
+    /* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be
+        n = (hx>>31)+1;
+       but ANSI C says a right shift of a signed negative quantity is
+       implementation defined.  */
+        n = ((uint32_t)hx>>31)-1;
+
+    /* (x<0)**(non-int) is NaN */
+        if((n|yisint)==0) return (x-x)/(x-x);
+
+        s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+        if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
+
+    /* |y| is huge */
+        if(iy>0x41e00000) { /* if |y| > 2**31 */
+            if(iy>0x43f00000){  /* if |y| > 2**64, must o/uflow */
+                if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+                if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+            }
+        /* over/underflow if x is not close to one */
+            if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
+            if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
+        /* now |1-x| is tiny <= 2**-20, suffice to compute 
+           log(x) by x-x^2/2+x^3/3-x^4/4 */
+            t = ax-one;         /* t has 20 trailing zeros */
+            w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+            u = ivln2_h*t;      /* ivln2_h has 21 sig. bits */
+            v = t*ivln2_l-w*ivln2;
+            t1 = u+v;
+            SET_LOW_WORD(t1,0);
+            t2 = v-(t1-u);
+        } else {
+            double ss,s2,s_h,s_l,t_h,t_l;
+            n = 0;
+        /* take care subnormal number */
+            if(ix<0x00100000)
+                {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
+            n  += ((ix)>>20)-0x3ff;
+            j  = ix&0x000fffff;
+        /* determine interval */
+            ix = j|0x3ff00000;          /* normalize ix */
+            if(j<=0x3988E) k=0;         /* |x|<sqrt(3/2) */
+            else if(j<0xBB67A) k=1;     /* |x|<sqrt(3)   */
+            else {k=0;n+=1;ix -= 0x00100000;}
+            SET_HIGH_WORD(ax,ix);
+
+        /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+            u = ax-bp[k];               /* bp[0]=1.0, bp[1]=1.5 */
+            v = one/(ax+bp[k]);
+            ss = u*v;
+            s_h = ss;
+            SET_LOW_WORD(s_h,0);
+        /* t_h=ax+bp[k] High */
+            t_h = zero;
+            SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
+            t_l = ax - (t_h-bp[k]);
+            s_l = v*((u-s_h*t_h)-s_h*t_l);
+        /* compute log(ax) */
+            s2 = ss*ss;
+            r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+            r += s_l*(s_h+ss);
+            s2  = s_h*s_h;
+            t_h = 3.0+s2+r;
+            SET_LOW_WORD(t_h,0);
+            t_l = r-((t_h-3.0)-s2);
+        /* u+v = ss*(1+...) */
+            u = s_h*t_h;
+            v = s_l*t_h+t_l*ss;
+        /* 2/(3log2)*(ss+...) */
+            p_h = u+v;
+            SET_LOW_WORD(p_h,0);
+            p_l = v-(p_h-u);
+            z_h = cp_h*p_h;             /* cp_h+cp_l = 2/(3*log2) */
+            z_l = cp_l*p_h+p_l*cp+dp_l[k];
+        /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+            t = (double)n;
+            t1 = (((z_h+z_l)+dp_h[k])+t);
+            SET_LOW_WORD(t1,0);
+            t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+        }
+
+    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+        y1  = y;
+        SET_LOW_WORD(y1,0);
+        p_l = (y-y1)*t1+y*t2;
+        p_h = y1*t1;
+        z = p_l+p_h;
+        EXTRACT_WORDS(j,i,z);
+        if (j>=0x40900000) {                            /* z >= 1024 */
+            if(((j-0x40900000)|i)!=0)                   /* if z > 1024 */
+                return s*huge*huge;                     /* overflow */
+            else {
+                if(p_l+ovt>z-p_h) return s*huge*huge;   /* overflow */
+            }
+        } else if((j&0x7fffffff)>=0x4090cc00 ) {        /* z <= -1075 */
+            if(((j-0xc090cc00)|i)!=0)           /* z < -1075 */
+                return s*tiny*tiny;             /* underflow */
+            else {
+                if(p_l<=z-p_h) return s*tiny*tiny;      /* underflow */
+            }
+        }
+    /*
+     * compute 2**(p_h+p_l)
+     */
+        i = j&0x7fffffff;
+        k = (i>>20)-0x3ff;
+        n = 0;
+        if(i>0x3fe00000) {              /* if |z| > 0.5, set n = [z+0.5] */
+            n = j+(0x00100000>>(k+1));
+            k = ((n&0x7fffffff)>>20)-0x3ff;     /* new k for n */
+            t = zero;
+            SET_HIGH_WORD(t,n&~(0x000fffff>>k));
+            n = ((n&0x000fffff)|0x00100000)>>(20-k);
+            if(j<0) n = -n;
+            p_h -= t;
+        } 
+        t = p_l+p_h;
+        SET_LOW_WORD(t,0);
+        u = t*lg2_h;
+        v = (p_l-(t-p_h))*lg2+t*lg2_l;
+        z = u+v;
+        w = v-(z-u);
+        t  = z*z;
+        t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+        r  = (z*t1)/(t1-two)-(w+z*w);
+        z  = one-(r-z);
+        GET_HIGH_WORD(j,z);
+        j += (n<<20);
+        if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
+        else SET_HIGH_WORD(z,j);
+        return s*z;
+}
diff --git a/src/math/e_powf.c b/src/math/e_powf.c
new file mode 100644
index 00000000..ae61c246
--- /dev/null
+++ b/src/math/e_powf.c
@@ -0,0 +1,243 @@
+/* e_powf.c -- float version of e_pow.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
+dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
+zero    =  0.0,
+one     =  1.0,
+two     =  2.0,
+two24   =  16777216.0,  /* 0x4b800000 */
+huge    =  1.0e30,
+tiny    =  1.0e-30,
+        /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1  =  6.0000002384e-01, /* 0x3f19999a */
+L2  =  4.2857143283e-01, /* 0x3edb6db7 */
+L3  =  3.3333334327e-01, /* 0x3eaaaaab */
+L4  =  2.7272811532e-01, /* 0x3e8ba305 */
+L5  =  2.3066075146e-01, /* 0x3e6c3255 */
+L6  =  2.0697501302e-01, /* 0x3e53f142 */
+P1   =  1.6666667163e-01, /* 0x3e2aaaab */
+P2   = -2.7777778450e-03, /* 0xbb360b61 */
+P3   =  6.6137559770e-05, /* 0x388ab355 */
+P4   = -1.6533901999e-06, /* 0xb5ddea0e */
+P5   =  4.1381369442e-08, /* 0x3331bb4c */
+lg2  =  6.9314718246e-01, /* 0x3f317218 */
+lg2_h  =  6.93145752e-01, /* 0x3f317200 */
+lg2_l  =  1.42860654e-06, /* 0x35bfbe8c */
+ovt =  4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
+cp    =  9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
+cp_h  =  9.6179199219e-01, /* 0x3f763800 =head of cp */
+cp_l  =  4.7017383622e-06, /* 0x369dc3a0 =tail of cp_h */
+ivln2    =  1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
+ivln2_h  =  1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
+ivln2_l  =  7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
+
+float
+powf(float x, float y)
+{
+        float z,ax,z_h,z_l,p_h,p_l;
+        float y1,t1,t2,r,s,sn,t,u,v,w;
+        int32_t i,j,k,yisint,n;
+        int32_t hx,hy,ix,iy,is;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hy,y);
+        ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
+
+    /* y==zero: x**0 = 1 */
+        if(iy==0) return one;
+
+    /* +-NaN return x+y */
+        if(ix > 0x7f800000 ||
+           iy > 0x7f800000)
+                return x+y;
+
+    /* determine if y is an odd int when x < 0
+     * yisint = 0       ... y is not an integer
+     * yisint = 1       ... y is an odd int
+     * yisint = 2       ... y is an even int
+     */
+        yisint  = 0;
+        if(hx<0) {
+            if(iy>=0x4b800000) yisint = 2; /* even integer y */
+            else if(iy>=0x3f800000) {
+                k = (iy>>23)-0x7f;         /* exponent */
+                j = iy>>(23-k);
+                if((j<<(23-k))==iy) yisint = 2-(j&1);
+            }
+        }
+
+    /* special value of y */
+        if (iy==0x7f800000) {   /* y is +-inf */
+            if (ix==0x3f800000)
+                return  y - y;  /* inf**+-1 is NaN */
+            else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
+                return (hy>=0)? y: zero;
+            else                        /* (|x|<1)**-,+inf = inf,0 */
+                return (hy<0)?-y: zero;
+        }
+        if(iy==0x3f800000) {    /* y is  +-1 */
+            if(hy<0) return one/x; else return x;
+        }
+        if(hy==0x40000000) return x*x; /* y is  2 */
+        if(hy==0x3f000000) {    /* y is  0.5 */
+            if(hx>=0)   /* x >= +0 */
+            return sqrtf(x);
+        }
+
+        ax   = fabsf(x);
+    /* special value of x */
+        if(ix==0x7f800000||ix==0||ix==0x3f800000){
+            z = ax;                     /*x is +-0,+-inf,+-1*/
+            if(hy<0) z = one/z; /* z = (1/|x|) */
+            if(hx<0) {
+                if(((ix-0x3f800000)|yisint)==0) {
+                    z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+                } else if(yisint==1)
+                    z = -z;             /* (x<0)**odd = -(|x|**odd) */
+            }
+            return z;
+        }
+
+        n = ((uint32_t)hx>>31)-1;
+
+    /* (x<0)**(non-int) is NaN */
+        if((n|yisint)==0) return (x-x)/(x-x);
+
+        sn = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+        if((n|(yisint-1))==0) sn = -one;/* (-ve)**(odd int) */
+
+    /* |y| is huge */
+        if(iy>0x4d000000) { /* if |y| > 2**27 */
+        /* over/underflow if x is not close to one */
+            if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
+            if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny;
+        /* now |1-x| is tiny <= 2**-20, suffice to compute
+           log(x) by x-x^2/2+x^3/3-x^4/4 */
+            t = ax-1;           /* t has 20 trailing zeros */
+            w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25));
+            u = ivln2_h*t;      /* ivln2_h has 16 sig. bits */
+            v = t*ivln2_l-w*ivln2;
+            t1 = u+v;
+            GET_FLOAT_WORD(is,t1);
+            SET_FLOAT_WORD(t1,is&0xfffff000);
+            t2 = v-(t1-u);
+        } else {
+            float s2,s_h,s_l,t_h,t_l;
+            n = 0;
+        /* take care subnormal number */
+            if(ix<0x00800000)
+                {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
+            n  += ((ix)>>23)-0x7f;
+            j  = ix&0x007fffff;
+        /* determine interval */
+            ix = j|0x3f800000;          /* normalize ix */
+            if(j<=0x1cc471) k=0;        /* |x|<sqrt(3/2) */
+            else if(j<0x5db3d7) k=1;    /* |x|<sqrt(3)   */
+            else {k=0;n+=1;ix -= 0x00800000;}
+            SET_FLOAT_WORD(ax,ix);
+
+        /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+            u = ax-bp[k];               /* bp[0]=1.0, bp[1]=1.5 */
+            v = one/(ax+bp[k]);
+            s = u*v;
+            s_h = s;
+            GET_FLOAT_WORD(is,s_h);
+            SET_FLOAT_WORD(s_h,is&0xfffff000);
+        /* t_h=ax+bp[k] High */
+            is = ((ix>>1)&0xfffff000)|0x20000000;
+            SET_FLOAT_WORD(t_h,is+0x00400000+(k<<21));
+            t_l = ax - (t_h-bp[k]);
+            s_l = v*((u-s_h*t_h)-s_h*t_l);
+        /* compute log(ax) */
+            s2 = s*s;
+            r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+            r += s_l*(s_h+s);
+            s2  = s_h*s_h;
+            t_h = (float)3.0+s2+r;
+            GET_FLOAT_WORD(is,t_h);
+            SET_FLOAT_WORD(t_h,is&0xfffff000);
+            t_l = r-((t_h-(float)3.0)-s2);
+        /* u+v = s*(1+...) */
+            u = s_h*t_h;
+            v = s_l*t_h+t_l*s;
+        /* 2/(3log2)*(s+...) */
+            p_h = u+v;
+            GET_FLOAT_WORD(is,p_h);
+            SET_FLOAT_WORD(p_h,is&0xfffff000);
+            p_l = v-(p_h-u);
+            z_h = cp_h*p_h;             /* cp_h+cp_l = 2/(3*log2) */
+            z_l = cp_l*p_h+p_l*cp+dp_l[k];
+        /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+            t = (float)n;
+            t1 = (((z_h+z_l)+dp_h[k])+t);
+            GET_FLOAT_WORD(is,t1);
+            SET_FLOAT_WORD(t1,is&0xfffff000);
+            t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+        }
+
+    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+        GET_FLOAT_WORD(is,y);
+        SET_FLOAT_WORD(y1,is&0xfffff000);
+        p_l = (y-y1)*t1+y*t2;
+        p_h = y1*t1;
+        z = p_l+p_h;
+        GET_FLOAT_WORD(j,z);
+        if (j>0x43000000)                               /* if z > 128 */
+            return sn*huge*huge;                        /* overflow */
+        else if (j==0x43000000) {                       /* if z == 128 */
+            if(p_l+ovt>z-p_h) return sn*huge*huge;      /* overflow */
+        }
+        else if ((j&0x7fffffff)>0x43160000)             /* z <= -150 */
+            return sn*tiny*tiny;                        /* underflow */
+        else if (j==0xc3160000){                        /* z == -150 */
+            if(p_l<=z-p_h) return sn*tiny*tiny;         /* underflow */
+        }
+    /*
+     * compute 2**(p_h+p_l)
+     */
+        i = j&0x7fffffff;
+        k = (i>>23)-0x7f;
+        n = 0;
+        if(i>0x3f000000) {              /* if |z| > 0.5, set n = [z+0.5] */
+            n = j+(0x00800000>>(k+1));
+            k = ((n&0x7fffffff)>>23)-0x7f;      /* new k for n */
+            SET_FLOAT_WORD(t,n&~(0x007fffff>>k));
+            n = ((n&0x007fffff)|0x00800000)>>(23-k);
+            if(j<0) n = -n;
+            p_h -= t;
+        }
+        t = p_l+p_h;
+        GET_FLOAT_WORD(is,t);
+        SET_FLOAT_WORD(t,is&0xffff8000);
+        u = t*lg2_h;
+        v = (p_l-(t-p_h))*lg2+t*lg2_l;
+        z = u+v;
+        w = v-(z-u);
+        t  = z*z;
+        t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+        r  = (z*t1)/(t1-two)-(w+z*w);
+        z  = one-(r-z);
+        GET_FLOAT_WORD(j,z);
+        j += (n<<23);
+        if((j>>23)<=0) z = scalbnf(z,n);        /* subnormal output */
+        else SET_FLOAT_WORD(z,j);
+        return sn*z;
+}
diff --git a/src/math/e_rem_pio2.c b/src/math/e_rem_pio2.c
new file mode 100644
index 00000000..9eee36ae
--- /dev/null
+++ b/src/math/e_rem_pio2.c
@@ -0,0 +1,163 @@
+
+/* @(#)e_rem_pio2.c 1.4 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_rem_pio2(x,y)
+ * 
+ * return the remainder of x rem pi/2 in y[0]+y[1] 
+ * use __kernel_rem_pio2()
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi 
+ */
+static const int32_t two_over_pi[] = {
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, 
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, 
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, 
+};
+
+static const int32_t npio2_hw[] = {
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2:  53 bits of 2/pi
+ * pio2_1:   first  33 bit of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 33 bit of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  33 bit of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+static const double
+zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t =  8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+int32_t __ieee754_rem_pio2(double x, double *y)
+{
+        double z,w,t,r,fn;
+        double tx[3];
+        int32_t e0,i,j,nx,n,ix,hx;
+        uint32_t low;
+
+        GET_HIGH_WORD(hx,x);            /* high word of x */
+        ix = hx&0x7fffffff;
+        if(ix<=0x3fe921fb)   /* |x| ~<= pi/4 , no need for reduction */
+            {y[0] = x; y[1] = 0; return 0;}
+        if(ix<0x4002d97c) {  /* |x| < 3pi/4, special case with n=+-1 */
+            if(hx>0) { 
+                z = x - pio2_1;
+                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
+                    y[0] = z - pio2_1t;
+                    y[1] = (z-y[0])-pio2_1t;
+                } else {                /* near pi/2, use 33+33+53 bit pi */
+                    z -= pio2_2;
+                    y[0] = z - pio2_2t;
+                    y[1] = (z-y[0])-pio2_2t;
+                }
+                return 1;
+            } else {    /* negative x */
+                z = x + pio2_1;
+                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
+                    y[0] = z + pio2_1t;
+                    y[1] = (z-y[0])+pio2_1t;
+                } else {                /* near pi/2, use 33+33+53 bit pi */
+                    z += pio2_2;
+                    y[0] = z + pio2_2t;
+                    y[1] = (z-y[0])+pio2_2t;
+                }
+                return -1;
+            }
+        }
+        if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+            t  = fabs(x);
+            n  = (int32_t) (t*invpio2+half);
+            fn = (double)n;
+            r  = t-fn*pio2_1;
+            w  = fn*pio2_1t;    /* 1st round good to 85 bit */
+            if(n<32&&ix!=npio2_hw[n-1]) {       
+                y[0] = r-w;     /* quick check no cancellation */
+            } else {
+                uint32_t high;
+                j  = ix>>20;
+                y[0] = r-w; 
+                GET_HIGH_WORD(high,y[0]);
+                i = j-((high>>20)&0x7ff);
+                if(i>16) {  /* 2nd iteration needed, good to 118 */
+                    t  = r;
+                    w  = fn*pio2_2;     
+                    r  = t-w;
+                    w  = fn*pio2_2t-((t-r)-w);  
+                    y[0] = r-w;
+                    GET_HIGH_WORD(high,y[0]);
+                    i = j-((high>>20)&0x7ff);
+                    if(i>49)  { /* 3rd iteration need, 151 bits acc */
+                        t  = r; /* will cover all possible cases */
+                        w  = fn*pio2_3; 
+                        r  = t-w;
+                        w  = fn*pio2_3t-((t-r)-w);      
+                        y[0] = r-w;
+                    }
+                }
+            }
+            y[1] = (r-y[0])-w;
+            if(hx<0)    {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+            else         return n;
+        }
+    /* 
+     * all other (large) arguments
+     */
+        if(ix>=0x7ff00000) {            /* x is inf or NaN */
+            y[0]=y[1]=x-x; return 0;
+        }
+    /* set z = scalbn(|x|,ilogb(x)-23) */
+        GET_LOW_WORD(low,x);
+        e0      = (ix>>20)-1046;        /* e0 = ilogb(z)-23; */
+	INSERT_WORDS(z, ix - ((int32_t)(e0<<20)), low);
+        for(i=0;i<2;i++) {
+                tx[i] = (double)((int32_t)(z));
+                z     = (z-tx[i])*two24;
+        }
+        tx[2] = z;
+        nx = 3;
+        while(tx[nx-1]==zero) nx--;     /* skip zero term */
+        n  =  __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+        if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+        return n;
+}
diff --git a/src/math/e_rem_pio2f.c b/src/math/e_rem_pio2f.c
new file mode 100644
index 00000000..4992ea0c
--- /dev/null
+++ b/src/math/e_rem_pio2f.c
@@ -0,0 +1,175 @@
+/* e_rem_pio2f.c -- float version of e_rem_pio2.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_rem_pio2f(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2f()
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+static const int32_t two_over_pi[] = {
+0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
+0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
+0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
+0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
+0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
+0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
+0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
+0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
+0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
+0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
+0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
+0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
+0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
+0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
+0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
+0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
+0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
+0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
+0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
+0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
+0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
+0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
+};
+
+/* This array is like the one in e_rem_pio2.c, but the numbers are
+   single precision and the last 8 bits are forced to 0.  */
+static const int32_t npio2_hw[] = {
+0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
+0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
+0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
+0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
+0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
+0x4242c700, 0x42490f00
+};
+
+/*
+ * invpio2:  24 bits of 2/pi
+ * pio2_1:   first  17 bit of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 17 bit of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  17 bit of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+static const float
+zero =  0.0000000000e+00, /* 0x00000000 */
+half =  5.0000000000e-01, /* 0x3f000000 */
+two8 =  2.5600000000e+02, /* 0x43800000 */
+invpio2 =  6.3661980629e-01, /* 0x3f22f984 */
+pio2_1  =  1.5707855225e+00, /* 0x3fc90f80 */
+pio2_1t =  1.0804334124e-05, /* 0x37354443 */
+pio2_2  =  1.0804273188e-05, /* 0x37354400 */
+pio2_2t =  6.0770999344e-11, /* 0x2e85a308 */
+pio2_3  =  6.0770943833e-11, /* 0x2e85a300 */
+pio2_3t =  6.1232342629e-17; /* 0x248d3132 */
+
+int32_t __ieee754_rem_pio2f(float x, float *y)
+{
+        float z,w,t,r,fn;
+        float tx[3];
+        int32_t e0,i,j,nx,n,ix,hx;
+
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix<=0x3f490fd8)   /* |x| ~<= pi/4 , no need for reduction */
+            {y[0] = x; y[1] = 0; return 0;}
+        if(ix<0x4016cbe4) {  /* |x| < 3pi/4, special case with n=+-1 */
+            if(hx>0) {
+                z = x - pio2_1;
+                if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+                    y[0] = z - pio2_1t;
+                    y[1] = (z-y[0])-pio2_1t;
+                } else {                /* near pi/2, use 24+24+24 bit pi */
+                    z -= pio2_2;
+                    y[0] = z - pio2_2t;
+                    y[1] = (z-y[0])-pio2_2t;
+                }
+                return 1;
+            } else {    /* negative x */
+                z = x + pio2_1;
+                if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+                    y[0] = z + pio2_1t;
+                    y[1] = (z-y[0])+pio2_1t;
+                } else {                /* near pi/2, use 24+24+24 bit pi */
+                    z += pio2_2;
+                    y[0] = z + pio2_2t;
+                    y[1] = (z-y[0])+pio2_2t;
+                }
+                return -1;
+            }
+        }
+        if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
+            t  = fabsf(x);
+            n  = (int32_t) (t*invpio2+half);
+            fn = (float)n;
+            r  = t-fn*pio2_1;
+            w  = fn*pio2_1t;    /* 1st round good to 40 bit */
+            if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
+                y[0] = r-w;     /* quick check no cancellation */
+            } else {
+                uint32_t high;
+                j  = ix>>23;
+                y[0] = r-w;
+                GET_FLOAT_WORD(high,y[0]);
+                i = j-((high>>23)&0xff);
+                if(i>8) {  /* 2nd iteration needed, good to 57 */
+                    t  = r;
+                    w  = fn*pio2_2;
+                    r  = t-w;
+                    w  = fn*pio2_2t-((t-r)-w);
+                    y[0] = r-w;
+                    GET_FLOAT_WORD(high,y[0]);
+                    i = j-((high>>23)&0xff);
+                    if(i>25)  { /* 3rd iteration need, 74 bits acc */
+                        t  = r; /* will cover all possible cases */
+                        w  = fn*pio2_3;
+                        r  = t-w;
+                        w  = fn*pio2_3t-((t-r)-w);
+                        y[0] = r-w;
+                    }
+                }
+            }
+            y[1] = (r-y[0])-w;
+            if(hx<0)    {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+            else         return n;
+        }
+    /*
+     * all other (large) arguments
+     */
+        if(ix>=0x7f800000) {            /* x is inf or NaN */
+            y[0]=y[1]=x-x; return 0;
+        }
+    /* set z = scalbn(|x|,ilogb(x)-7) */
+        e0      = (ix>>23)-134;         /* e0 = ilogb(z)-7; */
+        SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23)));
+        for(i=0;i<2;i++) {
+                tx[i] = (float)((int32_t)(z));
+                z     = (z-tx[i])*two8;
+        }
+        tx[2] = z;
+        nx = 3;
+        while(tx[nx-1]==zero) nx--;     /* skip zero term */
+        n  =  __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
+        if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+        return n;
+}
diff --git a/src/math/e_remainder.c b/src/math/e_remainder.c
new file mode 100644
index 00000000..9cb56919
--- /dev/null
+++ b/src/math/e_remainder.c
@@ -0,0 +1,69 @@
+
+/* @(#)e_remainder.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* remainder(x,p)
+ * Return :                  
+ *      returns  x REM p  =  x - [x/p]*p as if in infinite 
+ *      precise arithmetic, where [x/p] is the (infinite bit) 
+ *      integer nearest x/p (in half way case choose the even one).
+ * Method : 
+ *      Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double zero = 0.0;
+
+
+double
+remainder(double x, double p)
+{
+        int32_t hx,hp;
+        uint32_t sx,lx,lp;
+        double p_half;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hp,lp,p);
+        sx = hx&0x80000000;
+        hp &= 0x7fffffff;
+        hx &= 0x7fffffff;
+
+    /* purge off exception values */
+        if((hp|lp)==0) return (x*p)/(x*p);      /* p = 0 */
+        if((hx>=0x7ff00000)||                   /* x not finite */
+          ((hp>=0x7ff00000)&&                   /* p is NaN */
+          (((hp-0x7ff00000)|lp)!=0)))
+            return (x*p)/(x*p);
+
+
+        if (hp<=0x7fdfffff) x = fmod(x,p+p);  /* now x < 2p */
+        if (((hx-hp)|(lx-lp))==0) return zero*x;
+        x  = fabs(x);
+        p  = fabs(p);
+        if (hp<0x00200000) {
+            if(x+x>p) {
+                x-=p;
+                if(x+x>=p) x -= p;
+            }
+        } else {
+            p_half = 0.5*p;
+            if(x>p_half) {
+                x-=p;
+                if(x>=p_half) x -= p;
+            }
+        }
+        GET_HIGH_WORD(hx,x);
+        SET_HIGH_WORD(x,hx^sx);
+        return x;
+}
diff --git a/src/math/e_remainderf.c b/src/math/e_remainderf.c
new file mode 100644
index 00000000..c292367d
--- /dev/null
+++ b/src/math/e_remainderf.c
@@ -0,0 +1,61 @@
+/* e_remainderf.c -- float version of e_remainder.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float zero = 0.0;
+
+
+float
+remainderf(float x, float p)
+{
+        int32_t hx,hp;
+        uint32_t sx;
+        float p_half;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hp,p);
+        sx = hx&0x80000000;
+        hp &= 0x7fffffff;
+        hx &= 0x7fffffff;
+
+    /* purge off exception values */
+        if(hp==0) return (x*p)/(x*p);           /* p = 0 */
+        if((hx>=0x7f800000)||                   /* x not finite */
+          ((hp>0x7f800000)))                    /* p is NaN */
+            return (x*p)/(x*p);
+
+
+        if (hp<=0x7effffff) x = fmodf(x,p+p); /* now x < 2p */
+        if ((hx-hp)==0) return zero*x;
+        x  = fabsf(x);
+        p  = fabsf(p);
+        if (hp<0x01000000) {
+            if(x+x>p) {
+                x-=p;
+                if(x+x>=p) x -= p;
+            }
+        } else {
+            p_half = (float)0.5*p;
+            if(x>p_half) {
+                x-=p;
+                if(x>=p_half) x -= p;
+            }
+        }
+        GET_FLOAT_WORD(hx,x);
+        SET_FLOAT_WORD(x,hx^sx);
+        return x;
+}
diff --git a/src/math/e_scalb.c b/src/math/e_scalb.c
new file mode 100644
index 00000000..cee2b44f
--- /dev/null
+++ b/src/math/e_scalb.c
@@ -0,0 +1,35 @@
+
+/* @(#)e_scalb.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * scalb(x, fn) is provide for
+ * passing various standard test suite. One 
+ * should use scalbn() instead.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+scalb(double x, double fn)
+{
+        if (isnan(x)||isnan(fn)) return x*fn;
+        if (!isfinite(fn)) {
+            if(fn>0.0) return x*fn;
+            else       return x/(-fn);
+        }
+        if (rint(fn)!=fn) return (fn-fn)/(fn-fn);
+        if ( fn > 65000.0) return scalbn(x, 65000);
+        if (-fn > 65000.0) return scalbn(x,-65000);
+        return scalbn(x,(int)fn);
+}
diff --git a/src/math/e_scalbf.c b/src/math/e_scalbf.c
new file mode 100644
index 00000000..de7d7f67
--- /dev/null
+++ b/src/math/e_scalbf.c
@@ -0,0 +1,31 @@
+/* e_scalbf.c -- float version of e_scalb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+scalbf(float x, float fn)
+{
+        if (isnan(x)||isnan(fn)) return x*fn;
+        if (!isfinite(fn)) {
+            if(fn>(float)0.0) return x*fn;
+            else       return x/(-fn);
+        }
+        if (rintf(fn)!=fn) return (fn-fn)/(fn-fn);
+        if ( fn > (float)65000.0) return scalbnf(x, 65000);
+        if (-fn > (float)65000.0) return scalbnf(x,-65000);
+        return scalbnf(x,(int)fn);
+}
diff --git a/src/math/e_sinh.c b/src/math/e_sinh.c
new file mode 100644
index 00000000..3a574274
--- /dev/null
+++ b/src/math/e_sinh.c
@@ -0,0 +1,75 @@
+
+/* @(#)e_sinh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* sinh(x)
+ * Method : 
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ *      1. Replace x by |x| (sinh(-x) = -sinh(x)). 
+ *      2. 
+ *                                                  E + E/(E+1)
+ *          0        <= x <= 22     :  sinh(x) := --------------, E=expm1(x)
+ *                                                      2
+ *
+ *          22       <= x <= lnovft :  sinh(x) := exp(x)/2 
+ *          lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
+ *          ln2ovft  <  x           :  sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ *      sinh(x) is |x| if x is +INF, -INF, or NaN.
+ *      only sinh(0)=0 is exact for finite x.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one = 1.0, shuge = 1.0e307;
+
+double
+sinh(double x)
+{
+        double t,w,h;
+        int32_t ix,jx;
+        uint32_t lx;
+
+    /* High word of |x|. */
+        GET_HIGH_WORD(jx,x);
+        ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7ff00000) return x+x;  
+
+        h = 0.5;
+        if (jx<0) h = -h;
+    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+        if (ix < 0x40360000) {          /* |x|<22 */
+            if (ix<0x3e300000)          /* |x|<2**-28 */
+                if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+            t = expm1(fabs(x));
+            if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
+            return h*(t+t/(t+one));
+        }
+
+    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+        if (ix < 0x40862E42)  return h*exp(fabs(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+        GET_LOW_WORD(lx,x);
+        if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(uint32_t)0x8fb9f87d))) {
+            w = exp(0.5*fabs(x));
+            t = h*w;
+            return t*w;
+        }
+
+    /* |x| > overflowthresold, sinh(x) overflow */
+        return x*shuge;
+}
diff --git a/src/math/e_sinhf.c b/src/math/e_sinhf.c
new file mode 100644
index 00000000..fe60608a
--- /dev/null
+++ b/src/math/e_sinhf.c
@@ -0,0 +1,56 @@
+/* e_sinhf.c -- float version of e_sinh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one = 1.0, shuge = 1.0e37;
+
+float
+sinhf(float x)
+{
+        float t,w,h;
+        int32_t ix,jx;
+
+        GET_FLOAT_WORD(jx,x);
+        ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7f800000) return x+x;
+
+        h = 0.5;
+        if (jx<0) h = -h;
+    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+        if (ix < 0x41b00000) {          /* |x|<22 */
+            if (ix<0x31800000)          /* |x|<2**-28 */
+                if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+            t = expm1f(fabsf(x));
+            if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one));
+            return h*(t+t/(t+one));
+        }
+
+    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+        if (ix < 0x42b17180)  return h*expf(fabsf(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+        if (ix<=0x42b2d4fc) {
+            w = expf((float)0.5*fabsf(x));
+            t = h*w;
+            return t*w;
+        }
+
+    /* |x| > overflowthresold, sinh(x) overflow */
+        return x*shuge;
+}
diff --git a/src/math/e_sqrt.c b/src/math/e_sqrt.c
new file mode 100644
index 00000000..2bc68747
--- /dev/null
+++ b/src/math/e_sqrt.c
@@ -0,0 +1,442 @@
+
+/* @(#)e_sqrt.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* sqrt(x)
+ * Return correctly rounded sqrt.
+ *           ------------------------------------------
+ *           |  Use the hardware sqrt if you have one |
+ *           ------------------------------------------
+ * Method: 
+ *   Bit by bit method using integer arithmetic. (Slow, but portable) 
+ *   1. Normalization
+ *      Scale x to y in [1,4) with even powers of 2: 
+ *      find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
+ *              sqrt(x) = 2^k * sqrt(y)
+ *   2. Bit by bit computation
+ *      Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
+ *           i                                                   0
+ *                                     i+1         2
+ *          s  = 2*q , and      y  =  2   * ( y - q  ).         (1)
+ *           i      i            i                 i
+ *                                                        
+ *      To compute q    from q , one checks whether 
+ *                  i+1       i                       
+ *
+ *                            -(i+1) 2
+ *                      (q + 2      ) <= y.                     (2)
+ *                        i
+ *                                                            -(i+1)
+ *      If (2) is false, then q   = q ; otherwise q   = q  + 2      .
+ *                             i+1   i             i+1   i
+ *
+ *      With some algebric manipulation, it is not difficult to see
+ *      that (2) is equivalent to 
+ *                             -(i+1)
+ *                      s  +  2       <= y                      (3)
+ *                       i                i
+ *
+ *      The advantage of (3) is that s  and y  can be computed by 
+ *                                    i      i
+ *      the following recurrence formula:
+ *          if (3) is false
+ *
+ *          s     =  s  ,       y    = y   ;                    (4)
+ *           i+1      i          i+1    i
+ *
+ *          otherwise,
+ *                         -i                     -(i+1)
+ *          s     =  s  + 2  ,  y    = y  -  s  - 2             (5)
+ *           i+1      i          i+1    i     i
+ *                              
+ *      One may easily use induction to prove (4) and (5). 
+ *      Note. Since the left hand side of (3) contain only i+2 bits,
+ *            it does not necessary to do a full (53-bit) comparison 
+ *            in (3).
+ *   3. Final rounding
+ *      After generating the 53 bits result, we compute one more bit.
+ *      Together with the remainder, we can decide whether the
+ *      result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ *      (it will never equal to 1/2ulp).
+ *      The rounding mode can be detected by checking whether
+ *      huge + tiny is equal to huge, and whether huge - tiny is
+ *      equal to huge for some floating point number "huge" and "tiny".
+ *              
+ * Special cases:
+ *      sqrt(+-0) = +-0         ... exact
+ *      sqrt(inf) = inf
+ *      sqrt(-ve) = NaN         ... with invalid signal
+ *      sqrt(NaN) = NaN         ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static  const double    one     = 1.0, tiny=1.0e-300;
+
+double
+sqrt(double x)
+{
+        double z;
+        int32_t sign = (int)0x80000000;
+        int32_t ix0,s0,q,m,t,i;
+        uint32_t r,t1,s1,ix1,q1;
+
+        EXTRACT_WORDS(ix0,ix1,x);
+
+    /* take care of Inf and NaN */
+        if((ix0&0x7ff00000)==0x7ff00000) {                      
+            return x*x+x;               /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+                                           sqrt(-inf)=sNaN */
+        } 
+    /* take care of zero */
+        if(ix0<=0) {
+            if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+            else if(ix0<0)
+                return (x-x)/(x-x);             /* sqrt(-ve) = sNaN */
+        }
+    /* normalize x */
+        m = (ix0>>20);
+        if(m==0) {                              /* subnormal x */
+            while(ix0==0) {
+                m -= 21;
+                ix0 |= (ix1>>11); ix1 <<= 21;
+            }
+            for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+            m -= i-1;
+            ix0 |= (ix1>>(32-i));
+            ix1 <<= i;
+        }
+        m -= 1023;      /* unbias exponent */
+        ix0 = (ix0&0x000fffff)|0x00100000;
+        if(m&1){        /* odd m, double x to make it even */
+            ix0 += ix0 + ((ix1&sign)>>31);
+            ix1 += ix1;
+        }
+        m >>= 1;        /* m = [m/2] */
+
+    /* generate sqrt(x) bit by bit */
+        ix0 += ix0 + ((ix1&sign)>>31);
+        ix1 += ix1;
+        q = q1 = s0 = s1 = 0;   /* [q,q1] = sqrt(x) */
+        r = 0x00200000;         /* r = moving bit from right to left */
+
+        while(r!=0) {
+            t = s0+r; 
+            if(t<=ix0) { 
+                s0   = t+r; 
+                ix0 -= t; 
+                q   += r; 
+            } 
+            ix0 += ix0 + ((ix1&sign)>>31);
+            ix1 += ix1;
+            r>>=1;
+        }
+
+        r = sign;
+        while(r!=0) {
+            t1 = s1+r; 
+            t  = s0;
+            if((t<ix0)||((t==ix0)&&(t1<=ix1))) { 
+                s1  = t1+r;
+                if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
+                ix0 -= t;
+                if (ix1 < t1) ix0 -= 1;
+                ix1 -= t1;
+                q1  += r;
+            }
+            ix0 += ix0 + ((ix1&sign)>>31);
+            ix1 += ix1;
+            r>>=1;
+        }
+
+    /* use floating add to find out rounding direction */
+        if((ix0|ix1)!=0) {
+            z = one-tiny; /* trigger inexact flag */
+            if (z>=one) {
+                z = one+tiny;
+                if (q1==(uint32_t)0xffffffff) { q1=0; q += 1;}
+                else if (z>one) {
+                    if (q1==(uint32_t)0xfffffffe) q+=1;
+                    q1+=2; 
+                } else
+                    q1 += (q1&1);
+            }
+        }
+        ix0 = (q>>1)+0x3fe00000;
+        ix1 =  q1>>1;
+        if ((q&1)==1) ix1 |= sign;
+        ix0 += (m <<20);
+        INSERT_WORDS(z,ix0,ix1);
+        return z;
+}
+
+/*
+Other methods  (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan 
+and K.C. Ng, written in May, 1986)
+
+        Two algorithms are given here to implement sqrt(x) 
+        (IEEE double precision arithmetic) in software.
+        Both supply sqrt(x) correctly rounded. The first algorithm (in
+        Section A) uses newton iterations and involves four divisions.
+        The second one uses reciproot iterations to avoid division, but
+        requires more multiplications. Both algorithms need the ability
+        to chop results of arithmetic operations instead of round them, 
+        and the INEXACT flag to indicate when an arithmetic operation
+        is executed exactly with no roundoff error, all part of the 
+        standard (IEEE 754-1985). The ability to perform shift, add,
+        subtract and logical AND operations upon 32-bit words is needed
+        too, though not part of the standard.
+
+A.  sqrt(x) by Newton Iteration
+
+   (1)  Initial approximation
+
+        Let x0 and x1 be the leading and the trailing 32-bit words of
+        a floating point number x (in IEEE double format) respectively 
+
+            1    11                  52                           ...widths
+           ------------------------------------------------------
+        x: |s|    e     |             f                         |
+           ------------------------------------------------------
+              msb    lsb  msb                                 lsb ...order
+
+ 
+             ------------------------        ------------------------
+        x0:  |s|   e    |    f1     |    x1: |          f2           |
+             ------------------------        ------------------------
+
+        By performing shifts and subtracts on x0 and x1 (both regarded
+        as integers), we obtain an 8-bit approximation of sqrt(x) as
+        follows.
+
+                k  := (x0>>1) + 0x1ff80000;
+                y0 := k - T1[31&(k>>15)].       ... y ~ sqrt(x) to 8 bits
+        Here k is a 32-bit integer and T1[] is an integer array containing
+        correction terms. Now magically the floating value of y (y's
+        leading 32-bit word is y0, the value of its trailing word is 0)
+        approximates sqrt(x) to almost 8-bit.
+
+        Value of T1:
+        static int T1[32]= {
+        0,      1024,   3062,   5746,   9193,   13348,  18162,  23592,
+        29598,  36145,  43202,  50740,  58733,  67158,  75992,  85215,
+        83599,  71378,  60428,  50647,  41945,  34246,  27478,  21581,
+        16499,  12183,  8588,   5674,   3403,   1742,   661,    130,};
+
+    (2) Iterative refinement
+
+        Apply Heron's rule three times to y, we have y approximates 
+        sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+                y := (y+x/y)/2          ... almost 17 sig. bits
+                y := (y+x/y)/2          ... almost 35 sig. bits
+                y := y-(y-x/y)/2        ... within 1 ulp
+
+
+        Remark 1.
+            Another way to improve y to within 1 ulp is:
+
+                y := (y+x/y)            ... almost 17 sig. bits to 2*sqrt(x)
+                y := y - 0x00100006     ... almost 18 sig. bits to sqrt(x)
+
+                                2
+                            (x-y )*y
+                y := y + 2* ----------  ...within 1 ulp
+                               2
+                             3y  + x
+
+
+        This formula has one division fewer than the one above; however,
+        it requires more multiplications and additions. Also x must be
+        scaled in advance to avoid spurious overflow in evaluating the
+        expression 3y*y+x. Hence it is not recommended uless division
+        is slow. If division is very slow, then one should use the 
+        reciproot algorithm given in section B.
+
+    (3) Final adjustment
+
+        By twiddling y's last bit it is possible to force y to be 
+        correctly rounded according to the prevailing rounding mode
+        as follows. Let r and i be copies of the rounding mode and
+        inexact flag before entering the square root program. Also we
+        use the expression y+-ulp for the next representable floating
+        numbers (up and down) of y. Note that y+-ulp = either fixed
+        point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+        mode.
+
+                I := FALSE;     ... reset INEXACT flag I
+                R := RZ;        ... set rounding mode to round-toward-zero
+                z := x/y;       ... chopped quotient, possibly inexact
+                If(not I) then {        ... if the quotient is exact
+                    if(z=y) {
+                        I := i;  ... restore inexact flag
+                        R := r;  ... restore rounded mode
+                        return sqrt(x):=y.
+                    } else {
+                        z := z - ulp;   ... special rounding
+                    }
+                }
+                i := TRUE;              ... sqrt(x) is inexact
+                If (r=RN) then z=z+ulp  ... rounded-to-nearest
+                If (r=RP) then {        ... round-toward-+inf
+                    y = y+ulp; z=z+ulp;
+                }
+                y := y+z;               ... chopped sum
+                y0:=y0-0x00100000;      ... y := y/2 is correctly rounded.
+                I := i;                 ... restore inexact flag
+                R := r;                 ... restore rounded mode
+                return sqrt(x):=y.
+                    
+    (4) Special cases
+
+        Square root of +inf, +-0, or NaN is itself;
+        Square root of a negative number is NaN with invalid signal.
+
+
+B.  sqrt(x) by Reciproot Iteration
+
+   (1)  Initial approximation
+
+        Let x0 and x1 be the leading and the trailing 32-bit words of
+        a floating point number x (in IEEE double format) respectively
+        (see section A). By performing shifs and subtracts on x0 and y0,
+        we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+            k := 0x5fe80000 - (x0>>1);
+            y0:= k - T2[63&(k>>14)].    ... y ~ 1/sqrt(x) to 7.8 bits
+
+        Here k is a 32-bit integer and T2[] is an integer array 
+        containing correction terms. Now magically the floating
+        value of y (y's leading 32-bit word is y0, the value of
+        its trailing word y1 is set to zero) approximates 1/sqrt(x)
+        to almost 7.8-bit.
+
+        Value of T2:
+        static int T2[64]= {
+        0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+        0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+        0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+        0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+        0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+        0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+        0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+        0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+    (2) Iterative refinement
+
+        Apply Reciproot iteration three times to y and multiply the
+        result by x to get an approximation z that matches sqrt(x)
+        to about 1 ulp. To be exact, we will have 
+                -1ulp < sqrt(x)-z<1.0625ulp.
+        
+        ... set rounding mode to Round-to-nearest
+           y := y*(1.5-0.5*x*y*y)       ... almost 15 sig. bits to 1/sqrt(x)
+           y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+        ... special arrangement for better accuracy
+           z := x*y                     ... 29 bits to sqrt(x), with z*y<1
+           z := z + 0.5*z*(1-z*y)       ... about 1 ulp to sqrt(x)
+
+        Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+        (a) the term z*y in the final iteration is always less than 1; 
+        (b) the error in the final result is biased upward so that
+                -1 ulp < sqrt(x) - z < 1.0625 ulp
+            instead of |sqrt(x)-z|<1.03125ulp.
+
+    (3) Final adjustment
+
+        By twiddling y's last bit it is possible to force y to be 
+        correctly rounded according to the prevailing rounding mode
+        as follows. Let r and i be copies of the rounding mode and
+        inexact flag before entering the square root program. Also we
+        use the expression y+-ulp for the next representable floating
+        numbers (up and down) of y. Note that y+-ulp = either fixed
+        point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+        mode.
+
+        R := RZ;                ... set rounding mode to round-toward-zero
+        switch(r) {
+            case RN:            ... round-to-nearest
+               if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+               if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+               break;
+            case RZ:case RM:    ... round-to-zero or round-to--inf
+               R:=RP;           ... reset rounding mod to round-to-+inf
+               if(x<z*z ... rounded up) z = z - ulp; else
+               if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+               break;
+            case RP:            ... round-to-+inf
+               if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+               if(x>z*z ...chopped) z = z+ulp;
+               break;
+        }
+
+        Remark 3. The above comparisons can be done in fixed point. For
+        example, to compare x and w=z*z chopped, it suffices to compare
+        x1 and w1 (the trailing parts of x and w), regarding them as
+        two's complement integers.
+
+        ...Is z an exact square root?
+        To determine whether z is an exact square root of x, let z1 be the
+        trailing part of z, and also let x0 and x1 be the leading and
+        trailing parts of x.
+
+        If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+            I := 1;             ... Raise Inexact flag: z is not exact
+        else {
+            j := 1 - [(x0>>20)&1]       ... j = logb(x) mod 2
+            k := z1 >> 26;              ... get z's 25-th and 26-th 
+                                            fraction bits
+            I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+        }
+        R:= r           ... restore rounded mode
+        return sqrt(x):=z.
+
+        If multiplication is cheaper then the foregoing red tape, the 
+        Inexact flag can be evaluated by
+
+            I := i;
+            I := (z*z!=x) or I.
+
+        Note that z*z can overwrite I; this value must be sensed if it is 
+        True.
+
+        Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+        zero.
+
+                    --------------------
+                z1: |        f2        | 
+                    --------------------
+                bit 31             bit 0
+
+        Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+        or even of logb(x) have the following relations:
+
+        -------------------------------------------------
+        bit 27,26 of z1         bit 1,0 of x1   logb(x)
+        -------------------------------------------------
+        00                      00              odd and even
+        01                      01              even
+        10                      10              odd
+        10                      00              even
+        11                      01              even
+        -------------------------------------------------
+
+    (4) Special cases (see (4) of Section A).   
+ 
+ */
+ 
diff --git a/src/math/e_sqrtf.c b/src/math/e_sqrtf.c
new file mode 100644
index 00000000..03a15beb
--- /dev/null
+++ b/src/math/e_sqrtf.c
@@ -0,0 +1,85 @@
+/* e_sqrtf.c -- float version of e_sqrt.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static  const float     one     = 1.0, tiny=1.0e-30;
+
+float
+sqrtf(float x)
+{
+        float z;
+        int32_t sign = (int)0x80000000;
+        int32_t ix,s,q,m,t,i;
+        uint32_t r;
+
+        GET_FLOAT_WORD(ix,x);
+
+    /* take care of Inf and NaN */
+        if((ix&0x7f800000)==0x7f800000) {
+            return x*x+x;               /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+                                           sqrt(-inf)=sNaN */
+        }
+    /* take care of zero */
+        if(ix<=0) {
+            if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
+            else if(ix<0)
+                return (x-x)/(x-x);             /* sqrt(-ve) = sNaN */
+        }
+    /* normalize x */
+        m = (ix>>23);
+        if(m==0) {                              /* subnormal x */
+            for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
+            m -= i-1;
+        }
+        m -= 127;       /* unbias exponent */
+        ix = (ix&0x007fffff)|0x00800000;
+        if(m&1) /* odd m, double x to make it even */
+            ix += ix;
+        m >>= 1;        /* m = [m/2] */
+
+    /* generate sqrt(x) bit by bit */
+        ix += ix;
+        q = s = 0;              /* q = sqrt(x) */
+        r = 0x01000000;         /* r = moving bit from right to left */
+
+        while(r!=0) {
+            t = s+r;
+            if(t<=ix) {
+                s    = t+r;
+                ix  -= t;
+                q   += r;
+            }
+            ix += ix;
+            r>>=1;
+        }
+
+    /* use floating add to find out rounding direction */
+        if(ix!=0) {
+            z = one-tiny; /* trigger inexact flag */
+            if (z>=one) {
+                z = one+tiny;
+                if (z>one)
+                    q += 2;
+                else
+                    q += (q&1);
+            }
+        }
+        ix = (q>>1)+0x3f000000;
+        ix += (m <<23);
+        SET_FLOAT_WORD(z,ix);
+        return z;
+}
diff --git a/src/math/i386/e_exp.s b/src/math/i386/e_exp.s
new file mode 100644
index 00000000..d6c54a30
--- /dev/null
+++ b/src/math/i386/e_exp.s
@@ -0,0 +1,36 @@
+.global expf
+expf:
+	mov 4(%esp),%eax
+	flds 4(%esp)
+	shr $23,%eax
+	inc %al
+	jz 1f
+	jmp 0f
+
+.global exp
+exp:
+	mov 8(%esp),%eax
+	fldl 4(%esp)
+	shl %eax
+	cmp $0xffe00000,%eax
+	jae 1f
+
+0:	fldl2e
+	fmulp
+	fst %st(1)
+	frndint
+	fst %st(2)
+	fsubrp
+	f2xm1
+	fld1
+	faddp
+	fscale
+	fstp %st(1)
+	ret
+
+1:	fsts 4(%esp)
+	cmpl $0xff800000,4(%esp)
+	jnz 1f
+	fstp %st(0)
+	fldz
+1:	ret
diff --git a/src/math/i386/e_expf.s b/src/math/i386/e_expf.s
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/src/math/i386/e_expf.s
@@ -0,0 +1 @@
+
diff --git a/src/math/i386/e_log.s b/src/math/i386/e_log.s
new file mode 100644
index 00000000..34b8d38d
--- /dev/null
+++ b/src/math/i386/e_log.s
@@ -0,0 +1,6 @@
+.global log
+log:
+	fldln2
+	fldl 4(%esp)
+	fyl2x
+	ret
diff --git a/src/math/i386/e_log10.s b/src/math/i386/e_log10.s
new file mode 100644
index 00000000..7f48941b
--- /dev/null
+++ b/src/math/i386/e_log10.s
@@ -0,0 +1,6 @@
+.global log10
+log10:
+	fldlg2
+	fldl 4(%esp)
+	fyl2x
+	ret
diff --git a/src/math/i386/e_log10f.s b/src/math/i386/e_log10f.s
new file mode 100644
index 00000000..311486ea
--- /dev/null
+++ b/src/math/i386/e_log10f.s
@@ -0,0 +1,6 @@
+.global log10f
+log10f:
+	fldlg2
+	flds 4(%esp)
+	fyl2x
+	ret
diff --git a/src/math/i386/e_logf.s b/src/math/i386/e_logf.s
new file mode 100644
index 00000000..b8beec0f
--- /dev/null
+++ b/src/math/i386/e_logf.s
@@ -0,0 +1,6 @@
+.global logf
+logf:
+	fldln2
+	flds 4(%esp)
+	fyl2x
+	ret
diff --git a/src/math/i386/e_remainder.s b/src/math/i386/e_remainder.s
new file mode 100644
index 00000000..b7ff3ef8
--- /dev/null
+++ b/src/math/i386/e_remainder.s
@@ -0,0 +1,16 @@
+.global remainderf
+remainderf:
+	flds 8(%esp)
+	flds 4(%esp)
+	jmp 1f
+	
+.global remainder
+remainder:
+	fldl 12(%esp)
+	fldl 4(%esp)
+1:	fprem1
+	fstsw %ax
+	sahf
+	jp 1b
+	fstp %st(1)
+	ret
diff --git a/src/math/i386/e_remainderf.s b/src/math/i386/e_remainderf.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/e_remainderf.s
diff --git a/src/math/i386/e_sqrt.s b/src/math/i386/e_sqrt.s
new file mode 100644
index 00000000..11314dca
--- /dev/null
+++ b/src/math/i386/e_sqrt.s
@@ -0,0 +1,4 @@
+.global sqrt
+sqrt:	fldl 4(%esp)
+	fsqrt
+	ret
diff --git a/src/math/i386/e_sqrtf.s b/src/math/i386/e_sqrtf.s
new file mode 100644
index 00000000..015e24cd
--- /dev/null
+++ b/src/math/i386/e_sqrtf.s
@@ -0,0 +1,4 @@
+.global sqrtf
+sqrtf:	flds 4(%esp)
+	fsqrt
+	ret
diff --git a/src/math/i386/s_ceil.s b/src/math/i386/s_ceil.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_ceil.s
diff --git a/src/math/i386/s_ceilf.s b/src/math/i386/s_ceilf.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_ceilf.s
diff --git a/src/math/i386/s_fabs.s b/src/math/i386/s_fabs.s
new file mode 100644
index 00000000..10c70f37
--- /dev/null
+++ b/src/math/i386/s_fabs.s
@@ -0,0 +1,5 @@
+.global fabs
+fabs:
+	fldl 4(%esp)
+	fabs
+	ret
diff --git a/src/math/i386/s_fabsf.s b/src/math/i386/s_fabsf.s
new file mode 100644
index 00000000..45442699
--- /dev/null
+++ b/src/math/i386/s_fabsf.s
@@ -0,0 +1,5 @@
+.global fabsf
+fabsf:
+	flds 4(%esp)
+	fabs
+	ret
diff --git a/src/math/i386/s_floor.s b/src/math/i386/s_floor.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_floor.s
diff --git a/src/math/i386/s_floorf.s b/src/math/i386/s_floorf.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_floorf.s
diff --git a/src/math/i386/s_ldexp.s b/src/math/i386/s_ldexp.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_ldexp.s
diff --git a/src/math/i386/s_ldexpf.s b/src/math/i386/s_ldexpf.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_ldexpf.s
diff --git a/src/math/i386/s_rint.s b/src/math/i386/s_rint.s
new file mode 100644
index 00000000..5ba4ab4a
--- /dev/null
+++ b/src/math/i386/s_rint.s
@@ -0,0 +1,5 @@
+.global rint
+rint:
+	fldl 4(%esp)
+	frndint
+	ret
diff --git a/src/math/i386/s_rintf.s b/src/math/i386/s_rintf.s
new file mode 100644
index 00000000..d7aacd8f
--- /dev/null
+++ b/src/math/i386/s_rintf.s
@@ -0,0 +1,5 @@
+.global rintf
+rintf:
+	flds 4(%esp)
+	frndint
+	ret
diff --git a/src/math/i386/s_scalbln.s b/src/math/i386/s_scalbln.s
new file mode 100644
index 00000000..bd022b46
--- /dev/null
+++ b/src/math/i386/s_scalbln.s
@@ -0,0 +1,11 @@
+.global ldexp
+.global scalbn
+.global scalbln
+ldexp:
+scalbn:
+scalbln:
+	fildl 12(%esp)
+	fldl 4(%esp)
+	fscale
+	fstp %st(1)
+	ret
diff --git a/src/math/i386/s_scalblnf.s b/src/math/i386/s_scalblnf.s
new file mode 100644
index 00000000..379ec919
--- /dev/null
+++ b/src/math/i386/s_scalblnf.s
@@ -0,0 +1,11 @@
+.global ldexpf
+.global scalbnf
+.global scalblnf
+ldexpf:
+scalbnf:
+scalblnf:
+	fildl 8(%esp)
+	flds 4(%esp)
+	fscale
+	fstp %st(1)
+	ret
diff --git a/src/math/i386/s_trunc.s b/src/math/i386/s_trunc.s
new file mode 100644
index 00000000..0773891a
--- /dev/null
+++ b/src/math/i386/s_trunc.s
@@ -0,0 +1,36 @@
+.global ceilf
+ceilf:	flds 4(%esp)
+	jmp 1f
+	
+.global ceil
+ceil:	fldl 4(%esp)
+1:	mov $0x08fb,%edx
+	jmp 0f
+
+.global floorf
+floorf:	flds 4(%esp)
+	jmp 1f
+
+.global floor
+floor:	fldl 4(%esp)
+1:	mov $0x04f7,%edx
+	jmp 0f
+
+.global truncf
+truncf:	flds 4(%esp)
+	jmp 1f
+
+.global trunc
+trunc:	fldl 4(%esp)
+1:	mov $0x0cff,%edx
+
+0:	fstcw 4(%esp)
+	mov 5(%esp),%ah
+	or %dh,%ah
+	and %dl,%ah
+	xchg %ah,5(%esp)
+	fldcw 4(%esp)
+	frndint
+	mov %ah,5(%esp)
+	fldcw 4(%esp)
+	ret
diff --git a/src/math/i386/s_truncf.s b/src/math/i386/s_truncf.s
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/math/i386/s_truncf.s
diff --git a/src/math/k_cos.c b/src/math/k_cos.c
new file mode 100644
index 00000000..22e9841e
--- /dev/null
+++ b/src/math/k_cos.c
@@ -0,0 +1,85 @@
+
+/* @(#)k_cos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_cos( x,  y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x. 
+ *
+ * Algorithm
+ *      1. Since cos(-x) = cos(x), we need only to consider positive x.
+ *      2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ *      3. cos(x) is approximated by a polynomial of degree 14 on
+ *         [0,pi/4]
+ *                                       4            14
+ *              cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ *         where the remez error is
+ *      
+ *      |              2     4     6     8     10    12     14 |     -58
+ *      |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+ *      |                                                      | 
+ * 
+ *                     4     6     8     10    12     14 
+ *      4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+ *             cos(x) = 1 - x*x/2 + r
+ *         since cos(x+y) ~ cos(x) - sin(x)*y 
+ *                        ~ cos(x) - x*y,
+ *         a correction term is necessary in cos(x) and hence
+ *              cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ *         For better accuracy when x > 0.3, let qx = |x|/4 with
+ *         the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ *         Then
+ *              cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ *         Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ *         magnitude of the latter is at least a quarter of x*x/2,
+ *         thus, reducing the rounding error in the subtraction.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+double
+__kernel_cos(double x, double y)
+{
+        double a,hz,z,r,qx;
+        int32_t ix;
+        GET_HIGH_WORD(ix,x);
+        ix &= 0x7fffffff;                       /* ix = |x|'s high word*/
+        if(ix<0x3e400000) {                     /* if x < 2**27 */
+            if(((int)x)==0) return one;         /* generate inexact */
+        }
+        z  = x*x;
+        r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+        if(ix < 0x3FD33333)                     /* if |x| < 0.3 */ 
+            return one - (0.5*z - (z*r - x*y));
+        else {
+            if(ix > 0x3fe90000) {               /* x > 0.78125 */
+                qx = 0.28125;
+            } else {
+                INSERT_WORDS(qx,ix-0x00200000,0);       /* x/4 */
+            }
+            hz = 0.5*z-qx;
+            a  = one-qx;
+            return a - (hz - (z*r-x*y));
+        }
+}
diff --git a/src/math/k_cosf.c b/src/math/k_cosf.c
new file mode 100644
index 00000000..61dc3749
--- /dev/null
+++ b/src/math/k_cosf.c
@@ -0,0 +1,52 @@
+/* k_cosf.c -- float version of k_cos.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one =  1.0000000000e+00, /* 0x3f800000 */
+C1  =  4.1666667908e-02, /* 0x3d2aaaab */
+C2  = -1.3888889225e-03, /* 0xbab60b61 */
+C3  =  2.4801587642e-05, /* 0x37d00d01 */
+C4  = -2.7557314297e-07, /* 0xb493f27c */
+C5  =  2.0875723372e-09, /* 0x310f74f6 */
+C6  = -1.1359647598e-11; /* 0xad47d74e */
+
+float
+__kernel_cosf(float x, float y)
+{
+        float a,hz,z,r,qx;
+        int32_t ix;
+        GET_FLOAT_WORD(ix,x);
+        ix &= 0x7fffffff;                       /* ix = |x|'s high word*/
+        if(ix<0x32000000) {                     /* if x < 2**27 */
+            if(((int)x)==0) return one;         /* generate inexact */
+        }
+        z  = x*x;
+        r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+        if(ix < 0x3e99999a)                     /* if |x| < 0.3 */
+            return one - ((float)0.5*z - (z*r - x*y));
+        else {
+            if(ix > 0x3f480000) {               /* x > 0.78125 */
+                qx = (float)0.28125;
+            } else {
+                SET_FLOAT_WORD(qx,ix-0x01000000);       /* x/4 */
+            }
+            hz = (float)0.5*z-qx;
+            a  = one-qx;
+            return a - (hz - (z*r-x*y));
+        }
+}
diff --git a/src/math/k_rem_pio2.c b/src/math/k_rem_pio2.c
new file mode 100644
index 00000000..d993e4f2
--- /dev/null
+++ b/src/math/k_rem_pio2.c
@@ -0,0 +1,300 @@
+
+/* @(#)k_rem_pio2.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ * 
+ * __kernel_rem_pio2 return the last three digits of N with 
+ *              y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of 
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ *      x[]     The input value (must be positive) is broken into nx 
+ *              pieces of 24-bit integers in double precision format.
+ *              x[i] will be the i-th 24 bit of x. The scaled exponent 
+ *              of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 
+ *              match x's up to 24 bits.
+ *
+ *              Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ *                      e0 = ilogb(z)-23
+ *                      z  = scalbn(z,-e0)
+ *              for i = 0,1,2
+ *                      x[i] = floor(z)
+ *                      z    = (z-x[i])*2**24
+ *
+ *
+ *      y[]     ouput result in an array of double precision numbers.
+ *              The dimension of y[] is:
+ *                      24-bit  precision       1
+ *                      53-bit  precision       2
+ *                      64-bit  precision       2
+ *                      113-bit precision       3
+ *              The actual value is the sum of them. Thus for 113-bit
+ *              precison, one may have to do something like:
+ *
+ *              long double t,w,r_head, r_tail;
+ *              t = (long double)y[2] + (long double)y[1];
+ *              w = (long double)y[0];
+ *              r_head = t+w;
+ *              r_tail = w - (r_head - t);
+ *
+ *      e0      The exponent of x[0]
+ *
+ *      nx      dimension of x[]
+ *
+ *      prec    an integer indicating the precision:
+ *                      0       24  bits (single)
+ *                      1       53  bits (double)
+ *                      2       64  bits (extended)
+ *                      3       113 bits (quad)
+ *
+ *      ipio2[]
+ *              integer array, contains the (24*i)-th to (24*i+23)-th 
+ *              bit of 2/pi after binary point. The corresponding 
+ *              floating value is
+ *
+ *                      ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ *      double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ *      jk      jk+1 is the initial number of terms of ipio2[] needed
+ *              in the computation. The recommended value is 2,3,4,
+ *              6 for single, double, extended,and quad.
+ *
+ *      jz      local integer variable indicating the number of 
+ *              terms of ipio2[] used. 
+ *
+ *      jx      nx - 1
+ *
+ *      jv      index for pointing to the suitable ipio2[] for the
+ *              computation. In general, we want
+ *                      ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ *              is an integer. Thus
+ *                      e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ *              Hence jv = max(0,(e0-3)/24).
+ *
+ *      jp      jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ *      q[]     double array with integral value, representing the
+ *              24-bits chunk of the product of x and 2/pi.
+ *
+ *      q0      the corresponding exponent of q[0]. Note that the
+ *              exponent for q[i] would be q0-24*i.
+ *
+ *      PIo2[]  double precision array, obtained by cutting pi/2
+ *              into 24 bits chunks. 
+ *
+ *      f[]     ipio2[] in floating point 
+ *
+ *      iq[]    integer array by breaking up q[] in 24-bits chunk.
+ *
+ *      fq[]    final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ *      ih      integer. If >0 it indicates q[] is >= 0.5, hence
+ *              it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+
+static const double PIo2[] = {
+  1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+  7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+  5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+  3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+  1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+  1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+  2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+  2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+static const double                     
+zero   = 0.0,
+one    = 1.0,
+two24   =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24  =  5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+        int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+{
+        int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+        double z,fw,f[20],fq[20],q[20];
+
+    /* initialize jk*/
+        jk = init_jk[prec];
+        jp = jk;
+
+    /* determine jx,jv,q0, note that 3>q0 */
+        jx =  nx-1;
+        jv = (e0-3)/24; if(jv<0) jv=0;
+        q0 =  e0-24*(jv+1);
+
+    /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+        j = jv-jx; m = jx+jk;
+        for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+    /* compute q[0],q[1],...q[jk] */
+        for (i=0;i<=jk;i++) {
+            for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+        }
+
+        jz = jk;
+recompute:
+    /* distill q[] into iq[] reversingly */
+        for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+            fw    =  (double)((int32_t)(twon24* z));
+            iq[i] =  (int32_t)(z-two24*fw);
+            z     =  q[j-1]+fw;
+        }
+
+    /* compute n */
+        z  = scalbn(z,q0);              /* actual value of z */
+        z -= 8.0*floor(z*0.125);                /* trim off integer >= 8 */
+        n  = (int32_t) z;
+        z -= (double)n;
+        ih = 0;
+        if(q0>0) {      /* need iq[jz-1] to determine n */
+            i  = (iq[jz-1]>>(24-q0)); n += i;
+            iq[jz-1] -= i<<(24-q0);
+            ih = iq[jz-1]>>(23-q0);
+        } 
+        else if(q0==0) ih = iq[jz-1]>>23;
+        else if(z>=0.5) ih=2;
+
+        if(ih>0) {      /* q > 0.5 */
+            n += 1; carry = 0;
+            for(i=0;i<jz ;i++) {        /* compute 1-q */
+                j = iq[i];
+                if(carry==0) {
+                    if(j!=0) {
+                        carry = 1; iq[i] = 0x1000000- j;
+                    }
+                } else  iq[i] = 0xffffff - j;
+            }
+            if(q0>0) {          /* rare case: chance is 1 in 12 */
+                switch(q0) {
+                case 1:
+                   iq[jz-1] &= 0x7fffff; break;
+                case 2:
+                   iq[jz-1] &= 0x3fffff; break;
+                }
+            }
+            if(ih==2) {
+                z = one - z;
+                if(carry!=0) z -= scalbn(one,q0);
+            }
+        }
+
+    /* check if recomputation is needed */
+        if(z==zero) {
+            j = 0;
+            for (i=jz-1;i>=jk;i--) j |= iq[i];
+            if(j==0) { /* need recomputation */
+                for(k=1;iq[jk-k]==0;k++);   /* k = no. of terms needed */
+
+                for(i=jz+1;i<=jz+k;i++) {   /* add q[jz+1] to q[jz+k] */
+                    f[jx+i] = (double) ipio2[jv+i];
+                    for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+                    q[i] = fw;
+                }
+                jz += k;
+                goto recompute;
+            }
+        }
+
+    /* chop off zero terms */
+        if(z==0.0) {
+            jz -= 1; q0 -= 24;
+            while(iq[jz]==0) { jz--; q0-=24;}
+        } else { /* break z into 24-bit if necessary */
+            z = scalbn(z,-q0);
+            if(z>=two24) { 
+                fw = (double)((int32_t)(twon24*z));
+                iq[jz] = (int32_t)(z-two24*fw);
+                jz += 1; q0 += 24;
+                iq[jz] = (int32_t) fw;
+            } else iq[jz] = (int32_t) z ;
+        }
+
+    /* convert integer "bit" chunk to floating-point value */
+        fw = scalbn(one,q0);
+        for(i=jz;i>=0;i--) {
+            q[i] = fw*(double)iq[i]; fw*=twon24;
+        }
+
+    /* compute PIo2[0,...,jp]*q[jz,...,0] */
+        for(i=jz;i>=0;i--) {
+            for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+            fq[jz-i] = fw;
+        }
+
+    /* compress fq[] into y[] */
+        switch(prec) {
+            case 0:
+                fw = 0.0;
+                for (i=jz;i>=0;i--) fw += fq[i];
+                y[0] = (ih==0)? fw: -fw; 
+                break;
+            case 1:
+            case 2:
+                fw = 0.0;
+                for (i=jz;i>=0;i--) fw += fq[i]; 
+                y[0] = (ih==0)? fw: -fw; 
+                fw = fq[0]-fw;
+                for (i=1;i<=jz;i++) fw += fq[i];
+                y[1] = (ih==0)? fw: -fw; 
+                break;
+            case 3:     /* painful */
+                for (i=jz;i>0;i--) {
+                    fw      = fq[i-1]+fq[i]; 
+                    fq[i]  += fq[i-1]-fw;
+                    fq[i-1] = fw;
+                }
+                for (i=jz;i>1;i--) {
+                    fw      = fq[i-1]+fq[i]; 
+                    fq[i]  += fq[i-1]-fw;
+                    fq[i-1] = fw;
+                }
+                for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; 
+                if(ih==0) {
+                    y[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;
+                } else {
+                    y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+                }
+        }
+        return n&7;
+}
diff --git a/src/math/k_rem_pio2f.c b/src/math/k_rem_pio2f.c
new file mode 100644
index 00000000..b543f084
--- /dev/null
+++ b/src/math/k_rem_pio2f.c
@@ -0,0 +1,192 @@
+/* k_rem_pio2f.c -- float version of k_rem_pio2.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/* In the float version, the input parameter x contains 8 bit
+   integers, not 24 bit integers.  113 bit precision is not supported.  */
+
+static const int init_jk[] = {4,7,9}; /* initial value for jk */
+
+static const float PIo2[] = {
+  1.5703125000e+00, /* 0x3fc90000 */
+  4.5776367188e-04, /* 0x39f00000 */
+  2.5987625122e-05, /* 0x37da0000 */
+  7.5437128544e-08, /* 0x33a20000 */
+  6.0026650317e-11, /* 0x2e840000 */
+  7.3896444519e-13, /* 0x2b500000 */
+  5.3845816694e-15, /* 0x27c20000 */
+  5.6378512969e-18, /* 0x22d00000 */
+  8.3009228831e-20, /* 0x1fc40000 */
+  3.2756352257e-22, /* 0x1bc60000 */
+  6.3331015649e-25, /* 0x17440000 */
+};
+
+static const float
+zero   = 0.0,
+one    = 1.0,
+two8   =  2.5600000000e+02, /* 0x43800000 */
+twon8  =  3.9062500000e-03; /* 0x3b800000 */
+
+        int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2)
+{
+        int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+        float z,fw,f[20],fq[20],q[20];
+
+    /* initialize jk*/
+        jk = init_jk[prec];
+        jp = jk;
+
+    /* determine jx,jv,q0, note that 3>q0 */
+        jx =  nx-1;
+        jv = (e0-3)/8; if(jv<0) jv=0;
+        q0 =  e0-8*(jv+1);
+
+    /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+        j = jv-jx; m = jx+jk;
+        for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j];
+
+    /* compute q[0],q[1],...q[jk] */
+        for (i=0;i<=jk;i++) {
+            for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+        }
+
+        jz = jk;
+recompute:
+    /* distill q[] into iq[] reversingly */
+        for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+            fw    =  (float)((int32_t)(twon8* z));
+            iq[i] =  (int32_t)(z-two8*fw);
+            z     =  q[j-1]+fw;
+        }
+
+    /* compute n */
+        z  = scalbnf(z,q0);             /* actual value of z */
+        z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */
+        n  = (int32_t) z;
+        z -= (float)n;
+        ih = 0;
+        if(q0>0) {      /* need iq[jz-1] to determine n */
+            i  = (iq[jz-1]>>(8-q0)); n += i;
+            iq[jz-1] -= i<<(8-q0);
+            ih = iq[jz-1]>>(7-q0);
+        }
+        else if(q0==0) ih = iq[jz-1]>>7;
+        else if(z>=(float)0.5) ih=2;
+
+        if(ih>0) {      /* q > 0.5 */
+            n += 1; carry = 0;
+            for(i=0;i<jz ;i++) {        /* compute 1-q */
+                j = iq[i];
+                if(carry==0) {
+                    if(j!=0) {
+                        carry = 1; iq[i] = 0x100- j;
+                    }
+                } else  iq[i] = 0xff - j;
+            }
+            if(q0>0) {          /* rare case: chance is 1 in 12 */
+                switch(q0) {
+                case 1:
+                   iq[jz-1] &= 0x7f; break;
+                case 2:
+                   iq[jz-1] &= 0x3f; break;
+                }
+            }
+            if(ih==2) {
+                z = one - z;
+                if(carry!=0) z -= scalbnf(one,q0);
+            }
+        }
+
+    /* check if recomputation is needed */
+        if(z==zero) {
+            j = 0;
+            for (i=jz-1;i>=jk;i--) j |= iq[i];
+            if(j==0) { /* need recomputation */
+                for(k=1;iq[jk-k]==0;k++);   /* k = no. of terms needed */
+
+                for(i=jz+1;i<=jz+k;i++) {   /* add q[jz+1] to q[jz+k] */
+                    f[jx+i] = (float) ipio2[jv+i];
+                    for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+                    q[i] = fw;
+                }
+                jz += k;
+                goto recompute;
+            }
+        }
+
+    /* chop off zero terms */
+        if(z==(float)0.0) {
+            jz -= 1; q0 -= 8;
+            while(iq[jz]==0) { jz--; q0-=8;}
+        } else { /* break z into 8-bit if necessary */
+            z = scalbnf(z,-q0);
+            if(z>=two8) {
+                fw = (float)((int32_t)(twon8*z));
+                iq[jz] = (int32_t)(z-two8*fw);
+                jz += 1; q0 += 8;
+                iq[jz] = (int32_t) fw;
+            } else iq[jz] = (int32_t) z ;
+        }
+
+    /* convert integer "bit" chunk to floating-point value */
+        fw = scalbnf(one,q0);
+        for(i=jz;i>=0;i--) {
+            q[i] = fw*(float)iq[i]; fw*=twon8;
+        }
+
+    /* compute PIo2[0,...,jp]*q[jz,...,0] */
+        for(i=jz;i>=0;i--) {
+            for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+            fq[jz-i] = fw;
+        }
+
+    /* compress fq[] into y[] */
+        switch(prec) {
+            case 0:
+                fw = 0.0;
+                for (i=jz;i>=0;i--) fw += fq[i];
+                y[0] = (ih==0)? fw: -fw;
+                break;
+            case 1:
+            case 2:
+                fw = 0.0;
+                for (i=jz;i>=0;i--) fw += fq[i];
+                y[0] = (ih==0)? fw: -fw;
+                fw = fq[0]-fw;
+                for (i=1;i<=jz;i++) fw += fq[i];
+                y[1] = (ih==0)? fw: -fw;
+                break;
+            case 3:     /* painful */
+                for (i=jz;i>0;i--) {
+                    fw      = fq[i-1]+fq[i];
+                    fq[i]  += fq[i-1]-fw;
+                    fq[i-1] = fw;
+                }
+                for (i=jz;i>1;i--) {
+                    fw      = fq[i-1]+fq[i];
+                    fq[i]  += fq[i-1]-fw;
+                    fq[i-1] = fw;
+                }
+                for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+                if(ih==0) {
+                    y[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;
+                } else {
+                    y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+                }
+        }
+        return n&7;
+}
diff --git a/src/math/k_sin.c b/src/math/k_sin.c
new file mode 100644
index 00000000..9def2589
--- /dev/null
+++ b/src/math/k_sin.c
@@ -0,0 +1,68 @@
+
+/* @(#)k_sin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_sin( x, y, iy)
+ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). 
+ *
+ * Algorithm
+ *      1. Since sin(-x) = -sin(x), we need only to consider positive x. 
+ *      2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
+ *      3. sin(x) is approximated by a polynomial of degree 13 on
+ *         [0,pi/4]
+ *                               3            13
+ *              sin(x) ~ x + S1*x + ... + S6*x
+ *         where
+ *      
+ *      |sin(x)         2     4     6     8     10     12  |     -58
+ *      |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
+ *      |  x                                               | 
+ * 
+ *      4. sin(x+y) = sin(x) + sin'(x')*y
+ *                  ~ sin(x) + (1-x*x/2)*y
+ *         For better accuracy, let 
+ *                   3      2      2      2      2
+ *              r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ *         then                   3    2
+ *              sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+S1  = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2  =  8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3  = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4  =  2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5  = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6  =  1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+double
+__kernel_sin(double x, double y, int iy)
+{
+        double z,r,v;
+        int32_t ix;
+        GET_HIGH_WORD(ix,x);
+        ix &= 0x7fffffff;                       /* high word of x */
+        if(ix<0x3e400000)                       /* |x| < 2**-27 */
+           {if((int)x==0) return x;}            /* generate inexact */
+        z       =  x*x;
+        v       =  z*x;
+        r       =  S2+z*(S3+z*(S4+z*(S5+z*S6)));
+        if(iy==0) return x+v*(S1+z*r);
+        else      return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/src/math/k_sinf.c b/src/math/k_sinf.c
new file mode 100644
index 00000000..617f6148
--- /dev/null
+++ b/src/math/k_sinf.c
@@ -0,0 +1,42 @@
+/* k_sinf.c -- float version of k_sin.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+half =  5.0000000000e-01,/* 0x3f000000 */
+S1  = -1.6666667163e-01, /* 0xbe2aaaab */
+S2  =  8.3333337680e-03, /* 0x3c088889 */
+S3  = -1.9841270114e-04, /* 0xb9500d01 */
+S4  =  2.7557314297e-06, /* 0x3638ef1b */
+S5  = -2.5050759689e-08, /* 0xb2d72f34 */
+S6  =  1.5896910177e-10; /* 0x2f2ec9d3 */
+
+float
+__kernel_sinf(float x, float y, int iy)
+{
+        float z,r,v;
+        int32_t ix;
+        GET_FLOAT_WORD(ix,x);
+        ix &= 0x7fffffff;                       /* high word of x */
+        if(ix<0x32000000)                       /* |x| < 2**-27 */
+           {if((int)x==0) return x;}            /* generate inexact */
+        z       =  x*x;
+        v       =  z*x;
+        r       =  S2+z*(S3+z*(S4+z*(S5+z*S6)));
+        if(iy==0) return x+v*(S1+z*r);
+        else      return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/src/math/k_tan.c b/src/math/k_tan.c
new file mode 100644
index 00000000..f721ae6d
--- /dev/null
+++ b/src/math/k_tan.c
@@ -0,0 +1,149 @@
+/* @(#)k_tan.c 1.5 04/04/22 SMI */
+
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned.
+ *
+ * Algorithm
+ *      1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ *      2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ *      3. tan(x) is approximated by a odd polynomial of degree 27 on
+ *         [0,0.67434]
+ *                               3             27
+ *              tan(x) ~ x + T1*x + ... + T13*x
+ *         where
+ *
+ *              |tan(x)         2     4            26   |     -59.2
+ *              |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2
+ *              |  x                                    |
+ *
+ *         Note: tan(x+y) = tan(x) + tan'(x)*y
+ *                        ~ tan(x) + (1+x*x)*y
+ *         Therefore, for better accuracy in computing tan(x+y), let
+ *                   3      2      2       2       2
+ *              r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ *         then
+ *                                  3    2
+ *              tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ *      4. For x in [0.67434,pi/4],  let y = pi/4 - x, then
+ *              tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ *                     = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include <math.h>
+#include "math_private.h"
+static const double xxx[] = {
+                 3.33333333333334091986e-01,    /* 3FD55555, 55555563 */
+                 1.33333333333201242699e-01,    /* 3FC11111, 1110FE7A */
+                 5.39682539762260521377e-02,    /* 3FABA1BA, 1BB341FE */
+                 2.18694882948595424599e-02,    /* 3F9664F4, 8406D637 */
+                 8.86323982359930005737e-03,    /* 3F8226E3, E96E8493 */
+                 3.59207910759131235356e-03,    /* 3F6D6D22, C9560328 */
+                 1.45620945432529025516e-03,    /* 3F57DBC8, FEE08315 */
+                 5.88041240820264096874e-04,    /* 3F4344D8, F2F26501 */
+                 2.46463134818469906812e-04,    /* 3F3026F7, 1A8D1068 */
+                 7.81794442939557092300e-05,    /* 3F147E88, A03792A6 */
+                 7.14072491382608190305e-05,    /* 3F12B80F, 32F0A7E9 */
+                -1.85586374855275456654e-05,    /* BEF375CB, DB605373 */
+                 2.59073051863633712884e-05,    /* 3EFB2A70, 74BF7AD4 */
+/* one */        1.00000000000000000000e+00,    /* 3FF00000, 00000000 */
+/* pio4 */       7.85398163397448278999e-01,    /* 3FE921FB, 54442D18 */
+/* pio4lo */     3.06161699786838301793e-17     /* 3C81A626, 33145C07 */
+};
+#define one     xxx[13]
+#define pio4    xxx[14]
+#define pio4lo  xxx[15]
+#define T       xxx
+/* INDENT ON */
+
+double
+__kernel_tan(double x, double y, int iy) {
+        double z, r, v, w, s;
+        int32_t ix, hx;
+
+        GET_HIGH_WORD(hx,x);
+        ix = hx & 0x7fffffff;                   /* high word of |x| */
+        if (ix < 0x3e300000) {                  /* x < 2**-28 */
+                if ((int) x == 0) {             /* generate inexact */
+                        uint32_t low;
+                        GET_LOW_WORD(low,x);
+                        if (((ix | low) | (iy + 1)) == 0)
+                                return one / fabs(x);
+                        else {
+                                if (iy == 1)
+                                        return x;
+                                else {  /* compute -1 / (x+y) carefully */
+                                        double a, t;
+
+                                        z = w = x + y;
+                                        SET_LOW_WORD(z, 0);
+                                        v = y - (z - x);
+                                        t = a = -one / w;
+                                        SET_LOW_WORD(t, 0);
+                                        s = one + t * z;
+                                        return t + a * (s + t * v);
+                                }
+                        }
+                }
+        }
+        if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */
+                if (hx < 0) {
+                        x = -x;
+                        y = -y;
+                }
+                z = pio4 - x;
+                w = pio4lo - y;
+                x = z + w;
+                y = 0.0;
+        }
+        z = x * x;
+        w = z * z;
+        /*
+         * Break x^5*(T[1]+x^2*T[2]+...) into
+         * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+         * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+         */
+        r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] +
+                w * T[11]))));
+        v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] +
+                w * T[12])))));
+        s = z * x;
+        r = y + z * (s * (r + v) + y);
+        r += T[0] * s;
+        w = x + r;
+        if (ix >= 0x3FE59428) {
+                v = (double) iy;
+                return (double) (1 - ((hx >> 30) & 2)) *
+                        (v - 2.0 * (x - (w * w / (w + v) - r)));
+        }
+        if (iy == 1)
+                return w;
+        else {
+                /*
+                 * if allow error up to 2 ulp, simply return
+                 * -1.0 / (x+r) here
+                 */
+                /* compute -1.0 / (x+r) accurately */
+                double a, t;
+                z = w;
+                SET_LOW_WORD(z,0);
+                v = r - (z - x);        /* z+v = r+x */
+                t = a = -1.0 / w;       /* a = -1.0/w */
+                SET_LOW_WORD(t,0);
+                s = 1.0 + t * z;
+                return t + a * (s + t * v);
+        }
+}
diff --git a/src/math/k_tanf.c b/src/math/k_tanf.c
new file mode 100644
index 00000000..99ede58c
--- /dev/null
+++ b/src/math/k_tanf.c
@@ -0,0 +1,105 @@
+/* k_tanf.c -- float version of k_tan.c
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+static const float
+one   =  1.0000000000e+00, /* 0x3f800000 */
+pio4  =  7.8539812565e-01, /* 0x3f490fda */
+pio4lo=  3.7748947079e-08, /* 0x33222168 */
+T[] =  {
+  3.3333334327e-01, /* 0x3eaaaaab */
+  1.3333334029e-01, /* 0x3e088889 */
+  5.3968254477e-02, /* 0x3d5d0dd1 */
+  2.1869488060e-02, /* 0x3cb327a4 */
+  8.8632395491e-03, /* 0x3c11371f */
+  3.5920790397e-03, /* 0x3b6b6916 */
+  1.4562094584e-03, /* 0x3abede48 */
+  5.8804126456e-04, /* 0x3a1a26c8 */
+  2.4646313977e-04, /* 0x398137b9 */
+  7.8179444245e-05, /* 0x38a3f445 */
+  7.1407252108e-05, /* 0x3895c07a */
+ -1.8558637748e-05, /* 0xb79bae5f */
+  2.5907305826e-05, /* 0x37d95384 */
+};
+
+float
+__kernel_tanf(float x, float y, int iy)
+{
+        float z,r,v,w,s;
+        int32_t ix,hx;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;     /* high word of |x| */
+        if(ix<0x31800000) {                     /* x < 2**-28 */
+                if ((int) x == 0) {             /* generate inexact */
+                        if ((ix | (iy + 1)) == 0)
+                                return one / fabsf(x);
+                        else {
+                                if (iy == 1)
+                                        return x;
+                                else {  /* compute -1 / (x+y) carefully */
+                                        double a, t;
+
+                                        z = w = x + y;
+                                        GET_FLOAT_WORD(ix, z);
+                                        SET_FLOAT_WORD(z, ix & 0xfffff000);
+                                        v = y - (z - x);
+                                        t = a = -one / w;
+                                        GET_FLOAT_WORD(ix, t);
+                                        SET_FLOAT_WORD(t, ix & 0xfffff000);
+                                        s = one + t * z;
+                                        return t + a * (s + t * v);
+                                }
+                        }
+                }
+        }
+        if(ix>=0x3f2ca140) {                    /* |x|>=0.6744 */
+            if(hx<0) {x = -x; y = -y;}
+            z = pio4-x;
+            w = pio4lo-y;
+            x = z+w; y = 0.0;
+        }
+        z       =  x*x;
+        w       =  z*z;
+    /* Break x^5*(T[1]+x^2*T[2]+...) into
+     *    x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+     *    x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+     */
+        r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+        v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+        s = z*x;
+        r = y + z*(s*(r+v)+y);
+        r += T[0]*s;
+        w = x+r;
+        if(ix>=0x3f2ca140) {
+            v = (float)iy;
+            return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r)));
+        }
+        if(iy==1) return w;
+        else {          /* if allow error up to 2 ulp,
+                           simply return -1.0/(x+r) here */
+     /*  compute -1.0/(x+r) accurately */
+            float a,t;
+            int32_t i;
+            z  = w;
+            GET_FLOAT_WORD(i,z);
+            SET_FLOAT_WORD(z,i&0xfffff000);
+            v  = r-(z - x);     /* z+v = r+x */
+            t = a  = -(float)1.0/w;     /* a = -1.0/w */
+            GET_FLOAT_WORD(i,t);
+            SET_FLOAT_WORD(t,i&0xfffff000);
+            s  = (float)1.0+t*z;
+            return t+a*(s+t*v);
+        }
+}
diff --git a/src/math/math_private.h b/src/math/math_private.h
new file mode 100644
index 00000000..28a6a195
--- /dev/null
+++ b/src/math/math_private.h
@@ -0,0 +1,143 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef _MATH_PRIVATE_H_
+#define _MATH_PRIVATE_H_
+
+#include <inttypes.h>
+
+/*
+ * The original fdlibm code used statements like:
+ *      n0 = ((*(int*)&one)>>29)^1;             * index of high word *
+ *      ix0 = *(n0+(int*)&x);                   * high word of x *
+ *      ix1 = *((1-n0)+(int*)&x);               * low word of x *
+ * to dig two 32 bit words out of the 64 bit IEEE floating point
+ * value.  That is non-ANSI, and, moreover, the gcc instruction
+ * scheduler gets it wrong.  We instead use the following macros.
+ * Unlike the original code, we determine the endianness at compile
+ * time, not at run time; I don't see much benefit to selecting
+ * endianness at run time.
+ */
+
+/*
+ * A union which permits us to convert between a double and two 32 bit
+ * ints.
+ */
+
+typedef union
+{
+  double value;
+  uint64_t words;
+} ieee_double_shape_type;
+
+/* Get two 32 bit ints from a double.  */
+
+#define EXTRACT_WORDS(ix0,ix1,d)                                \
+do {                                                            \
+  ieee_double_shape_type ew_u;                                  \
+  ew_u.value = (d);                                             \
+  (ix0) = ew_u.words >> 32;                                     \
+  (ix1) = (uint32_t)ew_u.words;                                 \
+} while (0)
+
+/* Get the more significant 32 bit int from a double.  */
+
+#define GET_HIGH_WORD(i,d)                                      \
+do {                                                            \
+  ieee_double_shape_type gh_u;                                  \
+  gh_u.value = (d);                                             \
+  (i) = gh_u.words >> 32;                                       \
+} while (0)
+
+/* Get the less significant 32 bit int from a double.  */
+
+#define GET_LOW_WORD(i,d)                                       \
+do {                                                            \
+  ieee_double_shape_type gl_u;                                  \
+  gl_u.value = (d);                                             \
+  (i) = (uint32_t)gl_u.words;                                   \
+} while (0)
+
+/* Set a double from two 32 bit ints.  */
+
+#define INSERT_WORDS(d,ix0,ix1)                                 \
+do {                                                            \
+  ieee_double_shape_type iw_u;                                  \
+  iw_u.words = ((uint64_t)(ix0) << 32) | (ix1);                 \
+  (d) = iw_u.value;                                             \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int.  */
+
+#define SET_HIGH_WORD(d,v)                                      \
+do {                                                            \
+  ieee_double_shape_type sh_u;                                  \
+  sh_u.value = (d);                                             \
+  sh_u.words &= 0xffffffff;                                     \
+  sh_u.words |= ((uint64_t)(v) << 32);                          \
+  (d) = sh_u.value;                                             \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int.  */
+
+#define SET_LOW_WORD(d,v)                                       \
+do {                                                            \
+  ieee_double_shape_type sl_u;                                  \
+  sl_u.value = (d);                                             \
+  sl_u.words &= 0xffffffff00000000ull;                          \
+  sl_u.words |= (uint32_t)(v);                                  \
+  (d) = sl_u.value;                                             \
+} while (0)
+
+/*
+ * A union which permits us to convert between a float and a 32 bit
+ * int.
+ */
+
+typedef union
+{
+  float value;
+  uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float.  */
+
+#define GET_FLOAT_WORD(i,d)                                     \
+do {                                                            \
+  ieee_float_shape_type gf_u;                                   \
+  gf_u.value = (d);                                             \
+  (i) = gf_u.word;                                              \
+} while (0)
+
+/* Set a float from a 32 bit int.  */
+
+#define SET_FLOAT_WORD(d,i)                                     \
+do {                                                            \
+  ieee_float_shape_type sf_u;                                   \
+  sf_u.word = (i);                                              \
+  (d) = sf_u.value;                                             \
+} while (0)
+
+/* fdlibm kernel function */
+int     __ieee754_rem_pio2(double,double*);
+double  __kernel_sin(double,double,int);
+double  __kernel_cos(double,double);
+double  __kernel_tan(double,double,int);
+int     __kernel_rem_pio2(double*,double*,int,int,int,const int*);
+
+/* float versions of fdlibm kernel functions */
+int     __ieee754_rem_pio2f(float,float*);
+float   __kernel_sinf(float,float,int);
+float   __kernel_cosf(float,float);
+float   __kernel_tanf(float,float,int);
+int     __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
+
+#endif /* !_MATH_PRIVATE_H_ */
diff --git a/src/math/s_asinh.c b/src/math/s_asinh.c
new file mode 100644
index 00000000..26016091
--- /dev/null
+++ b/src/math/s_asinh.c
@@ -0,0 +1,53 @@
+/* @(#)s_asinh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* asinh(x)
+ * Method :
+ *      Based on
+ *              asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ *      we have
+ *      asinh(x) := x  if  1+x*x=1,
+ *               := sign(x)*(log(x)+ln2)) for large |x|, else
+ *               := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ *               := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+ln2 =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+huge=  1.00000000000000000000e+300;
+
+double
+asinh(double x)
+{
+        double t,w;
+        int32_t hx,ix;
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7ff00000) return x+x;  /* x is inf or NaN */
+        if(ix< 0x3e300000) {    /* |x|<2**-28 */
+            if(huge+x>one) return x;    /* return x inexact except 0 */
+        }
+        if(ix>0x41b00000) {     /* |x| > 2**28 */
+            w = log(fabs(x))+ln2;
+        } else if (ix>0x40000000) {     /* 2**28 > |x| > 2.0 */
+            t = fabs(x);
+            w = log(2.0*t+one/(sqrt(x*x+one)+t));
+        } else {                /* 2.0 > |x| > 2**-28 */
+            t = x*x;
+            w =log1p(fabs(x)+t/(one+sqrt(one+t)));
+        }
+        if(hx>0) return w; else return -w;
+}
diff --git a/src/math/s_asinhf.c b/src/math/s_asinhf.c
new file mode 100644
index 00000000..04f8d072
--- /dev/null
+++ b/src/math/s_asinhf.c
@@ -0,0 +1,45 @@
+/* s_asinhf.c -- float version of s_asinh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one =  1.0000000000e+00, /* 0x3F800000 */
+ln2 =  6.9314718246e-01, /* 0x3f317218 */
+huge=  1.0000000000e+30;
+
+float
+asinhf(float x)
+{
+        float t,w;
+        int32_t hx,ix;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7f800000) return x+x;  /* x is inf or NaN */
+        if(ix< 0x31800000) {    /* |x|<2**-28 */
+            if(huge+x>one) return x;    /* return x inexact except 0 */
+        }
+        if(ix>0x4d800000) {     /* |x| > 2**28 */
+            w = logf(fabsf(x))+ln2;
+        } else if (ix>0x40000000) {     /* 2**28 > |x| > 2.0 */
+            t = fabsf(x);
+            w = logf((float)2.0*t+one/(sqrtf(x*x+one)+t));
+        } else {                /* 2.0 > |x| > 2**-28 */
+            t = x*x;
+            w =log1pf(fabsf(x)+t/(one+sqrtf(one+t)));
+        }
+        if(hx>0) return w; else return -w;
+}
diff --git a/src/math/s_atan.c b/src/math/s_atan.c
new file mode 100644
index 00000000..1faac024
--- /dev/null
+++ b/src/math/s_atan.c
@@ -0,0 +1,115 @@
+/* @(#)s_atan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* atan(x)
+ * Method
+ *   1. Reduce x to positive by atan(x) = -atan(-x).
+ *   2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ *      is further reduced to one of the following intervals and the
+ *      arctangent of t is evaluated by the corresponding formula:
+ *
+ *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double atanhi[] = {
+  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+static const double atanlo[] = {
+  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+static const double aT[] = {
+  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+        static const double
+one   = 1.0,
+huge   = 1.0e300;
+
+double
+atan(double x)
+{
+        double w,s1,s2,z;
+        int32_t ix,hx,id;
+
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x44100000) {    /* if |x| >= 2^66 */
+            uint32_t low;
+            GET_LOW_WORD(low,x);
+            if(ix>0x7ff00000||
+                (ix==0x7ff00000&&(low!=0)))
+                return x+x;             /* NaN */
+            if(hx>0) return  atanhi[3]+atanlo[3];
+            else     return -atanhi[3]-atanlo[3];
+        } if (ix < 0x3fdc0000) {        /* |x| < 0.4375 */
+            if (ix < 0x3e200000) {      /* |x| < 2^-29 */
+                if(huge+x>one) return x;        /* raise inexact */
+            }
+            id = -1;
+        } else {
+        x = fabs(x);
+        if (ix < 0x3ff30000) {          /* |x| < 1.1875 */
+            if (ix < 0x3fe60000) {      /* 7/16 <=|x|<11/16 */
+                id = 0; x = (2.0*x-one)/(2.0+x);
+            } else {                    /* 11/16<=|x|< 19/16 */
+                id = 1; x  = (x-one)/(x+one);
+            }
+        } else {
+            if (ix < 0x40038000) {      /* |x| < 2.4375 */
+                id = 2; x  = (x-1.5)/(one+1.5*x);
+            } else {                    /* 2.4375 <= |x| < 2^66 */
+                id = 3; x  = -1.0/x;
+            }
+        }}
+    /* end of argument reduction */
+        z = x*x;
+        w = z*z;
+    /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+        s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+        s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+        if (id<0) return x - x*(s1+s2);
+        else {
+            z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+            return (hx<0)? -z:z;
+        }
+}
diff --git a/src/math/s_atanf.c b/src/math/s_atanf.c
new file mode 100644
index 00000000..03067e18
--- /dev/null
+++ b/src/math/s_atanf.c
@@ -0,0 +1,95 @@
+/* s_atanf.c -- float version of s_atan.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float atanhi[] = {
+  4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
+  7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
+  9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
+  1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
+};
+
+static const float atanlo[] = {
+  5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
+  3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
+  3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
+  7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
+};
+
+static const float aT[] = {
+  3.3333334327e-01, /* 0x3eaaaaaa */
+ -2.0000000298e-01, /* 0xbe4ccccd */
+  1.4285714924e-01, /* 0x3e124925 */
+ -1.1111110449e-01, /* 0xbde38e38 */
+  9.0908870101e-02, /* 0x3dba2e6e */
+ -7.6918758452e-02, /* 0xbd9d8795 */
+  6.6610731184e-02, /* 0x3d886b35 */
+ -5.8335702866e-02, /* 0xbd6ef16b */
+  4.9768779427e-02, /* 0x3d4bda59 */
+ -3.6531571299e-02, /* 0xbd15a221 */
+  1.6285819933e-02, /* 0x3c8569d7 */
+};
+
+        static const float
+one   = 1.0,
+huge   = 1.0e30;
+
+float
+atanf(float x)
+{
+        float w,s1,s2,z;
+        int32_t ix,hx,id;
+
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x50800000) {    /* if |x| >= 2^34 */
+            if(ix>0x7f800000)
+                return x+x;             /* NaN */
+            if(hx>0) return  atanhi[3]+atanlo[3];
+            else     return -atanhi[3]-atanlo[3];
+        } if (ix < 0x3ee00000) {        /* |x| < 0.4375 */
+            if (ix < 0x31000000) {      /* |x| < 2^-29 */
+                if(huge+x>one) return x;        /* raise inexact */
+            }
+            id = -1;
+        } else {
+        x = fabsf(x);
+        if (ix < 0x3f980000) {          /* |x| < 1.1875 */
+            if (ix < 0x3f300000) {      /* 7/16 <=|x|<11/16 */
+                id = 0; x = ((float)2.0*x-one)/((float)2.0+x);
+            } else {                    /* 11/16<=|x|< 19/16 */
+                id = 1; x  = (x-one)/(x+one);
+            }
+        } else {
+            if (ix < 0x401c0000) {      /* |x| < 2.4375 */
+                id = 2; x  = (x-(float)1.5)/(one+(float)1.5*x);
+            } else {                    /* 2.4375 <= |x| < 2^66 */
+                id = 3; x  = -(float)1.0/x;
+            }
+        }}
+    /* end of argument reduction */
+        z = x*x;
+        w = z*z;
+    /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+        s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+        s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+        if (id<0) return x - x*(s1+s2);
+        else {
+            z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+            return (hx<0)? -z:z;
+        }
+}
diff --git a/src/math/s_cbrt.c b/src/math/s_cbrt.c
new file mode 100644
index 00000000..8adcb191
--- /dev/null
+++ b/src/math/s_cbrt.c
@@ -0,0 +1,77 @@
+/* @(#)s_cbrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/* cbrt(x)
+ * Return cube root of x
+ */
+static const uint32_t
+        B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
+        B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
+
+static const double
+C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
+D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
+E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
+F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
+G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
+
+double
+cbrt(double x)
+{
+        int32_t hx;
+        double r,s,t=0.0,w;
+        uint32_t sign;
+        uint32_t high,low;
+
+        GET_HIGH_WORD(hx,x);
+        sign=hx&0x80000000;             /* sign= sign(x) */
+        hx  ^=sign;
+        if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
+        GET_LOW_WORD(low,x);
+        if((hx|low)==0)
+            return(x);          /* cbrt(0) is itself */
+
+        SET_HIGH_WORD(x,hx);    /* x <- |x| */
+    /* rough cbrt to 5 bits */
+        if(hx<0x00100000)               /* subnormal number */
+          {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
+           t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
+          }
+        else
+          SET_HIGH_WORD(t,hx/3+B1);
+
+
+    /* new cbrt to 23 bits, may be implemented in single precision */
+        r=t*t/x;
+        s=C+r*t;
+        t*=G+F/(s+E+D/s);
+
+    /* chopped to 20 bits and make it larger than cbrt(x) */
+        GET_HIGH_WORD(high,t);
+        INSERT_WORDS(t,high+0x00000001,0);
+
+
+    /* one step newton iteration to 53 bits with error less than 0.667 ulps */
+        s=t*t;          /* t*t is exact */
+        r=x/s;
+        w=t+t;
+        r=(r-t)/(w+r);  /* r-s is exact */
+        t=t+t*r;
+
+    /* retore the sign bit */
+        GET_HIGH_WORD(high,t);
+        SET_HIGH_WORD(t,high|sign);
+        return(t);
+}
diff --git a/src/math/s_cbrtf.c b/src/math/s_cbrtf.c
new file mode 100644
index 00000000..e7b46de7
--- /dev/null
+++ b/src/math/s_cbrtf.c
@@ -0,0 +1,67 @@
+/* s_cbrtf.c -- float version of s_cbrt.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/* cbrtf(x)
+ * Return cube root of x
+ */
+static const unsigned
+        B1 = 709958130, /* B1 = (84+2/3-0.03306235651)*2**23 */
+        B2 = 642849266; /* B2 = (76+2/3-0.03306235651)*2**23 */
+
+static const float
+C =  5.4285717010e-01, /* 19/35     = 0x3f0af8b0 */
+D = -7.0530611277e-01, /* -864/1225 = 0xbf348ef1 */
+E =  1.4142856598e+00, /* 99/70     = 0x3fb50750 */
+F =  1.6071428061e+00, /* 45/28     = 0x3fcdb6db */
+G =  3.5714286566e-01; /* 5/14      = 0x3eb6db6e */
+
+float
+cbrtf(float x)
+{
+        float r,s,t;
+        int32_t hx;
+        uint32_t sign;
+        uint32_t high;
+
+        GET_FLOAT_WORD(hx,x);
+        sign=hx&0x80000000;             /* sign= sign(x) */
+        hx  ^=sign;
+        if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */
+        if(hx==0)
+            return(x);          /* cbrt(0) is itself */
+
+        SET_FLOAT_WORD(x,hx);   /* x <- |x| */
+    /* rough cbrt to 5 bits */
+        if(hx<0x00800000)               /* subnormal number */
+          {SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */
+           t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,high/3+B2);
+          }
+        else
+          SET_FLOAT_WORD(t,hx/3+B1);
+
+
+    /* new cbrt to 23 bits */
+        r=t*t/x;
+        s=C+r*t;
+        t*=G+F/(s+E+D/s);
+
+    /* retore the sign bit */
+        GET_FLOAT_WORD(high,t);
+        SET_FLOAT_WORD(t,high|sign);
+        return(t);
+}
diff --git a/src/math/s_ceil.c b/src/math/s_ceil.c
new file mode 100644
index 00000000..1670cade
--- /dev/null
+++ b/src/math/s_ceil.c
@@ -0,0 +1,68 @@
+/* @(#)s_ceil.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *      Bit twiddling.
+ * Exception:
+ *      Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+ceil(double x)
+{
+        int32_t i0,i1,j0;
+        uint32_t i,j;
+        EXTRACT_WORDS(i0,i1,x);
+        j0 = ((i0>>20)&0x7ff)-0x3ff;
+        if(j0<20) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+                    if(i0<0) {i0=0x80000000;i1=0;}
+                    else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+                }
+            } else {
+                i = (0x000fffff)>>j0;
+                if(((i0&i)|i1)==0) return x; /* x is integral */
+                if(huge+x>0.0) {        /* raise inexact flag */
+                    if(i0>0) i0 += (0x00100000)>>j0;
+                    i0 &= (~i); i1=0;
+                }
+            }
+        } else if (j0>51) {
+            if(j0==0x400) return x+x;   /* inf or NaN */
+            else return x;              /* x is integral */
+        } else {
+            i = ((uint32_t)(0xffffffff))>>(j0-20);
+            if((i1&i)==0) return x;     /* x is integral */
+            if(huge+x>0.0) {            /* raise inexact flag */
+                if(i0>0) {
+                    if(j0==20) i0+=1;
+                    else {
+                        j = i1 + (1<<(52-j0));
+                        if(j<i1) i0+=1; /* got a carry */
+                        i1 = j;
+                    }
+                }
+                i1 &= (~i);
+            }
+        }
+        INSERT_WORDS(x,i0,i1);
+        return x;
+}
diff --git a/src/math/s_ceilf.c b/src/math/s_ceilf.c
new file mode 100644
index 00000000..3615041f
--- /dev/null
+++ b/src/math/s_ceilf.c
@@ -0,0 +1,49 @@
+/* s_ceilf.c -- float version of s_ceil.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float huge = 1.0e30;
+
+float
+ceilf(float x)
+{
+        int32_t i0,j0;
+        uint32_t i;
+
+        GET_FLOAT_WORD(i0,x);
+        j0 = ((i0>>23)&0xff)-0x7f;
+        if(j0<23) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+                    if(i0<0) {i0=0x80000000;}
+                    else if(i0!=0) { i0=0x3f800000;}
+                }
+            } else {
+                i = (0x007fffff)>>j0;
+                if((i0&i)==0) return x; /* x is integral */
+                if(huge+x>(float)0.0) { /* raise inexact flag */
+                    if(i0>0) i0 += (0x00800000)>>j0;
+                    i0 &= (~i);
+                }
+            }
+        } else {
+            if(j0==0x80) return x+x;    /* inf or NaN */
+            else return x;              /* x is integral */
+        }
+        SET_FLOAT_WORD(x,i0);
+        return x;
+}
diff --git a/src/math/s_copysign.c b/src/math/s_copysign.c
new file mode 100644
index 00000000..59d3877c
--- /dev/null
+++ b/src/math/s_copysign.c
@@ -0,0 +1,30 @@
+/* @(#)s_copysign.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+copysign(double x, double y)
+{
+        uint32_t hx,hy;
+        GET_HIGH_WORD(hx,x);
+        GET_HIGH_WORD(hy,y);
+        SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+        return x;
+}
diff --git a/src/math/s_copysignf.c b/src/math/s_copysignf.c
new file mode 100644
index 00000000..d650e8e5
--- /dev/null
+++ b/src/math/s_copysignf.c
@@ -0,0 +1,33 @@
+/* s_copysignf.c -- float version of s_copysign.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * copysignf(float x, float y)
+ * copysignf(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+copysignf(float x, float y)
+{
+        uint32_t ix,iy;
+        GET_FLOAT_WORD(ix,x);
+        GET_FLOAT_WORD(iy,y);
+        SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
+        return x;
+}
diff --git a/src/math/s_cos.c b/src/math/s_cos.c
new file mode 100644
index 00000000..1893ab13
--- /dev/null
+++ b/src/math/s_cos.c
@@ -0,0 +1,74 @@
+/* @(#)s_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ *      __kernel_sin            ... sine function on [-pi/4,pi/4]
+ *      __kernel_cos            ... cosine function on [-pi/4,pi/4]
+ *      __ieee754_rem_pio2      ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+cos(double x)
+{
+        double y[2],z=0.0;
+        int32_t n, ix;
+
+    /* High word of x. */
+        GET_HIGH_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
+
+    /* cos(Inf or NaN) is NaN */
+        else if (ix>=0x7ff00000) return x-x;
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2(x,y);
+            switch(n&3) {
+                case 0: return  __kernel_cos(y[0],y[1]);
+                case 1: return -__kernel_sin(y[0],y[1],1);
+                case 2: return -__kernel_cos(y[0],y[1]);
+                default:
+                        return  __kernel_sin(y[0],y[1],1);
+            }
+        }
+}
diff --git a/src/math/s_cosf.c b/src/math/s_cosf.c
new file mode 100644
index 00000000..14b8e98b
--- /dev/null
+++ b/src/math/s_cosf.c
@@ -0,0 +1,47 @@
+/* s_cosf.c -- float version of s_cos.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one=1.0;
+
+float
+cosf(float x)
+{
+        float y[2],z=0.0;
+        int32_t n,ix;
+
+        GET_FLOAT_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
+
+    /* cos(Inf or NaN) is NaN */
+        else if (ix>=0x7f800000) return x-x;
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2f(x,y);
+            switch(n&3) {
+                case 0: return  __kernel_cosf(y[0],y[1]);
+                case 1: return -__kernel_sinf(y[0],y[1],1);
+                case 2: return -__kernel_cosf(y[0],y[1]);
+                default:
+                        return  __kernel_sinf(y[0],y[1],1);
+            }
+        }
+}
diff --git a/src/math/s_erf.c b/src/math/s_erf.c
new file mode 100644
index 00000000..e321feea
--- /dev/null
+++ b/src/math/s_erf.c
@@ -0,0 +1,298 @@
+/* @(#)s_erf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* double erf(double x)
+ * double erfc(double x)
+ *                           x
+ *                    2      |\
+ *     erf(x)  =  ---------  | exp(-t*t)dt
+ *                 sqrt(pi) \|
+ *                           0
+ *
+ *     erfc(x) =  1-erf(x)
+ *  Note that
+ *              erf(-x) = -erf(x)
+ *              erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ *      1. For |x| in [0, 0.84375]
+ *          erf(x)  = x + x*R(x^2)
+ *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]
+ *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]
+ *         where R = P/Q where P is an odd poly of degree 8 and
+ *         Q is an odd poly of degree 10.
+ *                                               -57.90
+ *                      | R - (erf(x)-x)/x | <= 2
+ *
+ *
+ *         Remark. The formula is derived by noting
+ *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ *         and that
+ *          2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ *         is close to one. The interval is chosen because the fix
+ *         point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ *         near 0.6174), and by some experiment, 0.84375 is chosen to
+ *         guarantee the error is less than one ulp for erf.
+ *
+ *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ *         c = 0.84506291151 rounded to single (24 bits)
+ *              erf(x)  = sign(x) * (c  + P1(s)/Q1(s))
+ *              erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0
+ *                        1+(c+P1(s)/Q1(s))    if x < 0
+ *              |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ *         Remark: here we use the taylor series expansion at x=1.
+ *              erf(1+s) = erf(1) + s*Poly(s)
+ *                       = 0.845.. + P1(s)/Q1(s)
+ *         That is, we use rational approximation to approximate
+ *                      erf(1+s) - (c = (single)0.84506291151)
+ *         Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *         where
+ *              P1(s) = degree 6 poly in s
+ *              Q1(s) = degree 6 poly in s
+ *
+ *      3. For x in [1.25,1/0.35(~2.857143)],
+ *              erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ *              erf(x)  = 1 - erfc(x)
+ *         where
+ *              R1(z) = degree 7 poly in z, (z=1/x^2)
+ *              S1(z) = degree 8 poly in z
+ *
+ *      4. For x in [1/0.35,28]
+ *              erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ *                      = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ *                      = 2.0 - tiny            (if x <= -6)
+ *              erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ *              erf(x)  = sign(x)*(1.0 - tiny)
+ *         where
+ *              R2(z) = degree 6 poly in z, (z=1/x^2)
+ *              S2(z) = degree 7 poly in z
+ *
+ *      Note1:
+ *         To compute exp(-x*x-0.5625+R/S), let s be a single
+ *         precision number and s := x; then
+ *              -x*x = -s*s + (s-x)*(s+x)
+ *              exp(-x*x-0.5626+R/S) =
+ *                      exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ *      Note2:
+ *         Here 4 and 5 make use of the asymptotic series
+ *                        exp(-x*x)
+ *              erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ *                        x*sqrt(pi)
+ *         We use rational approximation to approximate
+ *              g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ *         Here is the error bound for R1/S1 and R2/S2
+ *              |R1/S1 - f(x)|  < 2**(-62.57)
+ *              |R2/S2 - f(x)|  < 2**(-61.52)
+ *
+ *      5. For inf > x >= 28
+ *              erf(x)  = sign(x) *(1 - tiny)  (raise inexact)
+ *              erfc(x) = tiny*tiny (raise underflow) if x > 0
+ *                      = 2 - tiny if x<0
+ *
+ *      7. Special case:
+ *              erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,
+ *              erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ *              erfc/erf(NaN) is NaN
+ */
+
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+tiny        = 1e-300,
+half=  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+two =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+        /* c = (float)0.84506291151 */
+erx =  8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx =  1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
+efx8=  1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0  =  1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1  = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2  = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3  = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4  = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1  =  3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2  =  6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3  =  5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4  =  1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5  = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+pa0  = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1  =  4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2  = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3  =  3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4  = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5  =  3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6  = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1  =  1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2  =  5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3  =  7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4  =  1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5  =  1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6  =  1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1  = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2  = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3  = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4  = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5  = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6  = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7  = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1  =  1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2  =  1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3  =  4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4  =  6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5  =  4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6  =  1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7  =  6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8  = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1  = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2  = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3  = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4  = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5  = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6  = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1  =  3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2  =  3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3  =  1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4  =  3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5  =  2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6  =  4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7  = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+double
+erf(double x)
+{
+        int32_t hx,ix,i;
+        double R,S,P,Q,s,y,z,r;
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7ff00000) {            /* erf(nan)=nan */
+            i = ((uint32_t)hx>>31)<<1;
+            return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
+        }
+
+        if(ix < 0x3feb0000) {           /* |x|<0.84375 */
+            if(ix < 0x3e300000) {       /* |x|<2**-28 */
+                if (ix < 0x00800000)
+                    return 0.125*(8.0*x+efx8*x);  /*avoid underflow */
+                return x + efx*x;
+            }
+            z = x*x;
+            r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+            s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+            y = r/s;
+            return x + x*y;
+        }
+        if(ix < 0x3ff40000) {           /* 0.84375 <= |x| < 1.25 */
+            s = fabs(x)-one;
+            P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+            Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+            if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+        }
+        if (ix >= 0x40180000) {         /* inf>|x|>=6 */
+            if(hx>=0) return one-tiny; else return tiny-one;
+        }
+        x = fabs(x);
+        s = one/(x*x);
+        if(ix< 0x4006DB6E) {    /* |x| < 1/0.35 */
+            R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+                                ra5+s*(ra6+s*ra7))))));
+            S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+                                sa5+s*(sa6+s*(sa7+s*sa8)))))));
+        } else {        /* |x| >= 1/0.35 */
+            R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+                                rb5+s*rb6)))));
+            S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+                                sb5+s*(sb6+s*sb7))))));
+        }
+        z  = x;
+        SET_LOW_WORD(z,0);
+        r  =  exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
+        if(hx>=0) return one-r/x; else return  r/x-one;
+}
+
+double
+erfc(double x)
+{
+        int32_t hx,ix;
+        double R,S,P,Q,s,y,z,r;
+        GET_HIGH_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7ff00000) {                    /* erfc(nan)=nan */
+                                                /* erfc(+-inf)=0,2 */
+            return (double)(((uint32_t)hx>>31)<<1)+one/x;
+        }
+
+        if(ix < 0x3feb0000) {           /* |x|<0.84375 */
+            if(ix < 0x3c700000)         /* |x|<2**-56 */
+                return one-x;
+            z = x*x;
+            r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+            s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+            y = r/s;
+            if(hx < 0x3fd00000) {       /* x<1/4 */
+                return one-(x+x*y);
+            } else {
+                r = x*y;
+                r += (x-half);
+                return half - r ;
+            }
+        }
+        if(ix < 0x3ff40000) {           /* 0.84375 <= |x| < 1.25 */
+            s = fabs(x)-one;
+            P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+            Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+            if(hx>=0) {
+                z  = one-erx; return z - P/Q;
+            } else {
+                z = erx+P/Q; return one+z;
+            }
+        }
+        if (ix < 0x403c0000) {          /* |x|<28 */
+            x = fabs(x);
+            s = one/(x*x);
+            if(ix< 0x4006DB6D) {        /* |x| < 1/.35 ~ 2.857143*/
+                R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+                                ra5+s*(ra6+s*ra7))))));
+                S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+                                sa5+s*(sa6+s*(sa7+s*sa8)))))));
+            } else {                    /* |x| >= 1/.35 ~ 2.857143 */
+                if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
+                R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+                                rb5+s*rb6)))));
+                S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+                                sb5+s*(sb6+s*sb7))))));
+            }
+            z  = x;
+            SET_LOW_WORD(z,0);
+            r  =  exp(-z*z-0.5625)*
+                        exp((z-x)*(z+x)+R/S);
+            if(hx>0) return r/x; else return two-r/x;
+        } else {
+            if(hx>0) return tiny*tiny; else return two-tiny;
+        }
+}
diff --git a/src/math/s_erff.c b/src/math/s_erff.c
new file mode 100644
index 00000000..28e2f7b3
--- /dev/null
+++ b/src/math/s_erff.c
@@ -0,0 +1,207 @@
+/* s_erff.c -- float version of s_erf.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+tiny        = 1e-30,
+half=  5.0000000000e-01, /* 0x3F000000 */
+one =  1.0000000000e+00, /* 0x3F800000 */
+two =  2.0000000000e+00, /* 0x40000000 */
+        /* c = (subfloat)0.84506291151 */
+erx =  8.4506291151e-01, /* 0x3f58560b */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx =  1.2837916613e-01, /* 0x3e0375d4 */
+efx8=  1.0270333290e+00, /* 0x3f8375d4 */
+pp0  =  1.2837916613e-01, /* 0x3e0375d4 */
+pp1  = -3.2504209876e-01, /* 0xbea66beb */
+pp2  = -2.8481749818e-02, /* 0xbce9528f */
+pp3  = -5.7702702470e-03, /* 0xbbbd1489 */
+pp4  = -2.3763017452e-05, /* 0xb7c756b1 */
+qq1  =  3.9791721106e-01, /* 0x3ecbbbce */
+qq2  =  6.5022252500e-02, /* 0x3d852a63 */
+qq3  =  5.0813062117e-03, /* 0x3ba68116 */
+qq4  =  1.3249473704e-04, /* 0x390aee49 */
+qq5  = -3.9602282413e-06, /* 0xb684e21a */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+pa0  = -2.3621185683e-03, /* 0xbb1acdc6 */
+pa1  =  4.1485610604e-01, /* 0x3ed46805 */
+pa2  = -3.7220788002e-01, /* 0xbebe9208 */
+pa3  =  3.1834661961e-01, /* 0x3ea2fe54 */
+pa4  = -1.1089469492e-01, /* 0xbde31cc2 */
+pa5  =  3.5478305072e-02, /* 0x3d1151b3 */
+pa6  = -2.1663755178e-03, /* 0xbb0df9c0 */
+qa1  =  1.0642088205e-01, /* 0x3dd9f331 */
+qa2  =  5.4039794207e-01, /* 0x3f0a5785 */
+qa3  =  7.1828655899e-02, /* 0x3d931ae7 */
+qa4  =  1.2617121637e-01, /* 0x3e013307 */
+qa5  =  1.3637083583e-02, /* 0x3c5f6e13 */
+qa6  =  1.1984500103e-02, /* 0x3c445aa3 */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.8649440333e-03, /* 0xbc21a093 */
+ra1  = -6.9385856390e-01, /* 0xbf31a0b7 */
+ra2  = -1.0558626175e+01, /* 0xc128f022 */
+ra3  = -6.2375331879e+01, /* 0xc2798057 */
+ra4  = -1.6239666748e+02, /* 0xc322658c */
+ra5  = -1.8460508728e+02, /* 0xc3389ae7 */
+ra6  = -8.1287437439e+01, /* 0xc2a2932b */
+ra7  = -9.8143291473e+00, /* 0xc11d077e */
+sa1  =  1.9651271820e+01, /* 0x419d35ce */
+sa2  =  1.3765776062e+02, /* 0x4309a863 */
+sa3  =  4.3456588745e+02, /* 0x43d9486f */
+sa4  =  6.4538726807e+02, /* 0x442158c9 */
+sa5  =  4.2900814819e+02, /* 0x43d6810b */
+sa6  =  1.0863500214e+02, /* 0x42d9451f */
+sa7  =  6.5702495575e+00, /* 0x40d23f7c */
+sa8  = -6.0424413532e-02, /* 0xbd777f97 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.8649431020e-03, /* 0xbc21a092 */
+rb1  = -7.9928326607e-01, /* 0xbf4c9dd4 */
+rb2  = -1.7757955551e+01, /* 0xc18e104b */
+rb3  = -1.6063638306e+02, /* 0xc320a2ea */
+rb4  = -6.3756646729e+02, /* 0xc41f6441 */
+rb5  = -1.0250950928e+03, /* 0xc480230b */
+rb6  = -4.8351919556e+02, /* 0xc3f1c275 */
+sb1  =  3.0338060379e+01, /* 0x41f2b459 */
+sb2  =  3.2579251099e+02, /* 0x43a2e571 */
+sb3  =  1.5367296143e+03, /* 0x44c01759 */
+sb4  =  3.1998581543e+03, /* 0x4547fdbb */
+sb5  =  2.5530502930e+03, /* 0x451f90ce */
+sb6  =  4.7452853394e+02, /* 0x43ed43a7 */
+sb7  = -2.2440952301e+01; /* 0xc1b38712 */
+
+float
+erff(float x)
+{
+        int32_t hx,ix,i;
+        float R,S,P,Q,s,y,z,r;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7f800000) {            /* erf(nan)=nan */
+            i = ((uint32_t)hx>>31)<<1;
+            return (float)(1-i)+one/x;  /* erf(+-inf)=+-1 */
+        }
+
+        if(ix < 0x3f580000) {           /* |x|<0.84375 */
+            if(ix < 0x31800000) {       /* |x|<2**-28 */
+                if (ix < 0x04000000)
+                    /*avoid underflow */
+                    return (float)0.125*((float)8.0*x+efx8*x);
+                return x + efx*x;
+            }
+            z = x*x;
+            r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+            s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+            y = r/s;
+            return x + x*y;
+        }
+        if(ix < 0x3fa00000) {           /* 0.84375 <= |x| < 1.25 */
+            s = fabsf(x)-one;
+            P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+            Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+            if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+        }
+        if (ix >= 0x40c00000) {         /* inf>|x|>=6 */
+            if(hx>=0) return one-tiny; else return tiny-one;
+        }
+        x = fabsf(x);
+        s = one/(x*x);
+        if(ix< 0x4036DB6E) {    /* |x| < 1/0.35 */
+            R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+                                ra5+s*(ra6+s*ra7))))));
+            S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+                                sa5+s*(sa6+s*(sa7+s*sa8)))))));
+        } else {        /* |x| >= 1/0.35 */
+            R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+                                rb5+s*rb6)))));
+            S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+                                sb5+s*(sb6+s*sb7))))));
+        }
+        GET_FLOAT_WORD(ix,x);
+        SET_FLOAT_WORD(z,ix&0xfffff000);
+        r  =  expf(-z*z-(float)0.5625)*expf((z-x)*(z+x)+R/S);
+        if(hx>=0) return one-r/x; else return  r/x-one;
+}
+
+float
+erfcf(float x)
+{
+        int32_t hx,ix;
+        float R,S,P,Q,s,y,z,r;
+        GET_FLOAT_WORD(hx,x);
+        ix = hx&0x7fffffff;
+        if(ix>=0x7f800000) {                    /* erfc(nan)=nan */
+                                                /* erfc(+-inf)=0,2 */
+            return (float)(((uint32_t)hx>>31)<<1)+one/x;
+        }
+
+        if(ix < 0x3f580000) {           /* |x|<0.84375 */
+            if(ix < 0x23800000)         /* |x|<2**-56 */
+                return one-x;
+            z = x*x;
+            r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+            s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+            y = r/s;
+            if(hx < 0x3e800000) {       /* x<1/4 */
+                return one-(x+x*y);
+            } else {
+                r = x*y;
+                r += (x-half);
+                return half - r ;
+            }
+        }
+        if(ix < 0x3fa00000) {           /* 0.84375 <= |x| < 1.25 */
+            s = fabsf(x)-one;
+            P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+            Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+            if(hx>=0) {
+                z  = one-erx; return z - P/Q;
+            } else {
+                z = erx+P/Q; return one+z;
+            }
+        }
+        if (ix < 0x41e00000) {          /* |x|<28 */
+            x = fabsf(x);
+            s = one/(x*x);
+            if(ix< 0x4036DB6D) {        /* |x| < 1/.35 ~ 2.857143*/
+                R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+                                ra5+s*(ra6+s*ra7))))));
+                S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+                                sa5+s*(sa6+s*(sa7+s*sa8)))))));
+            } else {                    /* |x| >= 1/.35 ~ 2.857143 */
+                if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */
+                R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+                                rb5+s*rb6)))));
+                S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+                                sb5+s*(sb6+s*sb7))))));
+            }
+            GET_FLOAT_WORD(ix,x);
+            SET_FLOAT_WORD(z,ix&0xfffff000);
+            r  =  expf(-z*z-(float)0.5625)*
+                        expf((z-x)*(z+x)+R/S);
+            if(hx>0) return r/x; else return two-r/x;
+        } else {
+            if(hx>0) return tiny*tiny; else return two-tiny;
+        }
+}
diff --git a/src/math/s_expm1.c b/src/math/s_expm1.c
new file mode 100644
index 00000000..6f1f6675
--- /dev/null
+++ b/src/math/s_expm1.c
@@ -0,0 +1,217 @@
+/* @(#)s_expm1.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658
+ *
+ *      Here a correction term c will be computed to compensate
+ *      the error in r when rounded to a floating-point number.
+ *
+ *   2. Approximating expm1(r) by a special rational function on
+ *      the interval [0,0.34658]:
+ *      Since
+ *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ *      we define R1(r*r) by
+ *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ *      That is,
+ *          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ *                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ *                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ *      We use a special Reme algorithm on [0,0.347] to generate
+ *      a polynomial of degree 5 in r*r to approximate R1. The
+ *      maximum error of this polynomial approximation is bounded
+ *      by 2**-61. In other words,
+ *          R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ *      where   Q1  =  -1.6666666666666567384E-2,
+ *              Q2  =   3.9682539681370365873E-4,
+ *              Q3  =  -9.9206344733435987357E-6,
+ *              Q4  =   2.5051361420808517002E-7,
+ *              Q5  =  -6.2843505682382617102E-9;
+ *      (where z=r*r, and the values of Q1 to Q5 are listed below)
+ *      with error bounded by
+ *          |                  5           |     -61
+ *          | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2
+ *          |                              |
+ *
+ *      expm1(r) = exp(r)-1 is then computed by the following
+ *      specific way which minimize the accumulation rounding error:
+ *                             2     3
+ *                            r     r    [ 3 - (R1 + R1*r/2)  ]
+ *            expm1(r) = r + --- + --- * [--------------------]
+ *                            2     2    [ 6 - r*(3 - R1*r/2) ]
+ *
+ *      To compensate the error in the argument reduction, we use
+ *              expm1(r+c) = expm1(r) + c + expm1(r)*c
+ *                         ~ expm1(r) + c + r*c
+ *      Thus c+r*c will be added in as the correction terms for
+ *      expm1(r+c). Now rearrange the term to avoid optimization
+ *      screw up:
+ *                      (      2                                    2 )
+ *                      ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
+ *       expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ *                      ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
+ *                      (                                             )
+ *
+ *                 = r - E
+ *   3. Scale back to obtain expm1(x):
+ *      From step 1, we have
+ *         expm1(x) = either 2^k*[expm1(r)+1] - 1
+ *                  = or     2^k*[expm1(r) + (1-2^-k)]
+ *   4. Implementation notes:
+ *      (A). To save one multiplication, we scale the coefficient Qi
+ *           to Qi*2^i, and replace z by (x^2)/2.
+ *      (B). To achieve maximum accuracy, we compute expm1(x) by
+ *        (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ *        (ii)  if k=0, return r-E
+ *        (iii) if k=-1, return 0.5*(r-E)-0.5
+ *        (iv)  if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ *                     else          return  1.0+2.0*(r-E);
+ *        (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ *        (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ *        (vii) return 2^k(1-((E+2^-k)-r))
+ *
+ * Special cases:
+ *      expm1(INF) is INF, expm1(NaN) is NaN;
+ *      expm1(-INF) is -1, and
+ *      for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *      For IEEE double
+ *          if x >  7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+one             = 1.0,
+huge            = 1.0e+300,
+tiny            = 1.0e-300,
+o_threshold     = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
+ln2_hi          = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
+ln2_lo          = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
+invln2          = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
+        /* scaled coefficients related to expm1 */
+Q1  =  -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2  =   1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3  =  -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4  =   4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5  =  -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+double
+expm1(double x)
+{
+        double y,hi,lo,c=0.0,t,e,hxs,hfx,r1;
+        int32_t k,xsb;
+        uint32_t hx;
+
+        GET_HIGH_WORD(hx,x);
+        xsb = hx&0x80000000;            /* sign bit of x */
+        if(xsb==0) y=x; else y= -x;     /* y = |x| */
+        hx &= 0x7fffffff;               /* high word of |x| */
+
+    /* filter out huge and non-finite argument */
+        if(hx >= 0x4043687A) {                  /* if |x|>=56*ln2 */
+            if(hx >= 0x40862E42) {              /* if |x|>=709.78... */
+                if(hx>=0x7ff00000) {
+                    uint32_t low;
+                    GET_LOW_WORD(low,x);
+                    if(((hx&0xfffff)|low)!=0)
+                         return x+x;     /* NaN */
+                    else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+                }
+                if(x > o_threshold) return huge*huge; /* overflow */
+            }
+            if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
+                if(x+tiny<0.0)          /* raise inexact */
+                return tiny-one;        /* return -1 */
+            }
+        }
+
+    /* argument reduction */
+        if(hx > 0x3fd62e42) {           /* if  |x| > 0.5 ln2 */
+            if(hx < 0x3FF0A2B2) {       /* and |x| < 1.5 ln2 */
+                if(xsb==0)
+                    {hi = x - ln2_hi; lo =  ln2_lo;  k =  1;}
+                else
+                    {hi = x + ln2_hi; lo = -ln2_lo;  k = -1;}
+            } else {
+                k  = invln2*x+((xsb==0)?0.5:-0.5);
+                t  = k;
+                hi = x - t*ln2_hi;      /* t*ln2_hi is exact here */
+                lo = t*ln2_lo;
+            }
+            x  = hi - lo;
+            c  = (hi-x)-lo;
+        }
+        else if(hx < 0x3c900000) {      /* when |x|<2**-54, return x */
+            t = huge+x; /* return x with inexact flags when x!=0 */
+            return x - (t-(huge+x));
+        }
+        else k = 0;
+
+    /* x is now in primary range */
+        hfx = 0.5*x;
+        hxs = x*hfx;
+        r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+        t  = 3.0-r1*hfx;
+        e  = hxs*((r1-t)/(6.0 - x*t));
+        if(k==0) return x - (x*e-hxs);          /* c is 0 */
+        else {
+            e  = (x*(e-c)-c);
+            e -= hxs;
+            if(k== -1) return 0.5*(x-e)-0.5;
+            if(k==1) {
+                if(x < -0.25) return -2.0*(e-(x+0.5));
+                else          return  one+2.0*(x-e);
+            }
+            if (k <= -2 || k>56) {   /* suffice to return exp(x)-1 */
+                uint32_t high;
+                y = one-(e-x);
+                GET_HIGH_WORD(high,y);
+                SET_HIGH_WORD(y,high+(k<<20));  /* add k to y's exponent */
+                return y-one;
+            }
+            t = one;
+            if(k<20) {
+                uint32_t high;
+                SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k));  /* t=1-2^-k */
+                y = t-(e-x);
+                GET_HIGH_WORD(high,y);
+                SET_HIGH_WORD(y,high+(k<<20));  /* add k to y's exponent */
+           } else {
+                uint32_t high;
+                SET_HIGH_WORD(t,((0x3ff-k)<<20));       /* 2^-k */
+                y = x-(e+t);
+                y += one;
+                GET_HIGH_WORD(high,y);
+                SET_HIGH_WORD(y,high+(k<<20));  /* add k to y's exponent */
+            }
+        }
+        return y;
+}
diff --git a/src/math/s_expm1f.c b/src/math/s_expm1f.c
new file mode 100644
index 00000000..b22cf0f9
--- /dev/null
+++ b/src/math/s_expm1f.c
@@ -0,0 +1,122 @@
+/* s_expm1f.c -- float version of s_expm1.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+one             = 1.0,
+huge            = 1.0e+30,
+tiny            = 1.0e-30,
+o_threshold     = 8.8721679688e+01,/* 0x42b17180 */
+ln2_hi          = 6.9313812256e-01,/* 0x3f317180 */
+ln2_lo          = 9.0580006145e-06,/* 0x3717f7d1 */
+invln2          = 1.4426950216e+00,/* 0x3fb8aa3b */
+        /* scaled coefficients related to expm1 */
+Q1  =  -3.3333335072e-02, /* 0xbd088889 */
+Q2  =   1.5873016091e-03, /* 0x3ad00d01 */
+Q3  =  -7.9365076090e-05, /* 0xb8a670cd */
+Q4  =   4.0082177293e-06, /* 0x36867e54 */
+Q5  =  -2.0109921195e-07; /* 0xb457edbb */
+
+float
+expm1f(float x)
+{
+        float y,hi,lo,c=0.0,t,e,hxs,hfx,r1;
+        int32_t k,xsb;
+        uint32_t hx;
+
+        GET_FLOAT_WORD(hx,x);
+        xsb = hx&0x80000000;            /* sign bit of x */
+        if(xsb==0) y=x; else y= -x;     /* y = |x| */
+        hx &= 0x7fffffff;               /* high word of |x| */
+
+    /* filter out huge and non-finite argument */
+        if(hx >= 0x4195b844) {                  /* if |x|>=27*ln2 */
+            if(hx >= 0x42b17218) {              /* if |x|>=88.721... */
+                if(hx>0x7f800000)
+                    return x+x;          /* NaN */
+                if(hx==0x7f800000)
+                    return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+                if(x > o_threshold) return huge*huge; /* overflow */
+            }
+            if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
+                if(x+tiny<(float)0.0)   /* raise inexact */
+                return tiny-one;        /* return -1 */
+            }
+        }
+
+    /* argument reduction */
+        if(hx > 0x3eb17218) {           /* if  |x| > 0.5 ln2 */
+            if(hx < 0x3F851592) {       /* and |x| < 1.5 ln2 */
+                if(xsb==0)
+                    {hi = x - ln2_hi; lo =  ln2_lo;  k =  1;}
+                else
+                    {hi = x + ln2_hi; lo = -ln2_lo;  k = -1;}
+            } else {
+                k  = invln2*x+((xsb==0)?(float)0.5:(float)-0.5);
+                t  = k;
+                hi = x - t*ln2_hi;      /* t*ln2_hi is exact here */
+                lo = t*ln2_lo;
+            }
+            x  = hi - lo;
+            c  = (hi-x)-lo;
+        }
+        else if(hx < 0x33000000) {      /* when |x|<2**-25, return x */
+            t = huge+x; /* return x with inexact flags when x!=0 */
+            return x - (t-(huge+x));
+        }
+        else k = 0;
+
+    /* x is now in primary range */
+        hfx = (float)0.5*x;
+        hxs = x*hfx;
+        r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+        t  = (float)3.0-r1*hfx;
+        e  = hxs*((r1-t)/((float)6.0 - x*t));
+        if(k==0) return x - (x*e-hxs);          /* c is 0 */
+        else {
+            e  = (x*(e-c)-c);
+            e -= hxs;
+            if(k== -1) return (float)0.5*(x-e)-(float)0.5;
+            if(k==1) {
+                if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5));
+                else          return  one+(float)2.0*(x-e);
+            }
+            if (k <= -2 || k>56) {   /* suffice to return exp(x)-1 */
+                int32_t i;
+                y = one-(e-x);
+                GET_FLOAT_WORD(i,y);
+                SET_FLOAT_WORD(y,i+(k<<23));    /* add k to y's exponent */
+                return y-one;
+            }
+            t = one;
+            if(k<23) {
+                int32_t i;
+                SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */
+                y = t-(e-x);
+                GET_FLOAT_WORD(i,y);
+                SET_FLOAT_WORD(y,i+(k<<23));    /* add k to y's exponent */
+           } else {
+                int32_t i;
+                SET_FLOAT_WORD(t,((0x7f-k)<<23));       /* 2^-k */
+                y = x-(e+t);
+                y += one;
+                GET_FLOAT_WORD(i,y);
+                SET_FLOAT_WORD(y,i+(k<<23));    /* add k to y's exponent */
+            }
+        }
+        return y;
+}
diff --git a/src/math/s_fabs.c b/src/math/s_fabs.c
new file mode 100644
index 00000000..74433250
--- /dev/null
+++ b/src/math/s_fabs.c
@@ -0,0 +1,27 @@
+/* @(#)s_fabs.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+fabs(double x)
+{
+        uint32_t high;
+        GET_HIGH_WORD(high,x);
+        SET_HIGH_WORD(x,high&0x7fffffff);
+        return x;
+}
diff --git a/src/math/s_fabsf.c b/src/math/s_fabsf.c
new file mode 100644
index 00000000..655d57d8
--- /dev/null
+++ b/src/math/s_fabsf.c
@@ -0,0 +1,30 @@
+/* s_fabsf.c -- float version of s_fabs.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * fabsf(x) returns the absolute value of x.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+fabsf(float x)
+{
+        uint32_t ix;
+        GET_FLOAT_WORD(ix,x);
+        SET_FLOAT_WORD(x,ix&0x7fffffff);
+        return x;
+}
diff --git a/src/math/s_floor.c b/src/math/s_floor.c
new file mode 100644
index 00000000..273cf6f4
--- /dev/null
+++ b/src/math/s_floor.c
@@ -0,0 +1,69 @@
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *      Bit twiddling.
+ * Exception:
+ *      Inexact flag raised if x not equal to floor(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+floor(double x)
+{
+        int32_t i0,i1,j0;
+        uint32_t i,j;
+        EXTRACT_WORDS(i0,i1,x);
+        j0 = ((i0>>20)&0x7ff)-0x3ff;
+        if(j0<20) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+                    if(i0>=0) {i0=i1=0;}
+                    else if(((i0&0x7fffffff)|i1)!=0)
+                        { i0=0xbff00000;i1=0;}
+                }
+            } else {
+                i = (0x000fffff)>>j0;
+                if(((i0&i)|i1)==0) return x; /* x is integral */
+                if(huge+x>0.0) {        /* raise inexact flag */
+                    if(i0<0) i0 += (0x00100000)>>j0;
+                    i0 &= (~i); i1=0;
+                }
+            }
+        } else if (j0>51) {
+            if(j0==0x400) return x+x;   /* inf or NaN */
+            else return x;              /* x is integral */
+        } else {
+            i = ((uint32_t)(0xffffffff))>>(j0-20);
+            if((i1&i)==0) return x;     /* x is integral */
+            if(huge+x>0.0) {            /* raise inexact flag */
+                if(i0<0) {
+                    if(j0==20) i0+=1;
+                    else {
+                        j = i1+(1<<(52-j0));
+                        if(j<i1) i0 +=1 ;       /* got a carry */
+                        i1=j;
+                    }
+                }
+                i1 &= (~i);
+            }
+        }
+        INSERT_WORDS(x,i0,i1);
+        return x;
+}
diff --git a/src/math/s_floorf.c b/src/math/s_floorf.c
new file mode 100644
index 00000000..1164decc
--- /dev/null
+++ b/src/math/s_floorf.c
@@ -0,0 +1,58 @@
+/* s_floorf.c -- float version of s_floor.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * floorf(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *      Bit twiddling.
+ * Exception:
+ *      Inexact flag raised if x not equal to floorf(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float huge = 1.0e30;
+
+float
+floorf(float x)
+{
+        int32_t i0,j0;
+        uint32_t i;
+        GET_FLOAT_WORD(i0,x);
+        j0 = ((i0>>23)&0xff)-0x7f;
+        if(j0<23) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+                    if(i0>=0) {i0=0;}
+                    else if((i0&0x7fffffff)!=0)
+                        { i0=0xbf800000;}
+                }
+            } else {
+                i = (0x007fffff)>>j0;
+                if((i0&i)==0) return x; /* x is integral */
+                if(huge+x>(float)0.0) { /* raise inexact flag */
+                    if(i0<0) i0 += (0x00800000)>>j0;
+                    i0 &= (~i);
+                }
+            }
+        } else {
+            if(j0==0x80) return x+x;    /* inf or NaN */
+            else return x;              /* x is integral */
+        }
+        SET_FLOAT_WORD(x,i0);
+        return x;
+}
diff --git a/src/math/s_ilogb.c b/src/math/s_ilogb.c
new file mode 100644
index 00000000..f1ac498a
--- /dev/null
+++ b/src/math/s_ilogb.c
@@ -0,0 +1,45 @@
+/* @(#)s_ilogb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* ilogb(double x)
+ * return the binary exponent of non-zero x
+ * ilogb(0) = FP_ILOGB0
+ * ilogb(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogb(inf) = INT_MAX (no signal is raised)
+ */
+
+#include <limits.h>
+
+#include <math.h>
+#include "math_private.h"
+
+int ilogb(double x)
+{
+        int32_t hx,lx,ix;
+
+        EXTRACT_WORDS(hx,lx,x);
+        hx &= 0x7fffffff;
+        if(hx<0x00100000) {
+            if((hx|lx)==0)
+                return FP_ILOGB0;
+            else                        /* subnormal x */
+                if(hx==0) {
+                    for (ix = -1043; lx>0; lx<<=1) ix -=1;
+                } else {
+                    for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+                }
+            return ix;
+        }
+        else if (hx<0x7ff00000) return (hx>>20)-1023;
+        else if (hx>0x7ff00000 || lx!=0) return FP_ILOGBNAN;
+        else return INT_MAX;
+}
diff --git a/src/math/s_ilogbf.c b/src/math/s_ilogbf.c
new file mode 100644
index 00000000..30359fef
--- /dev/null
+++ b/src/math/s_ilogbf.c
@@ -0,0 +1,37 @@
+/* s_ilogbf.c -- float version of s_ilogb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <limits.h>
+
+#include <math.h>
+#include "math_private.h"
+
+int ilogbf(float x)
+{
+        int32_t hx,ix;
+
+        GET_FLOAT_WORD(hx,x);
+        hx &= 0x7fffffff;
+        if(hx<0x00800000) {
+            if(hx==0)
+                return FP_ILOGB0;
+            else                        /* subnormal x */
+                for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+            return ix;
+        }
+        else if (hx<0x7f800000) return (hx>>23)-127;
+        else if (hx>0x7f800000) return FP_ILOGBNAN;
+        else return INT_MAX;
+}
diff --git a/src/math/s_ldexp.c b/src/math/s_ldexp.c
new file mode 100644
index 00000000..f4d1cd6a
--- /dev/null
+++ b/src/math/s_ldexp.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+double ldexp(double x, int n)
+{
+	return scalbn(x, n);
+}
diff --git a/src/math/s_ldexpf.c b/src/math/s_ldexpf.c
new file mode 100644
index 00000000..3bad5f39
--- /dev/null
+++ b/src/math/s_ldexpf.c
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float ldexpf(float x, int n)
+{
+	return scalbnf(x, n);
+}
diff --git a/src/math/s_llrint.c b/src/math/s_llrint.c
new file mode 100644
index 00000000..2b1e00d0
--- /dev/null
+++ b/src/math/s_llrint.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+// FIXME: incorrect exception behavior
+
+long long llrint(double x)
+{
+	return rint(x);
+}
diff --git a/src/math/s_log1p.c b/src/math/s_log1p.c
new file mode 100644
index 00000000..886d5ab1
--- /dev/null
+++ b/src/math/s_log1p.c
@@ -0,0 +1,157 @@
+/* @(#)s_log1p.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* double log1p(double x)
+ *
+ * Method :
+ *   1. Argument Reduction: find k and f such that
+ *                      1+x = 2^k * (1+f),
+ *         where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *      Note. If k=0, then f=x is exact. However, if k!=0, then f
+ *      may not be representable exactly. In that case, a correction
+ *      term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+ *      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+ *      and add back the correction term c/u.
+ *      (Note: when x > 2**53, one can simply return log(x))
+ *
+ *   2. Approximation of log1p(f).
+ *      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *               = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *               = 2s + s*R
+ *      We use a special Reme algorithm on [0,0.1716] to generate
+ *      a polynomial of degree 14 to approximate R The maximum error
+ *      of this polynomial approximation is bounded by 2**-58.45. In
+ *      other words,
+ *                      2      4      6      8      10      12      14
+ *          R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
+ *      (the values of Lp1 to Lp7 are listed in the program)
+ *      and
+ *          |      2          14          |     -58.45
+ *          | Lp1*s +...+Lp7*s    -  R(z) | <= 2
+ *          |                             |
+ *      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ *      In order to guarantee error in log below 1ulp, we compute log
+ *      by
+ *              log1p(f) = f - (hfsq - s*(hfsq+R)).
+ *
+ *      3. Finally, log1p(x) = k*ln2 + log1p(f).
+ *                           = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ *         Here ln2 is split into two floating point number:
+ *                      ln2_hi + ln2_lo,
+ *         where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ *      log1p(x) is NaN with signal if x < -1 (including -INF) ;
+ *      log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+ *      log1p(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ *
+ * Note: Assuming log() return accurate answer, the following
+ *       algorithm can be used to compute log1p(x) to within a few ULP:
+ *
+ *              u = 1+x;
+ *              if(u==1.0) return x ; else
+ *                         return log(u)*(x/(u-1.0));
+ *
+ *       See HP-15C Advanced Functions Handbook, p.193.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+ln2_hi  =  6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo  =  1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+two54   =  1.80143985094819840000e+16,  /* 43500000 00000000 */
+Lp1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lp2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lp3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lp4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lp5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lp6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+static const double zero = 0.0;
+
+double
+log1p(double x)
+{
+        double hfsq,f=0,c=0,s,z,R,u;
+        int32_t k,hx,hu=0,ax;
+
+        GET_HIGH_WORD(hx,x);
+        ax = hx&0x7fffffff;
+
+        k = 1;
+        if (hx < 0x3FDA827A) {                  /* x < 0.41422  */
+            if(ax>=0x3ff00000) {                /* x <= -1.0 */
+                if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
+                else return (x-x)/(x-x);        /* log1p(x<-1)=NaN */
+            }
+            if(ax<0x3e200000) {                 /* |x| < 2**-29 */
+                if(two54+x>zero                 /* raise inexact */
+                    &&ax<0x3c900000)            /* |x| < 2**-54 */
+                    return x;
+                else
+                    return x - x*x*0.5;
+            }
+            if(hx>0||hx<=((int32_t)0xbfd2bec3)) {
+                k=0;f=x;hu=1;}  /* -0.2929<x<0.41422 */
+        }
+        if (hx >= 0x7ff00000) return x+x;
+        if(k!=0) {
+            if(hx<0x43400000) {
+                u  = 1.0+x;
+                GET_HIGH_WORD(hu,u);
+                k  = (hu>>20)-1023;
+                c  = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
+                c /= u;
+            } else {
+                u  = x;
+                GET_HIGH_WORD(hu,u);
+                k  = (hu>>20)-1023;
+                c  = 0;
+            }
+            hu &= 0x000fffff;
+            if(hu<0x6a09e) {
+                SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */
+            } else {
+                k += 1;
+                SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */
+                hu = (0x00100000-hu)>>2;
+            }
+            f = u-1.0;
+        }
+        hfsq=0.5*f*f;
+        if(hu==0) {     /* |f| < 2**-20 */
+            if(f==zero) { if(k==0) return zero;
+                          else {c += k*ln2_lo; return k*ln2_hi+c;} }
+            R = hfsq*(1.0-0.66666666666666666*f);
+            if(k==0) return f-R; else
+                     return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+        }
+        s = f/(2.0+f);
+        z = s*s;
+        R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+        if(k==0) return f-(hfsq-s*(hfsq+R)); else
+                 return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
diff --git a/src/math/s_log1pf.c b/src/math/s_log1pf.c
new file mode 100644
index 00000000..dcdd6bb3
--- /dev/null
+++ b/src/math/s_log1pf.c
@@ -0,0 +1,96 @@
+/* s_log1pf.c -- float version of s_log1p.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+ln2_hi =   6.9313812256e-01,    /* 0x3f317180 */
+ln2_lo =   9.0580006145e-06,    /* 0x3717f7d1 */
+two25 =    3.355443200e+07,     /* 0x4c000000 */
+Lp1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lp2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lp3 = 2.8571429849e-01, /* 3E924925 */
+Lp4 = 2.2222198546e-01, /* 3E638E29 */
+Lp5 = 1.8183572590e-01, /* 3E3A3325 */
+Lp6 = 1.5313838422e-01, /* 3E1CD04F */
+Lp7 = 1.4798198640e-01; /* 3E178897 */
+
+static const float zero = 0.0;
+
+float
+log1pf(float x)
+{
+        float hfsq,f=0,c=0,s,z,R,u;
+        int32_t k,hx,hu=0,ax;
+
+        GET_FLOAT_WORD(hx,x);
+        ax = hx&0x7fffffff;
+
+        k = 1;
+        if (hx < 0x3ed413d7) {                  /* x < 0.41422  */
+            if(ax>=0x3f800000) {                /* x <= -1.0 */
+                if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */
+                else return (x-x)/(x-x);        /* log1p(x<-1)=NaN */
+            }
+            if(ax<0x31000000) {                 /* |x| < 2**-29 */
+                if(two25+x>zero                 /* raise inexact */
+                    &&ax<0x24800000)            /* |x| < 2**-54 */
+                    return x;
+                else
+                    return x - x*x*(float)0.5;
+            }
+            if(hx>0||hx<=((int32_t)0xbe95f61f)) {
+                k=0;f=x;hu=1;}  /* -0.2929<x<0.41422 */
+        }
+        if (hx >= 0x7f800000) return x+x;
+        if(k!=0) {
+            if(hx<0x5a000000) {
+                u  = (float)1.0+x;
+                GET_FLOAT_WORD(hu,u);
+                k  = (hu>>23)-127;
+                /* correction term */
+                c  = (k>0)? (float)1.0-(u-x):x-(u-(float)1.0);
+                c /= u;
+            } else {
+                u  = x;
+                GET_FLOAT_WORD(hu,u);
+                k  = (hu>>23)-127;
+                c  = 0;
+            }
+            hu &= 0x007fffff;
+            if(hu<0x3504f7) {
+                SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */
+            } else {
+                k += 1;
+                SET_FLOAT_WORD(u,hu|0x3f000000);        /* normalize u/2 */
+                hu = (0x00800000-hu)>>2;
+            }
+            f = u-(float)1.0;
+        }
+        hfsq=(float)0.5*f*f;
+        if(hu==0) {     /* |f| < 2**-20 */
+            if(f==zero) { if(k==0) return zero;
+                          else {c += k*ln2_lo; return k*ln2_hi+c;} }
+            R = hfsq*((float)1.0-(float)0.66666666666666666*f);
+            if(k==0) return f-R; else
+                     return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+        }
+        s = f/((float)2.0+f);
+        z = s*s;
+        R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+        if(k==0) return f-(hfsq-s*(hfsq+R)); else
+                 return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
diff --git a/src/math/s_logb.c b/src/math/s_logb.c
new file mode 100644
index 00000000..be399c77
--- /dev/null
+++ b/src/math/s_logb.c
@@ -0,0 +1,34 @@
+/* @(#)s_logb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * double logb(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+logb(double x)
+{
+        int32_t lx,ix;
+        EXTRACT_WORDS(ix,lx,x);
+        ix &= 0x7fffffff;                       /* high |x| */
+        if((ix|lx)==0) return -1.0/fabs(x);
+        if(ix>=0x7ff00000) return x*x;
+        if((ix>>=20)==0)                        /* IEEE 754 logb */
+                return -1022.0;
+        else
+                return (double) (ix-1023);
+}
diff --git a/src/math/s_logbf.c b/src/math/s_logbf.c
new file mode 100644
index 00000000..747664d3
--- /dev/null
+++ b/src/math/s_logbf.c
@@ -0,0 +1,31 @@
+/* s_logbf.c -- float version of s_logb.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+logbf(float x)
+{
+        int32_t ix;
+        GET_FLOAT_WORD(ix,x);
+        ix &= 0x7fffffff;                       /* high |x| */
+        if(ix==0) return (float)-1.0/fabsf(x);
+        if(ix>=0x7f800000) return x*x;
+        if((ix>>=23)==0)                        /* IEEE 754 logb */
+                return -126.0;
+        else
+                return (float) (ix-127);
+}
diff --git a/src/math/s_lrint.c b/src/math/s_lrint.c
new file mode 100644
index 00000000..da8e1989
--- /dev/null
+++ b/src/math/s_lrint.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+// FIXME: incorrect exception behavior
+
+long lrint(double x)
+{
+	return rint(x);
+}
diff --git a/src/math/s_lrintf.c b/src/math/s_lrintf.c
new file mode 100644
index 00000000..d0b469b9
--- /dev/null
+++ b/src/math/s_lrintf.c
@@ -0,0 +1,8 @@
+#include <math.h>
+
+// FIXME: incorrect exception behavior
+
+long lrintf(float x)
+{
+	return rintf(x);
+}
diff --git a/src/math/s_modf.c b/src/math/s_modf.c
new file mode 100644
index 00000000..a5528d6b
--- /dev/null
+++ b/src/math/s_modf.c
@@ -0,0 +1,71 @@
+/* @(#)s_modf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * modf(double x, double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ *      Bit twiddling.
+ *
+ * Exception:
+ *      No exception.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one = 1.0;
+
+double
+modf(double x, double *iptr)
+{
+        int32_t i0,i1,j0;
+        uint32_t i;
+        EXTRACT_WORDS(i0,i1,x);
+        j0 = ((i0>>20)&0x7ff)-0x3ff;    /* exponent of x */
+        if(j0<20) {                     /* integer part in high x */
+            if(j0<0) {                  /* |x|<1 */
+                INSERT_WORDS(*iptr,i0&0x80000000,0);    /* *iptr = +-0 */
+                return x;
+            } else {
+                i = (0x000fffff)>>j0;
+                if(((i0&i)|i1)==0) {            /* x is integral */
+                    uint32_t high;
+                    *iptr = x;
+                    GET_HIGH_WORD(high,x);
+                    INSERT_WORDS(x,high&0x80000000,0);  /* return +-0 */
+                    return x;
+                } else {
+                    INSERT_WORDS(*iptr,i0&(~i),0);
+                    return x - *iptr;
+                }
+            }
+        } else if (j0>51) {             /* no fraction part */
+            uint32_t high;
+            *iptr = x*one;
+            GET_HIGH_WORD(high,x);
+            INSERT_WORDS(x,high&0x80000000,0);  /* return +-0 */
+            return x;
+        } else {                        /* fraction part in low x */
+            i = ((uint32_t)(0xffffffff))>>(j0-20);
+            if((i1&i)==0) {             /* x is integral */
+                uint32_t high;
+                *iptr = x;
+                GET_HIGH_WORD(high,x);
+                INSERT_WORDS(x,high&0x80000000,0);      /* return +-0 */
+                return x;
+            } else {
+                INSERT_WORDS(*iptr,i0,i1&(~i));
+                return x - *iptr;
+            }
+        }
+}
diff --git a/src/math/s_modff.c b/src/math/s_modff.c
new file mode 100644
index 00000000..de4dfd25
--- /dev/null
+++ b/src/math/s_modff.c
@@ -0,0 +1,52 @@
+/* s_modff.c -- float version of s_modf.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one = 1.0;
+
+float
+modff(float x, float *iptr)
+{
+        int32_t i0,j0;
+        uint32_t i;
+        GET_FLOAT_WORD(i0,x);
+        j0 = ((i0>>23)&0xff)-0x7f;      /* exponent of x */
+        if(j0<23) {                     /* integer part in x */
+            if(j0<0) {                  /* |x|<1 */
+                SET_FLOAT_WORD(*iptr,i0&0x80000000);    /* *iptr = +-0 */
+                return x;
+            } else {
+                i = (0x007fffff)>>j0;
+                if((i0&i)==0) {                 /* x is integral */
+                    uint32_t ix;
+                    *iptr = x;
+                    GET_FLOAT_WORD(ix,x);
+                    SET_FLOAT_WORD(x,ix&0x80000000);    /* return +-0 */
+                    return x;
+                } else {
+                    SET_FLOAT_WORD(*iptr,i0&(~i));
+                    return x - *iptr;
+                }
+            }
+        } else {                        /* no fraction part */
+            uint32_t ix;
+            *iptr = x*one;
+            GET_FLOAT_WORD(ix,x);
+            SET_FLOAT_WORD(x,ix&0x80000000);    /* return +-0 */
+            return x;
+        }
+}
diff --git a/src/math/s_nextafter.c b/src/math/s_nextafter.c
new file mode 100644
index 00000000..46d298ec
--- /dev/null
+++ b/src/math/s_nextafter.c
@@ -0,0 +1,72 @@
+/* @(#)s_nextafter.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* IEEE functions
+ *      nextafter(x,y)
+ *      return the next machine floating-point number of x in the
+ *      direction toward y.
+ *   Special cases:
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+nextafter(double x, double y)
+{
+        volatile double t;
+        int32_t hx,hy,ix,iy;
+        uint32_t lx,ly;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hy,ly,y);
+        ix = hx&0x7fffffff;             /* |x| */
+        iy = hy&0x7fffffff;             /* |y| */
+
+        if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
+           ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
+           return x+y;
+        if(x==y) return y;              /* x=y, return y */
+        if((ix|lx)==0) {                        /* x == 0 */
+            INSERT_WORDS(x,hy&0x80000000,1);    /* return +-minsubnormal */
+            t = x*x;
+            if(t==x) return t; else return x;   /* raise underflow flag */
+        }
+        if(hx>=0) {                             /* x > 0 */
+            if(hx>hy||((hx==hy)&&(lx>ly))) {    /* x > y, x -= ulp */
+                if(lx==0) hx -= 1;
+                lx -= 1;
+            } else {                            /* x < y, x += ulp */
+                lx += 1;
+                if(lx==0) hx += 1;
+            }
+        } else {                                /* x < 0 */
+            if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
+                if(lx==0) hx -= 1;
+                lx -= 1;
+            } else {                            /* x > y, x += ulp */
+                lx += 1;
+                if(lx==0) hx += 1;
+            }
+        }
+        hy = hx&0x7ff00000;
+        if(hy>=0x7ff00000) return x+x;  /* overflow  */
+        if(hy<0x00100000) {             /* underflow */
+            t = x*x;
+            if(t!=x) {          /* raise underflow flag */
+                INSERT_WORDS(y,hx,lx);
+                return y;
+            }
+        }
+        INSERT_WORDS(x,hx,lx);
+        return x;
+}
diff --git a/src/math/s_nextafterf.c b/src/math/s_nextafterf.c
new file mode 100644
index 00000000..7ce08838
--- /dev/null
+++ b/src/math/s_nextafterf.c
@@ -0,0 +1,63 @@
+/* s_nextafterf.c -- float version of s_nextafter.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+nextafterf(float x, float y)
+{
+        volatile float t;
+        int32_t hx,hy,ix,iy;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hy,y);
+        ix = hx&0x7fffffff;             /* |x| */
+        iy = hy&0x7fffffff;             /* |y| */
+
+        if((ix>0x7f800000) ||   /* x is nan */
+           (iy>0x7f800000))     /* y is nan */
+           return x+y;
+        if(x==y) return y;              /* x=y, return y */
+        if(ix==0) {                             /* x == 0 */
+            SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
+            t = x*x;
+            if(t==x) return t; else return x;   /* raise underflow flag */
+        }
+        if(hx>=0) {                             /* x > 0 */
+            if(hx>hy) {                         /* x > y, x -= ulp */
+                hx -= 1;
+            } else {                            /* x < y, x += ulp */
+                hx += 1;
+            }
+        } else {                                /* x < 0 */
+            if(hy>=0||hx>hy){                   /* x < y, x -= ulp */
+                hx -= 1;
+            } else {                            /* x > y, x += ulp */
+                hx += 1;
+            }
+        }
+        hy = hx&0x7f800000;
+        if(hy>=0x7f800000) return x+x;  /* overflow  */
+        if(hy<0x00800000) {             /* underflow */
+            t = x*x;
+            if(t!=x) {          /* raise underflow flag */
+                SET_FLOAT_WORD(y,hx);
+                return y;
+            }
+        }
+        SET_FLOAT_WORD(x,hx);
+        return x;
+}
diff --git a/src/math/s_remquo.c b/src/math/s_remquo.c
new file mode 100644
index 00000000..1a2992d6
--- /dev/null
+++ b/src/math/s_remquo.c
@@ -0,0 +1,149 @@
+/* @(#)e_fmod.c 1.3 95/01/18 */
+/*-
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double Zero[] = {0.0, -0.0,};
+
+/*
+ * Return the IEEE remainder and set *quo to the last n bits of the
+ * quotient, rounded to the nearest integer.  We choose n=31 because
+ * we wind up computing all the integer bits of the quotient anyway as
+ * a side-effect of computing the remainder by the shift and subtract
+ * method.  In practice, this is far more bits than are needed to use
+ * remquo in reduction algorithms.
+ */
+double
+remquo(double x, double y, int *quo)
+{
+        int32_t n,hx,hy,hz,ix,iy,sx,i;
+        uint32_t lx,ly,lz,q,sxy;
+
+        EXTRACT_WORDS(hx,lx,x);
+        EXTRACT_WORDS(hy,ly,y);
+        sxy = (hx ^ hy) & 0x80000000;
+        sx = hx&0x80000000;             /* sign of x */
+        hx ^=sx;                /* |x| */
+        hy &= 0x7fffffff;       /* |y| */
+
+    /* purge off exception values */
+        if((hy|ly)==0||(hx>=0x7ff00000)||       /* y=0,or x not finite */
+          ((hy|((ly|-ly)>>31))>0x7ff00000))     /* or y is NaN */
+            return (x*y)/(x*y);
+        if(hx<=hy) {
+            if((hx<hy)||(lx<ly)) {
+                q = 0;
+                goto fixup;     /* |x|<|y| return x or x-y */
+            }
+            if(lx==ly) {
+                *quo = 1;
+                return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
+            }
+        }
+
+    /* determine ix = ilogb(x) */
+        if(hx<0x00100000) {     /* subnormal x */
+            if(hx==0) {
+                for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+            } else {
+                for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+            }
+        } else ix = (hx>>20)-1023;
+
+    /* determine iy = ilogb(y) */
+        if(hy<0x00100000) {     /* subnormal y */
+            if(hy==0) {
+                for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+            } else {
+                for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+            }
+        } else iy = (hy>>20)-1023;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+        if(ix >= -1022) 
+            hx = 0x00100000|(0x000fffff&hx);
+        else {          /* subnormal x, shift x to normal */
+            n = -1022-ix;
+            if(n<=31) {
+                hx = (hx<<n)|(lx>>(32-n));
+                lx <<= n;
+            } else {
+                hx = lx<<(n-32);
+                lx = 0;
+            }
+        }
+        if(iy >= -1022) 
+            hy = 0x00100000|(0x000fffff&hy);
+        else {          /* subnormal y, shift y to normal */
+            n = -1022-iy;
+            if(n<=31) {
+                hy = (hy<<n)|(ly>>(32-n));
+                ly <<= n;
+            } else {
+                hy = ly<<(n-32);
+                ly = 0;
+            }
+        }
+
+    /* fix point fmod */
+        n = ix - iy;
+        q = 0;
+        while(n--) {
+            hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+            if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+            else {hx = hz+hz+(lz>>31); lx = lz+lz; q++;}
+            q <<= 1;
+        }
+        hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+        if(hz>=0) {hx=hz;lx=lz;q++;}
+
+    /* convert back to floating value and restore the sign */
+        if((hx|lx)==0) {                        /* return sign(x)*0 */
+            *quo = (sxy ? -q : q);
+            return Zero[(uint32_t)sx>>31];
+        }
+        while(hx<0x00100000) {          /* normalize x */
+            hx = hx+hx+(lx>>31); lx = lx+lx;
+            iy -= 1;
+        }
+        if(iy>= -1022) {        /* normalize output */
+            hx = ((hx-0x00100000)|((iy+1023)<<20));
+        } else {                /* subnormal output */
+            n = -1022 - iy;
+            if(n<=20) {
+                lx = (lx>>n)|((uint32_t)hx<<(32-n));
+                hx >>= n;
+            } else if (n<=31) {
+                lx = (hx<<(32-n))|(lx>>n); hx = sx;
+            } else {
+                lx = hx>>(n-32); hx = sx;
+            }
+        }
+fixup:
+        INSERT_WORDS(x,hx,lx);
+        y = fabs(y);
+        if (y < 0x1p-1021) {
+            if (x+x>y || (x+x==y && (q & 1))) {
+                q++;
+                x-=y;
+            }
+        } else if (x>0.5*y || (x==0.5*y && (q & 1))) {
+            q++;
+            x-=y;
+        }
+        GET_HIGH_WORD(hx,x);
+        SET_HIGH_WORD(x,hx^sx);
+        q &= 0x7fffffff;
+        *quo = (sxy ? -q : q);
+        return x;
+}
diff --git a/src/math/s_remquof.c b/src/math/s_remquof.c
new file mode 100644
index 00000000..be2a561a
--- /dev/null
+++ b/src/math/s_remquof.c
@@ -0,0 +1,118 @@
+/* @(#)e_fmod.c 1.3 95/01/18 */
+/*-
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float Zero[] = {0.0, -0.0,};
+
+/*
+ * Return the IEEE remainder and set *quo to the last n bits of the
+ * quotient, rounded to the nearest integer.  We choose n=31 because
+ * we wind up computing all the integer bits of the quotient anyway as
+ * a side-effect of computing the remainder by the shift and subtract
+ * method.  In practice, this is far more bits than are needed to use
+ * remquo in reduction algorithms.
+ */
+float
+remquof(float x, float y, int *quo)
+{
+        int32_t n,hx,hy,hz,ix,iy,sx,i;
+        uint32_t q,sxy;
+
+        GET_FLOAT_WORD(hx,x);
+        GET_FLOAT_WORD(hy,y);
+        sxy = (hx ^ hy) & 0x80000000;
+        sx = hx&0x80000000;             /* sign of x */
+        hx ^=sx;                /* |x| */
+        hy &= 0x7fffffff;       /* |y| */
+
+    /* purge off exception values */
+        if(hy==0||hx>=0x7f800000||hy>0x7f800000) /* y=0,NaN;or x not finite */
+            return (x*y)/(x*y);
+        if(hx<hy) {
+            q = 0;
+            goto fixup; /* |x|<|y| return x or x-y */
+        } else if(hx==hy) {
+            *quo = 1;
+            return Zero[(uint32_t)sx>>31];     /* |x|=|y| return x*0*/
+        }
+
+    /* determine ix = ilogb(x) */
+        if(hx<0x00800000) {     /* subnormal x */
+            for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
+        } else ix = (hx>>23)-127;
+
+    /* determine iy = ilogb(y) */
+        if(hy<0x00800000) {     /* subnormal y */
+            for (iy = -126,i=(hy<<8); i>0; i<<=1) iy -=1;
+        } else iy = (hy>>23)-127;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+        if(ix >= -126)
+            hx = 0x00800000|(0x007fffff&hx);
+        else {          /* subnormal x, shift x to normal */
+            n = -126-ix;
+            hx <<= n;
+        }
+        if(iy >= -126)
+            hy = 0x00800000|(0x007fffff&hy);
+        else {          /* subnormal y, shift y to normal */
+            n = -126-iy;
+            hy <<= n;
+        }
+
+    /* fix point fmod */
+        n = ix - iy;
+        q = 0;
+        while(n--) {
+            hz=hx-hy;
+            if(hz<0) hx = hx << 1;
+            else {hx = hz << 1; q++;}
+            q <<= 1;
+        }
+        hz=hx-hy;
+        if(hz>=0) {hx=hz;q++;}
+
+    /* convert back to floating value and restore the sign */
+        if(hx==0) {                             /* return sign(x)*0 */
+            *quo = (sxy ? -q : q);
+            return Zero[(uint32_t)sx>>31];
+        }
+        while(hx<0x00800000) {          /* normalize x */
+            hx <<= 1;
+            iy -= 1;
+        }
+        if(iy>= -126) {         /* normalize output */
+            hx = ((hx-0x00800000)|((iy+127)<<23));
+        } else {                /* subnormal output */
+            n = -126 - iy;
+            hx >>= n;
+        }
+fixup:
+        SET_FLOAT_WORD(x,hx);
+        y = fabsf(y);
+        if (y < 0x1p-125f) {
+            if (x+x>y || (x+x==y && (q & 1))) {
+                q++;
+                x-=y;
+            }
+        } else if (x>0.5f*y || (x==0.5f*y && (q & 1))) {
+            q++;
+            x-=y;
+        }
+        GET_FLOAT_WORD(hx,x);
+        SET_FLOAT_WORD(x,hx^sx);
+        q &= 0x7fffffff;
+        *quo = (sxy ? -q : q);
+        return x;
+}
diff --git a/src/math/s_rint.c b/src/math/s_rint.c
new file mode 100644
index 00000000..aec7d3c9
--- /dev/null
+++ b/src/math/s_rint.c
@@ -0,0 +1,80 @@
+/* @(#)s_rint.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ *      Using floating addition.
+ * Exception:
+ *      Inexact flag raised if x not equal to rint(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+/*
+ * TWO23 is long double instead of double to avoid a bug in gcc.  Without
+ * this, gcc thinks that TWO23[sx]+x and w-TWO23[sx] already have double
+ * precision and doesn't clip them to double precision when they are
+ * assigned and returned.
+ */
+static const long double
+TWO52[2]={
+  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+double
+rint(double x)
+{
+        int32_t i0,j0,sx;
+        uint32_t i,i1;
+        double w,t;
+        EXTRACT_WORDS(i0,i1,x);
+        sx = (i0>>31)&1;
+        j0 = ((i0>>20)&0x7ff)-0x3ff;
+        if(j0<20) {
+            if(j0<0) {
+                if(((i0&0x7fffffff)|i1)==0) return x;
+                i1 |= (i0&0x0fffff);
+                i0 &= 0xfffe0000;
+                i0 |= ((i1|-i1)>>12)&0x80000;
+                SET_HIGH_WORD(x,i0);
+                w = TWO52[sx]+x;
+                t =  w-TWO52[sx];
+                GET_HIGH_WORD(i0,t);
+                SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+                return t;
+            } else {
+                i = (0x000fffff)>>j0;
+                if(((i0&i)|i1)==0) return x; /* x is integral */
+                i>>=1;
+                if(((i0&i)|i1)!=0) {
+                    if(j0==19) i1 = 0x40000000; else
+                    i0 = (i0&(~i))|((0x20000)>>j0);
+                }
+            }
+        } else if (j0>51) {
+            if(j0==0x400) return x+x;   /* inf or NaN */
+            else return x;              /* x is integral */
+        } else {
+            i = ((uint32_t)(0xffffffff))>>(j0-20);
+            if((i1&i)==0) return x;     /* x is integral */
+            i>>=1;
+            if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+        }
+        INSERT_WORDS(x,i0,i1);
+        w = TWO52[sx]+x;
+        return w-TWO52[sx];
+}
diff --git a/src/math/s_rintf.c b/src/math/s_rintf.c
new file mode 100644
index 00000000..c441870d
--- /dev/null
+++ b/src/math/s_rintf.c
@@ -0,0 +1,45 @@
+/* s_rintf.c -- float version of s_rint.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+TWO23[2]={
+  8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+float
+rintf(float x)
+{
+        int32_t i0,j0,sx;
+        volatile float w,t;     /* volatile works around gcc bug */
+        GET_FLOAT_WORD(i0,x);
+        sx = (i0>>31)&1;
+        j0 = ((i0>>23)&0xff)-0x7f;
+        if(j0<23) {
+            if(j0<0) {
+                if((i0&0x7fffffff)==0) return x;
+                w = TWO23[sx]+x;
+                t =  w-TWO23[sx];
+                return t;
+            }
+            w = TWO23[sx]+x;
+            return w-TWO23[sx];
+        }
+        if(j0==0x80) return x+x;        /* inf or NaN */
+        else return x;                  /* x is integral */
+}
diff --git a/src/math/s_round.c b/src/math/s_round.c
new file mode 100644
index 00000000..d5bea7a9
--- /dev/null
+++ b/src/math/s_round.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2003, Steven G. Kargl
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include <math.h>
+
+double
+round(double x)
+{
+	double t;
+
+	if (!isfinite(x))
+		return (x);
+
+	if (x >= 0.0) {
+		t = ceil(x);
+		if (t - x > 0.5)
+			t -= 1.0;
+		return (t);
+	} else {
+		t = ceil(-x);
+		if (t + x > 0.5)
+			t -= 1.0;
+		return (-t);
+	}
+}
diff --git a/src/math/s_roundf.c b/src/math/s_roundf.c
new file mode 100644
index 00000000..c4fc3e19
--- /dev/null
+++ b/src/math/s_roundf.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2003, Steven G. Kargl
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include <math.h>
+
+float
+roundf(float x)
+{
+	float t;
+
+	if (!isfinite(x))
+		return (x);
+
+	if (x >= 0.0) {
+		t = ceilf(x);
+		if (t - x > 0.5)
+			t -= 1.0;
+		return (t);
+	} else {
+		t = ceilf(-x);
+		if (t + x > 0.5)
+			t -= 1.0;
+		return (-t);
+	}
+}
diff --git a/src/math/s_scalbln.c b/src/math/s_scalbln.c
new file mode 100644
index 00000000..12b9391b
--- /dev/null
+++ b/src/math/s_scalbln.c
@@ -0,0 +1,61 @@
+/* @(#)s_scalbn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n  computed by  exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double
+two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge   = 1.0e+300,
+tiny   = 1.0e-300;
+
+double
+scalbln (double x, long n)
+{
+        int32_t k,hx,lx;
+        EXTRACT_WORDS(hx,lx,x);
+        k = (hx&0x7ff00000)>>20;                /* extract exponent */
+        if (k==0) {                             /* 0 or subnormal x */
+            if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+            x *= two54;
+            GET_HIGH_WORD(hx,x);
+            k = ((hx&0x7ff00000)>>20) - 54;
+            if (n< -50000) return tiny*x;       /*underflow*/
+            }
+        if (k==0x7ff) return x+x;               /* NaN or Inf */
+        k = k+n;
+        if (k >  0x7fe) return huge*copysign(huge,x); /* overflow  */
+        if (k > 0)                              /* normal result */
+            {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+        if (k <= -54) {
+            if (n > 50000)      /* in case integer overflow in n+k */
+                return huge*copysign(huge,x);   /*overflow*/
+            else return tiny*copysign(tiny,x);  /*underflow*/
+        }
+        k += 54;                                /* subnormal result */
+        SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+        return x*twom54;
+}
+
+double
+scalbn (double x, int n)
+{
+        return scalbln(x, n);
+}
diff --git a/src/math/s_scalblnf.c b/src/math/s_scalblnf.c
new file mode 100644
index 00000000..21e7641c
--- /dev/null
+++ b/src/math/s_scalblnf.c
@@ -0,0 +1,57 @@
+/* s_scalbnf.c -- float version of s_scalbn.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float
+two25   =  3.355443200e+07,     /* 0x4c000000 */
+twom25  =  2.9802322388e-08,    /* 0x33000000 */
+huge   = 1.0e+30,
+tiny   = 1.0e-30;
+
+float
+scalblnf (float x, long n)
+{
+        int32_t k,ix;
+        GET_FLOAT_WORD(ix,x);
+        k = (ix&0x7f800000)>>23;                /* extract exponent */
+        if (k==0) {                             /* 0 or subnormal x */
+            if ((ix&0x7fffffff)==0) return x; /* +-0 */
+            x *= two25;
+            GET_FLOAT_WORD(ix,x);
+            k = ((ix&0x7f800000)>>23) - 25;
+            if (n< -50000) return tiny*x;       /*underflow*/
+            }
+        if (k==0xff) return x+x;                /* NaN or Inf */
+        k = k+n;
+        if (k >  0xfe) return huge*copysignf(huge,x); /* overflow  */
+        if (k > 0)                              /* normal result */
+            {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
+        if (k <= -25) {
+            if (n > 50000)      /* in case integer overflow in n+k */
+                return huge*copysignf(huge,x);  /*overflow*/
+            else return tiny*copysignf(tiny,x); /*underflow*/
+        }
+        k += 25;                                /* subnormal result */
+        SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
+        return x*twom25;
+}
+
+float
+scalbnf (float x, int n)
+{
+        return scalblnf(x, n);
+}
diff --git a/src/math/s_sin.c b/src/math/s_sin.c
new file mode 100644
index 00000000..2a2774ed
--- /dev/null
+++ b/src/math/s_sin.c
@@ -0,0 +1,74 @@
+/* @(#)s_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ *      __kernel_sin            ... sine function on [-pi/4,pi/4]
+ *      __kernel_cos            ... cose function on [-pi/4,pi/4]
+ *      __ieee754_rem_pio2      ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+sin(double x)
+{
+        double y[2],z=0.0;
+        int32_t n, ix;
+
+    /* High word of x. */
+        GET_HIGH_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
+
+    /* sin(Inf or NaN) is NaN */
+        else if (ix>=0x7ff00000) return x-x;
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2(x,y);
+            switch(n&3) {
+                case 0: return  __kernel_sin(y[0],y[1],1);
+                case 1: return  __kernel_cos(y[0],y[1]);
+                case 2: return -__kernel_sin(y[0],y[1],1);
+                default:
+                        return -__kernel_cos(y[0],y[1]);
+            }
+        }
+}
diff --git a/src/math/s_sinf.c b/src/math/s_sinf.c
new file mode 100644
index 00000000..d2b8e806
--- /dev/null
+++ b/src/math/s_sinf.c
@@ -0,0 +1,45 @@
+/* s_sinf.c -- float version of s_sin.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+sinf(float x)
+{
+        float y[2],z=0.0;
+        int32_t n, ix;
+
+        GET_FLOAT_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
+
+    /* sin(Inf or NaN) is NaN */
+        else if (ix>=0x7f800000) return x-x;
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2f(x,y);
+            switch(n&3) {
+                case 0: return  __kernel_sinf(y[0],y[1],1);
+                case 1: return  __kernel_cosf(y[0],y[1]);
+                case 2: return -__kernel_sinf(y[0],y[1],1);
+                default:
+                        return -__kernel_cosf(y[0],y[1]);
+            }
+        }
+}
diff --git a/src/math/s_tan.c b/src/math/s_tan.c
new file mode 100644
index 00000000..3333cb3d
--- /dev/null
+++ b/src/math/s_tan.c
@@ -0,0 +1,68 @@
+/* @(#)s_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ *      __kernel_tan            ... tangent function on [-pi/4,pi/4]
+ *      __ieee754_rem_pio2      ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+double
+tan(double x)
+{
+        double y[2],z=0.0;
+        int32_t n, ix;
+
+    /* High word of x. */
+        GET_HIGH_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
+
+    /* tan(Inf or NaN) is NaN */
+        else if (ix>=0x7ff00000) return x-x;            /* NaN */
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2(x,y);
+            return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
+                                                        -1 -- n odd */
+        }
+}
diff --git a/src/math/s_tanf.c b/src/math/s_tanf.c
new file mode 100644
index 00000000..660dd9c3
--- /dev/null
+++ b/src/math/s_tanf.c
@@ -0,0 +1,40 @@
+/* s_tanf.c -- float version of s_tan.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+float
+tanf(float x)
+{
+        float y[2],z=0.0;
+        int32_t n, ix;
+
+        GET_FLOAT_WORD(ix,x);
+
+    /* |x| ~< pi/4 */
+        ix &= 0x7fffffff;
+        if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);
+
+    /* tan(Inf or NaN) is NaN */
+        else if (ix>=0x7f800000) return x-x;            /* NaN */
+
+    /* argument reduction needed */
+        else {
+            n = __ieee754_rem_pio2f(x,y);
+            return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
+                                                              -1 -- n odd */
+        }
+}
diff --git a/src/math/s_tanh.c b/src/math/s_tanh.c
new file mode 100644
index 00000000..78b8e849
--- /dev/null
+++ b/src/math/s_tanh.c
@@ -0,0 +1,74 @@
+/* @(#)s_tanh.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ *                                     x    -x
+ *                                    e  - e
+ *      0. tanh(x) is defined to be -----------
+ *                                     x    -x
+ *                                    e  + e
+ *      1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ *      2.  0      <= x <= 2**-55 : tanh(x) := x*(one+x)
+ *                                              -t
+ *          2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
+ *                                             t + 2
+ *                                                   2
+ *          1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t=expm1(2x)
+ *                                                 t + 2
+ *          22.0   <  x <= INF    : tanh(x) := 1.
+ *
+ * Special cases:
+ *      tanh(NaN) is NaN;
+ *      only tanh(0)=0 is exact for finite argument.
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double one=1.0, two=2.0, tiny = 1.0e-300;
+
+double
+tanh(double x)
+{
+        double t,z;
+        int32_t jx,ix;
+
+    /* High word of |x|. */
+        GET_HIGH_WORD(jx,x);
+        ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7ff00000) {
+            if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
+            else       return one/x-one;    /* tanh(NaN) = NaN */
+        }
+
+    /* |x| < 22 */
+        if (ix < 0x40360000) {          /* |x|<22 */
+            if (ix<0x3c800000)          /* |x|<2**-55 */
+                return x*(one+x);       /* tanh(small) = small */
+            if (ix>=0x3ff00000) {       /* |x|>=1  */
+                t = expm1(two*fabs(x));
+                z = one - two/(t+two);
+            } else {
+                t = expm1(-two*fabs(x));
+                z= -t/(t+two);
+            }
+    /* |x| > 22, return +-1 */
+        } else {
+            z = one - tiny;             /* raised inexact flag */
+        }
+        return (jx>=0)? z: -z;
+}
diff --git a/src/math/s_tanhf.c b/src/math/s_tanhf.c
new file mode 100644
index 00000000..a0820409
--- /dev/null
+++ b/src/math/s_tanhf.c
@@ -0,0 +1,52 @@
+/* s_tanhf.c -- float version of s_tanh.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float one=1.0, two=2.0, tiny = 1.0e-30;
+
+float
+tanhf(float x)
+{
+        float t,z;
+        int32_t jx,ix;
+
+        GET_FLOAT_WORD(jx,x);
+        ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+        if(ix>=0x7f800000) {
+            if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
+            else       return one/x-one;    /* tanh(NaN) = NaN */
+        }
+
+    /* |x| < 22 */
+        if (ix < 0x41b00000) {          /* |x|<22 */
+            if (ix<0x24000000)          /* |x|<2**-55 */
+                return x*(one+x);       /* tanh(small) = small */
+            if (ix>=0x3f800000) {       /* |x|>=1  */
+                t = expm1f(two*fabsf(x));
+                z = one - two/(t+two);
+            } else {
+                t = expm1f(-two*fabsf(x));
+                z= -t/(t+two);
+            }
+    /* |x| > 22, return +-1 */
+        } else {
+            z = one - tiny;             /* raised inexact flag */
+        }
+        return (jx>=0)? z: -z;
+}
diff --git a/src/math/s_trunc.c b/src/math/s_trunc.c
new file mode 100644
index 00000000..02c65567
--- /dev/null
+++ b/src/math/s_trunc.c
@@ -0,0 +1,58 @@
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * trunc(x)
+ * Return x rounded toward 0 to integral value
+ * Method:
+ *      Bit twiddling.
+ * Exception:
+ *      Inexact flag raised if x not equal to trunc(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+trunc(double x)
+{
+        int32_t i0,i1,j0;
+        uint32_t i,j;
+        EXTRACT_WORDS(i0,i1,x);
+        j0 = ((i0>>20)&0x7ff)-0x3ff;
+        if(j0<20) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */
+                    i0 &= 0x80000000U;
+                    i1 = 0;
+                }
+            } else {
+                i = (0x000fffff)>>j0;
+                if(((i0&i)|i1)==0) return x; /* x is integral */
+                if(huge+x>0.0) {        /* raise inexact flag */
+                    i0 &= (~i); i1=0;
+                }
+            }
+        } else if (j0>51) {
+            if(j0==0x400) return x+x;   /* inf or NaN */
+            else return x;              /* x is integral */
+        } else {
+            i = ((uint32_t)(0xffffffff))>>(j0-20);
+            if((i1&i)==0) return x;     /* x is integral */
+            if(huge+x>0.0)              /* raise inexact flag */
+                i1 &= (~i);
+        }
+        INSERT_WORDS(x,i0,i1);
+        return x;
+}
diff --git a/src/math/s_truncf.c b/src/math/s_truncf.c
new file mode 100644
index 00000000..c253e62b
--- /dev/null
+++ b/src/math/s_truncf.c
@@ -0,0 +1,50 @@
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * truncf(x)
+ * Return x rounded toward 0 to integral value
+ * Method:
+ *      Bit twiddling.
+ * Exception:
+ *      Inexact flag raised if x not equal to truncf(x).
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+static const float huge = 1.0e30F;
+
+float
+truncf(float x)
+{
+        int32_t i0,j0;
+        uint32_t i;
+        GET_FLOAT_WORD(i0,x);
+        j0 = ((i0>>23)&0xff)-0x7f;
+        if(j0<23) {
+            if(j0<0) {  /* raise inexact if x != 0 */
+                if(huge+x>0.0F)         /* |x|<1, so return 0*sign(x) */
+                    i0 &= 0x80000000;
+            } else {
+                i = (0x007fffff)>>j0;
+                if((i0&i)==0) return x; /* x is integral */
+                if(huge+x>0.0F)         /* raise inexact flag */
+                    i0 &= (~i);
+            }
+        } else {
+            if(j0==0x80) return x+x;    /* inf or NaN */
+            else return x;              /* x is integral */
+        }
+        SET_FLOAT_WORD(x,i0);
+        return x;
+}
diff --git a/src/misc/basename.c b/src/misc/basename.c
new file mode 100644
index 00000000..c87e00cd
--- /dev/null
+++ b/src/misc/basename.c
@@ -0,0 +1,12 @@
+#include <string.h>
+#include <libgen.h>
+
+char *basename(char *s)
+{
+	size_t i;
+	if (!s || !*s) return ".";
+	i = strlen(s)-1;
+	for (; i&&s[i]=='/'; i--) s[i] = 0;
+	for (; i&&s[i-1]!='/'; i--);
+	return s+i;
+}
diff --git a/src/misc/bswap_32.c b/src/misc/bswap_32.c
new file mode 100644
index 00000000..a2418ca9
--- /dev/null
+++ b/src/misc/bswap_32.c
@@ -0,0 +1,7 @@
+#include <endian.h>
+#include <stdint.h>
+
+uint32_t bswap_32(uint32_t x)
+{
+	return x>>24 | x>>16&0xff00 | x<<16&0xff0000 | x<<24;
+}
diff --git a/src/misc/bswap_64.c b/src/misc/bswap_64.c
new file mode 100644
index 00000000..961300b5
--- /dev/null
+++ b/src/misc/bswap_64.c
@@ -0,0 +1,9 @@
+#include <endian.h>
+#include <stdint.h>
+
+uint32_t bswap_32(uint32_t);
+
+uint64_t bswap_64(uint64_t x)
+{
+	return bswap_32(x)+0LL<<32 | bswap_32(x>>32);
+}
diff --git a/src/misc/crypt.c b/src/misc/crypt.c
new file mode 100644
index 00000000..42918ef0
--- /dev/null
+++ b/src/misc/crypt.c
@@ -0,0 +1,2578 @@
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * 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. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <davidb@werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ *	B. Schneier, Applied Cryptography: protocols, algorithms,
+ *	and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author).  A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * ARCHITECTURE ASSUMPTIONS:
+ *	It is assumed that the 8-byte arrays passed by reference can be
+ *	addressed as arrays of uint32_t's (ie. the CPU is not picky about
+ *	alignment).
+ */
+
+#include <stdint.h>
+#include "libc.h"
+
+static int i64c(int i)
+{
+	i &= 0x3f;
+	if (i == 0)
+		return '.';
+	if (i == 1)
+		return '/';
+	if (i < 12)
+		return ('0' - 2 + i);
+	if (i < 38)
+		return ('A' - 12 + i);
+	return ('a' - 38 + i);
+}
+
+/* Generated by const_des_init() (removed) */
+
+static const uint8_t final_perm[64] = {
+	0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01, 0x3b, 0x33, 0x2b, 0x23, 0x1b, 0x13, 0x0b, 0x03,
+	0x3d, 0x35, 0x2d, 0x25, 0x1d, 0x15, 0x0d, 0x05, 0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f, 0x07,
+	0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00, 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02,
+	0x3c, 0x34, 0x2c, 0x24, 0x1c, 0x14, 0x0c, 0x04, 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16, 0x0e, 0x06,
+};
+static const uint8_t m_sbox[4][4096] = {
+	{
+		0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7,
+		0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee,
+		0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+		0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5,
+		0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1,
+		0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+		0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec,
+		0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9,
+		0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+		0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+		0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a,
+		0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+		0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+		0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02,
+		0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+		0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+		0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47,
+		0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+		0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a,
+		0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45,
+		0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+		0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42,
+		0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c,
+		0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+		0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7,
+		0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe,
+		0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+		0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5,
+		0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1,
+		0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+		0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc,
+		0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9,
+		0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+		0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde,
+		0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda,
+		0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+		0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1,
+		0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2,
+		0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+		0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9,
+		0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77,
+		0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+		0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+		0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75,
+		0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+		0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+		0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c,
+		0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+		0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17,
+		0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e,
+		0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+		0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15,
+		0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11,
+		0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+		0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c,
+		0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19,
+		0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47,
+		0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+		0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a,
+		0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45,
+		0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+		0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42,
+		0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c,
+		0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+		0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27,
+		0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+		0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a,
+		0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25,
+		0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+		0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22,
+		0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c,
+		0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+		0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7,
+		0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee,
+		0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+		0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5,
+		0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1,
+		0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+		0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec,
+		0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9,
+		0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7,
+		0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe,
+		0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+		0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5,
+		0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1,
+		0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+		0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc,
+		0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9,
+		0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27,
+		0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+		0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a,
+		0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25,
+		0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+		0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22,
+		0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c,
+		0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+		0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7,
+		0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe,
+		0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+		0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5,
+		0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1,
+		0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+		0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc,
+		0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9,
+		0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+		0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde,
+		0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda,
+		0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+		0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1,
+		0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2,
+		0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+		0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9,
+		0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+		0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+		0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a,
+		0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+		0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+		0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82,
+		0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+		0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+		0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17,
+		0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e,
+		0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+		0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15,
+		0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11,
+		0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+		0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c,
+		0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19,
+		0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37,
+		0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+		0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a,
+		0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35,
+		0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+		0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32,
+		0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c,
+		0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+		0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7,
+		0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae,
+		0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+		0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5,
+		0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1,
+		0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+		0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac,
+		0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9,
+		0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7,
+		0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae,
+		0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+		0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5,
+		0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1,
+		0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+		0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac,
+		0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9,
+		0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+		0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e,
+		0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a,
+		0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+		0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61,
+		0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62,
+		0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+		0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69,
+		0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+		0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e,
+		0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a,
+		0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+		0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61,
+		0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62,
+		0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+		0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69,
+		0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7,
+		0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+		0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca,
+		0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5,
+		0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+		0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2,
+		0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc,
+		0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+		0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7,
+		0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+		0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca,
+		0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5,
+		0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+		0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2,
+		0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc,
+		0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+		0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7,
+		0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe,
+		0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+		0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5,
+		0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1,
+		0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+		0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc,
+		0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9,
+		0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57,
+		0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e,
+		0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+		0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55,
+		0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51,
+		0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+		0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c,
+		0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59,
+		0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+		0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e,
+		0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a,
+		0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+		0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91,
+		0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92,
+		0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+		0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99,
+		0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+		0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e,
+		0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a,
+		0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+		0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91,
+		0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92,
+		0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+		0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99,
+		0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57,
+		0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e,
+		0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+		0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55,
+		0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51,
+		0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+		0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c,
+		0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59,
+		0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+		0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+		0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a,
+		0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+		0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+		0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02,
+		0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+		0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+		0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37,
+		0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+		0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a,
+		0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35,
+		0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+		0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32,
+		0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c,
+		0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+		0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77,
+		0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+		0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+		0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75,
+		0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+		0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+		0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c,
+		0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+		0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+		0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+		0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a,
+		0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+		0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+		0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82,
+		0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+		0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+		0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47,
+		0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+		0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a,
+		0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45,
+		0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+		0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42,
+		0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c,
+		0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+		0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7,
+		0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe,
+		0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+		0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5,
+		0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1,
+		0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+		0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc,
+		0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9,
+		0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17,
+		0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e,
+		0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+		0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15,
+		0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11,
+		0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+		0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c,
+		0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19,
+		0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7,
+		0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+		0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca,
+		0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5,
+		0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+		0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2,
+		0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc,
+		0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+		0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7,
+		0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee,
+		0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+		0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5,
+		0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1,
+		0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+		0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec,
+		0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9,
+		0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+		0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+		0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a,
+		0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+		0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+		0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82,
+		0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+		0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+		0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87,
+		0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e,
+		0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a,
+		0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85,
+		0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81,
+		0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82,
+		0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c,
+		0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89,
+		0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27,
+		0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+		0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a,
+		0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25,
+		0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+		0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22,
+		0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c,
+		0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+		0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+		0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde,
+		0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda,
+		0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+		0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1,
+		0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2,
+		0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+		0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9,
+		0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47,
+		0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e,
+		0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a,
+		0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45,
+		0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41,
+		0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42,
+		0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c,
+		0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49,
+		0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+		0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e,
+		0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a,
+		0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+		0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61,
+		0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62,
+		0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+		0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69,
+		0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+		0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e,
+		0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a,
+		0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+		0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91,
+		0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92,
+		0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+		0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99,
+		0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27,
+		0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e,
+		0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a,
+		0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25,
+		0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21,
+		0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22,
+		0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c,
+		0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29,
+		0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17,
+		0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e,
+		0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a,
+		0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15,
+		0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11,
+		0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12,
+		0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c,
+		0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19,
+		0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7,
+		0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe,
+		0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+		0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5,
+		0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1,
+		0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+		0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc,
+		0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9,
+		0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77,
+		0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+		0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+		0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75,
+		0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+		0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+		0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c,
+		0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+		0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7,
+		0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe,
+		0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa,
+		0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5,
+		0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1,
+		0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2,
+		0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc,
+		0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9,
+		0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57,
+		0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e,
+		0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+		0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55,
+		0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51,
+		0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+		0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c,
+		0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59,
+		0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7,
+		0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce,
+		0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca,
+		0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5,
+		0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1,
+		0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2,
+		0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc,
+		0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9,
+		0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7,
+		0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe,
+		0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba,
+		0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5,
+		0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1,
+		0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2,
+		0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc,
+		0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9,
+		0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97,
+		0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e,
+		0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a,
+		0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95,
+		0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91,
+		0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92,
+		0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c,
+		0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99,
+		0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37,
+		0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+		0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a,
+		0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35,
+		0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+		0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32,
+		0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c,
+		0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+		0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77,
+		0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e,
+		0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a,
+		0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75,
+		0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71,
+		0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72,
+		0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c,
+		0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79,
+		0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7,
+		0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee,
+		0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea,
+		0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5,
+		0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1,
+		0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2,
+		0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec,
+		0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9,
+		0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37,
+		0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e,
+		0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a,
+		0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35,
+		0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31,
+		0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32,
+		0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c,
+		0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39,
+		0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7,
+		0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae,
+		0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+		0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5,
+		0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1,
+		0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+		0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac,
+		0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9,
+		0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7,
+		0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae,
+		0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa,
+		0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5,
+		0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1,
+		0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2,
+		0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac,
+		0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9,
+		0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+		0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+		0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a,
+		0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+		0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+		0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02,
+		0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+		0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+		0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57,
+		0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e,
+		0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a,
+		0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55,
+		0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51,
+		0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52,
+		0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c,
+		0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59,
+		0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67,
+		0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e,
+		0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a,
+		0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65,
+		0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61,
+		0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62,
+		0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c,
+		0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69,
+		0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07,
+		0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e,
+		0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a,
+		0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05,
+		0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01,
+		0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02,
+		0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c,
+		0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09,
+		0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7,
+		0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde,
+		0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda,
+		0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5,
+		0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1,
+		0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2,
+		0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc,
+		0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9,
+	},{
+		0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5,
+		0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3,
+		0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+		0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9,
+		0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6,
+		0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+		0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab,
+		0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae,
+		0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+		0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3,
+		0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc,
+		0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+		0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6,
+		0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8,
+		0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+		0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde,
+		0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05,
+		0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+		0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c,
+		0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09,
+		0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+		0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08,
+		0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b,
+		0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+		0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75,
+		0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+		0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c,
+		0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79,
+		0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+		0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78,
+		0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b,
+		0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+		0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+		0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93,
+		0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c,
+		0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+		0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96,
+		0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98,
+		0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+		0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e,
+		0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05,
+		0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+		0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c,
+		0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09,
+		0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+		0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08,
+		0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b,
+		0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+		0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5,
+		0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+		0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+		0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9,
+		0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+		0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+		0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb,
+		0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+		0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+		0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93,
+		0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c,
+		0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+		0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96,
+		0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98,
+		0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+		0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e,
+		0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+		0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+		0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c,
+		0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+		0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+		0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68,
+		0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+		0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+		0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+		0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33,
+		0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c,
+		0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+		0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36,
+		0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38,
+		0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+		0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e,
+		0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+		0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33,
+		0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c,
+		0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+		0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36,
+		0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38,
+		0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+		0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e,
+		0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45,
+		0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+		0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c,
+		0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49,
+		0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+		0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48,
+		0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b,
+		0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+		0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5,
+		0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3,
+		0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+		0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9,
+		0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6,
+		0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+		0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb,
+		0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe,
+		0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+		0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+		0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c,
+		0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+		0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+		0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68,
+		0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+		0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+		0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55,
+		0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+		0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c,
+		0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59,
+		0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+		0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58,
+		0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b,
+		0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+		0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5,
+		0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3,
+		0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+		0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9,
+		0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6,
+		0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+		0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab,
+		0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae,
+		0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+		0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13,
+		0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c,
+		0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+		0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16,
+		0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18,
+		0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+		0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e,
+		0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+		0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23,
+		0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c,
+		0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+		0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26,
+		0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28,
+		0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+		0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e,
+		0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+		0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3,
+		0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc,
+		0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+		0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6,
+		0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8,
+		0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+		0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde,
+		0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+		0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83,
+		0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+		0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+		0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86,
+		0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+		0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+		0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e,
+		0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5,
+		0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3,
+		0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+		0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9,
+		0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6,
+		0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+		0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb,
+		0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce,
+		0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55,
+		0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+		0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c,
+		0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59,
+		0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+		0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58,
+		0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b,
+		0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+		0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75,
+		0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+		0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c,
+		0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79,
+		0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+		0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78,
+		0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b,
+		0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+		0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5,
+		0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+		0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+		0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9,
+		0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+		0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+		0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb,
+		0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+		0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5,
+		0xb0, 0xb6, 0xb6, 0xbf, 0xb9, 0xb0, 0xba, 0xb3,
+		0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+		0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9,
+		0xba, 0xb3, 0xb6, 0xbf, 0xb9, 0xb0, 0xb0, 0xb6,
+		0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+		0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb,
+		0xb5, 0xbc, 0xb2, 0xb7, 0xb8, 0xb2, 0xb4, 0xbe,
+		0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5,
+		0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3,
+		0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+		0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9,
+		0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6,
+		0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+		0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb,
+		0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce,
+		0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45,
+		0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+		0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c,
+		0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49,
+		0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+		0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48,
+		0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b,
+		0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+		0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5,
+		0xb0, 0xb6, 0xb6, 0xbf, 0xb9, 0xb0, 0xba, 0xb3,
+		0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+		0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9,
+		0xba, 0xb3, 0xb6, 0xbf, 0xb9, 0xb0, 0xb0, 0xb6,
+		0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+		0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb,
+		0xb5, 0xbc, 0xb2, 0xb7, 0xb8, 0xb2, 0xb4, 0xbe,
+		0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+		0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23,
+		0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c,
+		0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+		0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26,
+		0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28,
+		0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+		0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e,
+		0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5,
+		0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3,
+		0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+		0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9,
+		0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6,
+		0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+		0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb,
+		0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe,
+		0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+		0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83,
+		0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+		0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+		0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86,
+		0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+		0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+		0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e,
+		0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+		0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13,
+		0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c,
+		0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+		0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16,
+		0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18,
+		0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+		0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e,
+		0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+		0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3,
+		0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc,
+		0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+		0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6,
+		0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8,
+		0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+		0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde,
+		0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+		0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13,
+		0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c,
+		0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+		0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16,
+		0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18,
+		0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+		0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e,
+		0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+		0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+		0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c,
+		0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+		0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+		0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68,
+		0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+		0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+		0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5,
+		0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3,
+		0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+		0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9,
+		0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6,
+		0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+		0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab,
+		0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae,
+		0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45,
+		0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+		0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c,
+		0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49,
+		0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+		0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48,
+		0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b,
+		0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+		0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5,
+		0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3,
+		0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc,
+		0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9,
+		0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6,
+		0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8,
+		0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb,
+		0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde,
+		0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+		0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93,
+		0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c,
+		0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+		0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96,
+		0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98,
+		0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+		0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e,
+		0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05,
+		0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+		0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c,
+		0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09,
+		0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+		0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08,
+		0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b,
+		0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+		0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+		0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83,
+		0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+		0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+		0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86,
+		0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+		0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+		0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e,
+		0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65,
+		0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63,
+		0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c,
+		0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69,
+		0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66,
+		0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68,
+		0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b,
+		0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e,
+		0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5,
+		0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3,
+		0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+		0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9,
+		0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6,
+		0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+		0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb,
+		0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe,
+		0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95,
+		0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93,
+		0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c,
+		0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99,
+		0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96,
+		0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98,
+		0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b,
+		0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e,
+		0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+		0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33,
+		0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c,
+		0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+		0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36,
+		0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38,
+		0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+		0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e,
+		0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85,
+		0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83,
+		0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c,
+		0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89,
+		0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86,
+		0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88,
+		0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b,
+		0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e,
+		0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05,
+		0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03,
+		0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c,
+		0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09,
+		0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06,
+		0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08,
+		0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b,
+		0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e,
+		0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75,
+		0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+		0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c,
+		0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79,
+		0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+		0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78,
+		0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b,
+		0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+		0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5,
+		0xb0, 0xb6, 0xb6, 0xbf, 0xb9, 0xb0, 0xba, 0xb3,
+		0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+		0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9,
+		0xba, 0xb3, 0xb6, 0xbf, 0xb9, 0xb0, 0xb0, 0xb6,
+		0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+		0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb,
+		0xb5, 0xbc, 0xb2, 0xb7, 0xb8, 0xb2, 0xb4, 0xbe,
+		0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45,
+		0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43,
+		0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c,
+		0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49,
+		0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46,
+		0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48,
+		0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b,
+		0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e,
+		0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15,
+		0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13,
+		0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c,
+		0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19,
+		0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16,
+		0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18,
+		0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b,
+		0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e,
+		0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5,
+		0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3,
+		0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc,
+		0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9,
+		0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6,
+		0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8,
+		0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb,
+		0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe,
+		0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+		0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23,
+		0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c,
+		0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+		0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26,
+		0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28,
+		0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+		0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e,
+		0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5,
+		0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+		0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+		0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9,
+		0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+		0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+		0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb,
+		0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+		0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5,
+		0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3,
+		0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+		0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9,
+		0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6,
+		0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+		0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb,
+		0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce,
+		0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35,
+		0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33,
+		0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c,
+		0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39,
+		0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36,
+		0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38,
+		0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b,
+		0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e,
+		0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55,
+		0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+		0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c,
+		0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59,
+		0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+		0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58,
+		0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b,
+		0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+		0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5,
+		0xb0, 0xb6, 0xb6, 0xbf, 0xb9, 0xb0, 0xba, 0xb3,
+		0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc,
+		0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9,
+		0xba, 0xb3, 0xb6, 0xbf, 0xb9, 0xb0, 0xb0, 0xb6,
+		0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8,
+		0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb,
+		0xb5, 0xbc, 0xb2, 0xb7, 0xb8, 0xb2, 0xb4, 0xbe,
+		0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5,
+		0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3,
+		0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac,
+		0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9,
+		0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6,
+		0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8,
+		0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab,
+		0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae,
+		0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55,
+		0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53,
+		0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c,
+		0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59,
+		0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56,
+		0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58,
+		0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b,
+		0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e,
+		0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5,
+		0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3,
+		0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec,
+		0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9,
+		0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6,
+		0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8,
+		0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb,
+		0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee,
+		0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25,
+		0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23,
+		0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c,
+		0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29,
+		0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26,
+		0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28,
+		0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b,
+		0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e,
+		0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75,
+		0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73,
+		0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c,
+		0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79,
+		0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76,
+		0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78,
+		0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b,
+		0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e,
+		0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5,
+		0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3,
+		0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc,
+		0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9,
+		0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6,
+		0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8,
+		0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb,
+		0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce,
+	},{
+		0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22,
+		0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25,
+		0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+		0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28,
+		0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c,
+		0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+		0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27,
+		0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d,
+		0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+		0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5,
+		0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee,
+		0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+		0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec,
+		0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea,
+		0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+		0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed,
+		0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+		0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5,
+		0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce,
+		0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+		0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc,
+		0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca,
+		0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+		0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd,
+		0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2,
+		0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5,
+		0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+		0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8,
+		0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc,
+		0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+		0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7,
+		0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd,
+		0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42,
+		0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+		0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e,
+		0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48,
+		0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+		0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a,
+		0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47,
+		0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+		0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22,
+		0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25,
+		0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+		0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28,
+		0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c,
+		0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+		0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27,
+		0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d,
+		0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12,
+		0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15,
+		0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+		0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18,
+		0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c,
+		0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+		0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17,
+		0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d,
+		0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+		0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5,
+		0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce,
+		0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+		0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc,
+		0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca,
+		0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+		0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd,
+		0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72,
+		0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+		0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e,
+		0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78,
+		0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+		0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a,
+		0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77,
+		0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+		0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42,
+		0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+		0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e,
+		0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48,
+		0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+		0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a,
+		0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47,
+		0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+		0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+		0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5,
+		0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae,
+		0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+		0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac,
+		0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa,
+		0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+		0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad,
+		0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72,
+		0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+		0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e,
+		0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78,
+		0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+		0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a,
+		0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77,
+		0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+		0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2,
+		0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5,
+		0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+		0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8,
+		0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc,
+		0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+		0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7,
+		0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd,
+		0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2,
+		0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5,
+		0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+		0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8,
+		0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc,
+		0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+		0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7,
+		0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd,
+		0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+		0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+		0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e,
+		0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+		0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+		0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a,
+		0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+		0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+		0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12,
+		0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15,
+		0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+		0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18,
+		0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c,
+		0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+		0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17,
+		0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d,
+		0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+		0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+		0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e,
+		0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+		0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+		0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a,
+		0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+		0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+		0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52,
+		0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55,
+		0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+		0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58,
+		0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c,
+		0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+		0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57,
+		0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d,
+		0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52,
+		0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55,
+		0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+		0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58,
+		0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c,
+		0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+		0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57,
+		0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d,
+		0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02,
+		0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+		0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e,
+		0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08,
+		0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+		0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a,
+		0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07,
+		0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+		0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+		0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35,
+		0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e,
+		0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+		0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c,
+		0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a,
+		0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+		0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d,
+		0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2,
+		0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5,
+		0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+		0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8,
+		0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc,
+		0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+		0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7,
+		0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd,
+		0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2,
+		0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5,
+		0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+		0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8,
+		0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc,
+		0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+		0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7,
+		0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd,
+		0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+		0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5,
+		0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae,
+		0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+		0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac,
+		0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa,
+		0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+		0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad,
+		0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2,
+		0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5,
+		0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+		0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8,
+		0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc,
+		0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+		0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7,
+		0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd,
+		0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+		0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35,
+		0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e,
+		0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+		0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c,
+		0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a,
+		0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+		0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d,
+		0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02,
+		0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+		0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e,
+		0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08,
+		0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+		0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a,
+		0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07,
+		0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+		0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92,
+		0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95,
+		0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+		0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98,
+		0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c,
+		0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+		0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97,
+		0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d,
+		0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+		0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5,
+		0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee,
+		0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+		0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec,
+		0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea,
+		0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+		0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed,
+		0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+		0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+		0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e,
+		0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+		0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+		0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a,
+		0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+		0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+		0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92,
+		0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95,
+		0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+		0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98,
+		0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c,
+		0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+		0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97,
+		0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d,
+		0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+		0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+		0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e,
+		0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+		0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+		0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a,
+		0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+		0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+		0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42,
+		0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+		0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e,
+		0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48,
+		0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+		0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a,
+		0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47,
+		0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+		0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2,
+		0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5,
+		0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+		0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8,
+		0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc,
+		0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+		0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7,
+		0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd,
+		0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22,
+		0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25,
+		0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+		0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28,
+		0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c,
+		0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+		0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27,
+		0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d,
+		0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+		0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+		0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e,
+		0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+		0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+		0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a,
+		0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+		0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+		0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12,
+		0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15,
+		0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+		0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18,
+		0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c,
+		0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+		0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17,
+		0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d,
+		0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+		0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5,
+		0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce,
+		0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+		0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc,
+		0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca,
+		0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+		0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd,
+		0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2,
+		0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5,
+		0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe,
+		0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8,
+		0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc,
+		0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba,
+		0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7,
+		0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd,
+		0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72,
+		0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+		0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e,
+		0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78,
+		0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+		0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a,
+		0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77,
+		0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+		0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+		0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5,
+		0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae,
+		0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+		0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac,
+		0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa,
+		0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+		0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad,
+		0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12,
+		0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15,
+		0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e,
+		0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18,
+		0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c,
+		0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a,
+		0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17,
+		0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d,
+		0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2,
+		0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5,
+		0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+		0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8,
+		0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc,
+		0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+		0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7,
+		0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd,
+		0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+		0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5,
+		0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee,
+		0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+		0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec,
+		0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea,
+		0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+		0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed,
+		0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72,
+		0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75,
+		0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e,
+		0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78,
+		0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c,
+		0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a,
+		0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77,
+		0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d,
+		0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22,
+		0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25,
+		0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e,
+		0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28,
+		0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c,
+		0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a,
+		0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27,
+		0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d,
+		0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82,
+		0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85,
+		0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e,
+		0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88,
+		0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c,
+		0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a,
+		0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87,
+		0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d,
+		0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2,
+		0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5,
+		0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde,
+		0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8,
+		0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc,
+		0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda,
+		0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7,
+		0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd,
+		0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2,
+		0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5,
+		0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+		0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8,
+		0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc,
+		0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+		0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7,
+		0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd,
+		0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+		0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+		0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e,
+		0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+		0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+		0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a,
+		0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+		0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+		0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92,
+		0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95,
+		0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+		0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98,
+		0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c,
+		0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+		0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97,
+		0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d,
+		0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2,
+		0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5,
+		0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe,
+		0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8,
+		0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc,
+		0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa,
+		0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7,
+		0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd,
+		0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2,
+		0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5,
+		0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce,
+		0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8,
+		0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc,
+		0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca,
+		0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7,
+		0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd,
+		0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02,
+		0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+		0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e,
+		0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08,
+		0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+		0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a,
+		0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07,
+		0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+		0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52,
+		0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55,
+		0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+		0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58,
+		0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c,
+		0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+		0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57,
+		0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d,
+		0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92,
+		0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95,
+		0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e,
+		0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98,
+		0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c,
+		0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a,
+		0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97,
+		0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d,
+		0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62,
+		0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65,
+		0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e,
+		0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68,
+		0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c,
+		0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a,
+		0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67,
+		0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d,
+		0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2,
+		0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5,
+		0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae,
+		0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8,
+		0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac,
+		0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa,
+		0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7,
+		0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad,
+		0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+		0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35,
+		0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e,
+		0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+		0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c,
+		0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a,
+		0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+		0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d,
+		0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42,
+		0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45,
+		0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e,
+		0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48,
+		0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c,
+		0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a,
+		0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47,
+		0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d,
+		0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02,
+		0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05,
+		0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e,
+		0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08,
+		0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c,
+		0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a,
+		0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07,
+		0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d,
+		0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52,
+		0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55,
+		0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e,
+		0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58,
+		0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c,
+		0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a,
+		0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57,
+		0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d,
+		0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2,
+		0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5,
+		0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee,
+		0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8,
+		0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec,
+		0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea,
+		0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7,
+		0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed,
+		0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32,
+		0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35,
+		0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e,
+		0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38,
+		0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c,
+		0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a,
+		0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37,
+		0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d,
+	},{
+		0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+		0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44,
+		0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+		0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+		0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47,
+		0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+		0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+		0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b,
+		0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+		0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+		0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb,
+		0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+		0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+		0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd,
+		0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+		0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+		0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8,
+		0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+		0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb,
+		0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2,
+		0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+		0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd,
+		0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0,
+		0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+		0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08,
+		0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+		0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b,
+		0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02,
+		0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+		0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d,
+		0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00,
+		0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+		0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+		0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+		0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b,
+		0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+		0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+		0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d,
+		0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+		0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+		0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8,
+		0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+		0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb,
+		0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2,
+		0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+		0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd,
+		0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0,
+		0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+		0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8,
+		0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4,
+		0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+		0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2,
+		0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7,
+		0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+		0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0,
+		0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb,
+		0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+		0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+		0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b,
+		0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+		0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+		0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d,
+		0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+		0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+		0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8,
+		0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+		0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb,
+		0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2,
+		0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+		0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd,
+		0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0,
+		0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+		0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+		0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44,
+		0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+		0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+		0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47,
+		0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+		0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+		0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b,
+		0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08,
+		0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+		0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b,
+		0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02,
+		0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+		0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d,
+		0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00,
+		0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+		0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98,
+		0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+		0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b,
+		0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92,
+		0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+		0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d,
+		0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90,
+		0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+		0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88,
+		0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84,
+		0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+		0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82,
+		0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87,
+		0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+		0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80,
+		0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b,
+		0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18,
+		0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+		0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b,
+		0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12,
+		0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+		0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d,
+		0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10,
+		0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+		0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+		0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+		0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb,
+		0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+		0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+		0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd,
+		0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+		0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+		0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8,
+		0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4,
+		0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+		0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2,
+		0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7,
+		0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+		0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0,
+		0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab,
+		0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+		0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34,
+		0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b,
+		0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+		0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37,
+		0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d,
+		0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+		0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b,
+		0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8,
+		0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4,
+		0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+		0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2,
+		0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7,
+		0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+		0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0,
+		0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb,
+		0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8,
+		0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4,
+		0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+		0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2,
+		0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7,
+		0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+		0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0,
+		0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb,
+		0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+		0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34,
+		0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b,
+		0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+		0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37,
+		0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d,
+		0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+		0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b,
+		0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98,
+		0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+		0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b,
+		0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92,
+		0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+		0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d,
+		0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90,
+		0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+		0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58,
+		0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54,
+		0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+		0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52,
+		0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57,
+		0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+		0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50,
+		0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b,
+		0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+		0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+		0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b,
+		0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+		0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+		0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d,
+		0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+		0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+		0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8,
+		0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4,
+		0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+		0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2,
+		0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7,
+		0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+		0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0,
+		0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb,
+		0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58,
+		0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54,
+		0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+		0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52,
+		0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57,
+		0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+		0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50,
+		0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b,
+		0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+		0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+		0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b,
+		0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+		0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+		0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d,
+		0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+		0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+		0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8,
+		0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4,
+		0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+		0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2,
+		0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7,
+		0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+		0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0,
+		0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab,
+		0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8,
+		0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+		0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb,
+		0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2,
+		0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+		0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd,
+		0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0,
+		0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+		0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+		0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64,
+		0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b,
+		0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+		0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67,
+		0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d,
+		0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+		0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b,
+		0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88,
+		0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84,
+		0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+		0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82,
+		0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87,
+		0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+		0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80,
+		0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b,
+		0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18,
+		0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+		0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b,
+		0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12,
+		0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+		0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d,
+		0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10,
+		0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+		0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+		0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64,
+		0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b,
+		0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+		0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67,
+		0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d,
+		0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+		0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b,
+		0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18,
+		0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+		0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b,
+		0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12,
+		0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+		0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d,
+		0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10,
+		0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+		0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+		0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64,
+		0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b,
+		0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+		0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67,
+		0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d,
+		0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+		0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b,
+		0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+		0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44,
+		0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+		0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+		0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47,
+		0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+		0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+		0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b,
+		0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8,
+		0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+		0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb,
+		0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2,
+		0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+		0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd,
+		0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0,
+		0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+		0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8,
+		0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4,
+		0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb,
+		0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2,
+		0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7,
+		0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd,
+		0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0,
+		0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb,
+		0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+		0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+		0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb,
+		0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+		0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+		0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd,
+		0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+		0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+		0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8,
+		0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4,
+		0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb,
+		0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2,
+		0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7,
+		0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd,
+		0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0,
+		0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb,
+		0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88,
+		0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84,
+		0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+		0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82,
+		0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87,
+		0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+		0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80,
+		0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b,
+		0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8,
+		0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4,
+		0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+		0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2,
+		0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7,
+		0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+		0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0,
+		0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb,
+		0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18,
+		0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14,
+		0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b,
+		0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12,
+		0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17,
+		0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d,
+		0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10,
+		0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b,
+		0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+		0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34,
+		0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b,
+		0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+		0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37,
+		0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d,
+		0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+		0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b,
+		0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48,
+		0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44,
+		0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b,
+		0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42,
+		0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47,
+		0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d,
+		0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40,
+		0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b,
+		0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+		0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+		0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b,
+		0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+		0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+		0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d,
+		0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+		0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+		0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8,
+		0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4,
+		0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+		0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2,
+		0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7,
+		0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+		0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0,
+		0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab,
+		0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8,
+		0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4,
+		0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+		0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2,
+		0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7,
+		0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+		0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0,
+		0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb,
+		0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78,
+		0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74,
+		0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b,
+		0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72,
+		0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77,
+		0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d,
+		0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70,
+		0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b,
+		0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8,
+		0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4,
+		0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab,
+		0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2,
+		0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7,
+		0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad,
+		0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0,
+		0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab,
+		0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98,
+		0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+		0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b,
+		0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92,
+		0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+		0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d,
+		0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90,
+		0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+		0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8,
+		0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+		0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb,
+		0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2,
+		0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+		0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd,
+		0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0,
+		0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+		0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58,
+		0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54,
+		0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+		0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52,
+		0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57,
+		0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+		0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50,
+		0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b,
+		0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68,
+		0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64,
+		0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b,
+		0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62,
+		0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67,
+		0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d,
+		0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60,
+		0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b,
+		0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08,
+		0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+		0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b,
+		0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02,
+		0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+		0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d,
+		0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00,
+		0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+		0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88,
+		0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84,
+		0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b,
+		0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82,
+		0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87,
+		0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d,
+		0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80,
+		0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b,
+		0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8,
+		0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4,
+		0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb,
+		0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2,
+		0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7,
+		0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd,
+		0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0,
+		0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb,
+		0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08,
+		0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04,
+		0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b,
+		0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02,
+		0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07,
+		0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d,
+		0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00,
+		0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b,
+		0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8,
+		0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4,
+		0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb,
+		0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2,
+		0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7,
+		0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed,
+		0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0,
+		0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb,
+		0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58,
+		0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54,
+		0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b,
+		0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52,
+		0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57,
+		0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d,
+		0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50,
+		0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b,
+		0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+		0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+		0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b,
+		0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+		0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+		0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d,
+		0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+		0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+		0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98,
+		0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94,
+		0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b,
+		0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92,
+		0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97,
+		0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d,
+		0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90,
+		0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b,
+		0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38,
+		0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34,
+		0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b,
+		0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32,
+		0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37,
+		0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d,
+		0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30,
+		0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b,
+		0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28,
+		0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24,
+		0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b,
+		0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22,
+		0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27,
+		0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d,
+		0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20,
+		0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b,
+		0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8,
+		0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4,
+		0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb,
+		0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2,
+		0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7,
+		0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd,
+		0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0,
+		0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb,
+	},
+};
+
+static const uint8_t key_perm[56] = {
+	57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
+	10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
+	63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
+	14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
+};
+
+static const uint8_t key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static const uint8_t comp_perm[48] = {
+	14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
+	23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
+	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+static const uint8_t pbox[32] = {
+	16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
+	 2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
+};
+
+static int
+ascii_to_bin(char ch)
+{
+	if (ch > 'z')
+		return 0;
+	if (ch >= 'a')
+		return (ch - 'a' + 38);
+	if (ch > 'Z')
+		return 0;
+	if (ch >= 'A')
+		return (ch - 'A' + 12);
+	if (ch > '9')
+		return 0;
+	if (ch >= '.')
+		return (ch - '.');
+	return 0;
+}
+
+
+
+struct des_ctx {
+	uint32_t saltbits; /* referenced 5 times */
+	uint8_t	un_pbox[32]; /* 2 times */
+	uint8_t	inv_comp_perm[56]; /* 3 times */
+	uint8_t	inv_key_perm[64]; /* 3 times */
+	uint32_t en_keysl[16], en_keysr[16]; /* 2 times each */
+	uint32_t fp_maskl[8][256], fp_maskr[8][256]; /* 9 times each */
+	uint32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; /* 9 times */
+	uint32_t comp_maskl[8][128], comp_maskr[8][128]; /* 9 times each */
+	uint32_t psbox[4][256]; /* 5 times */
+};
+#define D (*ctx)
+#define saltbits        (D.saltbits       )
+#define old_salt        (D.old_salt       )
+#define old_rawkey0     (D.old_rawkey0    )
+#define old_rawkey1     (D.old_rawkey1    )
+#define un_pbox         (D.un_pbox        )
+#define inv_comp_perm   (D.inv_comp_perm  )
+#define inv_key_perm    (D.inv_key_perm   )
+#define en_keysl        (D.en_keysl       )
+#define en_keysr        (D.en_keysr       )
+#define de_keysl        (D.de_keysl       )
+#define de_keysr        (D.de_keysr       )
+#define ip_maskl        (D.ip_maskl       )
+#define ip_maskr        (D.ip_maskr       )
+#define fp_maskl        (D.fp_maskl       )
+#define fp_maskr        (D.fp_maskr       )
+#define key_perm_maskl  (D.key_perm_maskl )
+#define key_perm_maskr  (D.key_perm_maskr )
+#define comp_maskl      (D.comp_maskl     )
+#define comp_maskr      (D.comp_maskr     )
+#define psbox           (D.psbox          )
+
+static struct des_ctx *des_init(struct des_ctx *ctx)
+{
+	int i, j, b, k, inbit, obit;
+	uint32_t p;
+
+	saltbits = 0;
+
+	/* Initialise the inverted key permutation. */
+	for (i = 0; i < 64; i++) {
+		inv_key_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key permutation and initialise the inverted key
+	 * compression permutation.
+	 */
+	for (i = 0; i < 56; i++) {
+		inv_key_perm[key_perm[i] - 1] = (uint8_t)i;
+		inv_comp_perm[i] = 255;
+	}
+
+	/* Invert the key compression permutation. */
+	for (i = 0; i < 48; i++) {
+		inv_comp_perm[comp_perm[i] - 1] = (uint8_t)i;
+	}
+
+	/*
+	 * Set up the OR-mask arrays for the initial and final permutations,
+	 * and for the key initial and compression permutations.
+	 */
+	for (k = 0; k < 8; k++) {
+		uint32_t il, ir;
+		uint32_t fl, fr;
+		for (i = 0; i < 256; i++) {
+			fl = 0;
+			fr = 0;
+			for (j = 0; j < 8; j++) {
+				inbit = 8 * k + j;
+				if (i & (0x80>>j)) {
+					obit = final_perm[inbit];
+					if (obit < 32)
+						fl |= 0x80000000UL >> obit;
+					else
+						fr |= 0x80000000UL >> obit-32;
+				}
+			}
+			fp_maskl[k][i] = fl;
+			fp_maskr[k][i] = fr;
+		}
+		for (i = 0; i < 128; i++) {
+			il = 0;
+			ir = 0;
+			for (j = 0; j < 7; j++) {
+				inbit = 8 * k + j;
+				if (i & (0x80 >> j + 1)) {
+					obit = inv_key_perm[inbit];
+					if (obit == 255)
+						continue;
+					if (obit < 28)
+						il |= 0x8000000UL >> obit;
+					else
+						ir |= 0x8000000UL >> obit-28;
+				}
+			}
+			key_perm_maskl[k][i] = il;
+			key_perm_maskr[k][i] = ir;
+			il = 0;
+			ir = 0;
+			for (j = 0; j < 7; j++) {
+				inbit = 7 * k + j;
+				if (i & (0x80 >> j + 1)) {
+					obit = inv_comp_perm[inbit];
+					if (obit == 255)
+						continue;
+					if (obit < 24)
+						il |= 0x800000UL >> obit;
+					else
+						ir |= 0x800000UL >> obit-24;
+				}
+			}
+			comp_maskl[k][i] = il;
+			comp_maskr[k][i] = ir;
+		}
+	}
+
+	/*
+	 * Invert the P-box permutation, and convert into OR-masks for
+	 * handling the output of the S-box arrays setup above.
+	 */
+	for (i = 0; i < 32; i++)
+		un_pbox[pbox[i] - 1] = (uint8_t)i;
+
+	for (b = 0; b < 4; b++) {
+		for (i = 0; i < 256; i++) {
+			p = 0;
+			for (j = 0; j < 8; j++) {
+				if (i & (0x80 >> j))
+					p |= 0x80000000>>un_pbox[8 * b + j];
+			}
+			psbox[b][i] = p;
+		}
+	}
+
+	return ctx;
+}
+
+
+static void setup_salt(struct des_ctx *ctx, uint32_t salt)
+{
+	uint32_t obit, saltbit;
+	int i;
+
+	saltbits = 0;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++) {
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+}
+
+static void des_setkey(struct des_ctx *ctx, const unsigned char *key)
+{
+	uint32_t k0, k1, rawkey0, rawkey1;
+	int shifts, round;
+
+	rawkey0 = key[0]<<24 | key[1]<<16 | key[2]<<8 | key[3];
+	rawkey1 = key[4]<<24 | key[5]<<16 | key[6]<<8 | key[7];
+
+	/*
+	 * Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = key_perm_maskl[0][rawkey0 >> 25]
+	   | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
+	   | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
+	   | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
+	   | key_perm_maskl[4][rawkey1 >> 25]
+	   | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
+	   | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
+	   | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
+	k1 = key_perm_maskr[0][rawkey0 >> 25]
+	   | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
+	   | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
+	   | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
+	   | key_perm_maskr[4][rawkey1 >> 25]
+	   | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
+	   | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
+	   | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
+	/*
+	 * Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++) {
+		uint32_t t0, t1;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
+				| comp_maskl[1][(t0 >> 14) & 0x7f]
+				| comp_maskl[2][(t0 >> 7) & 0x7f]
+				| comp_maskl[3][t0 & 0x7f]
+				| comp_maskl[4][(t1 >> 21) & 0x7f]
+				| comp_maskl[5][(t1 >> 14) & 0x7f]
+				| comp_maskl[6][(t1 >> 7) & 0x7f]
+				| comp_maskl[7][t1 & 0x7f];
+
+		en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
+				| comp_maskr[1][(t0 >> 14) & 0x7f]
+				| comp_maskr[2][(t0 >> 7) & 0x7f]
+				| comp_maskr[3][t0 & 0x7f]
+				| comp_maskr[4][(t1 >> 21) & 0x7f]
+				| comp_maskr[5][(t1 >> 14) & 0x7f]
+				| comp_maskr[6][(t1 >> 7) & 0x7f]
+				| comp_maskr[7][t1 & 0x7f];
+	}
+}
+
+
+static void do_des(struct des_ctx *ctx, uint32_t *l_out, uint32_t *r_out, int count)
+{
+	uint32_t l, r, *kl, *kr;
+	uint32_t f = f; /* silence gcc */
+	uint32_t r48l, r48r;
+	int round;
+
+	/* Do initial permutation (IP). */
+	l = r = 0;
+
+	do {
+		/* Do each round. */
+		kl = en_keysl;
+		kr = en_keysr;
+		round = 16;
+		do {
+			/* Expand R to 48 bits (simulate the E-box). */
+			r48l	= ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r	= ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+			/*
+			 * Do salting for crypt() and friends, and
+			 * XOR with the permuted key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+			/*
+			 * Do sbox lookups (which shrink it back to 32 bits)
+			 * and do the pbox permutation at the same time.
+			 */
+			f = psbox[0][m_sbox[0][r48l >> 12]]
+			  | psbox[1][m_sbox[1][r48l & 0xfff]]
+			  | psbox[2][m_sbox[2][r48r >> 12]]
+			  | psbox[3][m_sbox[3][r48r & 0xfff]];
+			/* Now that we've permuted things, complete f(). */
+			f ^= l;
+			l = r;
+			r = f;
+		} while (--round);
+		r = l;
+		l = f;
+	} while (--count);
+
+	/* Do final permutation (inverse of IP). */
+	*l_out	= fp_maskl[0][l >> 24]
+		| fp_maskl[1][(l >> 16) & 0xff]
+		| fp_maskl[2][(l >> 8) & 0xff]
+		| fp_maskl[3][l & 0xff]
+		| fp_maskl[4][r >> 24]
+		| fp_maskl[5][(r >> 16) & 0xff]
+		| fp_maskl[6][(r >> 8) & 0xff]
+		| fp_maskl[7][r & 0xff];
+	*r_out	= fp_maskr[0][l >> 24]
+		| fp_maskr[1][(l >> 16) & 0xff]
+		| fp_maskr[2][(l >> 8) & 0xff]
+		| fp_maskr[3][l & 0xff]
+		| fp_maskr[4][r >> 24]
+		| fp_maskr[5][(r >> 16) & 0xff]
+		| fp_maskr[6][(r >> 8) & 0xff]
+		| fp_maskr[7][r & 0xff];
+}
+
+#define DES_OUT_BUFSIZE 21
+
+static void
+to64_msb_first(char *s, unsigned v)
+{
+	*s++ = i64c(v >> 18); /* bits 23..18 */
+	*s++ = i64c(v >> 12); /* bits 17..12 */
+	*s++ = i64c(v >> 6); /* bits 11..6 */
+	*s   = i64c(v); /* bits 5..0 */
+}
+
+static char *
+des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE],
+		const unsigned char *key, const unsigned char *setting)
+{
+	uint32_t salt, r0, r1, keybuf[2];
+	uint8_t *q;
+
+	/*
+	 * Copy the key, shifting each character up by one bit
+	 * and padding with zeros.
+	 */
+	q = (uint8_t *)keybuf;
+	while (q - (uint8_t *)keybuf != 8) {
+		*q = *key << 1;
+		if (*q)
+			key++;
+		q++;
+	}
+	des_setkey(ctx, (char *)keybuf);
+
+	/*
+	 * setting - 2 bytes of salt
+	 * key - up to 8 characters
+	 */
+	salt = (ascii_to_bin(setting[1]) << 6)
+	     |  ascii_to_bin(setting[0]);
+
+	output[0] = setting[0];
+	/*
+	 * If the encrypted password that the salt was extracted from
+	 * is only 1 character long, the salt will be corrupted.  We
+	 * need to ensure that the output string doesn't have an extra
+	 * NUL in it!
+	 */
+	output[1] = setting[1] ? setting[1] : output[0];
+
+	setup_salt(ctx, salt);
+	/* Do it. */
+	do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */);
+
+	/* Now encode the result. */
+	/* Each call takes low-order 24 bits and stores 4 chars */
+	/* bits 31..8 of r0 */
+	to64_msb_first(output + 2, (r0 >> 8));
+	/* bits 7..0 of r0 and 31..16 of r1 */
+	to64_msb_first(output + 6, (r0 << 16) | (r1 >> 16));
+	/* bits 15..0 of r1 and two zero bits (plus extra zero byte) */
+	to64_msb_first(output + 10, (r1 << 8));
+	/* extra zero byte is encoded as '.', fixing it */
+	output[13] = '\0';
+
+	return output;
+}
+
+#undef C
+#undef init_perm
+#undef final_perm
+#undef m_sbox
+#undef D
+#undef const_ctx
+#undef saltbits
+#undef old_salt
+#undef old_rawkey0
+#undef old_rawkey1
+#undef un_pbox
+#undef inv_comp_perm
+#undef inv_key_perm
+#undef en_keysl
+#undef en_keysr
+#undef de_keysl
+#undef de_keysr
+#undef ip_maskl
+#undef ip_maskr
+#undef fp_maskl
+#undef fp_maskr
+#undef key_perm_maskl
+#undef key_perm_maskr
+#undef comp_maskl
+#undef comp_maskr
+#undef psbox
+
+struct crypt_data;
+
+char *__crypt_r(const char *clear, const char *salt, struct crypt_data *data)
+{
+	struct des_ctx des_ctx = { 0 };
+
+#if 0
+	/* MD5 or SHA? */
+	if (salt[0] == '$' && salt[1] && salt[2] == '$') {
+		if (salt[1] == '1')
+			return md5_crypt((char *)data, clear, salt);
+	}
+#endif
+
+	des_init(&des_ctx);
+	return des_crypt(&des_ctx, (char *)data, clear, salt);
+}
+
+weak_alias(__crypt_r, crypt_r);
+
+char *crypt(const char *clear, const char *salt)
+{
+	static char buf[128];
+	return __crypt_r(clear, salt, (void *)buf);
+}
diff --git a/src/misc/cuserid.c b/src/misc/cuserid.c
new file mode 100644
index 00000000..8ad0b9f3
--- /dev/null
+++ b/src/misc/cuserid.c
@@ -0,0 +1,13 @@
+#include <pwd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+char *cuserid(char *buf)
+{
+	struct passwd pw, *ppw;
+	long pwb[256];
+	if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw))
+		return 0;
+	snprintf(buf, L_cuserid, "%s", pw.pw_name);
+	return buf;
+}
diff --git a/src/misc/dirname.c b/src/misc/dirname.c
new file mode 100644
index 00000000..8f70dbb1
--- /dev/null
+++ b/src/misc/dirname.c
@@ -0,0 +1,15 @@
+#include <string.h>
+#include <libgen.h>
+
+char *dirname(char *s)
+{
+	size_t i;
+	if (!s || !*s || !strchr(s, '/')) return ".";
+	i = strlen(s)-1;
+	for (; i&&s[i]=='/'; i--);
+	for (; i&&s[i-1]!='/'; i--);
+	for (; i&&s[i-1]=='/'; i--);
+	if (!i && *s=='/') i++;
+	s[i] = 0;
+	return s;
+}
diff --git a/src/misc/ffs.c b/src/misc/ffs.c
new file mode 100644
index 00000000..2f7cb321
--- /dev/null
+++ b/src/misc/ffs.c
@@ -0,0 +1,9 @@
+#include <strings.h>
+
+int ffs(int i)
+{
+	unsigned int j = i;
+	for (i=1; j && !(j&1); j>>=1, i++);
+	if (j) return i;
+	return 0;
+}
diff --git a/src/misc/ftw.c b/src/misc/ftw.c
new file mode 100644
index 00000000..de01e39c
--- /dev/null
+++ b/src/misc/ftw.c
@@ -0,0 +1,9 @@
+#include <ftw.h>
+#include "libc.h"
+
+int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit)
+{
+	return nftw(path, (void *)fn, fd_limit, FTW_PHYS);
+}
+
+LFS64(ftw);
diff --git a/src/misc/getdomainname.c b/src/misc/getdomainname.c
new file mode 100644
index 00000000..7eb113d7
--- /dev/null
+++ b/src/misc/getdomainname.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <string.h>
+
+int getdomainname(char *name, size_t len)
+{
+	*name = 0;
+	return 0;
+}
diff --git a/src/misc/getgrouplist.c b/src/misc/getgrouplist.c
new file mode 100644
index 00000000..88f273d7
--- /dev/null
+++ b/src/misc/getgrouplist.c
@@ -0,0 +1,11 @@
+#include <grp.h>
+
+/* FIXME */
+
+int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
+{
+	if (*ngroups<1) return -1;
+	*groups = gid;
+	*ngroups = 1;
+	return 0;
+}
diff --git a/src/misc/getopt.c b/src/misc/getopt.c
new file mode 100644
index 00000000..abf0e847
--- /dev/null
+++ b/src/misc/getopt.c
@@ -0,0 +1,63 @@
+#include <unistd.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+
+char *optarg;
+int optind=1, opterr=1, optopt;
+static int optpos;
+
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
+		return -1;
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos) optpos++;
+	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optopt = c;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
+
+	if (d != c) {
+		if (optstring[0] != ':' && opterr) {
+			write(2, argv[0], strlen(argv[0]));
+			write(2, ": illegal option: ", 18);
+			write(2, optchar, k);
+			write(2, "\n", 1);
+		}
+		return '?';
+	}
+	if (optstring[i+1] == ':') {
+		if (optind >= argc) {
+			if (optstring[0] == ':') return ':';
+			if (opterr) {
+				write(2, argv[0], strlen(argv[0]));
+				write(2, ": option requires an argument: ", 31);
+				write(2, optchar, k);
+				write(2, "\n", 1);
+			}
+			return '?';
+		}
+		optarg = argv[optind++] + optpos;
+		optpos = 0;
+	}
+	return c;
+}
diff --git a/src/misc/getpriority.c b/src/misc/getpriority.c
new file mode 100644
index 00000000..2fb26b2b
--- /dev/null
+++ b/src/misc/getpriority.c
@@ -0,0 +1,9 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int getpriority(int which, id_t who)
+{
+	int ret = syscall2(__NR_getpriority, which, who);
+	if (ret < 0) return ret;
+	return 20-ret;
+}
diff --git a/src/misc/getrlimit.c b/src/misc/getrlimit.c
new file mode 100644
index 00000000..db25943b
--- /dev/null
+++ b/src/misc/getrlimit.c
@@ -0,0 +1,15 @@
+#include <sys/resource.h>
+#include "syscall.h"
+#include "libc.h"
+
+int getrlimit(int resource, struct rlimit *rlim)
+{
+	long k_rlim[2];
+	if (syscall2(__NR_ugetrlimit, resource, (long)k_rlim) < 0)
+		return -1;
+	rlim->rlim_cur = k_rlim[0];
+	rlim->rlim_max = k_rlim[1];
+	return 0;
+}
+
+LFS64(getrlimit);
diff --git a/src/misc/getrusage.c b/src/misc/getrusage.c
new file mode 100644
index 00000000..1b8850f9
--- /dev/null
+++ b/src/misc/getrusage.c
@@ -0,0 +1,20 @@
+#include <sys/resource.h>
+#include <string.h>
+#include "syscall.h"
+
+/* this is a huge hack to make up for the kernel's stupid 32bit time_t
+ * without having to recopy the whole rusage structure ourselves.. */
+
+int getrusage(int who, struct rusage *ru)
+{
+	struct { long tv_sec, tv_usec; } ktv[2];
+	char *fakeaddr = ((char *)ru + sizeof(struct timeval [2]) - sizeof ktv);
+	if (syscall2(__NR_getrusage, who, (long)fakeaddr) < 0)
+		return -1;
+	memcpy(ktv, fakeaddr, sizeof ktv);
+	ru->ru_utime.tv_sec  = ktv[0].tv_sec;
+	ru->ru_utime.tv_usec = ktv[0].tv_usec;
+	ru->ru_stime.tv_sec  = ktv[1].tv_sec;
+	ru->ru_stime.tv_usec = ktv[1].tv_usec;
+	return 0;
+}
diff --git a/src/misc/getsubopt.c b/src/misc/getsubopt.c
new file mode 100644
index 00000000..dac9bf9e
--- /dev/null
+++ b/src/misc/getsubopt.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include <string.h>
+
+int getsubopt(char **opt, char *const *keys, char **val)
+{
+	char *s = *opt;
+	int i;
+
+	*val = NULL;
+	*opt = strchr(s, ',');
+	if (*opt) *(*opt)++ = 0;
+	else *opt = s + strlen(s);
+
+	for (i=0; keys[i]; i++) {
+		size_t l = strlen(keys[i]);
+		if (strncmp(keys[i], s, l)) continue;
+		if (s[l] == '=')
+			*val = s + l;
+		else if (s[l]) continue;
+		return i;
+	}
+	return -1;
+}
diff --git a/src/misc/ioctl.c b/src/misc/ioctl.c
new file mode 100644
index 00000000..808b7c9c
--- /dev/null
+++ b/src/misc/ioctl.c
@@ -0,0 +1,13 @@
+#include <sys/ioctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int ioctl(int fd, int req, ...)
+{
+	void *arg;
+	va_list ap;
+	va_start(ap, req);
+	arg = va_arg(ap, void *);
+	va_end(ap);
+	return syscall3(__NR_ioctl, fd, req, (long)arg);
+}
diff --git a/src/misc/lockf.c b/src/misc/lockf.c
new file mode 100644
index 00000000..d8f82efd
--- /dev/null
+++ b/src/misc/lockf.c
@@ -0,0 +1,33 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "libc.h"
+
+int lockf(int fd, int op, off_t size)
+{
+	struct flock l = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_CUR,
+		.l_len = size,
+	};
+	switch (op) {
+	case F_TEST:
+		l.l_type = F_RDLCK;
+		if (fcntl(fd, F_GETLK, &l) < 0)
+			return -1;
+		if (l.l_type == F_UNLCK || l.l_pid == getpid())
+			return 0;
+		errno = EACCES;
+		return -1;
+	case F_ULOCK:
+		l.l_type = F_UNLCK;
+	case F_TLOCK:
+		return fcntl(fd, F_SETLK, &l);
+	case F_LOCK:
+		return fcntl(fd, F_SETLKW, &l);
+	}
+	errno = EINVAL;
+	return -1;
+}
+
+LFS64(lockf);
diff --git a/src/misc/nftw.c b/src/misc/nftw.c
new file mode 100644
index 00000000..1b94ac15
--- /dev/null
+++ b/src/misc/nftw.c
@@ -0,0 +1,121 @@
+#include <ftw.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include "libc.h"
+
+struct history
+{
+	struct history *chain;
+	dev_t dev;
+	ino_t ino;
+	int level;
+	int base;
+};
+
+#undef dirfd
+#define dirfd(d) (*(int *)d)
+
+static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h)
+{
+	size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l;
+	struct stat st;
+	struct history new;
+	int type;
+	int r;
+	struct FTW lev;
+	char *name;
+
+	if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
+		if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))
+			type = FTW_SLN;
+		else if (errno != EACCES) return -1;
+		else type = FTW_NS;
+	} else if (S_ISDIR(st.st_mode)) {
+		if (access(path, R_OK) < 0) type = FTW_DNR;
+		else if (flags & FTW_DEPTH) type = FTW_DP;
+		else type = FTW_D;
+	} else if (S_ISLNK(st.st_mode)) {
+		if (flags & FTW_PHYS) type = FTW_SL;
+		else type = FTW_SLN;
+	} else {
+		type = FTW_F;
+	}
+
+	if ((flags & FTW_MOUNT) && h
+	 && (st.st_dev != h->dev || st.st_ino != h->ino))
+		return 0;
+	
+	new.chain = h;
+	new.dev = st.st_dev;
+	new.ino = st.st_ino;
+	new.level = h ? h->level+1 : 0;
+	new.base = l+1;
+	
+	lev.level = new.level;
+	lev.base = h ? h->base : (name=strrchr(path, '/')) ? name-path : 0;
+
+	if (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	for (; h; h = h->chain)
+		if (h->dev == st.st_dev && h->ino == st.st_ino)
+			return 0;
+
+	if ((type == FTW_D || type == FTW_DP) && fd_limit) {
+		DIR *d = opendir(path);
+		if (d) {
+			struct dirent *de;
+			while ((de = readdir(d))) {
+				if (de->d_name[0] == '.'
+				 && (!de->d_name[1]
+				  || (de->d_name[1]=='.'
+				   && !de->d_name[2]))) continue;
+				if (strlen(de->d_name) >= PATH_MAX-l) {
+					errno = ENAMETOOLONG;
+					closedir(d);
+					return -1;
+				}
+				path[j]='/';
+				strcpy(path+j+1, de->d_name);
+				if ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {
+					closedir(d);
+					return r;
+				}
+			}
+			closedir(d);
+		} else if (errno != EACCES) {
+			return -1;
+		}
+	}
+
+	path[l] = 0;
+	if ((flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	return 0;
+}
+
+int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags)
+{
+	size_t l;
+	char pathbuf[PATH_MAX+1];
+
+	if (fd_limit <= 0) return 0;
+
+	l = strlen(path);
+	if (l > PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	memcpy(pathbuf, path, l+1);
+	
+	return do_nftw(pathbuf, fn, fd_limit, flags, NULL);
+}
+
+LFS64(nftw);
diff --git a/src/misc/openpty.c b/src/misc/openpty.c
new file mode 100644
index 00000000..0b4eb221
--- /dev/null
+++ b/src/misc/openpty.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pty.h>
+#include <stdio.h>
+
+/* Nonstandard, but vastly superior to the standard functions */
+
+int openpty(int *m, int *s, char *name, const struct termios *tio, const struct winsize *ws)
+{
+	int n=0;
+	char buf[20];
+
+	*m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
+	if (!*m) return -1;
+
+	if (ioctl(*m, TIOCSPTLCK, &n) || ioctl (*m, TIOCGPTN, &n)) {
+		close(*m);
+		return -1;
+	}
+
+	if (!name) name = buf;
+	snprintf(name, sizeof buf, "/dev/pts/%d", n);
+	if ((*s = open(name, O_RDWR|O_NOCTTY)) < 0) {
+		close(*m);
+		return -1;
+	}
+
+	if (tio) tcsetattr(*s, TCSANOW, tio);
+	if (ws) ioctl(*s, TIOCSWINSZ, ws);
+
+	return 0;
+}
diff --git a/src/misc/pty.c b/src/misc/pty.c
new file mode 100644
index 00000000..0d25a836
--- /dev/null
+++ b/src/misc/pty.c
@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int posix_openpt(int flags)
+{
+	return open("/dev/ptmx", flags);
+}
+
+int grantpt(int fd)
+{
+	return 0;
+}
+
+int unlockpt(int fd)
+{
+	int unlock = 0;
+	return ioctl(fd, TIOCSPTLCK, &unlock);
+}
+
+char *ptsname(int fd)
+{
+	static char buf[9 + sizeof(int)*3 + 1];
+	char *s = buf+sizeof(buf)-1;
+	int pty;
+	if (ioctl (fd, TIOCGPTN, &pty))
+		return NULL;
+	if (pty) for (; pty; pty/=10) *--s = '0' + pty%10;
+	else *--s = '0';
+	s -= 9;
+        s[0] = '/'; s[1] = 'd'; s[2] = 'e'; s[3] = 'v';
+	s[4] = '/'; s[5] = 'p'; s[6] = 't'; s[7] = 's'; s[8] = '/';
+	return s;
+}
diff --git a/src/misc/realpath.c b/src/misc/realpath.c
new file mode 100644
index 00000000..f6b55495
--- /dev/null
+++ b/src/misc/realpath.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+char *realpath(const char *filename, char *resolved)
+{
+	return 0;
+}
diff --git a/src/misc/sched_yield.c b/src/misc/sched_yield.c
new file mode 100644
index 00000000..8a68519e
--- /dev/null
+++ b/src/misc/sched_yield.c
@@ -0,0 +1,10 @@
+#include <sched.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __yield()
+{
+	return syscall0(__NR_sched_yield);
+}
+
+weak_alias(__yield, sched_yield);
diff --git a/src/misc/setpriority.c b/src/misc/setpriority.c
new file mode 100644
index 00000000..26da4b83
--- /dev/null
+++ b/src/misc/setpriority.c
@@ -0,0 +1,7 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int setpriority(int which, id_t who, int prio)
+{
+	return syscall3(__NR_getpriority, which, who, prio);
+}
diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c
new file mode 100644
index 00000000..7fdfc4e5
--- /dev/null
+++ b/src/misc/setrlimit.c
@@ -0,0 +1,11 @@
+#include <sys/resource.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setrlimit(int resource, const struct rlimit *rlim)
+{
+	long k_rlim[2] = { rlim->rlim_cur, rlim->rlim_max };
+	return syscall2(__NR_setrlimit, resource, (long)k_rlim);
+}
+
+LFS64(setrlimit);
diff --git a/src/misc/syslog.c b/src/misc/syslog.c
new file mode 100644
index 00000000..4809d2da
--- /dev/null
+++ b/src/misc/syslog.c
@@ -0,0 +1,115 @@
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include "libc.h"
+
+static int lock;
+static const char *log_ident;
+static int log_opt;
+static int log_facility = LOG_USER;
+static int log_mask = 0xff;
+static FILE *log_f;
+
+int setlogmask(int maskpri)
+{
+	int old = log_mask;
+	if (maskpri) log_mask = maskpri;
+	return old;
+}
+
+static const struct {
+	short sun_family;
+	char sun_path[9];
+} log_addr = {
+	AF_UNIX,
+	"/dev/log"
+};
+
+void closelog(void)
+{
+	LOCK(&lock);
+	if (log_f) fclose(log_f);
+	log_f = NULL;
+	UNLOCK(&lock);
+}
+
+static void __openlog(const char *ident, int opt, int facility)
+{
+	int fd;
+
+	log_ident = ident;
+	log_opt = opt;
+	log_facility = facility;
+
+	if (!(opt & LOG_NDELAY) || log_f) return;
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	if (connect(fd, (void *)&log_addr, sizeof(short) + sizeof "/dev/log") < 0)
+		close(fd);
+	else log_f = fdopen(fd, "wb");
+}
+
+void openlog(const char *ident, int opt, int facility)
+{
+	LOCK(&lock);
+	__openlog(ident, opt, facility);
+	UNLOCK(&lock);
+}
+
+void syslog(int priority, const char *message, ...)
+{
+	struct sigaction sa;
+	va_list ap;
+	char timebuf[16];
+	time_t now;
+	struct tm tm;
+	//const char *fmt, *ident, *sep;
+	//int i;
+
+	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
+
+	LOCK(&lock);
+
+	if (!log_f) __openlog(log_ident, log_opt | LOG_NDELAY, log_facility);
+	if (!log_f) {
+		UNLOCK(&lock);
+		return;
+	}
+
+	memset(&sa, 0, sizeof sa);
+	sa.sa_handler = SIG_IGN;
+	if (sigaction(SIGPIPE, &sa, &sa) < 0) {
+		// we must abandon logging or we might cause SIGPIPE
+		UNLOCK(&lock);
+		return;
+	}
+
+	now = time(NULL);
+	gmtime_r(&now, &tm);
+	strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
+
+	fprintf(log_f, "<%d>%s ", priority, timebuf);
+	if (log_ident) fprintf(log_f, "%s", log_ident);
+	if (log_opt & LOG_PID) fprintf(log_f, "[%d]", getpid());
+	if (log_ident) fprintf(log_f, ": ");
+
+	va_start(ap, message);
+	vfprintf(log_f, message, ap);
+	va_end(ap);
+	fputc(0, log_f);
+	fflush(log_f);
+
+	// Note: LOG_CONS is not supported because it is annoying!!
+	// syslogd will send messages to console if it deems them appropriate!
+
+	sigaction(SIGPIPE, &sa, NULL);
+
+	UNLOCK(&lock);
+}
diff --git a/src/misc/uname.c b/src/misc/uname.c
new file mode 100644
index 00000000..fbe86643
--- /dev/null
+++ b/src/misc/uname.c
@@ -0,0 +1,8 @@
+#include <sys/utsname.h>
+#include <string.h>
+#include "syscall.h"
+
+int uname(struct utsname *uts)
+{
+	return syscall1(__NR_uname, (long)uts);
+}
diff --git a/src/mman/madvise.c b/src/mman/madvise.c
new file mode 100644
index 00000000..f03647ca
--- /dev/null
+++ b/src/mman/madvise.c
@@ -0,0 +1,10 @@
+#include <sys/mman.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __madvise(void *addr, size_t len, int advice)
+{
+	return syscall3(__NR_madvise, (long)addr, len, advice);
+}
+
+weak_alias(__madvise, madvise);
diff --git a/src/mman/mlock.c b/src/mman/mlock.c
new file mode 100644
index 00000000..3c7c653c
--- /dev/null
+++ b/src/mman/mlock.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlock(const void *addr, size_t len)
+{
+	return syscall2(__NR_mlock, (long)addr, len);
+}
diff --git a/src/mman/mlockall.c b/src/mman/mlockall.c
new file mode 100644
index 00000000..782fc9db
--- /dev/null
+++ b/src/mman/mlockall.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlockall(int flags)
+{
+	return syscall1(__NR_mlockall, flags);
+}
diff --git a/src/mman/mmap.c b/src/mman/mmap.c
new file mode 100644
index 00000000..93c76582
--- /dev/null
+++ b/src/mman/mmap.c
@@ -0,0 +1,18 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <limits.h>
+#include "syscall.h"
+#include "libc.h"
+
+void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
+{
+	if (sizeof(off_t) > sizeof(long))
+		if (((long)off & 0xfff) | ((long)((unsigned long long)off>>(12 + 8*(sizeof(off_t)-sizeof(long))))))
+			start = (void *)-1;
+	return (void *)syscall6(__NR_mmap2, (long)start, len, prot, flags, fd, off>>12);
+}
+
+weak_alias(__mmap, mmap);
+
+LFS64(mmap);
diff --git a/src/mman/mprotect.c b/src/mman/mprotect.c
new file mode 100644
index 00000000..11d5e231
--- /dev/null
+++ b/src/mman/mprotect.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mprotect(void *addr, size_t len, int prot)
+{
+	return syscall3(__NR_mprotect, (long)addr, len, prot);
+}
diff --git a/src/mman/mremap.c b/src/mman/mremap.c
new file mode 100644
index 00000000..78491ef4
--- /dev/null
+++ b/src/mman/mremap.c
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
+{
+	va_list ap;
+	void *new_addr;
+	
+	va_start(ap, flags);
+	new_addr = va_arg(ap, void *);
+	va_end(ap);
+
+	return (void *)syscall5(__NR_mremap, (long)old_addr, old_len, new_len, flags, (long)new_addr);
+}
+
+weak_alias(__mremap, mremap);
diff --git a/src/mman/msync.c b/src/mman/msync.c
new file mode 100644
index 00000000..e0926470
--- /dev/null
+++ b/src/mman/msync.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include "syscall.h"
+
+int msync(void *start, size_t len, int flags)
+{
+	return syscall3(__NR_msync, (long)start, len, flags);
+}
diff --git a/src/mman/munlock.c b/src/mman/munlock.c
new file mode 100644
index 00000000..0db59815
--- /dev/null
+++ b/src/mman/munlock.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlock(const void *addr, size_t len)
+{
+	return syscall2(__NR_munlock, (long)addr, len);
+}
diff --git a/src/mman/munlockall.c b/src/mman/munlockall.c
new file mode 100644
index 00000000..ce3e86cc
--- /dev/null
+++ b/src/mman/munlockall.c
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlockall(void)
+{
+	return syscall0(__NR_munlockall);
+}
diff --git a/src/mman/munmap.c b/src/mman/munmap.c
new file mode 100644
index 00000000..c9661cda
--- /dev/null
+++ b/src/mman/munmap.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __munmap(void *start, size_t len)
+{
+	return syscall2(__NR_munmap, (long)start, len);
+}
+
+weak_alias(__munmap, munmap);
diff --git a/src/mman/posix_madvise.c b/src/mman/posix_madvise.c
new file mode 100644
index 00000000..4727ad75
--- /dev/null
+++ b/src/mman/posix_madvise.c
@@ -0,0 +1,6 @@
+#include <sys/mman.h>
+
+int posix_madvise(void *addr, size_t len, int advice)
+{
+	return 0;
+}
diff --git a/src/multibyte/btowc.c b/src/multibyte/btowc.c
new file mode 100644
index 00000000..9d2c3b16
--- /dev/null
+++ b/src/multibyte/btowc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <wchar.h>
+
+wint_t btowc(int c)
+{
+	return c<128U ? c : EOF;
+}
diff --git a/src/multibyte/decode.c b/src/multibyte/decode.c
new file mode 100644
index 00000000..8d3d3c0b
--- /dev/null
+++ b/src/multibyte/decode.c
@@ -0,0 +1,47 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+/* Decodes UTF-8 byte-by-byte. The c argument must be initialized to 0
+ * to begin decoding; when finished it will contain the Unicode scalar
+ * value decoded. Return value is 1 if finished, 0 if in-progress, and
+ * -1 if an invalid sequence was encountered. After an invalid sequence,
+ * the state (in c) automatically resets to 0 if a continuation byte was
+ * expected to facilitate a calling idiom of immediately retrying a
+ * failed decode call after processing the invalid sequence. If the
+ * second try fails, the byte is invalid as a starter as well.
+ *
+ * A trivial usage idiom is:
+ *       while (src<end && (n=decode(dst, *src))>=0) 1[dst+=n]=0, src++;
+ */
+
+int decode(unsigned *c, unsigned b)
+{
+	if (!*c) {
+		if (b < 0x80) {
+			*c = b;
+			return 1;
+		} else if (b-SA >= SB-SA) {
+			*c = FAILSTATE;
+			return -1;
+		}
+		*c = bittab[b-SA];
+		return 0;
+	}
+
+	if (OOB(*c,b)) {
+		*c = 0;
+		return -1;
+	}
+	*c = *c<<6 | b-0x80;
+	return !(*c&(1U<<31));
+}
diff --git a/src/multibyte/internal.c b/src/multibyte/internal.c
new file mode 100644
index 00000000..e9b938dd
--- /dev/null
+++ b/src/multibyte/internal.c
@@ -0,0 +1,60 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <inttypes.h>
+
+#include "internal.h"
+
+#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
+#define D(x) C((x+16))
+#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
+                 x==0xd ? R(0x80,0xa0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | x )
+#ifdef I_FAILED_TO_RTFM_RFC3629
+#define F0(x) (( x==0 ? R(0x90,0xc0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | x )
+#define F8(x) (( x==0 ? R(0xa0,0xc0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | ( R(0x80,0xc0) >> 18 ) \
+             | x )
+#define FC(x) (( x==0 ? R(0x88,0xc0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | ( R(0x80,0xc0) >> 18 ) \
+             | ( R(0x80,0xc0) >> 24 ) \
+             | x )
+#define F(x) ( x<8 ? F0(x) : x<12 ? F8((x&3)) : x<14 ? FC((x&1)) : -1 )
+#else
+#define F(x) ( ( x>=5 ? 0 : \
+                 x==0 ? R(0x90,0xc0) : \
+                 x==4 ? R(0x80,0xa0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | x )
+#endif
+
+const uint32_t bittab[] = {
+	              C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
+	C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
+	D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
+	D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
+	E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
+	E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
+	F(0x0),F(0x1),F(0x2),F(0x3),F(0x4),
+#ifdef I_FAILED_TO_RTFM_RFC3629
+	                                   F(0x5),F(0x6),F(0x7),
+	F(0x8),F(0x9),F(0xa),F(0xb),F(0xc),F(0xd)
+#endif
+};
diff --git a/src/multibyte/internal.h b/src/multibyte/internal.h
new file mode 100644
index 00000000..427519a2
--- /dev/null
+++ b/src/multibyte/internal.h
@@ -0,0 +1,61 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#define LIBC
+#ifndef LIBC
+/* rename functions not to conflict with libc */
+#ifndef myprefix
+#define myprefix fsmu8_
+#endif
+#define concat2(a,b) a ## b
+#define concat(a,b) concat2(a,b)
+#define prefix(b) concat(myprefix,b)
+
+#undef mblen
+#undef mbrlen
+#undef mbrtowc
+#undef mbsinit
+#undef mbsnrtowcs
+#undef mbsrtowcs
+#undef wcrtomb
+#undef wcsrtombs
+#undef wcstombs
+#undef wctomb
+#define mblen prefix(mblen)
+#define mbrlen prefix(mbrlen)
+#define mbrtowc prefix(mbrtowc)
+#define mbsinit prefix(mbsinit)
+#define mbsnrtowcs prefix(mbsnrtowcs)
+#define mbsrtowcs prefix(mbsrtowcs)
+#define mbstowcs prefix(mbstowcs)
+#define wcrtomb prefix(wcrtomb)
+#define wcsnrtombs prefix(wcsnrtombs)
+#define wcsrtombs prefix(wcsrtombs)
+#define wcstombs prefix(wcstombs)
+#define wctomb prefix(wctomb)
+
+#define bittab prefix(bittab)
+#else
+#define bittab __fsmu8
+#endif
+
+extern const uint32_t bittab[];
+
+/* Upper 6 state bits are a negative integer offset to bound-check next byte */
+/*    equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f      */
+#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
+
+/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
+#define R(a,b) ((uint32_t)((a==0x80 ? 0x40-b : -a) << 23))
+#define FAILSTATE R(0x80,0x80)
+
+#ifdef I_FAILED_TO_RTFM_RFC3629
+#define SA 0xc2
+#define SB 0xfe
+#else
+#define SA 0xc2
+#define SB 0xf5
+#endif
diff --git a/src/multibyte/mblen.c b/src/multibyte/mblen.c
new file mode 100644
index 00000000..26d35649
--- /dev/null
+++ b/src/multibyte/mblen.c
@@ -0,0 +1,17 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+int mblen(const char *s, size_t n)
+{
+	return mbtowc(0, s, n);
+}
diff --git a/src/multibyte/mbrlen.c b/src/multibyte/mbrlen.c
new file mode 100644
index 00000000..c9a9f033
--- /dev/null
+++ b/src/multibyte/mbrlen.c
@@ -0,0 +1,18 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t mbrlen(const char *s, size_t n, mbstate_t *st)
+{
+	static unsigned internal;
+	return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
+}
diff --git a/src/multibyte/mbrtowc.c b/src/multibyte/mbrtowc.c
new file mode 100644
index 00000000..09badebe
--- /dev/null
+++ b/src/multibyte/mbrtowc.c
@@ -0,0 +1,58 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t mbrtowc(wchar_t *wc, const char *src, size_t n, mbstate_t *st)
+{
+	static unsigned internal_state;
+	unsigned c;
+	const unsigned char *s = src;
+	const unsigned N = n;
+
+	if (!st) st = (void *)&internal_state;
+	c = *(unsigned *)st;
+	
+	if (!s) {
+		s = "";
+		wc = (void *)&wc;
+		n = 1;
+	} else if (!wc) wc = (void *)&wc;
+
+	if (!n) return -2;
+	if (!c) {
+		if ((unsigned)*s < 0x80) return !!(*wc = *s);
+		if ((unsigned)*s-SA > SB-SA) goto ilseq;
+		c = bittab[*s++-SA]; n--;
+	}
+
+	if (n) {
+		if (OOB(c,*s)) goto ilseq;
+loop:
+		c = c<<6 | *s++-0x80; n--;
+		if (!(c&(1U<<31))) {
+			*(unsigned *)st = 0;
+			*wc = c;
+			return N-n;
+		}
+		if (n) {
+			if ((unsigned)*s-0x80 >= 0x40) goto ilseq;
+			goto loop;
+		}
+	}
+
+	*(unsigned *)st = c;
+	return -2;
+ilseq:
+	*(unsigned *)st = FAILSTATE;
+	errno = EILSEQ;
+	return -1;
+}
diff --git a/src/multibyte/mbsinit.c b/src/multibyte/mbsinit.c
new file mode 100644
index 00000000..d307e5a7
--- /dev/null
+++ b/src/multibyte/mbsinit.c
@@ -0,0 +1,17 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+int mbsinit(const mbstate_t *st)
+{
+	return !*(unsigned *)st;
+}
diff --git a/src/multibyte/mbsnrtowcs.c b/src/multibyte/mbsnrtowcs.c
new file mode 100644
index 00000000..c6f0207f
--- /dev/null
+++ b/src/multibyte/mbsnrtowcs.c
@@ -0,0 +1,61 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "internal.h"
+
+size_t mbsnrtowcs(wchar_t *wcs, const char **src, size_t n, size_t wn, mbstate_t *st)
+{
+	size_t l, cnt=0, n2;
+	wchar_t *ws, wbuf[256];
+	const char *s = *src;
+
+	if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
+	else ws = wcs;
+
+	/* making sure output buffer size is at most n/4 will ensure
+	 * that mbsrtowcs never reads more than n input bytes. thus
+	 * we can use mbsrtowcs as long as it's practical.. */
+
+	while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
+		if (n2>=wn) n2=wn;
+		n -= n2;
+		l = mbsrtowcs(ws, &s, n2, st);
+		if (!(l+1)) {
+			cnt = l;
+			wn = 0;
+			break;
+		}
+		if (ws != wbuf) {
+			ws += l;
+			wn -= l;
+		}
+		cnt += l;
+	}
+	if (s) while (wn && n) {
+		l = mbrtowc(ws, s, n, st);
+		if (l+2<=2) {
+			if (!(l+1)) {
+				cnt = l;
+				break;
+			}
+			/* have to roll back partial character */
+			*(unsigned *)st = 0;
+			break;
+		}
+		s += l; n -= l;
+		/* safe - this loop runs fewer than sizeof(wbuf)/8 times */
+		ws++; wn--;
+		cnt++;
+	}
+	if (wcs) *src = s;
+	return cnt;
+}
diff --git a/src/multibyte/mbsrtowcs.c b/src/multibyte/mbsrtowcs.c
new file mode 100644
index 00000000..e2b43480
--- /dev/null
+++ b/src/multibyte/mbsrtowcs.c
@@ -0,0 +1,121 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t mbsrtowcs(wchar_t *ws, const char **src, size_t wn, mbstate_t *st)
+{
+	unsigned c;
+	const unsigned char *s = *src;
+	const wchar_t *wsorig = ws;
+
+	if (!st) st = (void *)&c, c = 0;
+	else c = *(unsigned *)st;
+
+	if (c) {
+		*(unsigned *)st = 0;
+		if (!ws) {
+			wn = 0;
+			goto resume0;
+		}
+		goto resume;
+	}
+
+	if (!ws) for (wn=0;;) {
+		if ((unsigned)*s-SA >= SB-SA) {
+			while (((unsigned)s&3) && (unsigned)*s-1<0x7f) s++, wn++;
+			while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) s+=4, wn+=4;
+			while ((unsigned)*s-1<0x7f) s++, wn++;
+			if (!*s) return wn;
+			if ((unsigned)*s-SA >= SB-SA) goto ilseq2;
+		}
+		c = bittab[*s++-SA];
+		do {
+resume0:
+			if (OOB(c,*s)) goto ilseq2; s++;
+			c <<= 6; if (!(c&(1U<<31))) break;
+#ifdef I_FAILED_TO_RTFM_RFC3629
+			if ((unsigned)*s++-0x80 >= 0x40) goto ilseq2;
+			c <<= 6; if (!(c&(1U<<31))) break;
+			if ((unsigned)*s++-0x80 >= 0x40) goto ilseq2;
+			c <<= 6; if (!(c&(1U<<31))) break;
+#endif
+			if ((unsigned)*s++-0x80 >= 0x40) goto ilseq2;
+			c <<= 6; if (!(c&(1U<<31))) break;
+			if ((unsigned)*s++-0x80 >= 0x40) goto ilseq2;
+		} while (0);
+		wn++; c = 0;
+	}
+
+	while (wn) {
+		if ((unsigned)*s-SA >= SB-SA) {
+			if (wn >= 7) {
+				while (((unsigned)s&3) && (unsigned)*s-1<0x7f) {
+					*ws++ = *s++;
+					wn--;
+				}
+				while (wn>=4 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+					*ws++ = *s++;
+					*ws++ = *s++;
+					*ws++ = *s++;
+					*ws++ = *s++;
+					wn -= 4;
+				}
+			}
+			while (wn && (unsigned)*s-1<0x7f) {
+				*ws++ = *s++;
+				wn--;
+			}
+			if (!wn) break;
+			if (!*s) {
+				*ws = 0;
+				*src = 0;
+				return ws-wsorig;
+			}
+			if ((unsigned)*s-SA >= SB-SA) goto ilseq;
+		}
+		c = bittab[*s++-SA];
+		do {
+resume:
+			if (OOB(c,*s)) goto ilseq;
+			c = (c<<6) | *s++-0x80;
+			if (!(c&(1U<<31))) break;
+
+#ifdef I_FAILED_TO_RTFM_RFC3629
+			if ((unsigned)*s-0x80 >= 0x40) goto ilseq;
+			c = (c<<6) | *s++-0x80;
+			if (!(c&(1U<<31))) break;
+
+			if ((unsigned)*s-0x80 >= 0x40) goto ilseq;
+			c = (c<<6) | *s++-0x80;
+			if (!(c&(1U<<31))) break;
+#endif
+
+			if ((unsigned)*s-0x80 >= 0x40) goto ilseq;
+			c = (c<<6) | *s++-0x80;
+			if (!(c&(1U<<31))) break;
+
+			if ((unsigned)*s-0x80 >= 0x40) goto ilseq;
+			c = (c<<6) | *s++-0x80;
+		} while (0);
+
+		*ws++ = c; wn--; c = 0;
+	}
+	*src = s;
+	return ws-wsorig;
+ilseq:
+	*src = s;
+ilseq2:
+	/* enter permanently failing state */
+	*(unsigned *)st = FAILSTATE;
+	errno = EILSEQ;
+	return -1;
+}
diff --git a/src/multibyte/mbstowcs.c b/src/multibyte/mbstowcs.c
new file mode 100644
index 00000000..23e1d925
--- /dev/null
+++ b/src/multibyte/mbstowcs.c
@@ -0,0 +1,18 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t mbstowcs(wchar_t *ws, const char *s, size_t wn)
+{
+	mbstate_t st = { 0 };
+	return mbsrtowcs(ws, (void*)&s, wn, &st);
+}
diff --git a/src/multibyte/mbtowc.c b/src/multibyte/mbtowc.c
new file mode 100644
index 00000000..bdcaeb3c
--- /dev/null
+++ b/src/multibyte/mbtowc.c
@@ -0,0 +1,19 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+int mbtowc(wchar_t *wc, const char *s, size_t n)
+{
+	mbstate_t st = { 0 };
+	n = mbrtowc(wc, s, n, &st);
+	return n+2 ? n : -1;
+}
diff --git a/src/multibyte/wcrtomb.c b/src/multibyte/wcrtomb.c
new file mode 100644
index 00000000..36180c8f
--- /dev/null
+++ b/src/multibyte/wcrtomb.c
@@ -0,0 +1,38 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t wcrtomb(char *s, wchar_t wc, mbstate_t *st)
+{
+	if (!s) return 1;
+	if ((unsigned)wc < 0x80) {
+		*s = wc;
+		return 1;
+	} else if ((unsigned)wc < 0x800) {
+		*s++ = 0xc0 | (wc>>6);
+		*s = 0x80 | (wc&0x3f);
+		return 2;
+	} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
+		*s++ = 0xe0 | (wc>>12);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 3;
+	} else if ((unsigned)wc-0x10000 < 0x100000) {
+		*s++ = 0xf0 | (wc>>18);
+		*s++ = 0x80 | ((wc>>12)&0x3f);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 4;
+	}
+	errno = EILSEQ;
+	return -1;
+}
diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c
new file mode 100644
index 00000000..666f6f3f
--- /dev/null
+++ b/src/multibyte/wcsnrtombs.c
@@ -0,0 +1,51 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t wcsnrtombs(char *dst, const wchar_t **wcs, size_t wn, size_t n, mbstate_t *st)
+{
+	size_t l, cnt=0, n2;
+	char *s, buf[256];
+	const wchar_t *ws = *wcs;
+
+	if (!dst) s = buf, n = sizeof buf;
+	else s = dst;
+
+	while ( n && ( (n2=wn)>=n || n2>32 ) ) {
+		if (n2>=n) n2=n;
+		wn -= n2;
+		l = wcsrtombs(s, &ws, n2, 0);
+		if (!(l+1)) {
+			cnt = l;
+			n = 0;
+			break;
+		}
+		if (s != buf) {
+			s += l;
+			n -= l;
+		}
+		cnt += l;
+	}
+	while (n && wn) {
+		l = wcrtomb(s, *ws, 0);
+		if (!(l+1)) {
+			cnt = l;
+			break;
+		}
+		ws++; wn--;
+		/* safe - this loop runs fewer than sizeof(buf) times */
+		s+=l; n-=l;
+		cnt++;
+	}
+	if (dst) *wcs = ws;
+	return cnt;
+}
diff --git a/src/multibyte/wcsrtombs.c b/src/multibyte/wcsrtombs.c
new file mode 100644
index 00000000..3c48d65b
--- /dev/null
+++ b/src/multibyte/wcsrtombs.c
@@ -0,0 +1,58 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t wcsrtombs(char *s, const wchar_t **ws, size_t n, mbstate_t *st)
+{
+	const wchar_t *ws2;
+	char buf[4];
+	size_t N = n, l;
+	if (!s) {
+		for (n=0, ws2=*ws; *ws2; ws2++) {
+			if (*ws2 >= 0x80) {
+				l = wcrtomb(buf, *ws2, 0);
+				if (!(l+1)) return -1;
+				n += l;
+			} else n++;
+		}
+		return n;
+	}
+	while (n>=4 && **ws) {
+		if (**ws >= 0x80) {
+			l = wcrtomb(s, **ws, 0);
+			if (!(l+1)) return -1;
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	while (n && **ws) {
+		if (**ws >= 0x80) {
+			l = wcrtomb(buf, **ws, 0);
+			if (!(l+1)) return -1;
+			if (l>n) return N-n;
+			wcrtomb(s, **ws, 0);
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	if (n) *s = 0;
+	*ws = 0;
+	return N-n;
+}
diff --git a/src/multibyte/wcstombs.c b/src/multibyte/wcstombs.c
new file mode 100644
index 00000000..b9c1b18a
--- /dev/null
+++ b/src/multibyte/wcstombs.c
@@ -0,0 +1,17 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+size_t wcstombs(char *s, const wchar_t *ws, size_t n)
+{
+	return wcsrtombs(s, &ws, n, 0);
+}
diff --git a/src/multibyte/wctob.c b/src/multibyte/wctob.c
new file mode 100644
index 00000000..d6353ee1
--- /dev/null
+++ b/src/multibyte/wctob.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int wctob(wint_t c)
+{
+	if (c < 128U) return c;
+	return EOF;
+}
diff --git a/src/multibyte/wctomb.c b/src/multibyte/wctomb.c
new file mode 100644
index 00000000..6910ef37
--- /dev/null
+++ b/src/multibyte/wctomb.c
@@ -0,0 +1,18 @@
+/* 
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <wchar.h>
+#include <errno.h>
+
+#include "internal.h"
+
+int wctomb(char *s, wchar_t wc)
+{
+	if (!s) return 0;
+	return wcrtomb(s, wc, 0);
+}
diff --git a/src/network/__dns.c b/src/network/__dns.c
new file mode 100644
index 00000000..73ec422d
--- /dev/null
+++ b/src/network/__dns.c
@@ -0,0 +1,267 @@
+#include <stdint.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "__dns.h"
+#include "stdio_impl.h"
+
+#define TIMEOUT 5
+#define RETRY 1
+#define PACKET_MAX 512
+#define PTR_MAX (64 + sizeof ".in-addr.arpa")
+
+int __dns_doqueries(unsigned char *dest, const char *name, int *rr, int rrcnt)
+{
+	time_t t0 = time(0);
+	int fd;
+	FILE *f, _f;
+	unsigned char _buf[64];
+	char line[64], *s, *z;
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = {0}, ns[3] = {{0}};
+	socklen_t sl;
+	int nns;
+	int family;
+	unsigned char q[280] = "", *r = dest;
+	int ql;
+	int rlen;
+	int got = 0, failed = 0;
+	int errcode = EAI_AGAIN;
+	int i, j;
+	struct timeval tv;
+	fd_set fds;
+	int id;
+
+	/* Construct query template - RR and ID will be filled later */
+	if (strlen(name)-1 >= 254U) return -1;
+	q[2] = q[5] = 1;
+	strcpy(q+13, name);
+	for (i=13; q[i]; i=j+1) {
+		for (j=i; q[j] && q[j] != '.'; j++);
+		if (j-i-1u > 62u) return -1;
+		q[i-1] = j-i;
+	}
+	q[i+3] = 1;
+	ql = i+4;
+
+	/* Make a reasonably unpredictable id */
+	gettimeofday(&tv, 0);
+	id = tv.tv_usec + tv.tv_usec/256 & 0xffff;
+
+	/* Get nameservers from resolv.conf, fallback to localhost */
+	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
+		if (strncmp(line, "nameserver", 10) || !isspace(line[10]))
+			continue;
+		for (s=line+11; isspace(*s); s++);
+		for (z=s; *z && !isspace(*z); z++);
+		*z=0;
+		if (__ipparse(ns+nns, family, s) < 0) continue;
+		ns[nns].sin.sin_port = htons(53);
+		family = ns[nns++].sin.sin_family;
+		sl = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+	}
+	if (f) __fclose_ca(f);
+	if (!nns) {
+		ns[0].sin.sin_family = AF_INET;
+		ns[0].sin.sin_port = htons(53);
+		nns=1;
+		sl = sizeof sa.sin;
+	}
+
+	/* Get local address and open/bind a socket */
+	sa.sin.sin_family = family;
+	fd = socket(family, SOCK_DGRAM, 0);
+	if (bind(fd, (void *)&sa, sl) < 0) {
+		close(fd);
+		return -1;
+	}
+	/* Nonblocking to work around Linux UDP select bug */
+	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
+
+	/* Loop until we timeout; break early on success */
+	for (; time(0)-t0 < TIMEOUT; ) {
+
+		/* Query all configured namservers in parallel */
+		for (i=0; i<rrcnt; i++) if (rr[i]) for (j=0; j<nns; j++) {
+			q[0] = id+i >> 8;
+			q[1] = id+i;
+			q[ql-3] = rr[i];
+			sendto(fd, q, ql, MSG_NOSIGNAL, (void *)&ns[j], sl);
+		}
+
+		/* Wait for a response, or until time to retry */
+		FD_ZERO(&fds);
+		FD_SET(fd, &fds);
+		tv.tv_sec = RETRY;
+		tv.tv_usec = 0;
+		if (select(fd+1, &fds, 0, 0, &tv) <= 0) continue;
+
+		/* Process any and all replies */
+		while (got+failed < rrcnt && (rlen = recvfrom(fd, r, 512, 0,
+			(void *)&sa, (socklen_t[1]){sl})) >= 2)
+		{
+			/* Ignore replies from addresses we didn't send to */
+			for (i=0; i<nns; i++) if (!memcmp(ns+i, &sa, sl)) break;
+			if (i==nns) continue;
+
+			/* Compute index of the query from id */
+			i = r[0]*256+r[1] - id & 0xffff;
+			if ((unsigned)i >= rrcnt || !rr[i]) continue;
+
+			/* Interpret the result code */
+			switch (r[3] & 15) {
+			case 0:
+				got++;
+				break;
+			case 3:
+				if (1) errcode = EAI_NONAME; else
+			default:
+				errcode = EAI_FAIL;
+				failed++;
+			}
+
+			/* Mark this record as answered */
+			rr[i] = 0;
+			r += 512;
+		}
+
+		/* Check to see if we have answers to all queries */
+		if (got+failed == rrcnt) break;
+	}
+	close(fd);
+
+	/* Return the number of results, or an error code if none */
+	if (got) return got;
+	return errcode;
+}
+
+static void mkptr4(char *s, const unsigned char *ip)
+{
+	sprintf(s, "%d.%d.%d.%d.in-addr.arpa",
+		ip[3], ip[2], ip[1], ip[0]);
+}
+
+static void mkptr6(char *s, const unsigned char *ip)
+{
+	static const char xdigits[] = "0123456789abcdef";
+	int i;
+	for (i=15; i>=0; i--) {
+		*s++ = xdigits[ip[i]&15]; *s++ = '.';
+		*s++ = xdigits[ip[i]>>4]; *s++ = '.';
+	}
+	strcpy(s, "ip6.arpa");
+}
+
+int __dns_query(unsigned char *r, const void *a, int family, int ptr)
+{
+	char buf[PTR_MAX];
+	int rr[2], rrcnt = 1;
+
+	if (ptr) {
+		if (family == AF_INET6) mkptr6(buf, a);
+		else mkptr4(buf, a);
+		rr[0] = RR_PTR;
+		a = buf;
+	} else if (family == AF_INET6) {
+		rr[0] = RR_AAAA;
+	} else {
+		rr[0] = RR_A;
+		if (family != AF_INET) rr[rrcnt++] = RR_AAAA;
+	}
+
+	return __dns_doqueries(r, a, rr, rrcnt);
+}
+
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static int decname(char *s, const unsigned char *b, const unsigned char *p)
+{
+	/* Remember jump destinations to detect loops and abort */
+	size_t seen[PACKET_MAX/8/sizeof(size_t)] = { 0 };
+	char *sz = s + HOST_NAME_MAX;
+	const unsigned char *pz = b+512;
+	for (;;) {
+		if (p>=pz) return -1;
+		else if (*p&0xc0) {
+			int j = (p[0]&1) | p[1];
+			if (BITOP(seen, j, &)) return -1;
+			BITOP(seen, j, |=);
+			p = b + j;
+		} else if (*p) {
+			if (p+*p+1>=pz || s+*p>=sz) return -1;
+			memcpy(s, p+1, *p);
+			s += *p+1;
+			p += *p+1;
+			s[-1] = *p ? '.' : 0;
+		} else return 0;
+	}
+}
+
+int __dns_get_rr(void *dest, size_t stride, size_t maxlen, size_t limit, const unsigned char *r, int rr, int dec)
+{
+	int qdcount, ancount;
+	const unsigned char *p;
+	char tmp[256];
+	int found = 0;
+	int len;
+
+	if ((r[3]&15)) return 0;
+	p = r+12;
+	qdcount = r[4]*256 + r[5];
+	ancount = r[6]*256 + r[7];
+	if (qdcount+ancount > 64) return -1;
+	while (qdcount--) {
+		while (p-r < 512 && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+506)
+			return -1;
+		p += 5 + !!*p;
+	}
+	while (ancount--) {
+		while (p-r < 512 && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+506)
+			return -1;
+		p += 1 + !!*p;
+		len = p[8]*256 + p[9];
+		if (p+len > r+512) return -1;
+		if (p[1]==rr && len <= maxlen) {
+			if (dec && decname(tmp, r, p+10)<0) return -1;
+			if (dest && limit) {
+				if (dec) strcpy(dest, tmp);
+				else memcpy(dest, p+10, len);
+				dest = (char *)dest + stride;
+				limit--;
+			}
+			found++;
+		}
+		p += 10 + len;
+	}
+	return found;
+}
+
+int __dns_count_addrs(const unsigned char *r, int cnt)
+{
+	int found=0, res, i;
+	static const int p[2][2] = { { 4, RR_A }, { 16, RR_AAAA } };
+
+	while (cnt--) for (i=0; i<2; i++) {
+		res = __dns_get_rr(0, 0, p[i][0], -1, r, p[i][1], 0);
+		if (res < 0) return res;
+		found += res;
+		r += 512;
+	}
+	return found;
+}
diff --git a/src/network/__dns.h b/src/network/__dns.h
new file mode 100644
index 00000000..9a3f7402
--- /dev/null
+++ b/src/network/__dns.h
@@ -0,0 +1,14 @@
+#include <stddef.h>
+
+#define RR_A 1
+#define RR_CNAME 5
+#define RR_PTR 12
+#define RR_AAAA 28
+
+int __dns_count_addrs(const unsigned char *, int);
+int __dns_get_rr(void *, size_t, size_t, size_t, const unsigned char *, int, int);
+
+int __dns_query(unsigned char *, const void *, int, int);
+int __ipparse(void *, int, const char *);
+
+int __dns_doqueries(unsigned char *, const char *, int *, int);
diff --git a/src/network/__ipparse.c b/src/network/__ipparse.c
new file mode 100644
index 00000000..ca9e5890
--- /dev/null
+++ b/src/network/__ipparse.c
@@ -0,0 +1,40 @@
+#include <string.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "__dns.h"
+#include <stdio.h>
+
+int __ipparse(void *dest, int family, const char *s)
+{
+	unsigned char *d = dest;
+	unsigned long a[16] = { 0 };
+	const char *z;
+	int i;
+
+	if (family == AF_INET6) goto not_v4;
+
+	for (i=0; i<4 && *s; i++) {
+		a[i] = strtoul(s, (char **)&z, 0);
+		if (z==s || (*z && *z != '.')) goto not_v4;
+		s=z+1;
+	}
+	switch (i) {
+	case 0:
+		a[1] = a[0] & 0xffffff;
+		a[0] >>= 24;
+	case 1:
+		a[2] = a[1] & 0xffff;
+		a[1] >>= 16;
+	case 2:
+		a[3] = a[2] & 0xff;
+		a[2] >>= 8;
+	}
+	((struct sockaddr_in *)d)->sin_family = AF_INET;
+	d = (void *)&((struct sockaddr_in *)d)->sin_addr;
+	for (i=0; i<4; i++) d[i] = a[i];
+	return 0;
+
+not_v4:
+	return -1;
+}
diff --git a/src/network/accept.c b/src/network/accept.c
new file mode 100644
index 00000000..83704096
--- /dev/null
+++ b/src/network/accept.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+int accept(int fd, struct sockaddr *addr, socklen_t *len)
+{
+	unsigned long args[] = { fd, (unsigned long)addr, (unsigned long)len };
+	int ret;
+	CANCELPT_BEGIN;
+	ret = syscall2(__NR_socketcall, SYS_ACCEPT, (long)args);
+	CANCELPT_END;
+	return ret;
+}
diff --git a/src/network/bind.c b/src/network/bind.c
new file mode 100644
index 00000000..3bef382c
--- /dev/null
+++ b/src/network/bind.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int bind(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	unsigned long args[] = { fd, (unsigned long)addr, len };
+	return syscall2(__NR_socketcall, SYS_BIND, (long)args);
+}
diff --git a/src/network/connect.c b/src/network/connect.c
new file mode 100644
index 00000000..6074122e
--- /dev/null
+++ b/src/network/connect.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+int connect(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	unsigned long args[] = { fd, (unsigned long)addr, len };
+	int ret;
+	CANCELPT_BEGIN;
+	ret = syscall2(__NR_socketcall, SYS_CONNECT, (long)args);
+	CANCELPT_END;
+	return ret;
+}
diff --git a/src/network/dn_expand.c b/src/network/dn_expand.c
new file mode 100644
index 00000000..01b449bb
--- /dev/null
+++ b/src/network/dn_expand.c
@@ -0,0 +1,28 @@
+#include <resolv.h>
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+int dn_expand(unsigned char *b, unsigned char *pz, unsigned char *p, unsigned char *s, int outlen)
+{
+	/* Remember jump destinations to detect loops and abort */
+	size_t seen[512/8/sizeof(size_t)] = { 0 };
+	unsigned char *sz = s + outlen;
+	if (pz-b > 512) return -1;
+	for (;;) {
+		if (p>=pz) return -1;
+		else if (*p&0xc0) {
+			int j = (p[0]&1) | p[1];
+			if (BITOP(seen, j, &)) return -1;
+			BITOP(seen, j, |=);
+			p = b + j;
+		} else if (*p) {
+			if (p+*p+1>=pz || s+*p>=sz) return -1;
+			memcpy(s, p+1, *p);
+			s += *p+1;
+			p += *p+1;
+			s[-1] = *p ? '.' : 0;
+		} else return 0;
+	}
+}
diff --git a/src/network/ent.c b/src/network/ent.c
new file mode 100644
index 00000000..4c2f24b5
--- /dev/null
+++ b/src/network/ent.c
@@ -0,0 +1,26 @@
+#include "libc.h"
+
+void sethostent(int x)
+{
+}
+
+void *gethostent()
+{
+	return 0;
+}
+
+void endhostent(void)
+{
+}
+
+weak_alias(sethostent, setnetent);
+weak_alias(gethostent, getnetent);
+weak_alias(endhostent, endnetent);
+
+weak_alias(sethostent, setservent);
+weak_alias(gethostent, getservent);
+weak_alias(endhostent, endservent);
+
+weak_alias(sethostent, setprotoent);
+weak_alias(gethostent, getprotoent);
+weak_alias(endhostent, endprotoent);
diff --git a/src/network/freeaddrinfo.c b/src/network/freeaddrinfo.c
new file mode 100644
index 00000000..df3798ae
--- /dev/null
+++ b/src/network/freeaddrinfo.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <netdb.h>
+
+void freeaddrinfo(struct addrinfo *p)
+{
+	free(p);
+}
diff --git a/src/network/gai_strerror.c b/src/network/gai_strerror.c
new file mode 100644
index 00000000..ea00bed7
--- /dev/null
+++ b/src/network/gai_strerror.c
@@ -0,0 +1,21 @@
+#include <netdb.h>
+
+static const char msgs[] =
+	"Invalid flags\0"
+	"Name does not resolve\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Unrecognized address family or invalid length\0"
+	"Unrecognized socket type\0"
+	"Unrecognized service\0"
+	"Out of memory\0"
+	"System error\0"
+	"Overflow\0"
+	"\0Unknown error";
+
+const char *gai_strerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode++; ecode && *s; ecode++, s++) for (; *s; s++);
+	return *s ? s : s+1;
+}
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c
new file mode 100644
index 00000000..90e85f6a
--- /dev/null
+++ b/src/network/getaddrinfo.c
@@ -0,0 +1,224 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include "__dns.h"
+#include "stdio_impl.h"
+
+static int is_valid(const char *host)
+{
+	const unsigned char *s;
+	if (strlen(host)-1 > 254 || mbstowcs(0, host, 0) > 255) return 0;
+	for (s=host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
+	return !*s;
+}
+
+#if 0
+static int have_af(int family)
+{
+	struct sockaddr_in6 sin6 = { .sin6_family = family };
+	socklen_t sl = family == AF_INET
+		? sizeof(struct sockaddr_in)
+		: sizeof(struct sockaddr_in6);
+	int sock = socket(family, SOCK_STREAM, 0);
+	int have = !bind(sock, (void *)&sin6, sl);
+	close(sock);
+	return have;
+}
+#endif
+
+#include <stdlib.h>
+#include <netdb.h>
+
+union sa {
+	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
+};
+
+struct aibuf {
+	struct addrinfo ai;
+	union sa sa;
+};
+
+/* Extra slots needed for storing canonical name */
+#define EXTRA ((256+sizeof(struct aibuf)-1)/sizeof(struct aibuf))
+
+int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, struct addrinfo **res)
+{
+	int flags = hint ? hint->ai_flags : 0;
+	int family = hint ? hint->ai_family : AF_UNSPEC;
+	int type = hint ? hint->ai_socktype : 0;
+	int proto = hint ? hint->ai_protocol : 0;
+	unsigned long port = 0;
+	struct aibuf *buf;
+	union sa sa = {{0}};
+	unsigned char reply[1024];
+	int i, j;
+	//char hostbuf[256];
+	char line[512];
+	FILE *f, _f;
+	unsigned char _buf[64];
+	char *z;
+	int result;
+	int cnt;
+
+	if (host && strlen(host)>255) return EAI_NONAME;
+	if (serv && strlen(serv)>32) return EAI_SERVICE;
+
+	if (type && !proto)
+		proto = type==SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
+	if (!type && proto)
+		type = proto==IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+
+	if (serv) {
+		port = strtoul(serv, &z, 0);
+		if (!*z && port > 65535) return EAI_SERVICE;
+		if (!port) {
+			if (flags & AI_NUMERICSERV) return EAI_SERVICE;
+
+			//f = fopen("/etc/services", "rb");
+			return EAI_SERVICE;
+		}
+		port = htons(port);
+	}
+
+	if (!host) {
+		if (family == AF_UNSPEC) family = AF_INET;
+		buf = calloc(sizeof *buf, 1+EXTRA);
+		if (!buf) return EAI_MEMORY;
+		buf->ai.ai_protocol = proto;
+		buf->ai.ai_socktype = type;
+		buf->ai.ai_addr = (void *)&buf->sa;
+		buf->ai.ai_addrlen = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+		buf->ai.ai_family = family;
+		buf->sa.sin.sin_family = family;
+		buf->sa.sin.sin_port = port;
+		if (!(flags & AI_PASSIVE)) {
+			if (family == AF_INET) {
+				0[(uint8_t*)&buf->sa.sin.sin_addr.s_addr]=127;
+				3[(uint8_t*)&buf->sa.sin.sin_addr.s_addr]=1;
+			} else buf[0].sa.sin6.sin6_addr.s6_addr[15] = 1;
+		}
+		*res = &buf->ai;
+		return 0;
+	}
+
+	/* Try as a numeric address */
+	if (__ipparse(&sa, family, host) >= 0) {
+		buf = calloc(sizeof *buf, 1+EXTRA);
+		if (!buf) return EAI_MEMORY;
+		family = sa.sin.sin_family;
+		buf->ai.ai_protocol = proto;
+		buf->ai.ai_socktype = type;
+		buf->ai.ai_addr = (void *)&buf->sa;
+		buf->ai.ai_addrlen = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+		buf->ai.ai_family = family;
+		buf->sa = sa;
+		buf->sa.sin.sin_port = port;
+		*res = &buf->ai;
+		return 0;
+	}
+
+	if (flags & AI_NUMERICHOST) return EAI_NONAME;
+
+	f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (f) while (fgets(line, sizeof line, f)) {
+		char *p;
+		size_t l = strlen(host);
+
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+		for(p=line+1; (p=strstr(p, host)) &&
+			(!isspace(p[-1]) || !isspace(p[l])); p++);
+		if (!p) continue;
+		__fclose_ca(f);
+
+		/* Isolate IP address to parse */
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		if (__ipparse(&sa, family, line) < 0) return EAI_NONAME;
+
+		/* Allocate and fill result buffer */
+		buf = calloc(sizeof *buf, 1+EXTRA);
+		if (!buf) return EAI_MEMORY;
+		family = sa.sin.sin_family;
+		buf->ai.ai_protocol = proto;
+		buf->ai.ai_socktype = type;
+		buf->ai.ai_addr = (void *)&buf->sa;
+		buf->ai.ai_addrlen = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+		buf->ai.ai_family = family;
+		buf->sa = sa;
+		buf->sa.sin.sin_port = port;
+
+		/* Extract first name as canonical name */
+		for (; *p && isspace(*p); p++);
+		buf->ai.ai_canonname = (void *)(buf+1);
+		snprintf(buf->ai.ai_canonname, 256, "%s", p);
+		for (p=buf->ai.ai_canonname; *p && !isspace(*p); p++);
+		*p = 0;
+		if (!is_valid(buf->ai.ai_canonname))
+			buf->ai.ai_canonname = 0;
+
+		*res = &buf->ai;
+		return 0;
+	}
+	if (f) __fclose_ca(f);
+
+#if 0
+	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	if (f) while (fgets(line, sizeof line, f)) {
+		if (!isspace(line[10]) || (strncmp(line, "search", 6)
+			&& strncmp(line, "domain", 6))) continue;
+	}
+	if (f) __fclose_ca(f);
+#endif
+
+	/* Perform one or more DNS queries for host */
+	memset(reply, 0, sizeof reply);
+	result = __dns_query(reply, host, family, 0);
+	if (result < 0) return result;
+
+	cnt = __dns_count_addrs(reply, result);
+	if (cnt <= 0) return EAI_NONAME;
+
+	buf = calloc(sizeof *buf, cnt+EXTRA);
+	if (!buf) return EAI_MEMORY;
+
+	i = 0;
+	if (family != AF_INET6) {
+		j = __dns_get_rr(&buf[i].sa.sin.sin_addr, sizeof *buf, 4, cnt-i, reply, RR_A, 0);
+		while (j--) buf[i++].sa.sin.sin_family = AF_INET;
+	}
+	if (family != AF_INET) {
+		j = __dns_get_rr(&buf[i].sa.sin6.sin6_addr, sizeof *buf, 16, cnt-i, reply, RR_AAAA, 0);
+		while (j--) buf[i++].sa.sin.sin_family = AF_INET6;
+	}
+	if (result>1) {
+		j = __dns_get_rr(&buf[i].sa.sin.sin_addr, sizeof *buf, 4, cnt-i, reply+512, RR_A, 0);
+		while (j--) buf[i++].sa.sin.sin_family = AF_INET;
+		j = __dns_get_rr(&buf[i].sa.sin6.sin6_addr, sizeof *buf, 16, cnt-i, reply+512, RR_AAAA, 0);
+		while (j--) buf[i++].sa.sin.sin_family = AF_INET6;
+	}
+
+	if (__dns_get_rr((void *)&buf[cnt], 0, 256, 1, reply, RR_CNAME, 1) < 0)
+		strcpy((void *)&buf[cnt], host);
+
+	for (i=0; i<cnt; i++) {
+		buf[i].ai.ai_protocol = proto;
+		buf[i].ai.ai_socktype = type;
+		buf[i].ai.ai_addr = (void *)&buf[i].sa;
+		buf[i].ai.ai_addrlen = buf[i].sa.sin.sin_family==AF_INET6
+			? sizeof sa.sin6 : sizeof sa.sin;
+		buf[i].ai.ai_family = buf[i].sa.sin.sin_family;
+		buf[i].sa.sin.sin_port = port;
+		buf[i].ai.ai_next = &buf[i+1].ai;
+		buf[i].ai.ai_canonname = (void *)&buf[cnt];
+	}
+	buf[cnt-1].ai.ai_next = 0;
+	*res = &buf->ai;
+
+	return 0;
+}
diff --git a/src/network/gethostbyaddr.c b/src/network/gethostbyaddr.c
new file mode 100644
index 00000000..51e1c569
--- /dev/null
+++ b/src/network/gethostbyaddr.c
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+
+struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
+{
+	static struct hostent h;
+	static long buf[512/sizeof(long)];
+	struct hostent *res;
+	if (gethostbyaddr_r(a, l, af, &h,
+		(void *)buf, sizeof buf, &res, &h_errno)) return 0;
+	return &h;
+}
diff --git a/src/network/gethostbyaddr_r.c b/src/network/gethostbyaddr_r.c
new file mode 100644
index 00000000..cdb1d503
--- /dev/null
+++ b/src/network/gethostbyaddr_r.c
@@ -0,0 +1,71 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <inttypes.h>
+
+int gethostbyaddr_r(const void *a, socklen_t l, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = { .sin.sin_family = af };
+	socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+	int i;
+
+	/* Load address argument into sockaddr structure */
+	if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16);
+	else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4);
+	else {
+		*err = NO_RECOVERY;
+		return -1;
+	}
+
+	/* Align buffer and check for space for pointers and ip address */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen <= 5*sizeof(char *)-i + l) {
+		errno = ERANGE;
+		return -1;
+	}
+	buf += sizeof(char *)-i;
+	buflen -= 5*sizeof(char *)-i + l;
+
+	h->h_addr_list = (void *)buf;
+	buf += 2*sizeof(char *);
+	h->h_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+
+	h->h_addr_list[0] = buf;
+	memcpy(h->h_addr_list[0], a, l);
+	buf += l;
+	h->h_addr_list[1] = 0;
+	h->h_aliases[0] = buf;
+	h->h_aliases[1] = 0;
+
+	switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) {
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return -1;
+	case EAI_OVERFLOW:
+		errno = ERANGE;
+	default:
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return -1;
+	case 0:
+		break;
+	}
+
+	h->h_addrtype = af;
+	h->h_name = h->h_aliases[0];
+	*res = h;
+	return 0;
+}
diff --git a/src/network/gethostbyname.c b/src/network/gethostbyname.c
new file mode 100644
index 00000000..5088a51e
--- /dev/null
+++ b/src/network/gethostbyname.c
@@ -0,0 +1,63 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+
+struct hostent *gethostbyname(const char *name)
+{
+	return gethostbyname2(name, AF_INET);
+}
+
+#if 0
+struct hostent *gethostbyname(const char *name)
+{
+	static struct hostent h;
+	static char *h_aliases[3];
+	static char h_canon[256];
+	static char *h_addr_list[10];
+	static char h_addr_data[10][4];
+	static const struct addrinfo hint = {
+		.ai_family = AF_INET, .ai_flags = AI_CANONNAME
+	};
+	struct addrinfo *ai, *p;
+	int i;
+
+	switch (getaddrinfo(name, 0, &hint, &ai)) {
+	case EAI_NONAME:
+		h_errno = HOST_NOT_FOUND;
+		break;
+	case EAI_AGAIN:
+		h_errno = TRY_AGAIN;
+		break;
+	case EAI_FAIL:
+		h_errno = NO_RECOVERY;
+		break;
+	default:
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		h_errno = NO_DATA;
+		break;
+	case 0:
+		break;
+	}
+
+	strcpy(h_canon, ai->ai_canonname);
+	h.h_name = h_canon;
+	h.h_aliases = h_aliases;
+	h.h_aliases[0] = h_canon;
+	h.h_aliases[1] = strcmp(h_canon, name) ? (char *)name : 0;
+	h.h_length = 4;
+	h.h_addr_list = h_addr_list;
+	for (i=0, p=ai; i<sizeof h_addr_data/4 && p; i++, p=p->ai_next) {
+		h.h_addr_list[i] = h_addr_data[i];
+		memcpy(h.h_addr_list[i],
+			&((struct sockaddr_in *)p->ai_addr)->sin_addr, 4);
+	}
+	h.h_addr_list[i] = 0;
+	h.h_addrtype = AF_INET;
+	freeaddrinfo(ai);
+	return &h;
+}
+#endif
diff --git a/src/network/gethostbyname2.c b/src/network/gethostbyname2.c
new file mode 100644
index 00000000..9fbe2647
--- /dev/null
+++ b/src/network/gethostbyname2.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+
+struct hostent *gethostbyname2(const char *name, int af)
+{
+	static struct hostent h;
+	static long buf[512/sizeof(long)];
+	struct hostent *res;
+	if (gethostbyname2_r(name, af, &h,
+		(void *)buf, sizeof buf, &res, &h_errno)) return 0;
+	return &h;
+}
diff --git a/src/network/gethostbyname2_r.c b/src/network/gethostbyname2_r.c
new file mode 100644
index 00000000..c2ed75b4
--- /dev/null
+++ b/src/network/gethostbyname2_r.c
@@ -0,0 +1,99 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <inttypes.h>
+
+int gethostbyname2_r(const char *name, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	struct addrinfo hint = {
+		.ai_family = af==AF_INET6 ? af : AF_INET,
+		.ai_flags = AI_CANONNAME
+	};
+	struct addrinfo *ai, *p;
+	int i;
+	size_t need;
+	const char *canon;
+
+	af = hint.ai_family;
+
+	/* Align buffer */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (i) {
+		if (buflen < sizeof(char *)-i) {
+			errno = ERANGE;
+			return -1;
+		}
+		buf += sizeof(char *)-i;
+		buflen -= sizeof(char *)-i;
+	}
+
+	getaddrinfo(name, 0, &hint, &ai);
+	switch (getaddrinfo(name, 0, &hint, &ai)) {
+	case EAI_NONAME:
+		*err = HOST_NOT_FOUND;
+		return -1;
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return -1;
+	default:
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return -1;
+	case 0:
+		break;
+	}
+
+	h->h_addrtype = af;
+	h->h_length = af==AF_INET6 ? 16 : 4;
+
+	canon = ai->ai_canonname ? ai->ai_canonname : name;
+	need = 4*sizeof(char *);
+	for (i=0, p=ai; p; i++, p=p->ai_next)
+		need += sizeof(char *) + h->h_length;
+	need += strlen(name)+1;
+	need += strlen(canon)+1;
+
+	if (need > buflen) {
+		freeaddrinfo(ai);
+		errno = ERANGE;
+		return -1;
+	}
+
+	h->h_aliases = (void *)buf;
+	buf += 3*sizeof(char *);
+	h->h_addr_list = (void *)buf;
+	buf += (i+1)*sizeof(char *);
+
+	h->h_name = h->h_aliases[0] = buf;
+	strcpy(h->h_name, canon);
+	buf += strlen(h->h_name)+1;
+
+	if (strcmp(h->h_name, name)) {
+		h->h_aliases[1] = buf;
+		strcpy(h->h_aliases[1], name);
+		buf += strlen(h->h_aliases[1])+1;
+	} else h->h_aliases[1] = 0;
+
+	h->h_aliases[2] = 0;
+
+	for (i=0, p=ai; p; i++, p=p->ai_next) {
+		h->h_addr_list[i] = (void *)buf;
+		buf += h->h_length;
+		memcpy(h->h_addr_list[i],
+			&((struct sockaddr_in *)p->ai_addr)->sin_addr,
+			h->h_length);
+	}
+	h->h_addr_list[i] = 0;
+
+	*res = h;
+	freeaddrinfo(ai);
+	return 0;
+}
diff --git a/src/network/gethostbyname_r.c b/src/network/gethostbyname_r.c
new file mode 100644
index 00000000..cd872541
--- /dev/null
+++ b/src/network/gethostbyname_r.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+int gethostbyname_r(const char *name,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err);
+}
diff --git a/src/network/getnameinfo.c b/src/network/getnameinfo.c
new file mode 100644
index 00000000..0763ca88
--- /dev/null
+++ b/src/network/getnameinfo.c
@@ -0,0 +1,54 @@
+#include <netdb.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "__dns.h"
+
+int getnameinfo(const struct sockaddr *sa, socklen_t sl,
+	char *node, socklen_t nodelen,
+	char *serv, socklen_t servlen,
+	int flags)
+{
+	char buf[256];
+	unsigned char reply[512];
+	int af = sa->sa_family;
+	unsigned char *a;
+
+	switch (af) {
+	case AF_INET:
+		a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
+		if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
+		break;
+	case AF_INET6:
+		a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+		if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
+		break;
+	default:
+		return EAI_FAMILY;
+	}
+
+	if (node && nodelen) {
+		if ((flags & NI_NUMERICHOST)
+			|| __dns_query(reply, a, af, 1) <= 0
+			|| __dns_get_rr(buf, 0, 256, 1, reply, RR_PTR, 1) <= 0)
+		{
+			if (flags & NI_NAMEREQD) return EAI_NONAME;
+			inet_ntop(af, a, buf, sizeof buf);
+		}
+		if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
+		strcpy(node, buf);
+	}
+
+	if (serv && servlen) {
+		if (snprintf(buf, sizeof buf, "%d",
+			ntohs(((struct sockaddr_in *)sa)->sin_port))>=servlen)
+			return EAI_OVERFLOW;
+		strcpy(serv, buf);
+	}
+
+	return 0;
+}
diff --git a/src/network/getpeername.c b/src/network/getpeername.c
new file mode 100644
index 00000000..7ecbe375
--- /dev/null
+++ b/src/network/getpeername.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int getpeername(int fd, struct sockaddr *addr, socklen_t *len)
+{
+	unsigned long args[] = { fd, (unsigned long)addr, (unsigned long)len };
+	return syscall2(__NR_socketcall, SYS_GETPEERNAME, (long)args);
+}
diff --git a/src/network/getservbyname.c b/src/network/getservbyname.c
new file mode 100644
index 00000000..0b00ce11
--- /dev/null
+++ b/src/network/getservbyname.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyname(const char *name, const char *prots)
+{
+	static struct servent se;
+	static long buf[32/sizeof(long)];
+	struct servent *res;
+	if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
diff --git a/src/network/getservbyname_r.c b/src/network/getservbyname_r.c
new file mode 100644
index 00000000..5c025150
--- /dev/null
+++ b/src/network/getservbyname_r.c
@@ -0,0 +1,41 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+
+int getservbyname_r(const char *name, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	struct addrinfo *ai, hint = { .ai_family = AF_INET };
+	int i;
+
+	/* Align buffer */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen < 3*sizeof(char *)-i) {
+		errno = ERANGE;
+		return -1;
+	}
+	buf += sizeof(char *)-i;
+	buflen -= sizeof(char *)-i;
+
+	if (!strcmp(prots, "tcp")) hint.ai_protocol = IPPROTO_TCP;
+	else if (!strcmp(prots, "udp")) hint.ai_protocol = IPPROTO_UDP;
+	else return -1;
+
+	if (getaddrinfo(0, name, &hint, &ai) < 0) return -1;
+
+	se->s_name = (char *)name;
+	se->s_aliases = (void *)buf;
+	se->s_aliases[0] = se->s_name;
+	se->s_aliases[1] = 0;
+	se->s_port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
+	se->s_proto = (char *)prots;
+
+	freeaddrinfo(ai);
+	*res = se;
+	return 0;
+}
diff --git a/src/network/getservbyport.c b/src/network/getservbyport.c
new file mode 100644
index 00000000..c9ecbb11
--- /dev/null
+++ b/src/network/getservbyport.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyport(int port, const char *prots)
+{
+	static struct servent se;
+	static long buf[32/sizeof(long)];
+	struct servent *res;
+	if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
diff --git a/src/network/getservbyport_r.c b/src/network/getservbyport_r.c
new file mode 100644
index 00000000..004a6168
--- /dev/null
+++ b/src/network/getservbyport_r.c
@@ -0,0 +1,43 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+
+int getservbyport_r(int port, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	int i;
+	struct sockaddr_in sin = {
+		.sin_family = AF_INET,
+		.sin_port = port,
+	};
+
+	/* Align buffer */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen < 3*sizeof(char *)-i) {
+		errno = ERANGE;
+		return -1;
+	}
+	buf += sizeof(char *)-i;
+	buflen -= sizeof(char *)-i;
+
+	if (strcmp(prots, "tcp") && strcmp(prots, "udp")) return -1;
+
+	se->s_port = port;
+	se->s_proto = (char *)prots;
+	se->s_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+	buflen -= 2*sizeof(char *);
+	se->s_aliases[1] = 0;
+	se->s_aliases[0] = se->s_name = buf;
+
+	if (getnameinfo((void *)&sin, sizeof sin, 0, 0, buf, buflen, 
+		strcmp(prots, "udp") ? 0 : NI_DGRAM) < 0) return -1;
+
+	*res = se;
+	return 0;
+}
diff --git a/src/network/getsockname.c b/src/network/getsockname.c
new file mode 100644
index 00000000..4b1002f8
--- /dev/null
+++ b/src/network/getsockname.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int getsockname(int fd, struct sockaddr *addr, socklen_t *len)
+{
+	unsigned long args[] = { fd, (unsigned long)addr, (unsigned long)len };
+	return syscall2(__NR_socketcall, SYS_GETSOCKNAME, (long)args);
+}
diff --git a/src/network/getsockopt.c b/src/network/getsockopt.c
new file mode 100644
index 00000000..8c818863
--- /dev/null
+++ b/src/network/getsockopt.c
@@ -0,0 +1,13 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
+{
+	unsigned long args[] = {
+		fd, level, optname,
+		(unsigned long)optval,
+		(unsigned long)optlen
+	};
+	return syscall2(__NR_socketcall, SYS_GETSOCKOPT, (long)args);
+}
diff --git a/src/network/h_errno.c b/src/network/h_errno.c
new file mode 100644
index 00000000..73ead046
--- /dev/null
+++ b/src/network/h_errno.c
@@ -0,0 +1 @@
+int h_errno;
diff --git a/src/network/hstrerror.c b/src/network/hstrerror.c
new file mode 100644
index 00000000..b7a6ab6c
--- /dev/null
+++ b/src/network/hstrerror.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+static const char msgs[] =
+	"Host not found\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Address not available\0"
+	"\0Unknown error";
+
+const char *hstrerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode--; ecode && *s; ecode--, s++) for (; *s; s++);
+	return *s ? s : s+1;
+}
diff --git a/src/network/htonl.c b/src/network/htonl.c
new file mode 100644
index 00000000..b21dace0
--- /dev/null
+++ b/src/network/htonl.c
@@ -0,0 +1,10 @@
+#include <netinet/in.h>
+
+uint32_t htonl(uint32_t n)
+{
+	union {
+		uint8_t b[4];
+		uint32_t i;
+	} u = { { n>>24, n>>16, n>>8, n } };
+	return u.i;
+}
diff --git a/src/network/htons.c b/src/network/htons.c
new file mode 100644
index 00000000..522504a5
--- /dev/null
+++ b/src/network/htons.c
@@ -0,0 +1,10 @@
+#include <netinet/in.h>
+
+uint16_t htons(uint16_t n)
+{
+	union {
+		uint8_t b[2];
+		uint16_t s;
+	} u = { { n>>8, n } };
+	return u.s;
+}
diff --git a/src/network/in6addr_any.c b/src/network/in6addr_any.c
new file mode 100644
index 00000000..995387fa
--- /dev/null
+++ b/src/network/in6addr_any.c
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
diff --git a/src/network/in6addr_loopback.c b/src/network/in6addr_loopback.c
new file mode 100644
index 00000000..b96005b8
--- /dev/null
+++ b/src/network/in6addr_loopback.c
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
diff --git a/src/network/inet_addr.c b/src/network/inet_addr.c
new file mode 100644
index 00000000..84137281
--- /dev/null
+++ b/src/network/inet_addr.c
@@ -0,0 +1,11 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "__dns.h"
+
+in_addr_t inet_addr(const char *p)
+{
+	struct sockaddr_in sin;
+	if (__ipparse(&sin, AF_INET, p)) return -1;
+	return sin.sin_addr.s_addr;
+}
diff --git a/src/network/inet_aton.c b/src/network/inet_aton.c
new file mode 100644
index 00000000..ea4ee165
--- /dev/null
+++ b/src/network/inet_aton.c
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+	return inet_pton(AF_INET, cp, (void *)inp) > 0;
+}
diff --git a/src/network/inet_ntoa.c b/src/network/inet_ntoa.c
new file mode 100644
index 00000000..71411e0b
--- /dev/null
+++ b/src/network/inet_ntoa.c
@@ -0,0 +1,10 @@
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *inet_ntoa(struct in_addr in)
+{
+	static char buf[16];
+	unsigned char *a = (void *)&in;
+	snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
+	return buf;
+}
diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c
new file mode 100644
index 00000000..3e8a6db0
--- /dev/null
+++ b/src/network/inet_ntop.c
@@ -0,0 +1,48 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+const char *inet_ntop(int af, const void *a0, char *s, socklen_t l)
+{
+	const unsigned char *a = a0;
+	int i, j, max, best;
+	char buf[100];
+
+	switch (af) {
+	case AF_INET:
+		if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
+			return s;
+		break;
+	case AF_INET6:
+		memset(buf, 'x', sizeof buf);
+		buf[sizeof buf-1]=0;
+		snprintf(buf, sizeof buf, 
+			"%.0x%x:%.0x%x:%.0x%x:%.0x%x:%.0x%x:%.0x%x:%.0x%x:%.0x%x",
+			a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
+			a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]);
+		/* Replace longest /(^0|:)[:0]{2,}/ with "::" */
+		for (i=best=0, max=2; buf[i]; i++) {
+			if (i && buf[i] != ':') continue;
+			j = strspn(buf+i, ":0");
+			if (j>max) best=i, max=j;
+		}
+		if (max>2) {
+			buf[best] = buf[best+1] = ':';
+			strcpy(buf+best+2, buf+best+max);
+		}
+		if (strlen(buf) < l) {
+			strcpy(s, buf);
+			return s;
+		}
+		break;
+	default:
+		errno = EAFNOSUPPORT;
+		return 0;
+	}
+	errno = ENOSPC;
+	return 0;
+}
diff --git a/src/network/inet_pton.c b/src/network/inet_pton.c
new file mode 100644
index 00000000..349c4025
--- /dev/null
+++ b/src/network/inet_pton.c
@@ -0,0 +1,31 @@
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include "__dns.h"
+
+int inet_pton(int af, const char *s, void *a0)
+{
+	unsigned char *a = a0;
+	const char *z;
+	unsigned long x;
+	int i;
+
+	/* Reimplement this because inet_pton cannot accept special v4 forms */
+	if (af==AF_INET) {
+		for (i=0; i<4 && *s; i++) {
+			a[i] = x = strtoul(s, (char **)&z, 10);
+			if (!isdigit(*s) || z==s || (*z && *z != '.') || x>255)
+				return 0;
+			s=z+1;
+		}
+		return 0;
+	} else if (af==AF_INET6) {
+		return !__ipparse(a, AF_INET6, s);
+	}
+
+	errno = EAFNOSUPPORT;
+	return 0;
+}
diff --git a/src/network/listen.c b/src/network/listen.c
new file mode 100644
index 00000000..7c8c1a8a
--- /dev/null
+++ b/src/network/listen.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int listen(int fd, int backlog)
+{
+	unsigned long args[] = { fd, backlog };
+	return syscall2(__NR_socketcall, SYS_LISTEN, (long)args);
+}
diff --git a/src/network/ntohl.c b/src/network/ntohl.c
new file mode 100644
index 00000000..64379196
--- /dev/null
+++ b/src/network/ntohl.c
@@ -0,0 +1,10 @@
+#include <netinet/in.h>
+
+uint32_t ntohl(uint32_t n)
+{
+	union {
+		uint32_t i;
+		uint8_t b[4];
+	} u = { n };
+	return (u.b[0]<<24) | (u.b[1]<<16) | (u.b[2]<<8) | u.b[3];
+}
diff --git a/src/network/ntohs.c b/src/network/ntohs.c
new file mode 100644
index 00000000..3544a479
--- /dev/null
+++ b/src/network/ntohs.c
@@ -0,0 +1,10 @@
+#include <netinet/in.h>
+
+uint16_t ntohs(uint16_t n)
+{
+	union {
+		uint16_t s;
+		uint8_t b[2];
+	} u = { n };
+	return (u.b[0]<<8) | u.b[1];
+}
diff --git a/src/network/proto.c b/src/network/proto.c
new file mode 100644
index 00000000..8c25c53a
--- /dev/null
+++ b/src/network/proto.c
@@ -0,0 +1,58 @@
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+/* do we really need all these?? */
+
+static int idx;
+static const unsigned char protos[][6] = {
+	"\000ip",
+	"\001icmp",
+	"\002igmp",
+	"\003ggp",
+	"\006tcp",
+	"\014pup",
+	"\021udp",
+	"\026idp",
+	"\377raw"
+	"\0\0"
+};
+
+void endprotoent(void)
+{
+	idx = 0;
+}
+
+void setprotoent(int stayopen)
+{
+	idx = 0;
+}
+
+struct protoent *getprotoent(void)
+{
+	static struct protoent p;
+	static const char *aliases;
+	if (!protos[idx][1]) return NULL;
+	p.p_proto = protos[idx][0];
+	p.p_name = (char *)protos[idx++]+1;
+	p.p_aliases = (char **)&aliases;
+	return &p;
+}
+
+struct protoent *getprotobyname(const char *name)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && strcmp(name, p->p_name));
+	return p;
+}
+
+struct protoent *getprotobynumber(int num)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && p->p_proto != num);
+	return p;
+}
diff --git a/src/network/recv.c b/src/network/recv.c
new file mode 100644
index 00000000..521a4b19
--- /dev/null
+++ b/src/network/recv.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t recv(int fd, void *buf, size_t len, int flags)
+{
+	unsigned long args[] = { fd, (unsigned long)buf, len, flags };
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_RECV, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/recvfrom.c b/src/network/recvfrom.c
new file mode 100644
index 00000000..df50114b
--- /dev/null
+++ b/src/network/recvfrom.c
@@ -0,0 +1,17 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *alen)
+{
+	unsigned long args[] = {
+		fd, (unsigned long)buf, len, flags,
+		(unsigned long)addr, (unsigned long)alen
+	};
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_RECVFROM, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/recvmsg.c b/src/network/recvmsg.c
new file mode 100644
index 00000000..ead16f9c
--- /dev/null
+++ b/src/network/recvmsg.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	unsigned long args[] = { fd, (unsigned long)msg, flags };
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_RECVMSG, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/res_init.c b/src/network/res_init.c
new file mode 100644
index 00000000..cbd5b155
--- /dev/null
+++ b/src/network/res_init.c
@@ -0,0 +1,4 @@
+int res_init()
+{
+	return 0;
+}
diff --git a/src/network/res_query.c b/src/network/res_query.c
new file mode 100644
index 00000000..4ebeb102
--- /dev/null
+++ b/src/network/res_query.c
@@ -0,0 +1,20 @@
+#include <netdb.h>
+#include "__dns.h"
+
+int res_query(const char *name, int class, int type, unsigned char *dest, int len)
+{
+	if (class != 1 || len < 512)
+		return -1;
+	switch(__dns_doqueries(dest, name, &type, 1)) {
+	case EAI_NONAME:
+		h_errno = HOST_NOT_FOUND;
+		return -1;
+	case EAI_AGAIN:
+		h_errno = TRY_AGAIN;
+		return -1;
+	case EAI_FAIL:
+		h_errno = NO_RECOVERY;
+		return -1;
+	}
+	return 512;
+}
diff --git a/src/network/send.c b/src/network/send.c
new file mode 100644
index 00000000..d72fb03c
--- /dev/null
+++ b/src/network/send.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t send(int fd, const void *buf, size_t len, int flags)
+{
+	unsigned long args[] = { fd, (unsigned long)buf, len, flags };
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_SEND, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/sendmsg.c b/src/network/sendmsg.c
new file mode 100644
index 00000000..ea2fe482
--- /dev/null
+++ b/src/network/sendmsg.c
@@ -0,0 +1,14 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+	unsigned long args[] = { fd, (unsigned long)msg, flags };
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_SENDMSG, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/sendto.c b/src/network/sendto.c
new file mode 100644
index 00000000..5d224b0b
--- /dev/null
+++ b/src/network/sendto.c
@@ -0,0 +1,17 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+#include "libc.h"
+
+ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+{
+	unsigned long args[] = {
+		fd, (unsigned long)buf, len, flags,
+		(unsigned long)addr, alen
+	};
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall2(__NR_socketcall, SYS_SENDTO, (long)args);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/network/serv.c b/src/network/serv.c
new file mode 100644
index 00000000..5ade6ad1
--- /dev/null
+++ b/src/network/serv.c
@@ -0,0 +1,16 @@
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+void endservent(void)
+{
+}
+
+void setservent(int stayopen)
+{
+}
+
+struct servent *getservent(void)
+{
+	return 0;
+}
diff --git a/src/network/setsockopt.c b/src/network/setsockopt.c
new file mode 100644
index 00000000..b50303b8
--- /dev/null
+++ b/src/network/setsockopt.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	unsigned long args[] = { fd, level, optname, (unsigned long)optval, optlen };
+	return syscall2(__NR_socketcall, SYS_SETSOCKOPT, (long)args);
+}
diff --git a/src/network/shutdown.c b/src/network/shutdown.c
new file mode 100644
index 00000000..91950c8a
--- /dev/null
+++ b/src/network/shutdown.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int shutdown(int fd, int how)
+{
+	unsigned long args[] = { fd, how };
+	return syscall2(__NR_socketcall, SYS_SHUTDOWN, (long)args);
+}
diff --git a/src/network/sockatmark.c b/src/network/sockatmark.c
new file mode 100644
index 00000000..5328a855
--- /dev/null
+++ b/src/network/sockatmark.c
@@ -0,0 +1,11 @@
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include "socketcall.h"
+
+int sockatmark(int s)
+{
+	int ret;
+	if (ioctl(s, SIOCATMARK, &ret) < 0)
+		return -1;
+	return ret;
+}
diff --git a/src/network/socket.c b/src/network/socket.c
new file mode 100644
index 00000000..afaeb411
--- /dev/null
+++ b/src/network/socket.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int socket(int domain, int type, int protocol)
+{
+	unsigned long args[] = { domain, type, protocol };
+	return syscall2(__NR_socketcall, SYS_SOCKET, (long)args);
+}
diff --git a/src/network/socketcall.h b/src/network/socketcall.h
new file mode 100644
index 00000000..9ae98587
--- /dev/null
+++ b/src/network/socketcall.h
@@ -0,0 +1,24 @@
+#define SYS_SOCKET      1
+#define SYS_BIND        2
+#define SYS_CONNECT     3
+#define SYS_LISTEN      4
+#define SYS_ACCEPT      5
+#define SYS_GETSOCKNAME 6
+#define SYS_GETPEERNAME 7
+#define SYS_SOCKETPAIR  8
+#define SYS_SEND        9
+#define SYS_RECV        10
+#define SYS_SENDTO      11
+#define SYS_RECVFROM    12
+#define SYS_SHUTDOWN    13
+#define SYS_SETSOCKOPT  14
+#define SYS_GETSOCKOPT  15
+#define SYS_SENDMSG     16
+#define SYS_RECVMSG     17
+
+#define FIOSETOWN       0x8901
+#define SIOCSPGRP       0x8902
+#define FIOGETOWN       0x8903
+#define SIOCGPGRP       0x8904
+#define SIOCATMARK      0x8905
+#define SIOCGSTAMP      0x8906
diff --git a/src/network/socketpair.c b/src/network/socketpair.c
new file mode 100644
index 00000000..65a47fd9
--- /dev/null
+++ b/src/network/socketpair.c
@@ -0,0 +1,9 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "socketcall.h"
+
+int socketpair(int domain, int type, int protocol, int fd[2])
+{
+	unsigned long args[] = { domain, type, protocol, (unsigned long)fd };
+	return syscall2(__NR_socketcall, SYS_SOCKETPAIR, (long)args);
+}
diff --git a/src/passwd/getgr_r.c b/src/passwd/getgr_r.c
new file mode 100644
index 00000000..5b1333e3
--- /dev/null
+++ b/src/passwd/getgr_r.c
@@ -0,0 +1,53 @@
+#include "pwf.h"
+
+#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
+
+static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	FILE *f;
+	char *line = 0;
+	size_t len = 0;
+	char **mem = 0;
+	size_t nmem = 0;
+	int rv = 0;
+	size_t i;
+
+	f = fopen("/etc/group", "rb");
+	if (!f) return errno;
+
+	*res = 0;
+	while (__getgrent_a(f, gr, &line, &len, &mem, &nmem)) {
+		if (name && !strcmp(name, gr->gr_name)
+		|| !name && gr->gr_gid == gid) {
+			if (size < len + nmem*sizeof(char *) + 32) {
+				rv = ERANGE;
+				break;
+			}
+			*res = gr;
+			buf += (16-(uintptr_t)buf)%16;
+			gr->gr_mem = (void *)buf;
+			buf += nmem*sizeof(char *);
+			memcpy(buf, line, len);
+			FIX(name);
+			FIX(passwd);
+			for (i=0; mem[i]; i++)
+				gr->gr_mem[i] = mem[i]-line+buf;
+			gr->gr_mem[i] = 0;
+			break;
+		}
+	}
+ 	free(mem);
+ 	free(line);
+	fclose(f);
+	return rv;
+}
+
+int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(name, 0, gr, buf, size, res);
+}
+
+int getgruid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(0, gid, gr, buf, size, res);
+}
diff --git a/src/passwd/getgrent.c b/src/passwd/getgrent.c
new file mode 100644
index 00000000..e9d25eba
--- /dev/null
+++ b/src/passwd/getgrent.c
@@ -0,0 +1,39 @@
+#include "pwf.h"
+
+static FILE *f;
+
+void setgrent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setgrent, endgrent);
+
+struct group *getgrent()
+{
+	static char *line, **mem;
+	static struct group gr;
+	size_t size=0, nmem=0;
+	if (!f) f = fopen("/etc/group", "rb");
+	if (!f) return 0;
+	return __getgrent_a(f, &gr, &line, &size, &mem, &nmem);
+}
+
+struct group *getgrgid(gid_t gid)
+{
+	struct group *gr;
+	setgrent();
+	while ((gr=getgrent()) && gr->gr_gid != gid);
+	endgrent();
+	return gr;
+}
+
+struct group *getgrnam(const char *name)
+{
+	struct group *gr;
+	setgrent();
+	while ((gr=getgrent()) && strcmp(gr->gr_name, name));
+	endgrent();
+	return gr;
+}
diff --git a/src/passwd/getgrent_a.c b/src/passwd/getgrent_a.c
new file mode 100644
index 00000000..ccb51d52
--- /dev/null
+++ b/src/passwd/getgrent_a.c
@@ -0,0 +1,46 @@
+#include "pwf.h"
+
+struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem)
+{
+	ssize_t l;
+	char *s, *mems;
+	size_t i;
+
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			free(*line);
+			*line = 0;
+			return 0;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		gr->gr_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_gid = atoi(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; mems = s;
+		break;
+	}
+
+	for (*nmem=!!*s; *s; s++)
+		if (*s==',') ++*nmem;
+	free(*mem);
+	*mem = calloc(sizeof(char *), *nmem+1);
+	if (!*mem) {
+		free(*line);
+		*line = 0;
+		return 0;
+	}
+	mem[0][0] = mems;
+	for (s=mems, i=0; *s; s++)
+		if (*s==',') *s++ = 0, mem[0][++i] = s;
+	mem[0][++i] = 0;
+	gr->gr_mem = *mem;
+	return gr;
+}
diff --git a/src/passwd/getpw_r.c b/src/passwd/getpw_r.c
new file mode 100644
index 00000000..7b331e8a
--- /dev/null
+++ b/src/passwd/getpw_r.c
@@ -0,0 +1,46 @@
+#include "pwf.h"
+
+#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
+
+static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	FILE *f;
+	char *line = 0;
+	size_t len = 0;
+	int rv = 0;
+
+	f = fopen("/etc/passwd", "rb");
+	if (!f) return errno;
+
+	*res = 0;
+	while (__getpwent_a(f, pw, &line, &len)) {
+		if (name && !strcmp(name, pw->pw_name)
+		|| !name && pw->pw_uid == uid) {
+			if (size < len) {
+				rv = ERANGE;
+				break;
+			}
+			*res = pw;
+			memcpy(buf, line, len);
+			FIX(name);
+			FIX(passwd);
+			FIX(gecos);
+			FIX(dir);
+			FIX(shell);
+			break;
+		}
+	}
+ 	free(line);
+	fclose(f);
+	return rv;
+}
+
+int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(name, 0, pw, buf, size, res);
+}
+
+int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(0, uid, pw, buf, size, res);
+}
diff --git a/src/passwd/getpwent.c b/src/passwd/getpwent.c
new file mode 100644
index 00000000..dabd411a
--- /dev/null
+++ b/src/passwd/getpwent.c
@@ -0,0 +1,39 @@
+#include "pwf.h"
+
+static FILE *f;
+
+void setpwent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setpwent, endpwent);
+
+struct passwd *getpwent()
+{
+	static char *line;
+	static struct passwd pw;
+	size_t size=0;
+	if (!f) f = fopen("/etc/passwd", "rb");
+	if (!f) return 0;
+	return __getpwent_a(f, &pw, &line, &size);
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+	struct passwd *pw;
+	setpwent();
+	while ((pw=getpwent()) && pw->pw_uid != uid);
+	endpwent();
+	return pw;
+}
+
+struct passwd *getpwnam(const char *name)
+{
+	struct passwd *pw;
+	setpwent();
+	while ((pw=getpwent()) && strcmp(pw->pw_name, name));
+	endpwent();
+	return pw;
+}
diff --git a/src/passwd/getpwent_a.c b/src/passwd/getpwent_a.c
new file mode 100644
index 00000000..aaf84edd
--- /dev/null
+++ b/src/passwd/getpwent_a.c
@@ -0,0 +1,37 @@
+#include "pwf.h"
+
+struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size)
+{
+	ssize_t l;
+	char *s;
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			free(*line);
+			*line = 0;
+			return 0;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		pw->pw_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_uid = atoi(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_gid = atoi(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_gecos = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_dir = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_shell = s;
+		return pw;
+	}
+}
diff --git a/src/passwd/getspent.c b/src/passwd/getspent.c
new file mode 100644
index 00000000..8574a480
--- /dev/null
+++ b/src/passwd/getspent.c
@@ -0,0 +1,14 @@
+#include "pwf.h"
+
+void setspent()
+{
+}
+
+void endspent()
+{
+}
+
+struct spwd *getspent()
+{
+	return 0;
+}
diff --git a/src/passwd/getspnam.c b/src/passwd/getspnam.c
new file mode 100644
index 00000000..041f8965
--- /dev/null
+++ b/src/passwd/getspnam.c
@@ -0,0 +1,17 @@
+#include "pwf.h"
+
+#define LINE_LIM 256
+
+struct spwd *getspnam(const char *name)
+{
+	static struct spwd sp;
+	static char *line;
+	struct spwd *res;
+	int e;
+
+	if (!line) line = malloc(LINE_LIM);
+	if (!line) return 0;
+	e = getspnam_r(name, &sp, line, LINE_LIM, &res);
+	if (e) errno = e;
+	return res;
+}
diff --git a/src/passwd/getspnam_r.c b/src/passwd/getspnam_r.c
new file mode 100644
index 00000000..1dd39ce0
--- /dev/null
+++ b/src/passwd/getspnam_r.c
@@ -0,0 +1,89 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include "pwf.h"
+
+/* This implementation support Openwall-style TCB passwords in place of
+ * traditional shadow, if the appropriate directories and files exist.
+ * Thus, it is careful to avoid following symlinks or blocking on fifos
+ * which a malicious user might create in place of his or her TCB shadow
+ * file. It also avoids any allocation to prevent memory-exhaustion
+ * attacks via huge TCB shadow files. */
+
+int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
+{
+	char path[20+NAME_MAX];
+	FILE *f = 0;
+	int rv = 0;
+	int fd;
+	size_t k, l = strlen(name);
+	char *s;
+	int skip = 0;
+
+	*res = 0;
+
+	/* Disallow potentially-malicious user names */
+	if (*name=='.' || strchr(name, '/') || !l)
+		return EINVAL;
+
+	/* Buffer size must at least be able to hold name, plus some.. */
+	if (size < l+100) return ERANGE;
+
+	/* Protect against truncation */
+	if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
+		return EINVAL;
+
+	fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK);
+	if (fd >= 0) {
+		f = fdopen(fd, "rb");
+		if (!f) {
+			close(fd);
+			return errno;
+		}
+	} else {
+		f = fopen("/etc/shadow", "rb");
+		if (!f) return errno;
+	}
+
+	while (fgets(buf, size, f) && (k=strlen(buf))>0) {
+		if (skip || strncmp(name, buf, l)) {
+			skip = buf[k-1] != '\n';
+			continue;
+		}
+		if (buf[k-1] != '\n') {
+			rv = ERANGE;
+			break;
+		}
+		buf[k-1] = 0;
+
+		s = buf;
+		sp->sp_namp = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_pwdp = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_lstchg = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_min = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_max = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_warn = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_inact = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_expire = atol(s);
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; sp->sp_flag = atol(s);
+		*res = sp;
+		break;
+	}
+	fclose(f);
+	return rv;
+}
diff --git a/src/passwd/lckpwdf.c b/src/passwd/lckpwdf.c
new file mode 100644
index 00000000..2feda617
--- /dev/null
+++ b/src/passwd/lckpwdf.c
@@ -0,0 +1,11 @@
+#include <shadow.h>
+
+int lckpwdf()
+{
+	return 0;
+}
+
+int ulckpwdf()
+{
+	return 0;
+}
diff --git a/src/passwd/pwf.h b/src/passwd/pwf.h
new file mode 100644
index 00000000..0a76ef80
--- /dev/null
+++ b/src/passwd/pwf.h
@@ -0,0 +1,13 @@
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include "libc.h"
+
+struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size);
+struct spwd *__getspent_a(FILE *f, struct spwd *sp, char **line, size_t *size);
+struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem);
diff --git a/src/prng/__rand48_step.c b/src/prng/__rand48_step.c
new file mode 100644
index 00000000..755b4f2f
--- /dev/null
+++ b/src/prng/__rand48_step.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc)
+{
+	uint64_t a, x;
+	x = xi[0] | xi[1]<<16 | xi[2]+0ULL<<32;
+	a = lc[0] | lc[1]<<16 | lc[2]+0ULL<<32;
+	x = a*x + lc[3];
+	xi[0] = x;
+	xi[1] = x>>16;
+	xi[2] = x>>32;
+	return x & 0xffffffffffffull;
+}
diff --git a/src/prng/__seed48.c b/src/prng/__seed48.c
new file mode 100644
index 00000000..05a4539e
--- /dev/null
+++ b/src/prng/__seed48.c
@@ -0,0 +1 @@
+unsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
diff --git a/src/prng/drand48.c b/src/prng/drand48.c
new file mode 100644
index 00000000..d808353c
--- /dev/null
+++ b/src/prng/drand48.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+double erand48(unsigned short s[3])
+{
+	union {
+		uint64_t u;
+		double f;
+	} x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 };
+	return x.f - 1.0;
+}
+
+double drand48(void)
+{
+	return erand48(__seed48);
+}
diff --git a/src/prng/lcong48.c b/src/prng/lcong48.c
new file mode 100644
index 00000000..32b27d42
--- /dev/null
+++ b/src/prng/lcong48.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned short __seed48[7];
+
+void lcong48(unsigned short p[7])
+{
+	memcpy(__seed48, p, sizeof __seed48);
+}
diff --git a/src/prng/lrand48.c b/src/prng/lrand48.c
new file mode 100644
index 00000000..a3c4e4e2
--- /dev/null
+++ b/src/prng/lrand48.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+long nrand48(unsigned short s[3])
+{
+	return __rand48_step(s, __seed48+3) >> 17;
+}
+
+long lrand48(void)
+{
+	return nrand48(__seed48);
+}
diff --git a/src/prng/mrand48.c b/src/prng/mrand48.c
new file mode 100644
index 00000000..ee650fc3
--- /dev/null
+++ b/src/prng/mrand48.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+long jrand48(unsigned short s[3])
+{
+	return __rand48_step(s, __seed48+3) >> 16;
+}
+
+long mrand48(void)
+{
+	return jrand48(__seed48);
+}
diff --git a/src/prng/rand.c b/src/prng/rand.c
new file mode 100644
index 00000000..e3ce6347
--- /dev/null
+++ b/src/prng/rand.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+
+static unsigned seed;
+
+void srand(unsigned s)
+{
+	seed = s-1;
+}
+
+int rand(void)
+{
+	return (seed = (seed+1) * 1103515245 + 12345 - 1)+1 & 0x7fffffff;
+}
diff --git a/src/prng/rand_r.c b/src/prng/rand_r.c
new file mode 100644
index 00000000..e96cfba9
--- /dev/null
+++ b/src/prng/rand_r.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+int rand_r(unsigned *seed)
+{
+	return (*seed = *seed * 1103515245 + 12345) & 0x7fffffff;
+}
diff --git a/src/prng/random.c b/src/prng/random.c
new file mode 100644
index 00000000..e6b7fd1f
--- /dev/null
+++ b/src/prng/random.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+/* FIXME */
+
+long random()
+{
+	return rand();
+}
diff --git a/src/prng/seed48.c b/src/prng/seed48.c
new file mode 100644
index 00000000..e0699c09
--- /dev/null
+++ b/src/prng/seed48.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned short __seed48[7];
+
+unsigned short *seed48(unsigned short *s)
+{
+	static unsigned short p[3];
+	memcpy(p, __seed48, sizeof p);
+	memcpy(__seed48, s, sizeof p);
+	return p;
+}
diff --git a/src/prng/srand48.c b/src/prng/srand48.c
new file mode 100644
index 00000000..0a56f6a0
--- /dev/null
+++ b/src/prng/srand48.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+void srand48(long seed)
+{
+	seed48((unsigned short [3]){ 0x330e, seed, seed>>16 });
+}
diff --git a/src/prng/srandom.c b/src/prng/srandom.c
new file mode 100644
index 00000000..77f4dcbd
--- /dev/null
+++ b/src/prng/srandom.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+/* FIXME */
+
+void srandom(unsigned seed)
+{
+	return srand(seed);
+}
diff --git a/src/process/execl.c b/src/process/execl.c
new file mode 100644
index 00000000..4c6eaa94
--- /dev/null
+++ b/src/process/execl.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execl(const char *path, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, path);
+	for (argc=0; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, path);
+		for (i=0; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		return execv(path, argv);
+	}
+}
diff --git a/src/process/execle.c b/src/process/execle.c
new file mode 100644
index 00000000..37f629d9
--- /dev/null
+++ b/src/process/execle.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execle(const char *path, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, path);
+	for (argc=0; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		char **envp;
+		va_start(ap, path);
+		for (i=0; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		envp = va_arg(ap, char **);
+		return execve(path, argv, envp);
+	}
+}
diff --git a/src/process/execlp.c b/src/process/execlp.c
new file mode 100644
index 00000000..33fb0f7f
--- /dev/null
+++ b/src/process/execlp.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execlp(const char *file, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, file);
+	for (argc=0; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, file);
+		for (i=0; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		return execvp(file, argv);
+	}
+}
diff --git a/src/process/execv.c b/src/process/execv.c
new file mode 100644
index 00000000..2ac0dec0
--- /dev/null
+++ b/src/process/execv.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+extern char **__environ;
+
+int execv(const char *path, char *const argv[])
+{
+	return execve(path, argv, __environ);
+}
diff --git a/src/process/execve.c b/src/process/execve.c
new file mode 100644
index 00000000..2a0b62d6
--- /dev/null
+++ b/src/process/execve.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int execve(const char *path, char *const argv[], char *const envp[])
+{
+	/* do we need to use environ if envp is null? */
+	return syscall3(__NR_execve, (long)path, (long)argv, (long)envp);
+}
diff --git a/src/process/execvp.c b/src/process/execvp.c
new file mode 100644
index 00000000..d799ddae
--- /dev/null
+++ b/src/process/execvp.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+extern char **__environ;
+
+int execvp(const char *file, char *const argv[])
+{
+	const char *p, *z, *path = getenv("PATH");
+	int l;
+
+	if (strchr(file, '/'))
+		return execve(file, argv, __environ);
+
+	/* FIXME: integer overflows */
+	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+	l = strlen(file) + strlen(path) + 2;
+
+	for(p=path; p && *p; p=z) {
+		char b[l];
+		z = strchr(p, ':');
+		if (z) {
+			memcpy(b, p, z-p);
+			b[z++-p] = 0;
+		} else strcpy(b, p);
+		strcat(b, "/");
+		strcat(b, file);
+		if (!access(b, X_OK))
+			return execve(b, argv, __environ);
+	}
+	errno = ENOENT;
+	return -1;
+}
diff --git a/src/process/fork.c b/src/process/fork.c
new file mode 100644
index 00000000..1213f0f5
--- /dev/null
+++ b/src/process/fork.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+/* FIXME: add support for atfork stupidity */
+
+pid_t fork(void)
+{
+	return syscall0(__NR_fork);
+}
diff --git a/src/process/system.c b/src/process/system.c
new file mode 100644
index 00000000..0f1c07b5
--- /dev/null
+++ b/src/process/system.c
@@ -0,0 +1,45 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+int system(const char *cmd)
+{
+	pid_t pid;
+	sigset_t old, new;
+	struct sigaction sa, oldint, oldquit;
+	int status;
+
+	if (!cmd) return 1;
+
+	sa.sa_handler = SIG_IGN;
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = 0;
+
+	sigaction(SIGINT, &sa, &oldint);
+	sigaction(SIGQUIT, &sa, &oldquit);
+	sigaddset(&sa.sa_mask, SIGCHLD);
+	sigprocmask(SIG_BLOCK, &new, &old);
+
+	pid = fork();
+	if (pid <= 0) {
+		sigaction(SIGINT, &oldint, NULL);
+		sigaction(SIGQUIT, &oldquit, NULL);
+		sigprocmask(SIG_SETMASK, &old, NULL);
+		if (pid == 0) {
+			execl("/bin/sh", "sh", "-c", cmd, (char *)0);
+			_exit(127);
+		}
+		return -1;
+	}
+	while (waitpid(pid, &status, 0) == -1)
+		if (errno != EINTR) {
+			status = -1;
+			break;
+		}
+	sigaction(SIGINT, &oldint, NULL);
+	sigaction(SIGQUIT, &oldquit, NULL);
+	sigprocmask(SIG_SETMASK, &old, NULL);
+	return status;
+}
diff --git a/src/process/vfork.c b/src/process/vfork.c
new file mode 100644
index 00000000..32a7a6ed
--- /dev/null
+++ b/src/process/vfork.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t vfork(void)
+{
+	/* vfork syscall cannot be made from C code */
+	return syscall0(__NR_fork);
+}
diff --git a/src/process/wait.c b/src/process/wait.c
new file mode 100644
index 00000000..34da102d
--- /dev/null
+++ b/src/process/wait.c
@@ -0,0 +1,6 @@
+#include <sys/wait.h>
+
+pid_t wait(int *status)
+{
+	return waitpid((pid_t)-1, status, 0);
+}
diff --git a/src/process/waitid.c b/src/process/waitid.c
new file mode 100644
index 00000000..0ec0d55c
--- /dev/null
+++ b/src/process/waitid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+int waitid(idtype_t type, id_t id, siginfo_t *info, int options)
+{
+	return syscall5(__NR_waitid, type, id, (long)info, options, 0);
+}
diff --git a/src/process/waitpid.c b/src/process/waitpid.c
new file mode 100644
index 00000000..0ddcd15a
--- /dev/null
+++ b/src/process/waitpid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+pid_t waitpid(pid_t pid, int *status, int options)
+{
+	return syscall4(__NR_wait4, pid, (long)status, options, 0);
+}
diff --git a/src/regex/fnmatch.c b/src/regex/fnmatch.c
new file mode 100644
index 00000000..5f2fccdb
--- /dev/null
+++ b/src/regex/fnmatch.c
@@ -0,0 +1,150 @@
+#include <fnmatch.h>
+#include <wctype.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include <limits.h>
+
+static int next(const char **s)
+{
+	wchar_t c;
+	int l = mbtowc(&c, *s, MB_LEN_MAX);
+	/* hack to allow literal matches of invalid byte sequences */
+	if (l < 0) return (unsigned char)*(*s)++ - 0x100;
+	*s += l;
+	return c;
+}
+
+#define BRACKET_ERROR  -0x100
+#define BRACKET_NOCHAR -0x101
+
+static int bracket_next(const char **s)
+{
+	int c;
+	int type;
+	if (**s == '[') {
+		type = *(*s+1);
+		if (type == '.' || type == '=') {
+			*s += 2;
+			c = next(s);
+			if (c <= 0) return BRACKET_ERROR;
+			if (**s == type && *(*s+1) == ']') {
+				*s += 2;
+				return c;
+			}
+			for (; **s && (**s != type || *(*s+1) != ']'); (*s)++);
+			if (!**s) return BRACKET_ERROR;
+			*s += 2;
+			return BRACKET_NOCHAR;
+		}
+	}
+	c = next(s);
+	if (c <= 0) return BRACKET_ERROR;
+	return c;
+}
+
+#define __FNM_CONT 0x8000
+
+int fnmatch(const char *p, const char *s, int flags)
+{
+	int c, d, k;
+	int not;
+	int match;
+	int first;
+	int no_slash = (flags & FNM_PATHNAME) ? '/' : 0;
+	int no_period = (flags & FNM_PERIOD) && !(flags & __FNM_CONT) ? '.' : 0x100;
+
+	flags |= __FNM_CONT;
+
+	while ((c = *p++)) {
+		switch (c) {
+		case '?':
+			k = next(&s);
+			if (!k || k == no_period || k == no_slash)
+				return FNM_NOMATCH;
+			break;
+		case '\\':
+			if (!(flags & FNM_NOESCAPE)) {
+				c = *p++;
+				goto literal;
+			}
+			if (*s++ != c) return FNM_NOMATCH;
+			break;
+		case '*':
+			for (; *p == '*'; p++);
+			if (*p && !*s) return FNM_NOMATCH;
+			if (*s == no_period)
+				return FNM_NOMATCH;
+			if (!*p && (!no_slash || !strchr(s, no_slash)))
+				return 0;
+			for (; *s; s++)
+				if (!fnmatch(p, s, flags))
+					return 0;
+				else if (*s == no_slash)
+					break;
+			return FNM_NOMATCH;
+		case '[':
+			not = (*p == '!' || *p == '^');
+			if (not) p++;
+			k = next(&s);
+			if (!k || k == no_slash || k == no_period)
+				return FNM_NOMATCH;
+			match = 0;
+			first = 1;
+			for (;;) {
+				if (!*p) return FNM_NOMATCH;
+				if (*p == ']' && !first) break;
+				first = 0;
+				if (*p == '[' && *(p+1) == ':') {
+					const char *z;
+					p += 2;
+					for (z=p; *z && (*z != ':' || *(z+1) != ']'); z++);
+					if (!*z || z-p > 32) { /* FIXME: symbolic const? */
+						return FNM_NOMATCH;
+					} else {
+						char class[z-p+1];
+						memcpy(class, p, z-p);
+						class[z-p] = 0;
+						if (iswctype(k, wctype(class)))
+							match = 1;
+					}
+					p = z+2;
+					continue;
+				}
+				c = bracket_next(&p);
+				if (c == BRACKET_ERROR)
+					return FNM_NOMATCH;
+				if (c == BRACKET_NOCHAR)
+					continue;
+				if (*p == '-' && *(p+1) != ']') {
+					p++;
+					d = bracket_next(&p);
+					if (d == BRACKET_ERROR)
+						return FNM_NOMATCH;
+					if (d == BRACKET_NOCHAR)
+						continue;
+					if (k >= c && k <= d)
+						match = 1;
+					continue;
+				}
+				if (k == c) match = 1;
+			}
+			p++;
+			if (not == match)
+				return FNM_NOMATCH;
+			break;
+		default:
+		literal:
+			if (*s++ != c)
+				return FNM_NOMATCH;
+			if (c == no_slash && (flags & FNM_PERIOD)) {
+				no_period = '.';
+				continue;
+			}
+			break;
+		}
+		no_period = 0x100;
+	}
+	if (*s) return FNM_NOMATCH;
+	return 0;
+}
diff --git a/src/regex/glob.c b/src/regex/glob.c
new file mode 100644
index 00000000..9a70f0bc
--- /dev/null
+++ b/src/regex/glob.c
@@ -0,0 +1,238 @@
+#include <glob.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "libc.h"
+
+struct match
+{
+	struct match *next;
+	char name[1];
+};
+
+static int is_literal(const char *p, int useesc)
+{
+	int bracket = 0;
+	for (; *p; p++) {
+		switch (*p) {
+		case '\\':
+			if (!useesc) break;
+		case '?':
+		case '*':
+			return 0;
+		case '[':
+			bracket = 1;
+			break;
+		case ']':
+			if (bracket) return 0;
+			break;
+		}
+	}
+	return 1;
+}
+
+static int append(struct match **tail, const char *name, size_t len, int mark)
+{
+	struct match *new = malloc(sizeof(struct match) + len + 1);
+	if (!new) return -1;
+	(*tail)->next = new;
+	new->next = NULL;
+	strcpy(new->name, name);
+	if (mark) strcat(new->name, "/");
+	*tail = new;
+	return 0;
+}
+
+static int match_in_dir(const char *d, const char *p, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
+{
+	DIR *dir;
+	long long de_buf[(sizeof(struct dirent) + NAME_MAX + sizeof(long long))/sizeof(long long)];
+	struct dirent *de;
+	char pat[strlen(p)+1];
+	char *p2;
+	size_t l = strlen(d);
+	int literal;
+	int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) | FNM_PERIOD;
+	int error;
+
+	if ((p2 = strchr(p, '/'))) {
+		strcpy(pat, p);
+		pat[p2-p] = 0;
+		for (; *p2 == '/'; p2++);
+		p = pat;
+	}
+	literal = is_literal(p, !(flags & GLOB_NOESCAPE));
+	if (*d == '/' && !*(d+1)) l = 0;
+
+	/* rely on opendir failing for nondirectory objects */
+	dir = opendir(*d ? d : ".");
+	error = errno;
+	if (!dir) {
+		/* this is not an error -- we let opendir call stat for us */
+		if (error == ENOTDIR) return 0;
+		if (error == EACCES && !*p) {
+			struct stat st;
+			if (!stat(d, &st) && S_ISDIR(st.st_mode)) {
+				if (append(tail, d, l, l))
+					return GLOB_NOSPACE;
+				return 0;
+			}
+		}
+		if (errfunc(d, error) || (flags & GLOB_ERR))
+			return GLOB_ABORTED;
+		return 0;
+	}
+	if (!*p) {
+		error = append(tail, d, l, l) ? GLOB_NOSPACE : 0;
+		closedir(dir);
+		return error;
+	}
+	while (!(error = readdir_r(dir, (void *)de_buf, &de)) && de) {
+		char namebuf[l+de->d_reclen+2], *name = namebuf;
+		if (!literal && fnmatch(p, de->d_name, fnm_flags))
+			continue;
+		if (literal && strcmp(p, de->d_name))
+			continue;
+		if (p2 && de->d_type && !S_ISDIR(de->d_type<<12) && !S_ISLNK(de->d_type<<12))
+			continue;
+		if (*d) {
+			memcpy(name, d, l);
+			name[l] = '/';
+			strcpy(name+l+1, de->d_name);
+		} else {
+			name = de->d_name;
+		}
+		if (p2) {
+			if ((error = match_in_dir(name, p2, flags, errfunc, tail))) {
+				closedir(dir);
+				return error;
+			}
+		} else {
+			int mark = 0;
+			if (flags & GLOB_MARK) {
+				if (de->d_type)
+					mark = S_ISDIR(de->d_type<<12);
+				else {
+					struct stat st;
+					stat(name, &st);
+					mark = S_ISDIR(st.st_mode);
+				}
+			}
+			if (append(tail, name, l+de->d_reclen+1, mark)) {
+				closedir(dir);
+				return GLOB_NOSPACE;
+			}
+		}
+	}
+	closedir(dir);
+	if (error && (errfunc(d, error) || (flags & GLOB_ERR)))
+		return GLOB_ABORTED;
+	return 0;
+}
+
+static int ignore_err(const char *path, int err)
+{
+	return 0;
+}
+
+static void freelist(struct match *head)
+{
+	struct match *match, *next;
+	for (match=head->next; match; match=next) {
+		next = match->next;
+		free(match);
+	}
+}
+
+static int sort(const void *a, const void *b)
+{
+	return strcmp(*(const char **)a, *(const char **)b);
+}
+
+int glob(const char *pat, int flags, int (*errfunc)(const char *path, int err), glob_t *g)
+{
+	const char *p=pat, *d;
+	struct match head = { .next = NULL }, *tail = &head;
+	size_t cnt, i;
+	size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
+	int error = 0;
+	
+	if (*p == '/') {
+		for (; *p == '/'; p++);
+		d = "/";
+	} else {
+		d = "";
+	}
+
+	if (!errfunc) errfunc = ignore_err;
+
+	if (!(flags & GLOB_APPEND)) {
+		g->gl_offs = offs;
+		g->gl_pathc = 0;
+		g->gl_pathv = NULL;
+	}
+
+	if (*p) error = match_in_dir(d, p, flags, errfunc, &tail);
+	if (error == GLOB_NOSPACE) {
+		freelist(&head);
+		return error;
+	}
+	
+	for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
+	if (!cnt) {
+		if (flags & GLOB_NOCHECK) {
+			tail = &head;
+			if (append(&tail, pat, strlen(pat), 0))
+				return GLOB_NOSPACE;
+			cnt++;
+		} else
+			return GLOB_NOMATCH;
+	}
+
+	if (flags & GLOB_APPEND) {
+		char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
+		if (!pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		g->gl_pathv = pathv;
+		offs += g->gl_pathc;
+	} else {
+		g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
+		if (!g->gl_pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		for (i=0; i<offs; i++)
+			g->gl_pathv[i] = NULL;
+	}
+	for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
+		g->gl_pathv[offs + i] = tail->name;
+	g->gl_pathv[offs + i] = NULL;
+	g->gl_pathc += cnt;
+
+	if (!(flags & GLOB_NOSORT))
+		qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
+	
+	return error;
+}
+
+void globfree(glob_t *g)
+{
+	size_t i;
+	for (i=0; i<g->gl_pathc; i++)
+		free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
+	free(g->gl_pathv);
+	g->gl_pathc = 0;
+	g->gl_pathv = NULL;
+}
+
+LFS64(glob);
+LFS64(globfree);
diff --git a/src/regex/regcomp.c b/src/regex/regcomp.c
new file mode 100644
index 00000000..3307942e
--- /dev/null
+++ b/src/regex/regcomp.c
@@ -0,0 +1,3362 @@
+/*
+  regcomp.c - TRE POSIX compatible regex compilation functions.
+
+  Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <regex.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+/***********************************************************************
+ from tre-ast.c and tre-ast.h
+***********************************************************************/
+
+/* The different AST node types. */
+typedef enum {
+  LITERAL,
+  CATENATION,
+  ITERATION,
+  UNION
+} tre_ast_type_t;
+
+/* Special subtypes of TRE_LITERAL. */
+#define EMPTY	  -1   /* Empty leaf (denotes empty string). */
+#define ASSERTION -2   /* Assertion leaf. */
+#define TAG	  -3   /* Tag leaf. */
+#define BACKREF	  -4   /* Back reference leaf. */
+
+#define IS_SPECIAL(x)	((x)->code_min < 0)
+#define IS_EMPTY(x)	((x)->code_min == EMPTY)
+#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
+#define IS_TAG(x)	((x)->code_min == TAG)
+#define IS_BACKREF(x)	((x)->code_min == BACKREF)
+
+/* Taken from tre-compile.h */
+typedef struct {
+  int position;
+  int code_min;
+  int code_max;
+  int *tags;
+  int assertions;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+  int backref;
+} tre_pos_and_tags_t;
+
+/* A generic AST node.  All AST nodes consist of this node on the top
+   level with `obj' pointing to the actual content. */
+typedef struct {
+  tre_ast_type_t type;   /* Type of the node. */
+  void *obj;             /* Pointer to actual node. */
+  int nullable;
+  int submatch_id;
+  int num_submatches;
+  int num_tags;
+  tre_pos_and_tags_t *firstpos;
+  tre_pos_and_tags_t *lastpos;
+} tre_ast_node_t;
+
+
+/* A "literal" node.  These are created for assertions, back references,
+   tags, matching parameter settings, and all expressions that match one
+   character. */
+typedef struct {
+  long code_min;
+  long code_max;
+  int position;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+} tre_literal_t;
+
+/* A "catenation" node.	 These are created when two regexps are concatenated.
+   If there are more than one subexpressions in sequence, the `left' part
+   holds all but the last, and `right' part holds the last subexpression
+   (catenation is left associative). */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_catenation_t;
+
+/* An "iteration" node.	 These are created for the "*", "+", "?", and "{m,n}"
+   operators. */
+typedef struct {
+  /* Subexpression to match. */
+  tre_ast_node_t *arg;
+  /* Minimum number of consecutive matches. */
+  int min;
+  /* Maximum number of consecutive matches. */
+  int max;
+} tre_iteration_t;
+
+/* An "union" node.  These are created for the "|" operator. */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_union_t;
+
+static tre_ast_node_t *
+tre_ast_new_node(tre_mem_t mem, tre_ast_type_t type, size_t size)
+{
+  tre_ast_node_t *node;
+
+  node = tre_mem_calloc(mem, sizeof(*node));
+  if (!node)
+    return NULL;
+  node->obj = tre_mem_calloc(mem, size);
+  if (!node->obj)
+    return NULL;
+  node->type = type;
+  node->nullable = -1;
+  node->submatch_id = -1;
+
+  return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
+{
+  tre_ast_node_t *node;
+  tre_literal_t *lit;
+
+  node = tre_ast_new_node(mem, LITERAL, sizeof(tre_literal_t));
+  if (!node)
+    return NULL;
+  lit = node->obj;
+  lit->code_min = code_min;
+  lit->code_max = code_max;
+  lit->position = position;
+
+  return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max)
+{
+  tre_ast_node_t *node;
+  tre_iteration_t *iter;
+
+  node = tre_ast_new_node(mem, ITERATION, sizeof(tre_iteration_t));
+  if (!node)
+    return NULL;
+  iter = node->obj;
+  iter->arg = arg;
+  iter->min = min;
+  iter->max = max;
+  node->num_submatches = arg->num_submatches;
+
+  return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
+{
+  tre_ast_node_t *node;
+
+  node = tre_ast_new_node(mem, UNION, sizeof(tre_union_t));
+  if (node == NULL)
+    return NULL;
+  ((tre_union_t *)node->obj)->left = left;
+  ((tre_union_t *)node->obj)->right = right;
+  node->num_submatches = left->num_submatches + right->num_submatches;
+
+  return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left,
+		       tre_ast_node_t *right)
+{
+  tre_ast_node_t *node;
+
+  node = tre_ast_new_node(mem, CATENATION, sizeof(tre_catenation_t));
+  if (node == NULL)
+    return NULL;
+  ((tre_catenation_t *)node->obj)->left = left;
+  ((tre_catenation_t *)node->obj)->right = right;
+  node->num_submatches = left->num_submatches + right->num_submatches;
+
+  return node;
+}
+
+/***********************************************************************
+ from tre-stack.c and tre-stack.h
+***********************************************************************/
+
+/* Just to save some typing. */
+#define STACK_PUSH(s, value)						      \
+  do									      \
+    {									      \
+      status = tre_stack_push(s, (void *)(value));			      \
+    }									      \
+  while (0)
+
+#define STACK_PUSHX(s, value)						      \
+  {									      \
+    status = tre_stack_push(s, (void *)(value));			      \
+    if (status != REG_OK)						      \
+      break;								      \
+  }
+
+#define STACK_PUSHR(s, value)						      \
+  {									      \
+    reg_errcode_t status;						      \
+    status = tre_stack_push(s, (void *)(value));			      \
+    if (status != REG_OK)						      \
+      return status;							      \
+  }
+
+typedef struct tre_stack_rec {
+  int size;
+  int max_size;
+  int increment;
+  int ptr;
+  void **stack;
+} tre_stack_t;
+
+
+static tre_stack_t *
+tre_stack_new(int size, int max_size, int increment)
+{
+  tre_stack_t *s;
+
+  s = xmalloc(sizeof(*s));
+  if (s != NULL)
+    {
+      s->stack = xmalloc(sizeof(*s->stack) * size);
+      if (s->stack == NULL)
+	{
+	  xfree(s);
+	  return NULL;
+	}
+      s->size = size;
+      s->max_size = max_size;
+      s->increment = increment;
+      s->ptr = 0;
+    }
+  return s;
+}
+
+static void
+tre_stack_destroy(tre_stack_t *s)
+{
+  xfree(s->stack);
+  xfree(s);
+}
+
+static int
+tre_stack_num_objects(tre_stack_t *s)
+{
+  return s->ptr;
+}
+
+static reg_errcode_t
+tre_stack_push(tre_stack_t *s, void *value)
+{
+  if (s->ptr < s->size)
+    {
+      s->stack[s->ptr] = value;
+      s->ptr++;
+    }
+  else
+    {
+      if (s->size >= s->max_size)
+	{
+	  DPRINT(("tre_stack_push: stack full\n"));
+	  return REG_ESPACE;
+	}
+      else
+	{
+	  void **new_buffer;
+	  int new_size;
+	  DPRINT(("tre_stack_push: trying to realloc more space\n"));
+	  new_size = s->size + s->increment;
+	  if (new_size > s->max_size)
+	    new_size = s->max_size;
+	  new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
+	  if (new_buffer == NULL)
+	    {
+	      DPRINT(("tre_stack_push: realloc failed.\n"));
+	      return REG_ESPACE;
+	    }
+	  DPRINT(("tre_stack_push: realloc succeeded.\n"));
+	  assert(new_size > s->size);
+	  s->size = new_size;
+	  s->stack = new_buffer;
+	  tre_stack_push(s, value);
+	}
+    }
+  return REG_OK;
+}
+
+static void *
+tre_stack_pop(tre_stack_t *s)
+{
+  return s->stack[--s->ptr];
+}
+
+
+/***********************************************************************
+ from tre-parse.c and tre-parse.h
+***********************************************************************/
+
+/* Parse context. */
+typedef struct {
+  /* Memory allocator.	The AST is allocated using this. */
+  tre_mem_t mem;
+  /* Stack used for keeping track of regexp syntax. */
+  tre_stack_t *stack;
+  /* The parse result. */
+  tre_ast_node_t *result;
+  /* The regexp to parse and its length. */
+  const tre_char_t *re;
+  /* The first character of the entire regexp. */
+  const tre_char_t *re_start;
+  /* The first character after the end of the regexp. */
+  const tre_char_t *re_end;
+  int len;
+  /* Current submatch ID. */
+  int submatch_id;
+  /* Current position (number of literal). */
+  int position;
+  /* The highest back reference or -1 if none seen so far. */
+  int max_backref;
+  /* Compilation flags. */
+  int cflags;
+  /* If this flag is set the top-level submatch is not captured. */
+  int nofirstsub;
+} tre_parse_ctx_t;
+
+static reg_errcode_t
+tre_new_item(tre_mem_t mem, int min, int max, int *i, int *max_i,
+	 tre_ast_node_t ***items)
+{
+  reg_errcode_t status;
+  tre_ast_node_t **array = *items;
+  /* Allocate more space if necessary. */
+  if (*i >= *max_i)
+    {
+      tre_ast_node_t **new_items;
+      DPRINT(("out of array space, i = %d\n", *i));
+      /* If the array is already 1024 items large, give up -- there's
+	 probably an error in the regexp (e.g. not a '\0' terminated
+	 string and missing ']') */
+      if (*max_i > 1024)
+	return REG_ESPACE;
+      *max_i *= 2;
+      new_items = xrealloc(array, sizeof(*items) * *max_i);
+      if (new_items == NULL)
+	return REG_ESPACE;
+      *items = array = new_items;
+    }
+  array[*i] = tre_ast_new_literal(mem, min, max, -1);
+  status = array[*i] == NULL ? REG_ESPACE : REG_OK;
+  (*i)++;
+  return status;
+}
+
+
+/* Expands a character class to character ranges. */
+static reg_errcode_t
+tre_expand_ctype(tre_mem_t mem, tre_ctype_t class, tre_ast_node_t ***items,
+		 int *i, int *max_i, int cflags)
+{
+  reg_errcode_t status = REG_OK;
+  tre_cint_t c;
+  int j, min = -1, max = 0;
+  assert(TRE_MB_CUR_MAX == 1);
+
+  DPRINT(("  expanding class to character ranges\n"));
+  for (j = 0; (j < 256) && (status == REG_OK); j++)
+    {
+      c = j;
+      if (tre_isctype(c, class)
+	  || ((cflags & REG_ICASE)
+	      && (tre_isctype(tre_tolower(c), class)
+		  || tre_isctype(tre_toupper(c), class))))
+{
+	  if (min < 0)
+	    min = c;
+	  max = c;
+	}
+      else if (min >= 0)
+	{
+	  DPRINT(("  range %c (%d) to %c (%d)\n", min, min, max, max));
+	  status = tre_new_item(mem, min, max, i, max_i, items);
+	  min = -1;
+	}
+    }
+  if (min >= 0 && status == REG_OK)
+    status = tre_new_item(mem, min, max, i, max_i, items);
+  return status;
+}
+
+
+static int
+tre_compare_items(const void *a, const void *b)
+{
+  tre_ast_node_t *node_a = *(tre_ast_node_t **)a;
+  tre_ast_node_t *node_b = *(tre_ast_node_t **)b;
+  tre_literal_t *l_a = node_a->obj, *l_b = node_b->obj;
+  int a_min = l_a->code_min, b_min = l_b->code_min;
+
+  if (a_min < b_min)
+    return -1;
+  else if (a_min > b_min)
+    return 1;
+  else
+    return 0;
+}
+
+/* Maximum number of character classes that can occur in a negated bracket
+   expression.	*/
+#define MAX_NEG_CLASSES 64
+
+/* Maximum length of character class names. */
+#define MAX_CLASS_NAME
+
+static reg_errcode_t
+tre_parse_bracket_items(tre_parse_ctx_t *ctx, int negate,
+			tre_ctype_t neg_classes[], int *num_neg_classes,
+			tre_ast_node_t ***items, int *num_items,
+			int *items_size)
+{
+  const tre_char_t *re = ctx->re;
+  reg_errcode_t status = REG_OK;
+  tre_ctype_t class = (tre_ctype_t)0;
+  int i = *num_items;
+  int max_i = *items_size;
+  int skip;
+
+  /* Build an array of the items in the bracket expression. */
+  while (status == REG_OK)
+    {
+      skip = 0;
+      if (re == ctx->re_end)
+	{
+	  status = REG_EBRACK;
+	}
+      else if (*re == ']' && re > ctx->re)
+	{
+	  DPRINT(("tre_parse_bracket:	done: '%.*" STRF "'\n",
+		  ctx->re_end - re, re));
+	  re++;
+	  break;
+	}
+      else
+	{
+	  tre_cint_t min = 0, max = 0;
+
+	  class = (tre_ctype_t)0;
+	  if (re + 2 < ctx->re_end
+	      && *(re + 1) == '-' && *(re + 2) != ']')
+	    {
+	      DPRINT(("tre_parse_bracket:  range: '%.*" STRF "'\n",
+		      ctx->re_end - re, re));
+	      min = *re;
+	      max = *(re + 2);
+	      re += 3;
+	      /* XXX - Should use collation order instead of encoding values
+		 in character ranges. */
+	      if (min > max)
+		status = REG_ERANGE;
+	    }
+	  else if (re + 1 < ctx->re_end
+		   && *re == '[' && *(re + 1) == '.')
+	    status = REG_ECOLLATE;
+	  else if (re + 1 < ctx->re_end
+		   && *re == '[' && *(re + 1) == '=')
+	    status = REG_ECOLLATE;
+	  else if (re + 1 < ctx->re_end
+		   && *re == '[' && *(re + 1) == ':')
+	    {
+	      char tmp_str[64];
+	      const tre_char_t *endptr = re + 2;
+	      int len;
+	      DPRINT(("tre_parse_bracket:  class: '%.*" STRF "'\n",
+		      ctx->re_end - re, re));
+	      while (endptr < ctx->re_end && *endptr != ':')
+		endptr++;
+	      if (endptr != ctx->re_end)
+		{
+		  len = MIN(endptr - re - 2, 63);
+#ifdef TRE_WCHAR
+		  {
+		    tre_char_t tmp_wcs[64];
+		    wcsncpy(tmp_wcs, re + 2, len);
+		    tmp_wcs[len] = '\0';
+#if defined HAVE_WCSRTOMBS
+		    {
+		      mbstate_t state;
+		      const tre_char_t *src = tmp_wcs;
+		      memset(&state, '\0', sizeof(state));
+		      len = wcsrtombs(tmp_str, &src, sizeof(tmp_str), &state);
+		    }
+#elif defined HAVE_WCSTOMBS
+		    len = wcstombs(tmp_str, tmp_wcs, 63);
+#endif /* defined HAVE_WCSTOMBS */
+		  }
+#else /* !TRE_WCHAR */
+		  strncpy(tmp_str, re + 2, len);
+#endif /* !TRE_WCHAR */
+		  tmp_str[len] = '\0';
+		  DPRINT(("  class name: %s\n", tmp_str));
+		  class = tre_ctype(tmp_str);
+		  if (!class)
+		    status = REG_ECTYPE;
+		  /* Optimize character classes for 8 bit character sets. */
+		  if (status == REG_OK && TRE_MB_CUR_MAX == 1)
+		    {
+		      status = tre_expand_ctype(ctx->mem, class, items,
+						&i, &max_i, ctx->cflags);
+		      class = (tre_ctype_t)0;
+		      skip = 1;
+		    }
+		  re = endptr + 2;
+		}
+	      else
+		status = REG_ECTYPE;
+	      min = 0;
+	      max = TRE_CHAR_MAX;
+	    }
+	  else
+	    {
+	      DPRINT(("tre_parse_bracket:   char: '%.*" STRF "'\n",
+		      ctx->re_end - re, re));
+	      if (*re == '-' && *(re + 1) != ']'
+		  && ctx->re != re)
+		/* Two ranges are not allowed to share and endpoint. */
+		status = REG_ERANGE;
+	      min = max = *re++;
+	    }
+
+	  if (status != REG_OK)
+	    break;
+
+	  if (class && negate)
+	    if (*num_neg_classes >= MAX_NEG_CLASSES)
+	      status = REG_ESPACE;
+	    else
+	      neg_classes[(*num_neg_classes)++] = class;
+	  else if (!skip)
+	    {
+	      status = tre_new_item(ctx->mem, min, max, &i, &max_i, items);
+	      if (status != REG_OK)
+		break;
+	      ((tre_literal_t*)((*items)[i-1])->obj)->class = class;
+	    }
+
+	  /* Add opposite-case counterpoints if REG_ICASE is present.
+	     This is broken if there are more than two "same" characters. */
+	  if (ctx->cflags & REG_ICASE && !class && status == REG_OK && !skip)
+	    {
+	      int cmin, ccurr;
+
+	      DPRINT(("adding opposite-case counterpoints\n"));
+	      while (min <= max)
+		{
+		  if (tre_islower(min))
+		    {
+		      cmin = ccurr = tre_toupper(min++);
+		      while (tre_islower(min) && tre_toupper(min) == ccurr + 1
+			     && min <= max)
+			ccurr = tre_toupper(min++);
+		      status = tre_new_item(ctx->mem, cmin, ccurr,
+					    &i, &max_i, items);
+		    }
+		  else if (tre_isupper(min))
+		    {
+		      cmin = ccurr = tre_tolower(min++);
+		      while (tre_isupper(min) && tre_tolower(min) == ccurr + 1
+			     && min <= max)
+			ccurr = tre_tolower(min++);
+		      status = tre_new_item(ctx->mem, cmin, ccurr,
+					    &i, &max_i, items);
+		    }
+		  else min++;
+		  if (status != REG_OK)
+		    break;
+		}
+	      if (status != REG_OK)
+		break;
+	    }
+	}
+    }
+  *num_items = i;
+  *items_size = max_i;
+  ctx->re = re;
+  return status;
+}
+
+static reg_errcode_t
+tre_parse_bracket(tre_parse_ctx_t *ctx, tre_ast_node_t **result)
+{
+  tre_ast_node_t *node = NULL;
+  int negate = 0;
+  reg_errcode_t status = REG_OK;
+  tre_ast_node_t **items, *u, *n;
+  int i = 0, j, max_i = 32, curr_max, curr_min;
+  tre_ctype_t neg_classes[MAX_NEG_CLASSES];
+  int num_neg_classes = 0;
+
+  /* Start off with an array of `max_i' elements. */
+  items = xmalloc(sizeof(*items) * max_i);
+  if (items == NULL)
+    return REG_ESPACE;
+
+  if (*ctx->re == '^')
+    {
+      DPRINT(("tre_parse_bracket: negate: '%.*" STRF "'\n",
+	      ctx->re_end - ctx->re, ctx->re));
+      negate = 1;
+      ctx->re++;
+    }
+
+  status = tre_parse_bracket_items(ctx, negate, neg_classes, &num_neg_classes,
+				   &items, &i, &max_i);
+
+  if (status != REG_OK)
+    goto parse_bracket_done;
+
+  /* Sort the array if we need to negate it. */
+  if (negate)
+    qsort(items, i, sizeof(*items), tre_compare_items);
+
+  curr_max = curr_min = 0;
+  /* Build a union of the items in the array, negated if necessary. */
+  for (j = 0; j < i && status == REG_OK; j++)
+    {
+      int min, max;
+      tre_literal_t *l = items[j]->obj;
+      min = l->code_min;
+      max = l->code_max;
+
+      DPRINT(("item: %d - %d, class %ld, curr_max = %d\n",
+	      (int)l->code_min, (int)l->code_max, (long)l->class, curr_max));
+
+      if (negate)
+	{
+	  if (min < curr_max)
+	    {
+	      /* Overlap. */
+	      curr_max = MAX(max + 1, curr_max);
+	      DPRINT(("overlap, curr_max = %d\n", curr_max));
+	      l = NULL;
+	    }
+	  else
+	    {
+	      /* No overlap. */
+	      curr_max = min - 1;
+	      if (curr_max >= curr_min)
+		{
+		  DPRINT(("no overlap\n"));
+		  l->code_min = curr_min;
+		  l->code_max = curr_max;
+		}
+	      else
+		{
+		  DPRINT(("no overlap, zero room\n"));
+		  l = NULL;
+		}
+	      curr_min = curr_max = max + 1;
+	    }
+	}
+
+      if (l != NULL)
+	{
+	  int k;
+	  DPRINT(("creating %d - %d\n", (int)l->code_min, (int)l->code_max));
+	  l->position = ctx->position;
+	  if (num_neg_classes > 0)
+	    {
+	      l->neg_classes = tre_mem_alloc(ctx->mem,
+					     (sizeof(l->neg_classes)
+					      * (num_neg_classes + 1)));
+	      if (l->neg_classes == NULL)
+		{
+		  status = REG_ESPACE;
+		  break;
+		}
+	      for (k = 0; k < num_neg_classes; k++)
+		l->neg_classes[k] = neg_classes[k];
+	      l->neg_classes[k] = (tre_ctype_t)0;
+	    }
+	  else
+	    l->neg_classes = NULL;
+	  if (node == NULL)
+	    node = items[j];
+	  else
+	    {
+	      u = tre_ast_new_union(ctx->mem, node, items[j]);
+	      if (u == NULL)
+		status = REG_ESPACE;
+	      node = u;
+	    }
+	}
+    }
+
+  if (status != REG_OK)
+    goto parse_bracket_done;
+
+  if (negate)
+    {
+      int k;
+      DPRINT(("final: creating %d - %d\n", curr_min, (int)TRE_CHAR_MAX));
+      n = tre_ast_new_literal(ctx->mem, curr_min, TRE_CHAR_MAX, ctx->position);
+      if (n == NULL)
+	status = REG_ESPACE;
+      else
+	{
+	  tre_literal_t *l = n->obj;
+	  if (num_neg_classes > 0)
+	    {
+	      l->neg_classes = tre_mem_alloc(ctx->mem,
+					     (sizeof(l->neg_classes)
+					      * (num_neg_classes + 1)));
+	      if (l->neg_classes == NULL)
+		{
+		  status = REG_ESPACE;
+		  goto parse_bracket_done;
+		}
+	      for (k = 0; k < num_neg_classes; k++)
+		l->neg_classes[k] = neg_classes[k];
+	      l->neg_classes[k] = (tre_ctype_t)0;
+	    }
+	  else
+	    l->neg_classes = NULL;
+	  if (node == NULL)
+	    node = n;
+	  else
+	    {
+	      u = tre_ast_new_union(ctx->mem, node, n);
+	      if (u == NULL)
+		status = REG_ESPACE;
+	      node = u;
+	    }
+	}
+    }
+
+  if (status != REG_OK)
+    goto parse_bracket_done;
+
+#ifdef TRE_DEBUG
+  tre_ast_print(node);
+#endif /* TRE_DEBUG */
+
+ parse_bracket_done:
+  xfree(items);
+  ctx->position++;
+  *result = node;
+  return status;
+}
+
+
+/* Parses a positive decimal integer.  Returns -1 if the string does not
+   contain a valid number. */
+static int
+tre_parse_int(const tre_char_t **regex, const tre_char_t *regex_end)
+{
+  int num = -1;
+  const tre_char_t *r = *regex;
+  while (r < regex_end && *r >= '0' && *r <= '9')
+    {
+      if (num < 0)
+	num = 0;
+      num = num * 10 + *r - '0';
+      r++;
+    }
+  *regex = r;
+  return num;
+}
+
+
+static reg_errcode_t
+tre_parse_bound(tre_parse_ctx_t *ctx, tre_ast_node_t **result)
+{
+  int min, max;
+  const tre_char_t *r = ctx->re;
+  const tre_char_t *start;
+  int counts_set = 0;
+
+  /* Parse number (minimum repetition count). */
+  min = -1;
+  if (r < ctx->re_end && *r >= '0' && *r <= '9') {
+    DPRINT(("tre_parse:	  min count: '%.*" STRF "'\n", ctx->re_end - r, r));
+    min = tre_parse_int(&r, ctx->re_end);
+  }
+
+  /* Parse comma and second number (maximum repetition count). */
+  max = min;
+  if (r < ctx->re_end && *r == ',')
+    {
+      r++;
+      DPRINT(("tre_parse:   max count: '%.*" STRF "'\n", ctx->re_end - r, r));
+      max = tre_parse_int(&r, ctx->re_end);
+    }
+
+  /* Check that the repeat counts are sane. */
+  if ((max >= 0 && min > max) || max > RE_DUP_MAX)
+    return REG_BADBR;
+
+
+  /*
+   '{'
+     optionally followed immediately by a number == minimum repcount
+     optionally followed by , then a number == maximum repcount
+  */
+
+
+  do {
+    int done;
+    start = r;
+
+    /* Parse count limit settings */
+    done = 0;
+    if (!counts_set)
+      while (r + 1 < ctx->re_end && !done)
+	{
+	  switch (*r)
+	    {
+	    case ',':
+	      r++;
+	      break;
+	    case ' ':
+	      r++;
+	      break;
+	    case '}':
+	      done = 1;
+	      break;
+	    default:
+	      done = 1;
+	      break;
+	    }
+	}
+  } while (start != r);
+
+  /* Missing }. */
+  if (r >= ctx->re_end)
+    return REG_EBRACE;
+
+  /* Empty contents of {}. */
+  if (r == ctx->re)
+    return REG_BADBR;
+
+  /* Parse the ending '}' or '\}'.*/
+  if (ctx->cflags & REG_EXTENDED)
+    {
+      if (r >= ctx->re_end || *r != '}')
+	return REG_BADBR;
+      r++;
+    }
+  else
+    {
+      if (r + 1 >= ctx->re_end
+	  || *r != '\\'
+	  || *(r + 1) != '}')
+	return REG_BADBR;
+      r += 2;
+    }
+
+
+  /* Create the AST node(s). */
+  if (min == 0 && max == 0)
+    {
+      *result = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+      if (*result == NULL)
+	return REG_ESPACE;
+    }
+  else
+    {
+      if (min < 0 && max < 0)
+	/* Only approximate parameters set, no repetitions. */
+	min = max = 1;
+
+      *result = tre_ast_new_iter(ctx->mem, *result, min, max);
+      if (!*result)
+	return REG_ESPACE;
+    }
+
+  ctx->re = r;
+  return REG_OK;
+}
+
+typedef enum {
+  PARSE_RE = 0,
+  PARSE_ATOM,
+  PARSE_MARK_FOR_SUBMATCH,
+  PARSE_BRANCH,
+  PARSE_PIECE,
+  PARSE_CATENATION,
+  PARSE_POST_CATENATION,
+  PARSE_UNION,
+  PARSE_POST_UNION,
+  PARSE_POSTFIX,
+  PARSE_RESTORE_CFLAGS
+} tre_parse_re_stack_symbol_t;
+
+
+static reg_errcode_t
+tre_parse(tre_parse_ctx_t *ctx)
+{
+  tre_ast_node_t *result = NULL;
+  tre_parse_re_stack_symbol_t symbol;
+  reg_errcode_t status = REG_OK;
+  tre_stack_t *stack = ctx->stack;
+  int bottom = tre_stack_num_objects(stack);
+  int depth = 0;
+
+  DPRINT(("tre_parse: parsing '%.*" STRF "', len = %d\n",
+	  ctx->len, ctx->re, ctx->len));
+
+  if (!ctx->nofirstsub)
+    {
+      STACK_PUSH(stack, ctx->re);
+      STACK_PUSH(stack, ctx->submatch_id);
+      STACK_PUSH(stack, PARSE_MARK_FOR_SUBMATCH);
+      ctx->submatch_id++;
+    }
+  STACK_PUSH(stack, PARSE_RE);
+  ctx->re_start = ctx->re;
+  ctx->re_end = ctx->re + ctx->len;
+
+
+  /* The following is basically just a recursive descent parser.  I use
+     an explicit stack instead of recursive functions mostly because of
+     two reasons: compatibility with systems which have an overflowable
+     call stack, and efficiency (both in lines of code and speed).  */
+  while (tre_stack_num_objects(stack) > bottom && status == REG_OK)
+    {
+      if (status != REG_OK)
+	break;
+      symbol = (tre_parse_re_stack_symbol_t)tre_stack_pop(stack);
+      switch (symbol)
+	{
+	case PARSE_RE:
+	  /* Parse a full regexp.  A regexp is one or more branches,
+	     separated by the union operator `|'. */
+	  if (ctx->cflags & REG_EXTENDED)
+	    STACK_PUSHX(stack, PARSE_UNION);
+	  STACK_PUSHX(stack, PARSE_BRANCH);
+	  break;
+
+	case PARSE_BRANCH:
+	  /* Parse a branch.  A branch is one or more pieces, concatenated.
+	     A piece is an atom possibly followed by a postfix operator. */
+	  STACK_PUSHX(stack, PARSE_CATENATION);
+	  STACK_PUSHX(stack, PARSE_PIECE);
+	  break;
+
+	case PARSE_PIECE:
+	  /* Parse a piece.  A piece is an atom possibly followed by one
+	     or more postfix operators. */
+	  STACK_PUSHX(stack, PARSE_POSTFIX);
+	  STACK_PUSHX(stack, PARSE_ATOM);
+	  break;
+
+	case PARSE_CATENATION:
+	  /* If the expression has not ended, parse another piece. */
+	  {
+	    tre_char_t c;
+	    if (ctx->re >= ctx->re_end)
+	      break;
+	    c = *ctx->re;
+	    if (ctx->cflags & REG_EXTENDED && c == '|')
+	      break;
+	    if ((ctx->cflags & REG_EXTENDED
+	         && c == ')' && depth > 0)
+	        || (!(ctx->cflags & REG_EXTENDED)
+		    && (c == '\\'
+		        && *(ctx->re + 1) == ')')))
+	      {
+	        if (!(ctx->cflags & REG_EXTENDED) && depth == 0)
+	          status = REG_EPAREN;
+	        DPRINT(("tre_parse:	  group end: '%.*" STRF "'\n",
+		        ctx->re_end - ctx->re, ctx->re));
+	        depth--;
+	        if (!(ctx->cflags & REG_EXTENDED))
+	          ctx->re += 2;
+	        break;
+	      }
+
+	    /* Left associative concatenation. */
+	    STACK_PUSHX(stack, PARSE_CATENATION);
+	    STACK_PUSHX(stack, result);
+	    STACK_PUSHX(stack, PARSE_POST_CATENATION);
+	    STACK_PUSHX(stack, PARSE_PIECE);
+	    break;
+	  }
+
+	case PARSE_POST_CATENATION:
+	  {
+	    tre_ast_node_t *tree = tre_stack_pop(stack);
+	    tre_ast_node_t *tmp_node;
+	    tmp_node = tre_ast_new_catenation(ctx->mem, tree, result);
+	    if (!tmp_node)
+	      return REG_ESPACE;
+	    result = tmp_node;
+	    break;
+	  }
+
+	case PARSE_UNION:
+	  if (ctx->re >= ctx->re_end)
+	    break;
+	  switch (*ctx->re)
+	    {
+	    case '|':
+	      DPRINT(("tre_parse:	union: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      STACK_PUSHX(stack, PARSE_UNION);
+	      STACK_PUSHX(stack, result);
+	      STACK_PUSHX(stack, PARSE_POST_UNION);
+	      STACK_PUSHX(stack, PARSE_BRANCH);
+	      ctx->re++;
+	      break;
+
+	    case ')':
+	      ctx->re++;
+	      break;
+
+	    default:
+	      break;
+	    }
+	  break;
+
+	case PARSE_POST_UNION:
+	  {
+	    tre_ast_node_t *tmp_node;
+	    tre_ast_node_t *tree = tre_stack_pop(stack);
+	    tmp_node = tre_ast_new_union(ctx->mem, tree, result);
+	    if (!tmp_node)
+	      return REG_ESPACE;
+	    result = tmp_node;
+	    break;
+	  }
+
+	case PARSE_POSTFIX:
+	  /* Parse postfix operators. */
+	  if (ctx->re >= ctx->re_end)
+	    break;
+	  switch (*ctx->re)
+	    {
+	    case '+':
+	    case '?':
+	      if (!(ctx->cflags & REG_EXTENDED))
+	        break;
+	    case '*':
+	      {
+		tre_ast_node_t *tmp_node;
+		int rep_min = 0;
+		int rep_max = -1;
+		if (*ctx->re == '+')
+		  rep_min = 1;
+		if (*ctx->re == '?')
+		  rep_max = 1;
+
+		ctx->re++;
+		tmp_node = tre_ast_new_iter(ctx->mem, result, rep_min, rep_max);
+		if (tmp_node == NULL)
+		  return REG_ESPACE;
+		result = tmp_node;
+		STACK_PUSHX(stack, PARSE_POSTFIX);
+		break;
+	      }
+
+	    case '\\':
+	      /* "\{" is special without REG_EXTENDED */
+	      if (!(ctx->cflags & REG_EXTENDED)
+		  && ctx->re + 1 < ctx->re_end
+		  && *(ctx->re + 1) == '{')
+		{
+		  ctx->re++;
+		  goto parse_brace;
+		}
+	      else
+		break;
+
+	    case '{':
+	      /* "{" is literal without REG_EXTENDED */
+	      if (!(ctx->cflags & REG_EXTENDED))
+		break;
+
+	    parse_brace:
+	      DPRINT(("tre_parse:	bound: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      ctx->re++;
+
+	      status = tre_parse_bound(ctx, &result);
+	      if (status != REG_OK)
+		return status;
+	      STACK_PUSHX(stack, PARSE_POSTFIX);
+	      break;
+	    }
+	  break;
+
+	case PARSE_ATOM:
+	  /* Parse an atom.  An atom is a regular expression enclosed in `()',
+	     an empty set of `()', a bracket expression, `.', `^', `$',
+	     a `\' followed by a character, or a single character. */
+
+	  /* End of regexp? (empty string). */
+	  if (ctx->re >= ctx->re_end)
+	    goto parse_literal;
+
+	  switch (*ctx->re)
+	    {
+	    case '(':  /* parenthesized subexpression */
+
+	      if (ctx->cflags & REG_EXTENDED
+		  || (ctx->re > ctx->re_start
+		      && *(ctx->re - 1) == '\\'))
+		{
+		  depth++;
+		    {
+		      DPRINT(("tre_parse: group begin: '%.*" STRF
+			      "', submatch %d\n",
+			      ctx->re_end - ctx->re, ctx->re,
+			      ctx->submatch_id));
+		      ctx->re++;
+		      /* First parse a whole RE, then mark the resulting tree
+			 for submatching. */
+		      STACK_PUSHX(stack, ctx->submatch_id);
+		      STACK_PUSHX(stack, PARSE_MARK_FOR_SUBMATCH);
+		      STACK_PUSHX(stack, PARSE_RE);
+		      ctx->submatch_id++;
+		    }
+		}
+	      else
+		goto parse_literal;
+	      break;
+
+	    case ')':  /* end of current subexpression */
+	      if ((ctx->cflags & REG_EXTENDED && depth > 0)
+		  || (ctx->re > ctx->re_start
+		      && *(ctx->re - 1) == '\\'))
+		{
+		  DPRINT(("tre_parse:	    empty: '%.*" STRF "'\n",
+			  ctx->re_end - ctx->re, ctx->re));
+		  /* We were expecting an atom, but instead the current
+		     subexpression was closed.	POSIX leaves the meaning of
+		     this to be implementation-defined.	 We interpret this as
+		     an empty expression (which matches an empty string).  */
+		  result = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		  if (result == NULL)
+		    return REG_ESPACE;
+		  if (!(ctx->cflags & REG_EXTENDED))
+		    ctx->re--;
+		}
+	      else
+		goto parse_literal;
+	      break;
+
+	    case '[': /* bracket expression */
+	      DPRINT(("tre_parse:     bracket: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      ctx->re++;
+	      status = tre_parse_bracket(ctx, &result);
+	      if (status != REG_OK)
+		return status;
+	      break;
+
+	    case '\\':
+	      /* If this is "\(" or "\)" chew off the backslash and
+		 try again. */
+	      if (!(ctx->cflags & REG_EXTENDED)
+		  && ctx->re + 1 < ctx->re_end
+		  && (*(ctx->re + 1) == '('
+		      || *(ctx->re + 1) == ')'))
+		{
+		  ctx->re++;
+		  STACK_PUSHX(stack, PARSE_ATOM);
+		  break;
+		}
+
+	      if (ctx->re + 1 >= ctx->re_end)
+		/* Trailing backslash. */
+		return REG_EESCAPE;
+
+	      DPRINT(("tre_parse:  bleep: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      ctx->re++;
+	      switch (*ctx->re)
+		{
+		default:
+		  if (!(ctx->cflags & REG_EXTENDED) && tre_isdigit(*ctx->re))
+		    {
+		      /* Back reference. */
+		      int val = *ctx->re - '0';
+		      DPRINT(("tre_parse:     backref: '%.*" STRF "'\n",
+			      ctx->re_end - ctx->re + 1, ctx->re - 1));
+		      result = tre_ast_new_literal(ctx->mem, BACKREF, val,
+						   ctx->position);
+		      if (result == NULL)
+			return REG_ESPACE;
+		      ctx->position++;
+		      ctx->max_backref = MAX(val, ctx->max_backref);
+		      ctx->re++;
+		    }
+		  else
+		    {
+		      /* Escaped character. */
+		      DPRINT(("tre_parse:     escaped: '%.*" STRF "'\n",
+			      ctx->re_end - ctx->re + 1, ctx->re - 1));
+		      result = tre_ast_new_literal(ctx->mem, *ctx->re, *ctx->re,
+						   ctx->position);
+		      ctx->position++;
+		      ctx->re++;
+		    }
+		  break;
+		}
+	      if (result == NULL)
+		return REG_ESPACE;
+	      break;
+
+	    case '.':	 /* the any-symbol */
+	      DPRINT(("tre_parse:	  any: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      if (ctx->cflags & REG_NEWLINE)
+		{
+		  tre_ast_node_t *tmp1;
+		  tre_ast_node_t *tmp2;
+		  tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n' - 1,
+					     ctx->position);
+		  if (!tmp1)
+		    return REG_ESPACE;
+		  tmp2 = tre_ast_new_literal(ctx->mem, '\n' + 1, TRE_CHAR_MAX,
+					     ctx->position + 1);
+		  if (!tmp2)
+		    return REG_ESPACE;
+		  result = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+		  if (!result)
+		    return REG_ESPACE;
+		  ctx->position += 2;
+		}
+	      else
+		{
+		  result = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX,
+					       ctx->position);
+		  if (!result)
+		    return REG_ESPACE;
+		  ctx->position++;
+		}
+	      ctx->re++;
+	      break;
+
+	    case '^':	 /* beginning of line assertion */
+	      /* '^' has a special meaning everywhere in EREs, and in the
+		 beginning of the RE and after \( is BREs. */
+	      if (ctx->cflags & REG_EXTENDED
+		  || (ctx->re - 2 >= ctx->re_start
+		      && *(ctx->re - 2) == '\\'
+		      && *(ctx->re - 1) == '(')
+		  || ctx->re == ctx->re_start)
+		{
+		  DPRINT(("tre_parse:	      BOL: '%.*" STRF "'\n",
+			  ctx->re_end - ctx->re, ctx->re));
+		  result = tre_ast_new_literal(ctx->mem, ASSERTION,
+					       ASSERT_AT_BOL, -1);
+		  if (result == NULL)
+		    return REG_ESPACE;
+		  ctx->re++;
+		}
+	      else
+		goto parse_literal;
+	      break;
+
+	    case '$':	 /* end of line assertion. */
+	      /* '$' is special everywhere in EREs, and in the end of the
+		 string and before \) is BREs. */
+	      if (ctx->cflags & REG_EXTENDED
+		  || (ctx->re + 2 < ctx->re_end
+		      && *(ctx->re + 1) == '\\'
+		      && *(ctx->re + 2) == ')')
+		  || ctx->re + 1 == ctx->re_end)
+		{
+		  DPRINT(("tre_parse:	      EOL: '%.*" STRF "'\n",
+			  ctx->re_end - ctx->re, ctx->re));
+		  result = tre_ast_new_literal(ctx->mem, ASSERTION,
+					       ASSERT_AT_EOL, -1);
+		  if (result == NULL)
+		    return REG_ESPACE;
+		  ctx->re++;
+		}
+	      else
+		goto parse_literal;
+	      break;
+
+	    default:
+	    parse_literal:
+
+	      /* We are expecting an atom.  If the subexpression (or the whole
+		 regexp ends here, we interpret it as an empty expression
+		 (which matches an empty string).  */
+	      if (
+		  (ctx->re >= ctx->re_end
+		   || *ctx->re == '*'
+		   || (ctx->cflags & REG_EXTENDED
+		       && (*ctx->re == '|'
+			   || *ctx->re == '{'
+			   || *ctx->re == '+'
+			   || *ctx->re == '?'))
+		   /* Test for "\)" in BRE mode. */
+		   || (!(ctx->cflags & REG_EXTENDED)
+		       && ctx->re + 1 < ctx->re_end
+		       && *ctx->re == '\\'
+		       && *(ctx->re + 1) == '{')))
+		{
+		  DPRINT(("tre_parse:	    empty: '%.*" STRF "'\n",
+			  ctx->re_end - ctx->re, ctx->re));
+		  result = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		  if (!result)
+		    return REG_ESPACE;
+		  break;
+		}
+
+	      DPRINT(("tre_parse:     literal: '%.*" STRF "'\n",
+		      ctx->re_end - ctx->re, ctx->re));
+	      /* Note that we can't use an tre_isalpha() test here, since there
+		 may be characters which are alphabetic but neither upper or
+		 lower case. */
+	      if (ctx->cflags & REG_ICASE
+		  && (tre_isupper(*ctx->re) || tre_islower(*ctx->re)))
+		{
+		  tre_ast_node_t *tmp1;
+		  tre_ast_node_t *tmp2;
+
+		  /* XXX - Can there be more than one opposite-case
+		     counterpoints for some character in some locale?  Or
+		     more than two characters which all should be regarded
+		     the same character if case is ignored?  If yes, there
+		     does not seem to be a portable way to detect it.  I guess
+		     that at least for multi-character collating elements there
+		     could be several opposite-case counterpoints, but they
+		     cannot be supported portably anyway. */
+		  tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(*ctx->re),
+					     tre_toupper(*ctx->re),
+					     ctx->position);
+		  if (!tmp1)
+		    return REG_ESPACE;
+		  tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(*ctx->re),
+					     tre_tolower(*ctx->re),
+					     ctx->position);
+		  if (!tmp2)
+		    return REG_ESPACE;
+		  result = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+		  if (!result)
+		    return REG_ESPACE;
+		}
+	      else
+		{
+		  result = tre_ast_new_literal(ctx->mem, *ctx->re, *ctx->re,
+					       ctx->position);
+		  if (!result)
+		    return REG_ESPACE;
+		}
+	      ctx->position++;
+	      ctx->re++;
+	      break;
+	    }
+	  break;
+
+	case PARSE_MARK_FOR_SUBMATCH:
+	  {
+	    int submatch_id = (int)tre_stack_pop(stack);
+
+	    if (result->submatch_id >= 0)
+	      {
+		tre_ast_node_t *n, *tmp_node;
+		n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		if (n == NULL)
+		  return REG_ESPACE;
+		tmp_node = tre_ast_new_catenation(ctx->mem, n, result);
+		if (tmp_node == NULL)
+		  return REG_ESPACE;
+		tmp_node->num_submatches = result->num_submatches;
+		result = tmp_node;
+	      }
+	    result->submatch_id = submatch_id;
+	    result->num_submatches++;
+	    break;
+	  }
+
+	case PARSE_RESTORE_CFLAGS:
+	  ctx->cflags = (int)tre_stack_pop(stack);
+	  break;
+	}
+    }
+
+  /* Check for missing closing parentheses. */
+  if (depth > 0)
+    return REG_EPAREN;
+
+  if (status == REG_OK)
+    ctx->result = result;
+
+  return status;
+}
+
+
+/***********************************************************************
+ from tre-compile.c
+***********************************************************************/
+
+/*
+  Algorithms to setup tags so that submatch addressing can be done.
+*/
+
+
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the left child a new tag with number `tag_id' to `node' is added,
+   and the right child is the old root. */
+/*              OR                  */
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the right child a new tag with number `tag_id' to `node' is added,
+   and the left child is the old root. */
+static reg_errcode_t
+tre_add_tag(tre_mem_t mem, tre_ast_node_t *node, int tag_id, int right)
+{
+  tre_catenation_t *c;
+  tre_ast_node_t *child_tag, *child_old;
+
+  DPRINT(("add_tag_%s: tag %d\n", right ? "right" : "left", tag_id));
+
+  c = tre_mem_alloc(mem, sizeof(*c));
+  if (c == NULL)
+    return REG_ESPACE;
+  child_tag = tre_ast_new_literal(mem, TAG, tag_id, -1);
+  if (child_tag == NULL)
+    return REG_ESPACE;
+  child_old = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
+  if (child_old == NULL)
+    return REG_ESPACE;
+
+  child_old->obj = node->obj;
+  child_old->type = node->type;
+  child_old->nullable = -1;
+  child_old->submatch_id = -1;
+  child_old->firstpos = NULL;
+  child_old->lastpos = NULL;
+  child_old->num_tags = 0;
+  node->obj = c;
+  node->type = CATENATION;
+
+  c->right = c->left = child_old;
+  if (right) c->right = child_tag;
+  else c->left = child_tag;
+
+  return REG_OK;
+}
+
+typedef enum {
+  ADDTAGS_RECURSE,
+  ADDTAGS_AFTER_ITERATION,
+  ADDTAGS_AFTER_UNION_LEFT,
+  ADDTAGS_AFTER_UNION_RIGHT,
+  ADDTAGS_AFTER_CAT_LEFT,
+  ADDTAGS_AFTER_CAT_RIGHT,
+  ADDTAGS_SET_SUBMATCH_END
+} tre_addtags_symbol_t;
+
+
+typedef struct {
+  int tag;
+  int next_tag;
+} tre_tag_states_t;
+
+/* Adds tags to appropriate locations in the parse tree in `tree', so that
+   subexpressions marked for submatch addressing can be traced. */
+static reg_errcode_t
+tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
+	     tre_tnfa_t *tnfa)
+{
+  reg_errcode_t status = REG_OK;
+  tre_addtags_symbol_t symbol;
+  tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */
+  int bottom = tre_stack_num_objects(stack);
+  /* True for first pass (counting number of needed tags) */
+  int first_pass = (mem == NULL || tnfa == NULL);
+  int *regset, *orig_regset;
+  int num_tags = 0; /* Total number of tags. */
+  int tag = 0;	    /* The tag that is to be added next. */
+  int next_tag = 1; /* Next tag to use after this one. */
+  int *parents;	    /* Stack of submatches the current submatch is
+		       contained in. */
+  tre_tag_states_t *saved_states;
+
+  tre_tag_direction_t direction = TRE_TAG_MINIMIZE;
+  if (!first_pass)
+      tnfa->end_tag = 0;
+
+  regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));
+  if (regset == NULL)
+    return REG_ESPACE;
+  regset[0] = -1;
+  orig_regset = regset;
+
+  parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));
+  if (parents == NULL)
+    {
+      xfree(regset);
+      return REG_ESPACE;
+    }
+  parents[0] = -1;
+
+  saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));
+  if (saved_states == NULL)
+    {
+      xfree(regset);
+      xfree(parents);
+      return REG_ESPACE;
+    }
+  else
+    {
+      unsigned int i;
+      for (i = 0; i <= tnfa->num_submatches; i++)
+	saved_states[i].tag = -1;
+    }
+
+  STACK_PUSH(stack, node);
+  STACK_PUSH(stack, ADDTAGS_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_addtags_symbol_t)tre_stack_pop(stack);
+      switch (symbol)
+	{
+
+	case ADDTAGS_SET_SUBMATCH_END:
+	  {
+	    int id = (int)tre_stack_pop(stack);
+	    int i;
+
+	    /* Add end of this submatch to regset. */
+	    for (i = 0; regset[i] >= 0; i++);
+	    regset[i] = id * 2 + 1;
+	    regset[i + 1] = -1;
+
+	    /* Pop this submatch from the parents stack. */
+	    for (i = 0; parents[i] >= 0; i++);
+	    parents[i - 1] = -1;
+	    break;
+	  }
+
+	case ADDTAGS_RECURSE:
+	  node = tre_stack_pop(stack);
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int id = node->submatch_id;
+	      int i;
+
+
+	      /* Add start of this submatch to regset. */
+	      for (i = 0; regset[i] >= 0; i++);
+	      regset[i] = id * 2;
+	      regset[i + 1] = -1;
+
+	      if (!first_pass)
+		{
+		  for (i = 0; parents[i] >= 0; i++);
+		  tnfa->submatch_data[id].parents = NULL;
+		  if (i > 0)
+		    {
+		      int *p = xmalloc(sizeof(*p) * (i + 1));
+		      if (p == NULL)
+			{
+			  status = REG_ESPACE;
+			  break;
+			}
+		      assert(tnfa->submatch_data[id].parents == NULL);
+		      tnfa->submatch_data[id].parents = p;
+		      for (i = 0; parents[i] >= 0; i++)
+			p[i] = parents[i];
+		      p[i] = -1;
+		    }
+		}
+
+	      /* Add end of this submatch to regset after processing this
+		 node. */
+	      STACK_PUSHX(stack, node->submatch_id);
+	      STACK_PUSHX(stack, ADDTAGS_SET_SUBMATCH_END);
+	    }
+
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    int i;
+		    DPRINT(("Literal %d-%d\n",
+			    (int)lit->code_min, (int)lit->code_max));
+		    if (regset[0] >= 0)
+		      {
+			/* Regset is not empty, so add a tag before the
+			   literal or backref. */
+			if (!first_pass)
+			  {
+			    status = tre_add_tag(mem, node, tag, 0 /*left*/);
+			    tnfa->tag_directions[tag] = direction;
+			    /* Go through the regset and set submatch data for
+			       submatches that are using this tag. */
+			    for (i = 0; regset[i] >= 0; i++)
+			      {
+				int id = regset[i] >> 1;
+				int start = !(regset[i] & 1);
+				DPRINT(("  Using tag %d for %s offset of "
+					"submatch %d\n", tag,
+					start ? "start" : "end", id));
+				if (start)
+				  tnfa->submatch_data[id].so_tag = tag;
+				else
+				  tnfa->submatch_data[id].eo_tag = tag;
+			      }
+			  }
+			else
+			  {
+			    DPRINT(("  num_tags = 1\n"));
+			    node->num_tags = 1;
+			  }
+
+			DPRINT(("  num_tags++\n"));
+			regset[0] = -1;
+			tag = next_tag;
+			num_tags++;
+			next_tag++;
+		      }
+		  }
+		else
+		  {
+		    assert(!IS_TAG(lit));
+		  }
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_ast_node_t *left = cat->left;
+		tre_ast_node_t *right = cat->right;
+		int reserved_tag = -1;
+		DPRINT(("Catenation, next_tag = %d\n", next_tag));
+
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, node);
+		STACK_PUSHX(stack, ADDTAGS_AFTER_CAT_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, right);
+		STACK_PUSHX(stack, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, next_tag + left->num_tags);
+		DPRINT(("  Pushing %d for after left\n",
+			next_tag + left->num_tags));
+		if (left->num_tags > 0 && right->num_tags > 0)
+		  {
+		    /* Reserve the next tag to the right child. */
+		    DPRINT(("  Reserving next_tag %d to right child\n",
+			    next_tag));
+		    reserved_tag = next_tag;
+		    next_tag++;
+		  }
+		STACK_PUSHX(stack, reserved_tag);
+		STACK_PUSHX(stack, ADDTAGS_AFTER_CAT_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, left);
+		STACK_PUSHX(stack, ADDTAGS_RECURSE);
+
+		}
+	      break;
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		DPRINT(("Iteration\n"));
+
+		if (first_pass)
+		  {
+		    STACK_PUSHX(stack, regset[0] >= 0);
+		  }
+		else
+		  {
+		    STACK_PUSHX(stack, tag);
+		  }
+		STACK_PUSHX(stack, node);
+		STACK_PUSHX(stack, ADDTAGS_AFTER_ITERATION);
+
+		STACK_PUSHX(stack, iter->arg);
+		STACK_PUSHX(stack, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag(mem, node, tag, 0 /*left*/);
+			tnfa->tag_directions[tag] = direction;
+			/* Go through the regset and set submatch data for
+			   submatches that are using this tag. */
+			for (i = 0; regset[i] >= 0; i++)
+			  {
+			    int id = regset[i] >> 1;
+			    int start = !(regset[i] & 1);
+			    DPRINT(("  Using tag %d for %s offset of "
+				    "submatch %d\n", tag,
+				    start ? "start" : "end", id));
+			    if (start)
+			      tnfa->submatch_data[id].so_tag = tag;
+			    else
+			      tnfa->submatch_data[id].eo_tag = tag;
+			  }
+		      }
+
+		    DPRINT(("  num_tags++\n"));
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+		direction = TRE_TAG_MINIMIZE;
+	      }
+	      break;
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_ast_node_t *left = uni->left;
+		tre_ast_node_t *right = uni->right;
+		int left_tag;
+		int right_tag;
+
+		if (regset[0] >= 0)
+		  {
+		    left_tag = next_tag;
+		    right_tag = next_tag + 1;
+		  }
+		else
+		  {
+		    left_tag = tag;
+		    right_tag = next_tag;
+		  }
+
+		DPRINT(("Union\n"));
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, right_tag);
+		STACK_PUSHX(stack, left_tag);
+		STACK_PUSHX(stack, regset);
+		STACK_PUSHX(stack, regset[0] >= 0);
+		STACK_PUSHX(stack, node);
+		STACK_PUSHX(stack, right);
+		STACK_PUSHX(stack, left);
+		STACK_PUSHX(stack, ADDTAGS_AFTER_UNION_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, right);
+		STACK_PUSHX(stack, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, ADDTAGS_AFTER_UNION_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, left);
+		STACK_PUSHX(stack, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag(mem, node, tag, 0 /*left*/);
+			tnfa->tag_directions[tag] = direction;
+			/* Go through the regset and set submatch data for
+			   submatches that are using this tag. */
+			for (i = 0; regset[i] >= 0; i++)
+			  {
+			    int id = regset[i] >> 1;
+			    int start = !(regset[i] & 1);
+			    DPRINT(("  Using tag %d for %s offset of "
+				    "submatch %d\n", tag,
+				    start ? "start" : "end", id));
+			    if (start)
+			      tnfa->submatch_data[id].so_tag = tag;
+			    else
+			      tnfa->submatch_data[id].eo_tag = tag;
+			  }
+		      }
+
+		    DPRINT(("  num_tags++\n"));
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+
+		if (node->num_submatches > 0)
+		  {
+		    /* The next two tags are reserved for markers. */
+		    next_tag++;
+		    tag = next_tag;
+		    next_tag++;
+		  }
+
+		break;
+	      }
+	    }
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int i;
+	      /* Push this submatch on the parents stack. */
+	      for (i = 0; parents[i] >= 0; i++);
+	      parents[i] = node->submatch_id;
+	      parents[i + 1] = -1;
+	    }
+
+	  break; /* end case: ADDTAGS_RECURSE */
+
+	case ADDTAGS_AFTER_ITERATION:
+	  {
+	    int enter_tag;
+	    node = tre_stack_pop(stack);
+	    if (first_pass)
+		node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags
+		  + (int)tre_stack_pop(stack);
+	    else
+		enter_tag = (int)tre_stack_pop(stack);
+
+	    DPRINT(("After iteration\n"));
+	    direction = TRE_TAG_MAXIMIZE;
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_LEFT:
+	  {
+	    int new_tag = (int)tre_stack_pop(stack);
+	    next_tag = (int)tre_stack_pop(stack);
+	    DPRINT(("After cat left, tag = %d, next_tag = %d\n",
+		    tag, next_tag));
+	    if (new_tag >= 0)
+	      {
+		DPRINT(("  Setting tag to %d\n", new_tag));
+		tag = new_tag;
+	      }
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_RIGHT:
+	  DPRINT(("After cat right\n"));
+	  node = tre_stack_pop(stack);
+	  if (first_pass)
+	    node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags
+	      + ((tre_catenation_t *)node->obj)->right->num_tags;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_LEFT:
+	  DPRINT(("After union left\n"));
+	  /* Lift the bottom of the `regset' array so that when processing
+	     the right operand the items currently in the array are
+	     invisible.	 The original bottom was saved at ADDTAGS_UNION and
+	     will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */
+	  while (*regset >= 0)
+	    regset++;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_RIGHT:
+	  {
+	    int added_tags, tag_left, tag_right;
+	    tre_ast_node_t *left = tre_stack_pop(stack);
+	    tre_ast_node_t *right = tre_stack_pop(stack);
+	    DPRINT(("After union right\n"));
+	    node = tre_stack_pop(stack);
+	    added_tags = (int)tre_stack_pop(stack);
+	    if (first_pass)
+	      {
+		node->num_tags = ((tre_union_t *)node->obj)->left->num_tags
+		  + ((tre_union_t *)node->obj)->right->num_tags + added_tags
+		  + ((node->num_submatches > 0) ? 2 : 0);
+	      }
+	    regset = tre_stack_pop(stack);
+	    tag_left = (int)tre_stack_pop(stack);
+	    tag_right = (int)tre_stack_pop(stack);
+
+	    /* Add tags after both children, the left child gets a smaller
+	       tag than the right child.  This guarantees that we prefer
+	       the left child over the right child. */
+	    /* XXX - This is not always necessary (if the children have
+	       tags which must be seen for every match of that child). */
+	    /* XXX - Check if this is the only place where tre_add_tag_right
+	       is used.	 If so, use tre_add_tag_left (putting the tag before
+	       the child as opposed after the child) and throw away
+	       tre_add_tag_right. */
+	    if (node->num_submatches > 0)
+	      {
+		if (!first_pass)
+		  {
+		    status = tre_add_tag(mem, left, tag_left, 1 /*right*/);
+		    tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
+		    status = tre_add_tag(mem, right, tag_right, 1 /*right*/);
+		    tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
+		  }
+		DPRINT(("  num_tags += 2\n"));
+		num_tags += 2;
+	      }
+	    direction = TRE_TAG_MAXIMIZE;
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+
+	} /* end switch(symbol) */
+    } /* end while(tre_stack_num_objects(stack) > bottom) */
+
+  if (!first_pass)
+    {
+      int i;
+      /* Go through the regset and set submatch data for
+	 submatches that are using this tag. */
+      for (i = 0; regset[i] >= 0; i++)
+	{
+	  int id = regset[i] >> 1;
+	  int start = !(regset[i] & 1);
+	  DPRINT(("  Using tag %d for %s offset of "
+		  "submatch %d\n", num_tags,
+		  start ? "start" : "end", id));
+	  if (start)
+	    tnfa->submatch_data[id].so_tag = num_tags;
+	  else
+	    tnfa->submatch_data[id].eo_tag = num_tags;
+	}
+    }
+
+  DPRINT(("tre_add_tags: %s complete.  Number of tags %d.\n",
+	  first_pass? "First pass" : "Second pass", num_tags));
+
+  assert(tree->num_tags == num_tags);
+  tnfa->end_tag = num_tags;
+  tnfa->num_tags = num_tags;
+  xfree(orig_regset);
+  xfree(parents);
+  xfree(saved_states);
+  return status;
+}
+
+
+
+/*
+  AST to TNFA compilation routines.
+*/
+
+typedef enum {
+  COPY_RECURSE,
+  COPY_SET_RESULT_PTR
+} tre_copyast_symbol_t;
+
+/* Flags for tre_copy_ast(). */
+#define COPY_REMOVE_TAGS	 1
+#define COPY_MAXIMIZE_FIRST_TAG	 2
+
+static reg_errcode_t
+tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	     int flags, int *pos_add, tre_tag_direction_t *tag_directions,
+	     tre_ast_node_t **copy, int *max_pos)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int num_copied = 0;
+  int first_tag = 1;
+  tre_ast_node_t **result = copy;
+  tre_copyast_symbol_t symbol;
+
+  STACK_PUSH(stack, ast);
+  STACK_PUSH(stack, COPY_RECURSE);
+
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_copyast_symbol_t)tre_stack_pop(stack);
+      switch (symbol)
+	{
+	case COPY_SET_RESULT_PTR:
+	  result = tre_stack_pop(stack);
+	  break;
+	case COPY_RECURSE:
+	  node = tre_stack_pop(stack);
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+		int pos = lit->position;
+		int min = lit->code_min;
+		int max = lit->code_max;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    /* XXX - e.g. [ab] has only one position but two
+		       nodes, so we are creating holes in the state space
+		       here.  Not fatal, just wastes memory. */
+		    pos += *pos_add;
+		    num_copied++;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
+		  {
+		    /* Change this tag to empty. */
+		    min = EMPTY;
+		    max = pos = -1;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
+			 && first_tag)
+		  {
+		    /* Maximize the first tag. */
+		    tag_directions[max] = TRE_TAG_MAXIMIZE;
+		    first_tag = 0;
+		  }
+		*result = tre_ast_new_literal(mem, min, max, pos);
+		if (*result == NULL)
+		  status = REG_ESPACE;
+
+		if (pos > *max_pos)
+		  *max_pos = pos;
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_union_t *copy;
+		*result = tre_ast_new_union(mem, uni->left, uni->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		copy = (*result)->obj;
+		result = &copy->left;
+		STACK_PUSHX(stack, uni->right);
+		STACK_PUSHX(stack, COPY_RECURSE);
+		STACK_PUSHX(stack, &copy->right);
+		STACK_PUSHX(stack, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, uni->left);
+		STACK_PUSHX(stack, COPY_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_catenation_t *copy;
+		*result = tre_ast_new_catenation(mem, cat->left, cat->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		copy = (*result)->obj;
+		copy->left = NULL;
+		copy->right = NULL;
+		result = &copy->left;
+
+		STACK_PUSHX(stack, cat->right);
+		STACK_PUSHX(stack, COPY_RECURSE);
+		STACK_PUSHX(stack, &copy->right);
+		STACK_PUSHX(stack, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, cat->left);
+		STACK_PUSHX(stack, COPY_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, iter->arg);
+		STACK_PUSHX(stack, COPY_RECURSE);
+		*result = tre_ast_new_iter(mem, iter->arg, iter->min, iter->max);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		iter = (*result)->obj;
+		result = &iter->arg;
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	}
+    }
+  *pos_add += num_copied;
+  return status;
+}
+
+typedef enum {
+  EXPAND_RECURSE,
+  EXPAND_AFTER_ITER
+} tre_expand_ast_symbol_t;
+
+/* Expands each iteration node that has a finite nonzero minimum or maximum
+   iteration count to a catenated sequence of copies of the node. */
+static reg_errcode_t
+tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	       int *position, tre_tag_direction_t *tag_directions,
+	       int *max_depth)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int pos_add = 0;
+  int pos_add_total = 0;
+  int max_pos = 0;
+  /* Approximate parameter nesting level. */
+  int iter_depth = 0;
+
+  STACK_PUSHR(stack, ast);
+  STACK_PUSHR(stack, EXPAND_RECURSE);
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      tre_expand_ast_symbol_t symbol;
+
+      if (status != REG_OK)
+	break;
+
+      DPRINT(("pos_add %d\n", pos_add));
+
+      symbol = (tre_expand_ast_symbol_t)tre_stack_pop(stack);
+      node = tre_stack_pop(stack);
+      switch (symbol)
+	{
+	case EXPAND_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit= node->obj;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    lit->position += pos_add;
+		    if (lit->position > max_pos)
+		      max_pos = lit->position;
+		  }
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		STACK_PUSHX(stack, uni->right);
+		STACK_PUSHX(stack, EXPAND_RECURSE);
+		STACK_PUSHX(stack, uni->left);
+		STACK_PUSHX(stack, EXPAND_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		STACK_PUSHX(stack, cat->right);
+		STACK_PUSHX(stack, EXPAND_RECURSE);
+		STACK_PUSHX(stack, cat->left);
+		STACK_PUSHX(stack, EXPAND_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, pos_add);
+		STACK_PUSHX(stack, node);
+		STACK_PUSHX(stack, EXPAND_AFTER_ITER);
+		STACK_PUSHX(stack, iter->arg);
+		STACK_PUSHX(stack, EXPAND_RECURSE);
+		/* If we are going to expand this node at EXPAND_AFTER_ITER
+		   then don't increase the `pos' fields of the nodes now, it
+		   will get done when expanding. */
+		if (iter->min > 1 || iter->max > 1)
+		  pos_add = 0;
+		iter_depth++;
+		DPRINT(("iter\n"));
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	case EXPAND_AFTER_ITER:
+	  {
+	    tre_iteration_t *iter = node->obj;
+	    int pos_add_last;
+	    pos_add = (int)tre_stack_pop(stack);
+	    pos_add_last = pos_add;
+	    if (iter->min > 1 || iter->max > 1)
+	      {
+		tre_ast_node_t *seq1 = NULL, *seq2 = NULL;
+		int i;
+		int pos_add_save = pos_add;
+
+		/* Create a catenated sequence of copies of the node. */
+		for (i = 0; i < iter->min; i++)
+		  {
+		    tre_ast_node_t *copy;
+		    /* Remove tags from all but the last copy. */
+		    int flags = ((i + 1 < iter->min)
+				 ? COPY_REMOVE_TAGS
+				 : COPY_MAXIMIZE_FIRST_TAG);
+		    DPRINT(("  pos_add %d\n", pos_add));
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, flags,
+					  &pos_add, tag_directions, &copy,
+					  &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    if (seq1 != NULL)
+		      seq1 = tre_ast_new_catenation(mem, seq1, copy);
+		    else
+		      seq1 = copy;
+		    if (seq1 == NULL)
+		      return REG_ESPACE;
+		  }
+
+		if (iter->max == -1)
+		  {
+		    /* No upper limit. */
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, 0,
+					  &pos_add, NULL, &seq2, &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    seq2 = tre_ast_new_iter(mem, seq2, 0, -1);
+		    if (seq2 == NULL)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    for (i = iter->min; i < iter->max; i++)
+		      {
+			tre_ast_node_t *tmp, *copy;
+			pos_add_save = pos_add;
+			status = tre_copy_ast(mem, stack, iter->arg, 0,
+					      &pos_add, NULL, &copy, &max_pos);
+			if (status != REG_OK)
+			  return status;
+			if (seq2 != NULL)
+			  seq2 = tre_ast_new_catenation(mem, copy, seq2);
+			else
+			  seq2 = copy;
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+			tmp = tre_ast_new_literal(mem, EMPTY, -1, -1);
+			if (tmp == NULL)
+			  return REG_ESPACE;
+			seq2 = tre_ast_new_union(mem, tmp, seq2);
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+		      }
+		  }
+
+		pos_add = pos_add_save;
+		if (seq1 == NULL)
+		  seq1 = seq2;
+		else if (seq2 != NULL)
+		  seq1 = tre_ast_new_catenation(mem, seq1, seq2);
+		if (seq1 == NULL)
+		  return REG_ESPACE;
+		node->obj = seq1->obj;
+		node->type = seq1->type;
+	      }
+
+	    iter_depth--;
+	    pos_add_total += pos_add - pos_add_last;
+	    if (iter_depth == 0)
+	      pos_add = pos_add_total;
+
+	    break;
+	  }
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  *position += pos_add_total;
+
+  /* `max_pos' should never be larger than `*position' if the above
+     code works, but just an extra safeguard let's make sure
+     `*position' is set large enough so enough memory will be
+     allocated for the transition table. */
+  if (max_pos > *position)
+    *position = max_pos;
+
+#ifdef TRE_DEBUG
+  DPRINT(("Expanded AST:\n"));
+  tre_ast_print(ast);
+  DPRINT(("*position %d, max_pos %d\n", *position, max_pos));
+#endif
+
+  return status;
+}
+
+static tre_pos_and_tags_t *
+tre_set_empty(tre_mem_t mem)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set));
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = -1;
+  new_set[0].code_min = -1;
+  new_set[0].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_one(tre_mem_t mem, int position, int code_min, int code_max,
+	    tre_ctype_t class, tre_ctype_t *neg_classes, int backref)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = position;
+  new_set[0].code_min = code_min;
+  new_set[0].code_max = code_max;
+  new_set[0].class = class;
+  new_set[0].neg_classes = neg_classes;
+  new_set[0].backref = backref;
+  new_set[1].position = -1;
+  new_set[1].code_min = -1;
+  new_set[1].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,
+	      int *tags, int assertions)
+{
+  int s1, s2, i, j;
+  tre_pos_and_tags_t *new_set;
+  int *new_tags;
+  int num_tags;
+
+  for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);
+  for (s1 = 0; set1[s1].position >= 0; s1++);
+  for (s2 = 0; set2[s2].position >= 0; s2++);
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));
+  if (!new_set )
+    return NULL;
+
+  for (s1 = 0; set1[s1].position >= 0; s1++)
+    {
+      new_set[s1].position = set1[s1].position;
+      new_set[s1].code_min = set1[s1].code_min;
+      new_set[s1].code_max = set1[s1].code_max;
+      new_set[s1].assertions = set1[s1].assertions | assertions;
+      new_set[s1].class = set1[s1].class;
+      new_set[s1].neg_classes = set1[s1].neg_classes;
+      new_set[s1].backref = set1[s1].backref;
+      if (set1[s1].tags == NULL && tags == NULL)
+	new_set[s1].tags = NULL;
+      else
+	{
+	  for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)
+					 * (i + num_tags + 1)));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set1[s1].tags[j];
+	  for (i = 0; i < num_tags; i++)
+	    new_tags[j + i] = tags[i];
+	  new_tags[j + i] = -1;
+	  new_set[s1].tags = new_tags;
+	}
+    }
+
+  for (s2 = 0; set2[s2].position >= 0; s2++)
+    {
+      new_set[s1 + s2].position = set2[s2].position;
+      new_set[s1 + s2].code_min = set2[s2].code_min;
+      new_set[s1 + s2].code_max = set2[s2].code_max;
+      /* XXX - why not | assertions here as well? */
+      new_set[s1 + s2].assertions = set2[s2].assertions;
+      new_set[s1 + s2].class = set2[s2].class;
+      new_set[s1 + s2].neg_classes = set2[s2].neg_classes;
+      new_set[s1 + s2].backref = set2[s2].backref;
+      if (set2[s2].tags == NULL)
+	new_set[s1 + s2].tags = NULL;
+      else
+	{
+	  for (i = 0; set2[s2].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set2[s2].tags[j];
+	  new_tags[j] = -1;
+	  new_set[s1 + s2].tags = new_tags;
+	}
+    }
+  new_set[s1 + s2].position = -1;
+  return new_set;
+}
+
+/* Finds the empty path through `node' which is the one that should be
+   taken according to POSIX.2 rules, and adds the tags on that path to
+   `tags'.   `tags' may be NULL.  If `num_tags_seen' is not NULL, it is
+   set to the number of tags seen on the path. */
+static reg_errcode_t
+tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,
+		int *assertions, int *num_tags_seen)
+{
+  tre_literal_t *lit;
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  int i;
+  int bottom = tre_stack_num_objects(stack);
+  reg_errcode_t status = REG_OK;
+  if (num_tags_seen)
+    *num_tags_seen = 0;
+
+  status = tre_stack_push(stack, node);
+
+  /* Walk through the tree recursively. */
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      node = tre_stack_pop(stack);
+
+      switch (node->type)
+	{
+	case LITERAL:
+	  lit = (tre_literal_t *)node->obj;
+	  switch (lit->code_min)
+	    {
+	    case TAG:
+	      if (lit->code_max >= 0)
+		{
+		  if (tags != NULL)
+		    {
+		      /* Add the tag to `tags'. */
+		      for (i = 0; tags[i] >= 0; i++)
+			if (tags[i] == lit->code_max)
+			  break;
+		      if (tags[i] < 0)
+			{
+			  tags[i] = lit->code_max;
+			  tags[i + 1] = -1;
+			}
+		    }
+		  if (num_tags_seen)
+		    (*num_tags_seen)++;
+		}
+	      break;
+	    case ASSERTION:
+	      assert(lit->code_max >= 1
+		     || lit->code_max <= ASSERT_LAST);
+	      if (assertions != NULL)
+		*assertions |= lit->code_max;
+	      break;
+	    case EMPTY:
+	      break;
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+
+	case UNION:
+	  /* Subexpressions starting earlier take priority over ones
+	     starting later, so we prefer the left subexpression over the
+	     right subexpression. */
+	  uni = (tre_union_t *)node->obj;
+	  if (uni->left->nullable)
+	    STACK_PUSHX(stack, uni->left)
+	  else if (uni->right->nullable)
+	    STACK_PUSHX(stack, uni->right)
+	  else
+	    assert(0);
+	  break;
+
+	case CATENATION:
+	  /* The path must go through both children. */
+	  cat = (tre_catenation_t *)node->obj;
+	  assert(cat->left->nullable);
+	  assert(cat->right->nullable);
+	  STACK_PUSHX(stack, cat->left);
+	  STACK_PUSHX(stack, cat->right);
+	  break;
+
+	case ITERATION:
+	  /* A match with an empty string is preferred over no match at
+	     all, so we go through the argument if possible. */
+	  iter = (tre_iteration_t *)node->obj;
+	  if (iter->arg->nullable)
+	    STACK_PUSHX(stack, iter->arg);
+	  break;
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return status;
+}
+
+
+typedef enum {
+  NFL_RECURSE,
+  NFL_POST_UNION,
+  NFL_POST_CATENATION,
+  NFL_POST_ITERATION
+} tre_nfl_stack_symbol_t;
+
+
+/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for
+   the nodes of the AST `tree'. */
+static reg_errcode_t
+tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)
+{
+  int bottom = tre_stack_num_objects(stack);
+
+  STACK_PUSHR(stack, tree);
+  STACK_PUSHR(stack, NFL_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      tre_nfl_stack_symbol_t symbol;
+      tre_ast_node_t *node;
+
+      symbol = (tre_nfl_stack_symbol_t) tre_stack_pop(stack);
+      node = tre_stack_pop(stack);
+      switch (symbol)
+	{
+	case NFL_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = (tre_literal_t *)node->obj;
+		if (IS_BACKREF(lit))
+		  {
+		    /* Back references: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos = tre_set_one(mem, lit->position, 0,
+					     TRE_CHAR_MAX, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position, 0,
+						TRE_CHAR_MAX, 0, NULL,
+						lit->code_max);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else if (lit->code_min < 0)
+		  {
+		    /* Tags, empty strings and zero width assertions:
+		       nullable = true, firstpos = {}, and lastpos = {}. */
+		    node->nullable = 1;
+		    node->firstpos = tre_set_empty(mem);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_empty(mem);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    /* Literal at position i: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos =
+		      tre_set_one(mem, lit->position, lit->code_min,
+				  lit->code_max, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position,
+						lit->code_min, lit->code_max,
+						lit->class, lit->neg_classes,
+						-1);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		break;
+	      }
+
+	    case UNION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, node);
+	      STACK_PUSHR(stack, NFL_POST_UNION);
+	      STACK_PUSHR(stack, ((tre_union_t *)node->obj)->right);
+	      STACK_PUSHR(stack, NFL_RECURSE);
+	      STACK_PUSHR(stack, ((tre_union_t *)node->obj)->left);
+	      STACK_PUSHR(stack, NFL_RECURSE);
+	      break;
+
+	    case CATENATION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, node);
+	      STACK_PUSHR(stack, NFL_POST_CATENATION);
+	      STACK_PUSHR(stack, ((tre_catenation_t *)node->obj)->right);
+	      STACK_PUSHR(stack, NFL_RECURSE);
+	      STACK_PUSHR(stack, ((tre_catenation_t *)node->obj)->left);
+	      STACK_PUSHR(stack, NFL_RECURSE);
+	      break;
+
+	    case ITERATION:
+	      /* Compute the attributes for the subtree, and after that for
+		 this node. */
+	      STACK_PUSHR(stack, node);
+	      STACK_PUSHR(stack, NFL_POST_ITERATION);
+	      STACK_PUSHR(stack, ((tre_iteration_t *)node->obj)->arg);
+	      STACK_PUSHR(stack, NFL_RECURSE);
+	      break;
+	    }
+	  break; /* end case: NFL_RECURSE */
+
+	case NFL_POST_UNION:
+	  {
+	    tre_union_t *uni = (tre_union_t *)node->obj;
+	    node->nullable = uni->left->nullable || uni->right->nullable;
+	    node->firstpos = tre_set_union(mem, uni->left->firstpos,
+					   uni->right->firstpos, NULL, 0);
+	    if (!node->firstpos)
+	      return REG_ESPACE;
+	    node->lastpos = tre_set_union(mem, uni->left->lastpos,
+					  uni->right->lastpos, NULL, 0);
+	    if (!node->lastpos)
+	      return REG_ESPACE;
+	    break;
+	  }
+
+	case NFL_POST_ITERATION:
+	  {
+	    tre_iteration_t *iter = (tre_iteration_t *)node->obj;
+
+	    if (iter->min == 0 || iter->arg->nullable)
+	      node->nullable = 1;
+	    else
+	      node->nullable = 0;
+	    node->firstpos = iter->arg->firstpos;
+	    node->lastpos = iter->arg->lastpos;
+	    break;
+	  }
+
+	case NFL_POST_CATENATION:
+	  {
+	    int num_tags, *tags, assertions;
+	    reg_errcode_t status;
+	    tre_catenation_t *cat = node->obj;
+	    node->nullable = cat->left->nullable && cat->right->nullable;
+
+	    /* Compute firstpos. */
+	    if (cat->left->nullable)
+	      {
+		/* The left side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags. */
+		status = tre_match_empty(stack, cat->left,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(*tags) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags. */
+		status = tre_match_empty(stack, cat->left, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->firstpos =
+		  tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->firstpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->firstpos = cat->left->firstpos;
+	      }
+
+	    /* Compute lastpos. */
+	    if (cat->right->nullable)
+	      {
+		/* The right side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags. */
+		status = tre_match_empty(stack, cat->right,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(int) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags. */
+		status = tre_match_empty(stack, cat->right, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->lastpos =
+		  tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->lastpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->lastpos = cat->right->lastpos;
+	      }
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return REG_OK;
+}
+
+
+/* Adds a transition from each position in `p1' to each position in `p2'. */
+static reg_errcode_t
+tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
+	       tre_tnfa_transition_t *transitions,
+	       int *counts, int *offs)
+{
+  tre_pos_and_tags_t *orig_p2 = p2;
+  tre_tnfa_transition_t *trans;
+  int i, j, k, l, dup, prev_p2_pos;
+
+  if (transitions != NULL)
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	prev_p2_pos = -1;
+	while (p2->position >= 0)
+	  {
+	    /* Optimization: if this position was already handled, skip it. */
+	    if (p2->position == prev_p2_pos)
+	      {
+		p2++;
+		continue;
+	      }
+	    prev_p2_pos = p2->position;
+	    /* Set `trans' to point to the next unused transition from
+	       position `p1->position'. */
+	    trans = transitions + offs[p1->position];
+	    while (trans->state != NULL)
+	      {
+#if 0
+		/* If we find a previous transition from `p1->position' to
+		   `p2->position', it is overwritten.  This can happen only
+		   if there are nested loops in the regexp, like in "((a)*)*".
+		   In POSIX.2 repetition using the outer loop is always
+		   preferred over using the inner loop.	 Therefore the
+		   transition for the inner loop is useless and can be thrown
+		   away. */
+		/* XXX - The same position is used for all nodes in a bracket
+		   expression, so this optimization cannot be used (it will
+		   break bracket expressions) unless I figure out a way to
+		   detect it here. */
+		if (trans->state_id == p2->position)
+		  {
+		    DPRINT(("*"));
+		    break;
+		  }
+#endif
+		trans++;
+	      }
+
+	    if (trans->state == NULL)
+	      (trans + 1)->state = NULL;
+	    /* Use the character ranges, assertions, etc. from `p1' for
+	       the transition from `p1' to `p2'. */
+	    trans->code_min = p1->code_min;
+	    trans->code_max = p1->code_max;
+	    trans->state = transitions + offs[p2->position];
+	    trans->state_id = p2->position;
+	    trans->assertions = p1->assertions | p2->assertions
+	      | (p1->class ? ASSERT_CHAR_CLASS : 0)
+	      | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);
+	    if (p1->backref >= 0)
+	      {
+		assert((trans->assertions & ASSERT_CHAR_CLASS) == 0);
+		assert(p2->backref < 0);
+		trans->u.backref = p1->backref;
+		trans->assertions |= ASSERT_BACKREF;
+	      }
+	    else
+	      trans->u.class = p1->class;
+	    if (p1->neg_classes != NULL)
+	      {
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
+		trans->neg_classes =
+		  xmalloc(sizeof(*trans->neg_classes) * (i + 1));
+		if (trans->neg_classes == NULL)
+		  return REG_ESPACE;
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
+		  trans->neg_classes[i] = p1->neg_classes[i];
+		trans->neg_classes[i] = (tre_ctype_t)0;
+	      }
+	    else
+	      trans->neg_classes = NULL;
+
+	    /* Find out how many tags this transition has. */
+	    i = 0;
+	    if (p1->tags != NULL)
+	      while(p1->tags[i] >= 0)
+		i++;
+	    j = 0;
+	    if (p2->tags != NULL)
+	      while(p2->tags[j] >= 0)
+		j++;
+
+	    /* If we are overwriting a transition, free the old tag array. */
+	    if (trans->tags != NULL)
+	      xfree(trans->tags);
+	    trans->tags = NULL;
+
+	    /* If there were any tags, allocate an array and fill it. */
+	    if (i + j > 0)
+	      {
+		trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));
+		if (!trans->tags)
+		  return REG_ESPACE;
+		i = 0;
+		if (p1->tags != NULL)
+		  while(p1->tags[i] >= 0)
+		    {
+		      trans->tags[i] = p1->tags[i];
+		      i++;
+		    }
+		l = i;
+		j = 0;
+		if (p2->tags != NULL)
+		  while (p2->tags[j] >= 0)
+		    {
+		      /* Don't add duplicates. */
+		      dup = 0;
+		      for (k = 0; k < i; k++)
+			if (trans->tags[k] == p2->tags[j])
+			  {
+			    dup = 1;
+			    break;
+			  }
+		      if (!dup)
+			trans->tags[l++] = p2->tags[j];
+		      j++;
+		    }
+		trans->tags[l] = -1;
+	      }
+
+
+#ifdef TRE_DEBUG
+	    {
+	      int *tags;
+
+	      DPRINT(("	 %2d -> %2d on %3d", p1->position, p2->position,
+		      p1->code_min));
+	      if (p1->code_max != p1->code_min)
+		DPRINT(("-%3d", p1->code_max));
+	      tags = trans->tags;
+	      if (tags)
+		{
+		  DPRINT((", tags ["));
+		  while (*tags >= 0)
+		    {
+		      DPRINT(("%d", *tags));
+		      tags++;
+		      if (*tags >= 0)
+			DPRINT((","));
+		    }
+		  DPRINT(("]"));
+		}
+	      if (trans->assertions)
+		DPRINT((", assert %d", trans->assertions));
+	      if (trans->assertions & ASSERT_BACKREF)
+		DPRINT((", backref %d", trans->u.backref));
+	      else if (trans->class)
+		DPRINT((", class %ld", (long)trans->class));
+	      if (trans->neg_classes)
+		DPRINT((", neg_classes %p", trans->neg_classes));
+	      DPRINT(("\n"));
+	    }
+#endif /* TRE_DEBUG */
+	    p2++;
+	  }
+	p1++;
+      }
+  else
+    /* Compute a maximum limit for the number of transitions leaving
+       from each state. */
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	while (p2->position >= 0)
+	  {
+	    counts[p1->position]++;
+	    p2++;
+	  }
+	p1++;
+      }
+  return REG_OK;
+}
+
+/* Converts the syntax tree to a TNFA.	All the transitions in the TNFA are
+   labelled with one character range (there are no transitions on empty
+   strings).  The TNFA takes O(n^2) space in the worst case, `n' is size of
+   the regexp. */
+static reg_errcode_t
+tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,
+		int *counts, int *offs)
+{
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  reg_errcode_t errcode = REG_OK;
+
+  /* XXX - recurse using a stack!. */
+  switch (node->type)
+    {
+    case LITERAL:
+      break;
+    case UNION:
+      uni = (tre_union_t *)node->obj;
+      errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);
+      break;
+
+    case CATENATION:
+      cat = (tre_catenation_t *)node->obj;
+      /* Add a transition from each position in cat->left->lastpos
+	 to each position in cat->right->firstpos. */
+      errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,
+			       transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);
+      break;
+
+    case ITERATION:
+      iter = (tre_iteration_t *)node->obj;
+      assert(iter->max == -1 || iter->max == 1);
+
+      if (iter->max == -1)
+	{
+	  assert(iter->min == 0 || iter->min == 1);
+	  /* Add a transition from each last position in the iterated
+	     expression to each first position. */
+	  errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,
+				   transitions, counts, offs);
+	  if (errcode != REG_OK)
+	    return errcode;
+	}
+      errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);
+      break;
+    }
+  return errcode;
+}
+
+
+static void
+tre_free(regex_t *preg)
+{
+  tre_tnfa_t *tnfa;
+  unsigned int i;
+  tre_tnfa_transition_t *trans;
+
+  tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+  if (!tnfa)
+    return;
+
+  for (i = 0; i < tnfa->num_transitions; i++)
+    if (tnfa->transitions[i].state)
+      {
+	if (tnfa->transitions[i].tags)
+	  xfree(tnfa->transitions[i].tags);
+	if (tnfa->transitions[i].neg_classes)
+	  xfree(tnfa->transitions[i].neg_classes);
+      }
+  if (tnfa->transitions)
+    xfree(tnfa->transitions);
+
+  if (tnfa->initial)
+    {
+      for (trans = tnfa->initial; trans->state; trans++)
+	{
+	  if (trans->tags)
+	    xfree(trans->tags);
+	}
+      xfree(tnfa->initial);
+    }
+
+  if (tnfa->submatch_data)
+    {
+      for (i = 0; i < tnfa->num_submatches; i++)
+	if (tnfa->submatch_data[i].parents)
+	  xfree(tnfa->submatch_data[i].parents);
+      xfree(tnfa->submatch_data);
+    }
+
+  if (tnfa->tag_directions)
+    xfree(tnfa->tag_directions);
+  xfree(tnfa);
+}
+
+
+#define ERROR_EXIT(err)		  \
+  do				  \
+    {				  \
+      errcode = err;		  \
+      if (1) goto error_exit;	  \
+    }				  \
+ while (0)
+
+
+static int
+tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags)
+{
+  tre_stack_t *stack;
+  tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;
+  tre_pos_and_tags_t *p;
+  int *counts = NULL, *offs = NULL;
+  int i, add = 0;
+  tre_tnfa_transition_t *transitions, *initial;
+  tre_tnfa_t *tnfa = NULL;
+  tre_submatch_data_t *submatch_data;
+  tre_tag_direction_t *tag_directions = NULL;
+  reg_errcode_t errcode;
+  tre_mem_t mem;
+
+  /* Parse context. */
+  tre_parse_ctx_t parse_ctx;
+
+  /* Allocate a stack used throughout the compilation process for various
+     purposes. */
+  stack = tre_stack_new(512, 10240, 128);
+  if (!stack)
+    return REG_ESPACE;
+  /* Allocate a fast memory allocator. */
+  mem = tre_mem_new();
+  if (!mem)
+    {
+      tre_stack_destroy(stack);
+      return REG_ESPACE;
+    }
+
+  /* Parse the regexp. */
+  memset(&parse_ctx, 0, sizeof(parse_ctx));
+  parse_ctx.mem = mem;
+  parse_ctx.stack = stack;
+  parse_ctx.re = regex;
+  parse_ctx.len = n;
+  parse_ctx.cflags = cflags;
+  parse_ctx.max_backref = -1;
+  DPRINT(("tre_compile: parsing '%.*" STRF "'\n", n, regex));
+  errcode = tre_parse(&parse_ctx);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+  preg->re_nsub = parse_ctx.submatch_id - 1;
+  tree = parse_ctx.result;
+
+#ifdef TRE_DEBUG
+  tre_ast_print(tree);
+#endif /* TRE_DEBUG */
+
+  /* Referring to nonexistent subexpressions is illegal. */
+  if (parse_ctx.max_backref > (int)preg->re_nsub)
+    ERROR_EXIT(REG_ESUBREG);
+
+  /* Allocate the TNFA struct. */
+  tnfa = xcalloc(1, sizeof(tre_tnfa_t));
+  if (tnfa == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->have_backrefs = parse_ctx.max_backref >= 0;
+  tnfa->num_submatches = parse_ctx.submatch_id;
+
+  /* Set up tags for submatch addressing.  If REG_NOSUB is set and the
+     regexp does not have back references, this can be skipped. */
+  if (tnfa->have_backrefs || !(cflags & REG_NOSUB))
+    {
+      DPRINT(("tre_compile: setting up tags\n"));
+
+      /* Figure out how many tags we will need. */
+      errcode = tre_add_tags(NULL, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+#ifdef TRE_DEBUG
+      tre_ast_print(tree);
+#endif /* TRE_DEBUG */
+
+      if (tnfa->num_tags > 0)
+	{
+	  tag_directions = xmalloc(sizeof(*tag_directions)
+				   * (tnfa->num_tags + 1));
+	  if (tag_directions == NULL)
+	    ERROR_EXIT(REG_ESPACE);
+	  tnfa->tag_directions = tag_directions;
+	  memset(tag_directions, -1,
+		 sizeof(*tag_directions) * (tnfa->num_tags + 1));
+	}
+
+      submatch_data = xcalloc(parse_ctx.submatch_id, sizeof(*submatch_data));
+      if (submatch_data == NULL)
+	ERROR_EXIT(REG_ESPACE);
+      tnfa->submatch_data = submatch_data;
+
+      errcode = tre_add_tags(mem, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+
+#ifdef TRE_DEBUG
+      for (i = 0; i < parse_ctx.submatch_id; i++)
+	DPRINT(("pmatch[%d] = {t%d, t%d}\n",
+		i, submatch_data[i].so_tag, submatch_data[i].eo_tag));
+      for (i = 0; i < tnfa->num_tags; i++)
+	DPRINT(("t%d is %s\n", i,
+		tag_directions[i] == TRE_TAG_MINIMIZE ?
+		"minimized" : "maximized"));
+#endif /* TRE_DEBUG */
+    }
+
+  /* Expand iteration nodes. */
+  errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,
+			   tag_directions, NULL);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  /* Add a dummy node for the final state.
+     XXX - For certain patterns this dummy node can be optimized away,
+	   for example "a*" or "ab*".	Figure out a simple way to detect
+	   this possibility. */
+  tmp_ast_l = tree;
+  tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
+  if (tmp_ast_r == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
+  if (tree == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+#ifdef TRE_DEBUG
+  tre_ast_print(tree);
+  DPRINT(("Number of states: %d\n", parse_ctx.position));
+#endif /* TRE_DEBUG */
+
+  errcode = tre_compute_nfl(mem, stack, tree);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  counts = xmalloc(sizeof(int) * parse_ctx.position);
+  if (counts == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  offs = xmalloc(sizeof(int) * parse_ctx.position);
+  if (offs == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  for (i = 0; i < parse_ctx.position; i++)
+    counts[i] = 0;
+  tre_ast_to_tnfa(tree, NULL, counts, NULL);
+
+  add = 0;
+  for (i = 0; i < parse_ctx.position; i++)
+    {
+      offs[i] = add;
+      add += counts[i] + 1;
+      counts[i] = 0;
+    }
+  transitions = xcalloc(add + 1, sizeof(*transitions));
+  if (transitions == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->transitions = transitions;
+  tnfa->num_transitions = add;
+
+  DPRINT(("Converting to TNFA:\n"));
+  errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  p = tree->firstpos;
+  i = 0;
+  while (p->position >= 0)
+    {
+      i++;
+
+#ifdef TRE_DEBUG
+      {
+	int *tags;
+	DPRINT(("initial: %d", p->position));
+	tags = p->tags;
+	if (tags != NULL)
+	  {
+	    if (*tags >= 0)
+	      DPRINT(("/"));
+	    while (*tags >= 0)
+	      {
+		DPRINT(("%d", *tags));
+		tags++;
+		if (*tags >= 0)
+		  DPRINT((","));
+	      }
+	  }
+	DPRINT((", assert %d", p->assertions));
+	DPRINT(("\n"));
+      }
+#endif /* TRE_DEBUG */
+
+      p++;
+    }
+
+  initial = xcalloc(i + 1, sizeof(tre_tnfa_transition_t));
+  if (initial == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->initial = initial;
+
+  i = 0;
+  for (p = tree->firstpos; p->position >= 0; p++)
+    {
+      initial[i].state = transitions + offs[p->position];
+      initial[i].state_id = p->position;
+      initial[i].tags = NULL;
+      /* Copy the arrays p->tags, they are allocated
+	 from a tre_mem object. */
+      if (p->tags)
+	{
+	  int j;
+	  for (j = 0; p->tags[j] >= 0; j++);
+	  initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));
+	  if (!initial[i].tags)
+	    ERROR_EXIT(REG_ESPACE);
+	  memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));
+	}
+      initial[i].assertions = p->assertions;
+      i++;
+    }
+  initial[i].state = NULL;
+
+  tnfa->num_transitions = add;
+  tnfa->final = transitions + offs[tree->lastpos[0].position];
+  tnfa->num_states = parse_ctx.position;
+  tnfa->cflags = cflags;
+
+  DPRINT(("final state %p\n", (void *)tnfa->final));
+
+  tre_mem_destroy(mem);
+  tre_stack_destroy(stack);
+  xfree(counts);
+  xfree(offs);
+
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  return REG_OK;
+
+ error_exit:
+  /* Free everything that was allocated and return the error code. */
+  tre_mem_destroy(mem);
+  if (stack != NULL)
+    tre_stack_destroy(stack);
+  if (counts != NULL)
+    xfree(counts);
+  if (offs != NULL)
+    xfree(offs);
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  tre_free(preg);
+  return errcode;
+}
+
+
+/***********************************************************************
+ from regcomp.c
+***********************************************************************/
+
+int
+regcomp(regex_t *preg, const char *regex, int cflags)
+{
+  int ret;
+  tre_char_t *wregex;
+  size_t n = strlen(regex);
+
+  if (n+1 > SIZE_MAX/sizeof(tre_char_t))
+    return REG_ESPACE;
+  wregex = xmalloc(sizeof(tre_char_t) * (n + 1));
+  if (wregex == NULL)
+    return REG_ESPACE;
+
+  n = mbstowcs(wregex, regex, n+1);
+  if (n == (size_t)-1) {
+    xfree(wregex);
+    return REG_BADPAT;
+  }
+
+  ret = tre_compile(preg, wregex, n, cflags);
+  xfree(wregex);
+
+  return ret;
+}
+
+void
+regfree(regex_t *preg)
+{
+  tre_free(preg);
+}
+
+/* EOF */
diff --git a/src/regex/regerror.c b/src/regex/regerror.c
new file mode 100644
index 00000000..39d70b2a
--- /dev/null
+++ b/src/regex/regerror.c
@@ -0,0 +1,75 @@
+/*
+  regerror.c - POSIX regerror() implementation for TRE.
+
+  Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#include <string.h>
+#include <regex.h>
+
+/* Error message strings for error codes listed in `regex.h'.  This list
+   needs to be in sync with the codes listed there, naturally. */
+
+/* Converted to single string by Rich Felker to remove the need for
+ * data relocations at runtime, 27 Feb 2006. */
+
+static const char tre_error_messages[] = {
+  "No error\0"
+  "No match\0"
+  "Invalid regexp\0"
+  "Unknown collating element\0"
+  "Unknown character class name\0"
+  "Trailing backslash\0"
+  "Invalid back reference\0"
+  "Missing ']'\0"
+  "Missing ')'\0"
+  "Missing '}'\0"
+  "Invalid contents of {}\0"
+  "Invalid character range\0"
+  "Out of memory\0"
+  "XXX\0"
+};
+
+size_t
+regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
+{
+  const char *err;
+  size_t err_len;
+
+  if (errcode >= 0 && errcode <= REG_BADRPT)
+    for (err=tre_error_messages; errcode; errcode--, err+=strlen(err)+1);
+  else
+    err = "Unknown error";
+
+  err_len = strlen(err) + 1;
+  if (errbuf_size > 0 && errbuf != NULL)
+    {
+      if (err_len > errbuf_size)
+	{
+	  memcpy(errbuf, err, errbuf_size - 1);
+	  errbuf[errbuf_size - 1] = '\0';
+	}
+      else
+	{
+	  strcpy(errbuf, err);
+	}
+    }
+  return err_len;
+}
+
+/* EOF */
diff --git a/src/regex/regexec.c b/src/regex/regexec.c
new file mode 100644
index 00000000..0c3d2834
--- /dev/null
+++ b/src/regex/regexec.c
@@ -0,0 +1,1107 @@
+/*
+  regexec.c - TRE POSIX compatible matching functions (and more).
+
+  Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+
+#include <regex.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, int *tags, int match_eo);
+
+/***********************************************************************
+ from tre-match-utils.h
+***********************************************************************/
+
+#define GET_NEXT_WCHAR() do {                                                 \
+    prev_c = next_c; pos += pos_add_next;                                     \
+    if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) {        \
+        if (pos_add_next < 0) return REG_NOMATCH;                             \
+        else pos_add_next++;                                                  \
+    }                                                                         \
+    str_byte += pos_add_next;                                                 \
+  } while (0)
+
+#define CHECK_ASSERTIONS(assertions)					      \
+  (((assertions & ASSERT_AT_BOL)					      \
+    && (pos > 0 || reg_notbol)						      \
+    && (prev_c != L'\n' || !reg_newline))				      \
+   || ((assertions & ASSERT_AT_EOL)					      \
+       && (next_c != L'\0' || reg_noteol)				      \
+       && (next_c != L'\n' || !reg_newline)))
+
+/* Returns 1 if `t1' wins `t2', 0 otherwise. */
+static int
+tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,
+	      int *t1, int *t2)
+{
+  int i;
+  for (i = 0; i < num_tags; i++)
+    {
+      if (tag_directions[i] == TRE_TAG_MINIMIZE)
+	{
+	  if (t1[i] < t2[i])
+	    return 1;
+	  if (t1[i] > t2[i])
+	    return 0;
+	}
+      else
+	{
+	  if (t1[i] > t2[i])
+	    return 1;
+	  if (t1[i] < t2[i])
+	    return 0;
+	}
+    }
+  /*  assert(0);*/
+  return 0;
+}
+
+static int
+tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
+{
+  DPRINT(("neg_char_classes_test: %p, %d, %d\n", classes, wc, icase));
+  while (*classes != (tre_ctype_t)0)
+    if ((!icase && tre_isctype(wc, *classes))
+	|| (icase && (tre_isctype(tre_toupper(wc), *classes)
+		      || tre_isctype(tre_tolower(wc), *classes))))
+      return 1; /* Match. */
+    else
+      classes++;
+  return 0; /* No match. */
+}
+
+
+/***********************************************************************
+ from tre-match-parallel.c
+***********************************************************************/
+
+/*
+  This algorithm searches for matches basically by reading characters
+  in the searched string one by one, starting at the beginning.	 All
+  matching paths in the TNFA are traversed in parallel.	 When two or
+  more paths reach the same state, exactly one is chosen according to
+  tag ordering rules; if returning submatches is not required it does
+  not matter which path is chosen.
+
+  The worst case time required for finding the leftmost and longest
+  match, or determining that there is no match, is always linearly
+  dependent on the length of the text being searched.
+
+  This algorithm cannot handle TNFAs with back referencing nodes.
+  See `tre-match-backtrack.c'.
+*/
+
+
+typedef struct {
+  tre_tnfa_transition_t *state;
+  int *tags;
+} tre_tnfa_reach_t;
+
+typedef struct {
+  int pos;
+  int **tags;
+} tre_reach_pos_t;
+
+
+#ifdef TRE_DEBUG
+static void
+tre_print_reach(const tre_tnfa_t *tnfa, tre_tnfa_reach_t *reach, int num_tags)
+{
+  int i;
+
+  while (reach->state != NULL)
+    {
+      DPRINT((" %p", (void *)reach->state));
+      if (num_tags > 0)
+	{
+	  DPRINT(("/"));
+	  for (i = 0; i < num_tags; i++)
+	    {
+	      DPRINT(("%d:%d", i, reach->tags[i]));
+	      if (i < (num_tags-1))
+		DPRINT((","));
+	    }
+	}
+      reach++;
+    }
+  DPRINT(("\n"));
+
+}
+#endif /* TRE_DEBUG */
+
+static reg_errcode_t
+tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len,
+		      int *match_tags, int eflags, int *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  int pos = -1;
+  int pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+
+  char *buf;
+  tre_tnfa_transition_t *trans_i;
+  tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
+  tre_reach_pos_t *reach_pos;
+  int *tag_i;
+  int num_tags, i;
+
+  int match_eo = -1;	   /* end offset of match (-1 if no match found yet) */
+  int new_match = 0;
+  int *tmp_tags = NULL;
+  int *tmp_iptr;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!match_tags)
+    num_tags = 0;
+  else
+    num_tags = tnfa->num_tags;
+
+  /* Allocate memory for temporary data required for matching.	This needs to
+     be done for every matching operation to be thread safe.  This allocates
+     everything in a single large block from the stack frame using alloca()
+     or with malloc() if alloca is unavailable. */
+  {
+    int tbytes, rbytes, pbytes, xbytes, total_bytes;
+    char *tmp_buf;
+    /* Compute the length of the block we need. */
+    tbytes = sizeof(*tmp_tags) * num_tags;
+    rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
+    pbytes = sizeof(*reach_pos) * tnfa->num_states;
+    xbytes = sizeof(int) * num_tags;
+    total_bytes =
+      (sizeof(long) - 1) * 4 /* for alignment paddings */
+      + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;
+
+    /* Allocate the memory. */
+#ifdef TRE_USE_ALLOCA
+    buf = alloca(total_bytes);
+#else /* !TRE_USE_ALLOCA */
+    buf = xmalloc(total_bytes);
+#endif /* !TRE_USE_ALLOCA */
+    if (buf == NULL)
+      return REG_ESPACE;
+    memset(buf, 0, total_bytes);
+
+    /* Get the various pointers within tmp_buf (properly aligned). */
+    tmp_tags = (void *)buf;
+    tmp_buf = buf + tbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_next = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_pos = (void *)tmp_buf;
+    tmp_buf += pbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    for (i = 0; i < tnfa->num_states; i++)
+      {
+	reach[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+	reach_next[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+      }
+  }
+
+  for (i = 0; i < tnfa->num_states; i++)
+    reach_pos[i].pos = -1;
+
+  GET_NEXT_WCHAR();
+  pos = 0;
+
+  DPRINT(("length: %d\n", len));
+  DPRINT(("pos:chr/code | states and tags\n"));
+  DPRINT(("-------------+------------------------------------------------\n"));
+
+  reach_next_i = reach_next;
+  while (1)
+    {
+      /* If no match found yet, add the initial states to `reach_next'. */
+      if (match_eo < 0)
+	{
+	  DPRINT((" init >"));
+	  trans_i = tnfa->initial;
+	  while (trans_i->state != NULL)
+	    {
+	      if (reach_pos[trans_i->state_id].pos < pos)
+		{
+		  if (trans_i->assertions
+		      && CHECK_ASSERTIONS(trans_i->assertions))
+		    {
+		      DPRINT(("assertion failed\n"));
+		      trans_i++;
+		      continue;
+		    }
+
+		  DPRINT((" %p", (void *)trans_i->state));
+		  reach_next_i->state = trans_i->state;
+		  for (i = 0; i < num_tags; i++)
+		    reach_next_i->tags[i] = -1;
+		  tag_i = trans_i->tags;
+		  if (tag_i)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  reach_next_i->tags[*tag_i] = pos;
+			tag_i++;
+		      }
+		  if (reach_next_i->state == tnfa->final)
+		    {
+		      DPRINT(("	 found empty match\n"));
+		      match_eo = pos;
+		      new_match = 1;
+		      for (i = 0; i < num_tags; i++)
+			match_tags[i] = reach_next_i->tags[i];
+		    }
+		  reach_pos[trans_i->state_id].pos = pos;
+		  reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+		  reach_next_i++;
+		}
+	      trans_i++;
+	    }
+	  DPRINT(("\n"));
+	  reach_next_i->state = NULL;
+	}
+      else
+	{
+	  if (num_tags == 0 || reach_next_i == reach_next)
+	    /* We have found a match. */
+	    break;
+	}
+
+      /* Check for end of string. */
+      if (!next_c) break;
+
+      GET_NEXT_WCHAR();
+
+#ifdef TRE_DEBUG
+      DPRINT(("%3d:%2lc/%05d |", pos - 1, (tre_cint_t)prev_c, (int)prev_c));
+      tre_print_reach(tnfa, reach_next, num_tags);
+      DPRINT(("%3d:%2lc/%05d |", pos, (tre_cint_t)next_c, (int)next_c));
+      tre_print_reach(tnfa, reach_next, num_tags);
+#endif /* TRE_DEBUG */
+
+      /* Swap `reach' and `reach_next'. */
+      reach_i = reach;
+      reach = reach_next;
+      reach_next = reach_i;
+
+      /* For each state in `reach' see if there is a transition leaving with
+	 the current input symbol to a state not yet in `reach_next', and
+	 add the destination states to `reach_next'. */
+      reach_next_i = reach_next;
+      for (reach_i = reach; reach_i->state; reach_i++)
+	{
+	  for (trans_i = reach_i->state; trans_i->state; trans_i++)
+	    {
+	      /* Does this transition match the input symbol? */
+	      if (trans_i->code_min <= prev_c &&
+		  trans_i->code_max >= prev_c)
+		{
+		  if (trans_i->assertions
+		      && (CHECK_ASSERTIONS(trans_i->assertions)
+			  /* Handle character class transitions. */
+			  || ((trans_i->assertions & ASSERT_CHAR_CLASS)
+			      && !(tnfa->cflags & REG_ICASE)
+			      && !tre_isctype((tre_cint_t)prev_c,
+					      trans_i->u.class))
+			  || ((trans_i->assertions & ASSERT_CHAR_CLASS)
+			      && (tnfa->cflags & REG_ICASE)
+			      && (!tre_isctype(tre_tolower((tre_cint_t)prev_c),
+					       trans_i->u.class)
+				  && !tre_isctype(tre_toupper((tre_cint_t)prev_c),
+						  trans_i->u.class)))
+			  || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG)
+			      && tre_neg_char_classes_match(trans_i->neg_classes,
+							    (tre_cint_t)prev_c,
+							    tnfa->cflags & REG_ICASE))))
+		    {
+		      DPRINT(("assertion failed\n"));
+		      continue;
+		    }
+
+		  /* Compute the tags after this transition. */
+		  for (i = 0; i < num_tags; i++)
+		    tmp_tags[i] = reach_i->tags[i];
+		  tag_i = trans_i->tags;
+		  if (tag_i != NULL)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  tmp_tags[*tag_i] = pos;
+			tag_i++;
+		      }
+
+		  if (reach_pos[trans_i->state_id].pos < pos)
+		    {
+		      /* Found an unvisited node. */
+		      reach_next_i->state = trans_i->state;
+		      tmp_iptr = reach_next_i->tags;
+		      reach_next_i->tags = tmp_tags;
+		      tmp_tags = tmp_iptr;
+		      reach_pos[trans_i->state_id].pos = pos;
+		      reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+
+		      if (reach_next_i->state == tnfa->final
+			  && (match_eo == -1
+			      || (num_tags > 0
+				  && reach_next_i->tags[0] <= match_tags[0])))
+			{
+			  DPRINT(("  found match %p\n", trans_i->state));
+			  match_eo = pos;
+			  new_match = 1;
+			  for (i = 0; i < num_tags; i++)
+			    match_tags[i] = reach_next_i->tags[i];
+			}
+		      reach_next_i++;
+
+		    }
+		  else
+		    {
+		      assert(reach_pos[trans_i->state_id].pos == pos);
+		      /* Another path has also reached this state.  We choose
+			 the winner by examining the tag values for both
+			 paths. */
+		      if (tre_tag_order(num_tags, tnfa->tag_directions,
+					tmp_tags,
+					*reach_pos[trans_i->state_id].tags))
+			{
+			  /* The new path wins. */
+			  tmp_iptr = *reach_pos[trans_i->state_id].tags;
+			  *reach_pos[trans_i->state_id].tags = tmp_tags;
+			  if (trans_i->state == tnfa->final)
+			    {
+			      DPRINT(("	 found better match\n"));
+			      match_eo = pos;
+			      new_match = 1;
+			      for (i = 0; i < num_tags; i++)
+				match_tags[i] = tmp_tags[i];
+			    }
+			  tmp_tags = tmp_iptr;
+			}
+		    }
+		}
+	    }
+	}
+      reach_next_i->state = NULL;
+    }
+
+  DPRINT(("match end offset = %d\n", match_eo));
+
+#ifndef TRE_USE_ALLOCA
+  if (buf)
+    xfree(buf);
+#endif /* !TRE_USE_ALLOCA */
+
+  *match_end_ofs = match_eo;
+  return match_eo >= 0 ? REG_OK : REG_NOMATCH;
+}
+
+
+/***********************************************************************
+ from tre-match-backtrack.c
+***********************************************************************/
+
+/*
+  This matcher is for regexps that use back referencing.  Regexp matching
+  with back referencing is an NP-complete problem on the number of back
+  references.  The easiest way to match them is to use a backtracking
+  routine which basically goes through all possible paths in the TNFA
+  and chooses the one which results in the best (leftmost and longest)
+  match.  This can be spectacularly expensive and may run out of stack
+  space, but there really is no better known generic algorithm.	 Quoting
+  Henry Spencer from comp.compilers:
+  <URL: http://compilers.iecc.com/comparch/article/93-03-102>
+
+    POSIX.2 REs require longest match, which is really exciting to
+    implement since the obsolete ("basic") variant also includes
+    \<digit>.  I haven't found a better way of tackling this than doing
+    a preliminary match using a DFA (or simulation) on a modified RE
+    that just replicates subREs for \<digit>, and then doing a
+    backtracking match to determine whether the subRE matches were
+    right.  This can be rather slow, but I console myself with the
+    thought that people who use \<digit> deserve very slow execution.
+    (Pun unintentional but very appropriate.)
+
+*/
+
+typedef struct {
+  int pos;
+  const char *str_byte;
+  tre_tnfa_transition_t *state;
+  int state_id;
+  int next_c;
+  int *tags;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+} tre_backtrack_item_t;
+
+typedef struct tre_backtrack_struct {
+  tre_backtrack_item_t item;
+  struct tre_backtrack_struct *prev;
+  struct tre_backtrack_struct *next;
+} *tre_backtrack_t;
+
+#ifdef TRE_MBSTATE
+#define BT_STACK_MBSTATE_IN  stack->item.mbstate = (mbstate)
+#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
+#else /* !TRE_MBSTATE */
+#define BT_STACK_MBSTATE_IN
+#define BT_STACK_MBSTATE_OUT
+#endif /* !TRE_MBSTATE */
+
+
+#ifdef TRE_USE_ALLOCA
+#define tre_bt_mem_new		  tre_mem_newa
+#define tre_bt_mem_alloc	  tre_mem_alloca
+#define tre_bt_mem_destroy(obj)	  do { } while (0)
+#else /* !TRE_USE_ALLOCA */
+#define tre_bt_mem_new		  tre_mem_new
+#define tre_bt_mem_alloc	  tre_mem_alloc
+#define tre_bt_mem_destroy	  tre_mem_destroy
+#endif /* !TRE_USE_ALLOCA */
+
+
+#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \
+  do									      \
+    {									      \
+      int i;								      \
+      if (!stack->next)							      \
+	{								      \
+	  tre_backtrack_t s;						      \
+	  s = tre_bt_mem_alloc(mem, sizeof(*s));			      \
+	  if (!s)							      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  s->prev = stack;						      \
+	  s->next = NULL;						      \
+	  s->item.tags = tre_bt_mem_alloc(mem,				      \
+					  sizeof(*tags) * tnfa->num_tags);    \
+	  if (!s->item.tags)						      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  stack->next = s;						      \
+	  stack = s;							      \
+	}								      \
+      else								      \
+	stack = stack->next;						      \
+      stack->item.pos = (_pos);						      \
+      stack->item.str_byte = (_str_byte);				      \
+      stack->item.state = (_state);					      \
+      stack->item.state_id = (_state_id);				      \
+      stack->item.next_c = (_next_c);					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	stack->item.tags[i] = (_tags)[i];				      \
+      BT_STACK_MBSTATE_IN;						      \
+    }									      \
+  while (0)
+
+#define BT_STACK_POP()							      \
+  do									      \
+    {									      \
+      int i;								      \
+      assert(stack->prev);						      \
+      pos = stack->item.pos;						      \
+      str_byte = stack->item.str_byte;					      \
+      state = stack->item.state;					      \
+      next_c = stack->item.next_c;					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	tags[i] = stack->item.tags[i];					      \
+      BT_STACK_MBSTATE_OUT;						      \
+      stack = stack->prev;						      \
+    }									      \
+  while (0)
+
+#undef MIN
+#define MIN(a, b) ((a) <= (b) ? (a) : (b))
+
+static reg_errcode_t
+tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
+		       int len, int *match_tags,
+		       int eflags, int *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  int pos = 0;
+  int pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+
+  /* These are used to remember the necessary values of the above
+     variables to return to the position where the current search
+     started from. */
+  int next_c_start;
+  const char *str_byte_start;
+  int pos_start = -1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate_start;
+#endif /* TRE_MBSTATE */
+
+  /* Compilation flags for this regexp. */
+  int cflags = tnfa->cflags;
+
+  /* End offset of best match so far, or -1 if no match found yet. */
+  int match_eo = -1;
+  /* Tag arrays. */
+  int *next_tags, *tags = NULL;
+  /* Current TNFA state. */
+  tre_tnfa_transition_t *state;
+  int *states_seen = NULL;
+
+  /* Memory allocator to for allocating the backtracking stack. */
+  tre_mem_t mem = tre_bt_mem_new();
+
+  /* The backtracking stack. */
+  tre_backtrack_t stack;
+
+  tre_tnfa_transition_t *trans_i;
+  regmatch_t *pmatch = NULL;
+  int ret;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!mem)
+    return REG_ESPACE;
+  stack = tre_bt_mem_alloc(mem, sizeof(*stack));
+  if (!stack)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+  stack->prev = NULL;
+  stack->next = NULL;
+
+#ifdef TRE_USE_ALLOCA
+  tags = alloca(sizeof(*tags) * tnfa->num_tags);
+  pmatch = alloca(sizeof(*pmatch) * tnfa->num_submatches);
+  states_seen = alloca(sizeof(*states_seen) * tnfa->num_states);
+#else /* !TRE_USE_ALLOCA */
+  tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+  if (!tags)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+  pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);
+  if (!pmatch)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+  states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);
+  if (!states_seen)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+#endif /* !TRE_USE_ALLOCA */
+
+ retry:
+  {
+    int i;
+    for (i = 0; i < tnfa->num_tags; i++)
+      {
+	tags[i] = -1;
+	if (match_tags)
+	  match_tags[i] = -1;
+      }
+    for (i = 0; i < tnfa->num_states; i++)
+      states_seen[i] = 0;
+  }
+
+  state = NULL;
+  pos = pos_start;
+  GET_NEXT_WCHAR();
+  pos_start = pos;
+  next_c_start = next_c;
+  str_byte_start = str_byte;
+#ifdef TRE_MBSTATE
+  mbstate_start = mbstate;
+#endif /* TRE_MBSTATE */
+
+  /* Handle initial states. */
+  next_tags = NULL;
+  for (trans_i = tnfa->initial; trans_i->state; trans_i++)
+    {
+      DPRINT(("> init %p, prev_c %lc\n", trans_i->state, (tre_cint_t)prev_c));
+      if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))
+	{
+	  DPRINT(("assert failed\n"));
+	  continue;
+	}
+      if (state == NULL)
+	{
+	  /* Start from this state. */
+	  state = trans_i->state;
+	  next_tags = trans_i->tags;
+	}
+      else
+	{
+	  /* Backtrack to this state. */
+	  DPRINT(("saving state %d for backtracking\n", trans_i->state_id));
+	  BT_STACK_PUSH(pos, str_byte, str_wide, trans_i->state,
+			trans_i->state_id, next_c, tags, mbstate);
+	  {
+	    int *tmp = trans_i->tags;
+	    if (tmp)
+	      while (*tmp >= 0)
+		stack->item.tags[*tmp++] = pos;
+	  }
+	}
+    }
+
+  if (next_tags)
+    for (; *next_tags >= 0; next_tags++)
+      tags[*next_tags] = pos;
+
+
+  DPRINT(("entering match loop, pos %d, str_byte %p\n", pos, str_byte));
+  DPRINT(("pos:chr/code | state and tags\n"));
+  DPRINT(("-------------+------------------------------------------------\n"));
+
+  if (state == NULL)
+    goto backtrack;
+
+  while (1)
+    {
+      tre_tnfa_transition_t *trans_i, *next_state;
+      int empty_br_match;
+
+      DPRINT(("start loop\n"));
+      if (state == tnfa->final)
+	{
+	  DPRINT(("  match found, %d %d\n", match_eo, pos));
+	  if (match_eo < pos
+	      || (match_eo == pos
+		  && match_tags
+		  && tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
+				   tags, match_tags)))
+	    {
+	      int i;
+	      /* This match wins the previous match. */
+	      DPRINT(("	 win previous\n"));
+	      match_eo = pos;
+	      if (match_tags)
+		for (i = 0; i < tnfa->num_tags; i++)
+		  match_tags[i] = tags[i];
+	    }
+	  /* Our TNFAs never have transitions leaving from the final state,
+	     so we jump right to backtracking. */
+	  goto backtrack;
+	}
+
+#ifdef TRE_DEBUG
+      DPRINT(("%3d:%2lc/%05d | %p ", pos, (tre_cint_t)next_c, (int)next_c,
+	      state));
+      {
+	int i;
+	for (i = 0; i < tnfa->num_tags; i++)
+	  DPRINT(("%d%s", tags[i], i < tnfa->num_tags - 1 ? ", " : ""));
+	DPRINT(("\n"));
+      }
+#endif /* TRE_DEBUG */
+
+      /* Go to the next character in the input string. */
+      empty_br_match = 0;
+      trans_i = state;
+      if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)
+	{
+	  /* This is a back reference state.  All transitions leaving from
+	     this state have the same back reference "assertion".  Instead
+	     of reading the next character, we match the back reference. */
+	  int so, eo, bt = trans_i->u.backref;
+	  int bt_len;
+	  int result;
+
+	  DPRINT(("  should match back reference %d\n", bt));
+	  /* Get the substring we need to match against.  Remember to
+	     turn off REG_NOSUB temporarily. */
+	  tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & !REG_NOSUB,
+			  tnfa, tags, pos);
+	  so = pmatch[bt].rm_so;
+	  eo = pmatch[bt].rm_eo;
+	  bt_len = eo - so;
+
+	  if (len < 0)
+	    {
+	      result = strncmp((char*)string + so, str_byte - 1, bt_len);
+	    }
+	  else if (len - pos < bt_len)
+	    result = 1;
+	  else
+	    result = memcmp((char*)string + so, str_byte - 1, bt_len);
+
+	  /* We can ignore multibyte characters here because the backref
+	     string is already aligned at character boundaries. */
+	  if (result == 0)
+	    {
+	      /* Back reference matched.  Check for infinite loop. */
+	      if (bt_len == 0)
+		empty_br_match = 1;
+	      if (empty_br_match && states_seen[trans_i->state_id])
+		{
+		  DPRINT(("  avoid loop\n"));
+		  goto backtrack;
+		}
+
+	      states_seen[trans_i->state_id] = empty_br_match;
+
+	      /* Advance in input string and resync `prev_c', `next_c'
+		 and pos. */
+	      DPRINT(("	 back reference matched\n"));
+	      str_byte += bt_len - 1;
+	      pos += bt_len - 1;
+	      GET_NEXT_WCHAR();
+	      DPRINT(("	 pos now %d\n", pos));
+	    }
+	  else
+	    {
+	      DPRINT(("	 back reference did not match\n"));
+	      goto backtrack;
+	    }
+	}
+      else
+	{
+	  /* Check for end of string. */
+	  if (len < 0)
+	    {
+	      if (next_c == L'\0')
+		goto backtrack;
+	    }
+	  else
+	    {
+	      if (pos >= len)
+		goto backtrack;
+	    }
+
+	  /* Read the next character. */
+	  GET_NEXT_WCHAR();
+	}
+
+      next_state = NULL;
+      for (trans_i = state; trans_i->state; trans_i++)
+	{
+	  DPRINT(("  transition %d-%d (%c-%c) %d to %d\n",
+		  trans_i->code_min, trans_i->code_max,
+		  trans_i->code_min, trans_i->code_max,
+		  trans_i->assertions, trans_i->state_id));
+	  if (trans_i->code_min <= prev_c && trans_i->code_max >= prev_c)
+	    {
+	      if (trans_i->assertions
+		  && (CHECK_ASSERTIONS(trans_i->assertions)
+		      /* Handle character class transitions. */
+		      || ((trans_i->assertions & ASSERT_CHAR_CLASS)
+			  && !(cflags & REG_ICASE)
+			  && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class))
+		      || ((trans_i->assertions & ASSERT_CHAR_CLASS)
+			  && (cflags & REG_ICASE)
+			  && (!tre_isctype(tre_tolower((tre_cint_t)prev_c),
+					   trans_i->u.class)
+			      && !tre_isctype(tre_toupper((tre_cint_t)prev_c),
+					      trans_i->u.class)))
+		      || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG)
+			  && tre_neg_char_classes_match(trans_i->neg_classes,
+							(tre_cint_t)prev_c,
+							cflags & REG_ICASE))))
+		{
+		  DPRINT(("  assertion failed\n"));
+		  continue;
+		}
+
+	      if (next_state == NULL)
+		{
+		  /* First matching transition. */
+		  DPRINT(("  Next state is %d\n", trans_i->state_id));
+		  next_state = trans_i->state;
+		  next_tags = trans_i->tags;
+		}
+	      else
+		{
+		  /* Second mathing transition.	 We may need to backtrack here
+		     to take this transition instead of the first one, so we
+		     push this transition in the backtracking stack so we can
+		     jump back here if needed. */
+		  DPRINT(("  saving state %d for backtracking\n",
+			  trans_i->state_id));
+		  BT_STACK_PUSH(pos, str_byte, str_wide, trans_i->state,
+				trans_i->state_id, next_c, tags, mbstate);
+		  {
+		    int *tmp;
+		    for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
+		      stack->item.tags[*tmp] = pos;
+		  }
+#if 0 /* XXX - it's important not to look at all transitions here to keep
+	 the stack small! */
+		  break;
+#endif
+		}
+	    }
+	}
+
+      if (next_state != NULL)
+	{
+	  /* Matching transitions were found.  Take the first one. */
+	  state = next_state;
+
+	  /* Update the tag values. */
+	  if (next_tags)
+	    while (*next_tags >= 0)
+	      tags[*next_tags++] = pos;
+	}
+      else
+	{
+	backtrack:
+	  /* A matching transition was not found.  Try to backtrack. */
+	  if (stack->prev)
+	    {
+	      DPRINT(("	 backtracking\n"));
+	      if (stack->item.state->assertions && ASSERT_BACKREF)
+		{
+		  DPRINT(("  states_seen[%d] = 0\n",
+			  stack->item.state_id));
+		  states_seen[stack->item.state_id] = 0;
+		}
+
+	      BT_STACK_POP();
+	    }
+	  else if (match_eo < 0)
+	    {
+	      /* Try starting from a later position in the input string. */
+	      /* Check for end of string. */
+	      if (len < 0)
+		{
+		  if (next_c == L'\0')
+		    {
+		      DPRINT(("end of string.\n"));
+		      break;
+		    }
+		}
+	      else
+		{
+		  if (pos >= len)
+		    {
+		      DPRINT(("end of string.\n"));
+		      break;
+		    }
+		}
+	      DPRINT(("restarting from next start position\n"));
+	      next_c = next_c_start;
+#ifdef TRE_MBSTATE
+	      mbstate = mbstate_start;
+#endif /* TRE_MBSTATE */
+	      str_byte = str_byte_start;
+	      goto retry;
+	    }
+	  else
+	    {
+	      DPRINT(("finished\n"));
+	      break;
+	    }
+	}
+    }
+
+  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
+  *match_end_ofs = match_eo;
+
+ error_exit:
+  tre_bt_mem_destroy(mem);
+#ifndef TRE_USE_ALLOCA
+  if (tags)
+    xfree(tags);
+  if (pmatch)
+    xfree(pmatch);
+  if (states_seen)
+    xfree(states_seen);
+#endif /* !TRE_USE_ALLOCA */
+
+  return ret;
+}
+
+
+/***********************************************************************
+ from regexec.c
+***********************************************************************/
+
+/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
+   endpoint values. */
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, int *tags, int match_eo)
+{
+  tre_submatch_data_t *submatch_data;
+  unsigned int i, j;
+  int *parents;
+
+  i = 0;
+  if (match_eo >= 0 && !(cflags & REG_NOSUB))
+    {
+      /* Construct submatch offsets from the tags. */
+      DPRINT(("end tag = t%d = %d\n", tnfa->end_tag, match_eo));
+      submatch_data = tnfa->submatch_data;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (submatch_data[i].so_tag == tnfa->end_tag)
+	    pmatch[i].rm_so = match_eo;
+	  else
+	    pmatch[i].rm_so = tags[submatch_data[i].so_tag];
+
+	  if (submatch_data[i].eo_tag == tnfa->end_tag)
+	    pmatch[i].rm_eo = match_eo;
+	  else
+	    pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];
+
+	  /* If either of the endpoints were not used, this submatch
+	     was not part of the match. */
+	  if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
+	    pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+
+	  DPRINT(("pmatch[%d] = {t%d = %d, t%d = %d}\n", i,
+		  submatch_data[i].so_tag, pmatch[i].rm_so,
+		  submatch_data[i].eo_tag, pmatch[i].rm_eo));
+	  i++;
+	}
+      /* Reset all submatches that are not within all of their parent
+	 submatches. */
+      i = 0;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (pmatch[i].rm_eo == -1)
+	    assert(pmatch[i].rm_so == -1);
+	  assert(pmatch[i].rm_so <= pmatch[i].rm_eo);
+
+	  parents = submatch_data[i].parents;
+	  if (parents != NULL)
+	    for (j = 0; parents[j] >= 0; j++)
+	      {
+		DPRINT(("pmatch[%d] parent %d\n", i, parents[j]));
+		if (pmatch[i].rm_so < pmatch[parents[j]].rm_so
+		    || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
+		  pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+	      }
+	  i++;
+	}
+    }
+
+  while (i < nmatch)
+    {
+      pmatch[i].rm_so = -1;
+      pmatch[i].rm_eo = -1;
+      i++;
+    }
+}
+
+
+/*
+  Wrapper functions for POSIX compatible regexp matching.
+*/
+
+static int
+tre_match(const tre_tnfa_t *tnfa, const void *string, size_t len,
+	  size_t nmatch, regmatch_t pmatch[], int eflags)
+{
+  reg_errcode_t status;
+  int *tags = NULL, eo;
+  if (tnfa->num_tags > 0 && nmatch > 0)
+    {
+#ifdef TRE_USE_ALLOCA
+      tags = alloca(sizeof(*tags) * tnfa->num_tags);
+#else /* !TRE_USE_ALLOCA */
+      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+#endif /* !TRE_USE_ALLOCA */
+      if (tags == NULL)
+	return REG_ESPACE;
+    }
+
+  /* Dispatch to the appropriate matcher. */
+  if (tnfa->have_backrefs)
+    {
+      /* The regex has back references, use the backtracking matcher. */
+      status = tre_tnfa_run_backtrack(tnfa, string, len, tags, eflags, &eo);
+    }
+  else
+    {
+      /* Exact matching, no back references, use the parallel matcher. */
+      status = tre_tnfa_run_parallel(tnfa, string, len, tags, eflags, &eo);
+    }
+
+  if (status == REG_OK)
+    /* A match was found, so fill the submatch registers. */
+    tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
+#ifndef TRE_USE_ALLOCA
+  if (tags)
+    xfree(tags);
+#endif /* !TRE_USE_ALLOCA */
+  return status;
+}
+
+int
+regexec(const regex_t *preg, const char *str,
+	size_t nmatch, regmatch_t pmatch[], int eflags)
+{
+  return tre_match((void *)preg->TRE_REGEX_T_FIELD, str, -1,
+                   nmatch, pmatch, eflags);
+}
+
+/* EOF */
diff --git a/src/regex/tre-mem.c b/src/regex/tre-mem.c
new file mode 100644
index 00000000..d7bdd3db
--- /dev/null
+++ b/src/regex/tre-mem.c
@@ -0,0 +1,163 @@
+/*
+  tre-mem.c - TRE memory allocator
+
+  Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+/*
+  This memory allocator is for allocating small memory blocks efficiently
+  in terms of memory overhead and execution speed.  The allocated blocks
+  cannot be freed individually, only all at once.  There can be multiple
+  allocators, though.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tre.h"
+
+
+/* Returns a new memory allocator or NULL if out of memory. */
+tre_mem_t
+tre_mem_new_impl(int provided, void *provided_block)
+{
+  tre_mem_t mem;
+  if (provided)
+    {
+      mem = provided_block;
+      memset(mem, 0, sizeof(*mem));
+    }
+  else
+    mem = xcalloc(1, sizeof(*mem));
+  if (mem == NULL)
+    return NULL;
+  return mem;
+}
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+void
+tre_mem_destroy(tre_mem_t mem)
+{
+  tre_list_t *tmp, *l = mem->blocks;
+
+  while (l != NULL)
+    {
+      xfree(l->data);
+      tmp = l->next;
+      xfree(l);
+      l = tmp;
+    }
+  xfree(mem);
+}
+
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+void *
+tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+		   int zero, size_t size)
+{
+  void *ptr;
+
+  if (mem->failed)
+    {
+      DPRINT(("tre_mem_alloc: oops, called after failure?!\n"));
+      return NULL;
+    }
+
+#ifdef MALLOC_DEBUGGING
+  if (!provided)
+    {
+      ptr = xmalloc(1);
+      if (ptr == NULL)
+	{
+	  DPRINT(("tre_mem_alloc: xmalloc forced failure\n"));
+	  mem->failed = 1;
+	  return NULL;
+	}
+      xfree(ptr);
+    }
+#endif /* MALLOC_DEBUGGING */
+
+  if (mem->n < size)
+    {
+      /* We need more memory than is available in the current block.
+	 Allocate a new block. */
+      tre_list_t *l;
+      if (provided)
+	{
+	  DPRINT(("tre_mem_alloc: using provided block\n"));
+	  if (provided_block == NULL)
+	    {
+	      DPRINT(("tre_mem_alloc: provided block was NULL\n"));
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  mem->ptr = provided_block;
+	  mem->n = TRE_MEM_BLOCK_SIZE;
+	}
+      else
+	{
+	  int block_size;
+	  if (size * 8 > TRE_MEM_BLOCK_SIZE)
+	    block_size = size * 8;
+	  else
+	    block_size = TRE_MEM_BLOCK_SIZE;
+	  DPRINT(("tre_mem_alloc: allocating new %d byte block\n",
+		  block_size));
+	  l = xmalloc(sizeof(*l));
+	  if (l == NULL)
+	    {
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->data = xmalloc(block_size);
+	  if (l->data == NULL)
+	    {
+	      xfree(l);
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->next = NULL;
+	  if (mem->current != NULL)
+	    mem->current->next = l;
+	  if (mem->blocks == NULL)
+	    mem->blocks = l;
+	  mem->current = l;
+	  mem->ptr = l->data;
+	  mem->n = block_size;
+	}
+    }
+
+  /* Make sure the next pointer will be aligned. */
+  size += ALIGN(mem->ptr + size, long);
+
+  /* Allocate from current block. */
+  ptr = mem->ptr;
+  mem->ptr += size;
+  mem->n -= size;
+
+  /* Set to zero if needed. */
+  if (zero)
+    memset(ptr, 0, size);
+
+  return ptr;
+}
+
+/* EOF */
diff --git a/src/regex/tre.h b/src/regex/tre.h
new file mode 100644
index 00000000..bfd171f4
--- /dev/null
+++ b/src/regex/tre.h
@@ -0,0 +1,269 @@
+/*
+  tre-internal.h - TRE internal definitions
+
+  Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#include <regex.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#define TRE_MULTIBYTE 1
+#undef  TRE_MBSTATE
+#define TRE_WCHAR 1
+#define TRE_USE_SYSTEM_WCTYPE 1
+#define HAVE_WCSTOMBS 1
+#define TRE_MB_CUR_MAX MB_CUR_MAX
+
+#define NDEBUG
+
+#define TRE_REGEX_T_FIELD __opaque
+typedef int reg_errcode_t;
+
+typedef wchar_t tre_char_t;
+
+
+#ifdef TRE_DEBUG
+#include <stdio.h>
+#define DPRINT(msg) do {printf msg; fflush(stdout);} while(0)
+#else /* !TRE_DEBUG */
+#define DPRINT(msg) do { } while(0)
+#endif /* !TRE_DEBUG */
+
+#define elementsof(x)	( sizeof(x) / sizeof(x[0]) )
+
+#if 1
+int __mbtowc(wchar_t *, const char *);
+#define tre_mbrtowc(pwc, s, n, ps) (__mbtowc((pwc), (s)))
+#else
+#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))
+#endif
+
+/* Wide characters. */
+typedef wint_t tre_cint_t;
+#define TRE_CHAR_MAX WCHAR_MAX
+
+#ifdef TRE_MULTIBYTE
+#define TRE_MB_CUR_MAX MB_CUR_MAX
+#else /* !TRE_MULTIBYTE */
+#define TRE_MB_CUR_MAX 1
+#endif /* !TRE_MULTIBYTE */
+
+#define tre_isalnum iswalnum
+#define tre_isalpha iswalpha
+#define tre_isblank iswblank
+#define tre_iscntrl iswcntrl
+#define tre_isdigit iswdigit
+#define tre_isgraph iswgraph
+#define tre_islower iswlower
+#define tre_isprint iswprint
+#define tre_ispunct iswpunct
+#define tre_isspace iswspace
+#define tre_isupper iswupper
+#define tre_isxdigit iswxdigit
+
+#define tre_tolower towlower
+#define tre_toupper towupper
+#define tre_strlen  wcslen
+
+/* Use system provided iswctype() and wctype(). */
+typedef wctype_t tre_ctype_t;
+#define tre_isctype iswctype
+#define tre_ctype   wctype
+
+/* Returns number of bytes to add to (char *)ptr to make it
+   properly aligned for the type. */
+#define ALIGN(ptr, type) \
+  ((((long)ptr) % sizeof(type)) \
+   ? (sizeof(type) - (((long)ptr) % sizeof(type))) \
+   : 0)
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+
+/* Define STRF to the correct printf formatter for strings. */
+#define STRF "ls"
+
+/* TNFA transition type. A TNFA state is an array of transitions,
+   the terminator is a transition with NULL `state'. */
+typedef struct tnfa_transition tre_tnfa_transition_t;
+
+struct tnfa_transition {
+  /* Range of accepted characters. */
+  tre_cint_t code_min;
+  tre_cint_t code_max;
+  /* Pointer to the destination state. */
+  tre_tnfa_transition_t *state;
+  /* ID number of the destination state. */
+  int state_id;
+  /* -1 terminated array of tags (or NULL). */
+  int *tags;
+  /* Assertion bitmap. */
+  int assertions;
+  /* Assertion parameters. */
+  union {
+    /* Character class assertion. */
+    tre_ctype_t class;
+    /* Back reference assertion. */
+    int backref;
+  } u;
+  /* Negative character class assertions. */
+  tre_ctype_t *neg_classes;
+};
+
+
+/* Assertions. */
+#define ASSERT_AT_BOL		  1   /* Beginning of line. */
+#define ASSERT_AT_EOL		  2   /* End of line. */
+#define ASSERT_CHAR_CLASS	  4   /* Character class in `class'. */
+#define ASSERT_CHAR_CLASS_NEG	  8   /* Character classes in `neg_classes'. */
+#define ASSERT_AT_BOW		 16   /* Beginning of word. */
+#define ASSERT_AT_EOW		 32   /* End of word. */
+#define ASSERT_AT_WB		 64   /* Word boundary. */
+#define ASSERT_AT_WB_NEG	128   /* Not a word boundary. */
+#define ASSERT_BACKREF		256   /* A back reference in `backref'. */
+#define ASSERT_LAST		256
+
+/* Tag directions. */
+typedef enum {
+  TRE_TAG_MINIMIZE = 0,
+  TRE_TAG_MAXIMIZE = 1
+} tre_tag_direction_t;
+
+/* Instructions to compute submatch register values from tag values
+   after a successful match.  */
+struct tre_submatch_data {
+  /* Tag that gives the value for rm_so (submatch start offset). */
+  int so_tag;
+  /* Tag that gives the value for rm_eo (submatch end offset). */
+  int eo_tag;
+  /* List of submatches this submatch is contained in. */
+  int *parents;
+};
+
+typedef struct tre_submatch_data tre_submatch_data_t;
+
+
+/* TNFA definition. */
+typedef struct tnfa tre_tnfa_t;
+
+struct tnfa {
+  tre_tnfa_transition_t *transitions;
+  unsigned int num_transitions;
+  tre_tnfa_transition_t *initial;
+  tre_tnfa_transition_t *final;
+  tre_submatch_data_t *submatch_data;
+  unsigned int num_submatches;
+  tre_tag_direction_t *tag_directions;
+  int num_tags;
+  int end_tag;
+  int num_states;
+  int cflags;
+  int have_backrefs;
+};
+
+#if 0
+static int
+tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags);
+
+static void
+tre_free(regex_t *preg);
+
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, int *tags, int match_eo);
+
+static reg_errcode_t
+tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len,
+		      tre_str_type_t type, int *match_tags, int eflags,
+		      int *match_end_ofs);
+
+static reg_errcode_t
+tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len,
+		      tre_str_type_t type, int *match_tags, int eflags,
+		      int *match_end_ofs);
+
+static reg_errcode_t
+tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
+		       int len, tre_str_type_t type, int *match_tags,
+		       int eflags, int *match_end_ofs);
+#endif
+
+/* from tre-mem.h: */
+
+#define TRE_MEM_BLOCK_SIZE 1024
+
+typedef struct tre_list {
+  void *data;
+  struct tre_list *next;
+} tre_list_t;
+
+typedef struct tre_mem_struct {
+  tre_list_t *blocks;
+  tre_list_t *current;
+  char *ptr;
+  size_t n;
+  int failed;
+  void **provided;
+} *tre_mem_t;
+
+#define tre_mem_new_impl   __tre_mem_new_impl
+#define tre_mem_alloc_impl __tre_mem_alloc_impl
+#define tre_mem_destroy    __tre_mem_destroy
+
+tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
+void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+			 int zero, size_t size);
+
+/* Returns a new memory allocator or NULL if out of memory. */
+#define tre_mem_new()  tre_mem_new_impl(0, NULL)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed.  The memory
+   is set to zero. */
+#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)
+
+#ifdef TRE_USE_ALLOCA
+/* alloca() versions.  Like above, but memory is allocated with alloca()
+   instead of malloc(). */
+
+#define tre_mem_newa() \
+  tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))
+
+#define tre_mem_alloca(mem, size)					      \
+  ((mem)->n >= (size)							      \
+   ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size))			      \
+   : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))
+#endif /* TRE_USE_ALLOCA */
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+void tre_mem_destroy(tre_mem_t mem);
+
+#define xmalloc malloc
+#define xcalloc calloc
+#define xfree free
+#define xrealloc realloc
+
+/* EOF */
diff --git a/src/select/poll.c b/src/select/poll.c
new file mode 100644
index 00000000..e92943e1
--- /dev/null
+++ b/src/select/poll.c
@@ -0,0 +1,12 @@
+#include <poll.h>
+#include "syscall.h"
+#include "libc.h"
+
+int poll(struct pollfd *fds, nfds_t n, int timeout)
+{
+	int r;
+	CANCELPT_BEGIN;
+	r = syscall3(__NR_poll, (long)fds, n, timeout);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/select/pselect.c b/src/select/pselect.c
new file mode 100644
index 00000000..795c5b0d
--- /dev/null
+++ b/src/select/pselect.c
@@ -0,0 +1,15 @@
+#include <sys/select.h>
+#include "syscall.h"
+#include "libc.h"
+
+int pselect(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *ts, const sigset_t *mask)
+{
+	int r;
+	long data[2] = { (long)mask, 8 };
+	struct timespec ts_tmp;
+	if (ts) ts_tmp = *ts;
+	CANCELPT_BEGIN;
+	r = syscall6(__NR_pselect6, n, (long)rfds, (long)wfds, (long)efds, ts ? (long)&ts_tmp : 0, (long)data);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/select/select.c b/src/select/select.c
new file mode 100644
index 00000000..a604d094
--- /dev/null
+++ b/src/select/select.c
@@ -0,0 +1,12 @@
+#include <sys/select.h>
+#include "syscall.h"
+#include "libc.h"
+
+int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
+{
+	int r;
+	CANCELPT_BEGIN;
+	r = syscall5(__NR__newselect, n, (long)rfds, (long)wfds, (long)efds, (long)tv);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/setjmp/i386/longjmp.s b/src/setjmp/i386/longjmp.s
new file mode 100644
index 00000000..c1a956c3
--- /dev/null
+++ b/src/setjmp/i386/longjmp.s
@@ -0,0 +1,22 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	movl  4(%esp),%edx
+	movl  8(%esp),%eax
+	testl    %eax,%eax
+	jnz .L0
+	incl     %eax
+.L0:
+	movl   (%edx),%ebx
+	movl  4(%edx),%esi
+	movl  8(%edx),%edi
+	movl 12(%edx),%ebp
+	movl 16(%edx),%ecx
+	movl     %ecx,%esp
+	movl 20(%edx),%ecx
+	jmp *%ecx
+.size _longjmp,.-_longjmp
+.size longjmp,.-longjmp
diff --git a/src/setjmp/i386/setjmp.s b/src/setjmp/i386/setjmp.s
new file mode 100644
index 00000000..6c078b10
--- /dev/null
+++ b/src/setjmp/i386/setjmp.s
@@ -0,0 +1,23 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,%function
+.type _setjmp,%function
+.type setjmp,%function
+__setjmp:
+_setjmp:
+setjmp:
+	movl 4(%esp), %eax
+	movl    %ebx, (%eax)
+	movl    %esi, 4(%eax)
+	movl    %edi, 8(%eax)
+	movl    %ebp, 12(%eax)
+	leal 4(%esp), %ecx
+	movl    %ecx, 16(%eax)
+	movl  (%esp), %ecx
+	movl    %ecx, 20(%eax)
+	xorl    %eax, %eax
+	ret
+.size __setjmp,.-__setjmp
+.size _setjmp,.-_setjmp
+.size setjmp,.-setjmp
diff --git a/src/setjmp/longjmp.c b/src/setjmp/longjmp.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/setjmp/longjmp.c
diff --git a/src/setjmp/setjmp.c b/src/setjmp/setjmp.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/setjmp/setjmp.c
diff --git a/src/signal/bsd_signal.c b/src/signal/bsd_signal.c
new file mode 100644
index 00000000..0b9a6855
--- /dev/null
+++ b/src/signal/bsd_signal.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+void (*bsd_signal(int sig, void (*func)(int)))(int)
+{
+	return signal(sig, func);
+}
diff --git a/src/signal/getitimer.c b/src/signal/getitimer.c
new file mode 100644
index 00000000..222d113e
--- /dev/null
+++ b/src/signal/getitimer.c
@@ -0,0 +1,12 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int getitimer(int which, struct itimerval *old)
+{
+	int ret;
+	long kold[4];
+
+	if (!(ret = syscall2(__NR_getitimer, which, (long)&kold)))
+		*old = (struct itimerval){ { kold[0], kold[1] }, { kold[2], kold[3] } };
+	return ret;
+}
diff --git a/src/signal/i386/sigsetjmp.s b/src/signal/i386/sigsetjmp.s
new file mode 100644
index 00000000..0e7eefb0
--- /dev/null
+++ b/src/signal/i386/sigsetjmp.s
@@ -0,0 +1,13 @@
+.global sigsetjmp
+sigsetjmp:
+	mov 4(%esp),%eax
+	mov 8(%esp),%ecx
+	mov %ecx,24(%eax)
+	jecxz 1f
+	add $28,%eax
+	push %eax
+	push $0
+	push $2
+	call sigprocmask
+	add $12,%esp
+1:	jmp setjmp
diff --git a/src/signal/kill.c b/src/signal/kill.c
new file mode 100644
index 00000000..cc4b51e1
--- /dev/null
+++ b/src/signal/kill.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int kill(pid_t pid, int sig)
+{
+	return syscall2(__NR_kill, pid, sig);
+}
diff --git a/src/signal/killpg.c b/src/signal/killpg.c
new file mode 100644
index 00000000..315ed447
--- /dev/null
+++ b/src/signal/killpg.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <errno.h>
+
+int killpg(pid_t pgid, int sig)
+{
+	if (pgid < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+	return kill(-pgid, sig);
+}
diff --git a/src/signal/raise.c b/src/signal/raise.c
new file mode 100644
index 00000000..52f8b428
--- /dev/null
+++ b/src/signal/raise.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int raise(int sig)
+{
+	return __syscall_kill(__syscall_getpid(), sig);
+}
diff --git a/src/signal/setitimer.c b/src/signal/setitimer.c
new file mode 100644
index 00000000..cacab036
--- /dev/null
+++ b/src/signal/setitimer.c
@@ -0,0 +1,15 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int setitimer(int which, const struct itimerval *new, struct itimerval *old)
+{
+	int ret;
+	long knew[4] = {
+		new->it_interval.tv_sec, new->it_interval.tv_usec,
+		new->it_value.tv_sec, new->it_value.tv_usec
+	}, kold[4];
+
+	if (!(ret = syscall3(__NR_setitimer, which, (long)&knew, old ? (long)&kold : 0)) && old)
+		*old = (struct itimerval){ { kold[0], kold[1] }, { kold[2], kold[3] } };
+	return ret;
+}
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
new file mode 100644
index 00000000..4acd1730
--- /dev/null
+++ b/src/signal/sigaction.c
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+static void restorer()
+{
+	syscall0(__NR_rt_sigreturn);
+}
+
+int __libc_sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
+{
+	struct {
+		void *handler;
+		unsigned long flags;
+		void (*restorer)(void);
+		sigset_t mask;
+	} ksa, kold;
+	long pksa=0, pkold=0;
+	if (sa) {
+		ksa.handler = sa->sa_handler;
+		ksa.flags = sa->sa_flags;
+		ksa.restorer = restorer;
+		ksa.mask = sa->sa_mask;
+		pksa = (long)&ksa;
+	}
+	if (old) pkold = (long)&kold;
+	if (syscall4(__NR_rt_sigaction, sig, pksa, pkold, 8))
+		return -1;
+	if (old) {
+		old->sa_handler = kold.handler;
+		old->sa_flags = kold.flags;
+		old->sa_mask = kold.mask;
+	}
+	return 0;
+}
+
+int __sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
+{
+	if (sig == SIGCANCEL || sig == SIGSYSCALL) {
+		errno = EINVAL;
+		return -1;
+	}
+	return __libc_sigaction(sig, sa, old);
+}
+
+weak_alias(__sigaction, sigaction);
diff --git a/src/signal/sigaddset.c b/src/signal/sigaddset.c
new file mode 100644
index 00000000..23e655db
--- /dev/null
+++ b/src/signal/sigaddset.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigaddset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= 8*sizeof(sigset_t)) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
+	return 0;
+}
diff --git a/src/signal/sigaltstack.c b/src/signal/sigaltstack.c
new file mode 100644
index 00000000..3cc2d456
--- /dev/null
+++ b/src/signal/sigaltstack.c
@@ -0,0 +1,8 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigaltstack(const stack_t *ss, stack_t *old)
+{
+	/* depends on kernel struct matching */
+	return syscall2(__NR_sigaltstack, (long)ss, (long)old);
+}
diff --git a/src/signal/sigdelset.c b/src/signal/sigdelset.c
new file mode 100644
index 00000000..14042fb8
--- /dev/null
+++ b/src/signal/sigdelset.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigdelset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= 8*sizeof(sigset_t)) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] &=~(1UL<<(s&8*sizeof *set->__bits-1));
+	return 0;
+}
diff --git a/src/signal/sigemptyset.c b/src/signal/sigemptyset.c
new file mode 100644
index 00000000..91f77adf
--- /dev/null
+++ b/src/signal/sigemptyset.c
@@ -0,0 +1,8 @@
+#include <signal.h>
+#include <string.h>
+
+int sigemptyset(sigset_t *set)
+{
+	memset(set, 0, sizeof *set);
+	return 0;
+}
diff --git a/src/signal/sigfillset.c b/src/signal/sigfillset.c
new file mode 100644
index 00000000..fab50a52
--- /dev/null
+++ b/src/signal/sigfillset.c
@@ -0,0 +1,8 @@
+#include <signal.h>
+#include <string.h>
+
+int sigfillset(sigset_t *set)
+{
+	memset(set, -1, sizeof *set);
+	return 0;
+}
diff --git a/src/signal/sighold.c b/src/signal/sighold.c
new file mode 100644
index 00000000..5b0f6b18
--- /dev/null
+++ b/src/signal/sighold.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <stdlib.h>
+
+int sighold(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_BLOCK, &mask, NULL);
+}
diff --git a/src/signal/sigignore.c b/src/signal/sigignore.c
new file mode 100644
index 00000000..98dff61e
--- /dev/null
+++ b/src/signal/sigignore.c
@@ -0,0 +1,12 @@
+#include <signal.h>
+#include <stdlib.h>
+
+int sigignore(int sig)
+{
+	struct sigaction sa;
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = 0;
+	return sigaction(sig, &sa, NULL);
+}
diff --git a/src/signal/siginterrupt.c b/src/signal/siginterrupt.c
new file mode 100644
index 00000000..60b34054
--- /dev/null
+++ b/src/signal/siginterrupt.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <signal.h>
+
+int siginterrupt(int sig, int flag)
+{
+	struct sigaction sa;
+
+	sigaction(sig, NULL, &sa);
+	if (flag) sa.sa_flags &= ~SA_RESTART;
+	else sa.sa_flags |= SA_RESTART;
+
+	return sigaction(sig, &sa, NULL);
+}
diff --git a/src/signal/sigismember.c b/src/signal/sigismember.c
new file mode 100644
index 00000000..afd29e52
--- /dev/null
+++ b/src/signal/sigismember.c
@@ -0,0 +1,12 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigismember(const sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= 8*sizeof(sigset_t)) {
+		errno = EINVAL;
+		return -1;
+	}
+	return !!(set->__bits[s/8/sizeof *set->__bits] & 1UL<<(s&8*sizeof *set->__bits-1));
+}
diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c
new file mode 100644
index 00000000..33ac30ea
--- /dev/null
+++ b/src/signal/siglongjmp.c
@@ -0,0 +1,12 @@
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+
+void siglongjmp(sigjmp_buf buf, int ret)
+{
+	long *flag = buf + sizeof(jmp_buf)/sizeof(long);
+	sigset_t *mask = (void *)(flag + 1);
+	if (*flag)
+		sigprocmask (SIG_SETMASK, mask, NULL);
+	longjmp((void *)buf, ret);
+}
diff --git a/src/signal/signal.c b/src/signal/signal.c
new file mode 100644
index 00000000..08902760
--- /dev/null
+++ b/src/signal/signal.c
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <stddef.h>
+#include "syscall.h"
+
+int __sigaction(int, const struct sigaction *, struct sigaction *);
+
+void (*signal(int sig, void (*func)(int)))(int)
+{
+	struct sigaction sa = { .sa_handler = func, .sa_flags = SA_RESTART };
+	if (__sigaction(sig, &sa, &sa) < 0)
+		return SIG_ERR;
+	return sa.sa_handler;
+}
diff --git a/src/signal/sigpause.c b/src/signal/sigpause.c
new file mode 100644
index 00000000..263c00f5
--- /dev/null
+++ b/src/signal/sigpause.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <stdlib.h>
+
+int sigpause(int sig)
+{
+	sigset_t mask;
+
+	if (sigprocmask(0, NULL, &mask) < 0 || sigdelset(&mask, sig) < 0)
+		return -1;
+	return sigsuspend(&mask);
+}
diff --git a/src/signal/sigpending.c b/src/signal/sigpending.c
new file mode 100644
index 00000000..7deda256
--- /dev/null
+++ b/src/signal/sigpending.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigpending(sigset_t *set)
+{
+	return syscall2(__NR_rt_sigpending, (long)set, SYSCALL_SIGSET_SIZE);
+}
diff --git a/src/signal/sigprocmask.c b/src/signal/sigprocmask.c
new file mode 100644
index 00000000..e89f8765
--- /dev/null
+++ b/src/signal/sigprocmask.c
@@ -0,0 +1,23 @@
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __libc_sigprocmask(int how, const sigset_t *set, sigset_t *old)
+{
+	return syscall4(__NR_rt_sigprocmask, how, (long)set, (long)old, 8);
+}
+
+int __sigprocmask(int how, const sigset_t *set, sigset_t *old)
+{
+	sigset_t tmp;
+	/* Quickly mask out bits 32 and 33 (thread control signals) */
+	if (0 && how != SIG_UNBLOCK && (set->__bits[4/sizeof *set->__bits] & 3UL<<(32&8*sizeof *set->__bits-1))) {
+		tmp = *set;
+		set = &tmp;
+		tmp.__bits[4/sizeof *set->__bits] &= ~(3UL<<(32&8*sizeof *set->__bits-1));
+	}
+	return __libc_sigprocmask(how, set, old);
+}
+
+weak_alias(__sigprocmask, sigprocmask);
+weak_alias(__sigprocmask, pthread_sigmask);
diff --git a/src/signal/sigqueue.c b/src/signal/sigqueue.c
new file mode 100644
index 00000000..ce3abf6c
--- /dev/null
+++ b/src/signal/sigqueue.c
@@ -0,0 +1,14 @@
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include "syscall.h"
+
+int sigqueue(pid_t pid, int sig, const union sigval value)
+{
+	siginfo_t si = {
+		.si_signo = sig,
+		.si_code = -1,
+		.si_value = value,
+	};
+	return syscall3(__NR_rt_sigqueueinfo, pid, sig, (long)&si);
+}
diff --git a/src/signal/sigrelse.c b/src/signal/sigrelse.c
new file mode 100644
index 00000000..b0b3024b
--- /dev/null
+++ b/src/signal/sigrelse.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <stdlib.h>
+
+int sigrelse(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_UNBLOCK, &mask, NULL);
+}
diff --git a/src/signal/sigrtmax.c b/src/signal/sigrtmax.c
new file mode 100644
index 00000000..0ef29873
--- /dev/null
+++ b/src/signal/sigrtmax.c
@@ -0,0 +1,4 @@
+int __libc_current_sigrtmax()
+{
+	return 64;
+}
diff --git a/src/signal/sigrtmin.c b/src/signal/sigrtmin.c
new file mode 100644
index 00000000..7ad06d22
--- /dev/null
+++ b/src/signal/sigrtmin.c
@@ -0,0 +1,4 @@
+int __libc_current_sigrtmin()
+{
+	return 34;
+}
diff --git a/src/signal/sigset.c b/src/signal/sigset.c
new file mode 100644
index 00000000..1b6b38fd
--- /dev/null
+++ b/src/signal/sigset.c
@@ -0,0 +1,28 @@
+#include <signal.h>
+#include <stdlib.h>
+
+void (*sigset(int sig, void (*handler)(int)))(int)
+{
+	struct sigaction sa, sa_old;
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0)
+		return SIG_ERR;
+	
+	if (handler == SIG_HOLD) {
+		if (sigaction(sig, NULL, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_BLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	} else {
+		sa.sa_handler = handler;
+		sa.sa_flags = 0;
+		sigemptyset(&sa.sa_mask);
+		if (sigaction(sig, &sa, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	}
+	return sigismember(&mask, sig) ? SIG_HOLD : sa_old.sa_handler;
+}
diff --git a/src/signal/sigsetjmp.c b/src/signal/sigsetjmp.c
new file mode 100644
index 00000000..a6667a27
--- /dev/null
+++ b/src/signal/sigsetjmp.c
@@ -0,0 +1,17 @@
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+
+/* !!! This function will not work unless the compiler performs
+ * tail call optimization. Machine-specific asm versions should
+ * be created instead even though the workaround (tail call)
+ * is entirely non-machine-specific... */
+
+int sigsetjmp(sigjmp_buf buf, int save)
+{
+	long *flag = buf + sizeof(jmp_buf)/sizeof(long);
+	sigset_t *mask = (void *)(flag + 1);
+	if ((*flag = save))
+		sigprocmask (SIG_SETMASK, NULL, mask);
+	return setjmp((void *)buf);
+}
diff --git a/src/signal/sigsuspend.c b/src/signal/sigsuspend.c
new file mode 100644
index 00000000..1acdab06
--- /dev/null
+++ b/src/signal/sigsuspend.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigsuspend(const sigset_t *mask)
+{
+	return syscall2(__NR_rt_sigsuspend, (long)mask, sizeof(sigset_t));
+}
diff --git a/src/signal/sigtimedwait.c b/src/signal/sigtimedwait.c
new file mode 100644
index 00000000..155185de
--- /dev/null
+++ b/src/signal/sigtimedwait.c
@@ -0,0 +1,12 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigtimedwait(const sigset_t *mask, siginfo_t *si, const struct timespec *timeout)
+{
+	long k_timeout[2];
+	if (timeout) {
+		k_timeout[0] = timeout->tv_sec;
+		k_timeout[1] = timeout->tv_nsec;
+	}
+	return syscall4(__NR_rt_sigtimedwait, (long)mask, (long)si, timeout ? (long)k_timeout : 0, SYSCALL_SIGSET_SIZE);
+}
diff --git a/src/signal/sigwait.c b/src/signal/sigwait.c
new file mode 100644
index 00000000..9569d6b0
--- /dev/null
+++ b/src/signal/sigwait.c
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <stddef.h>
+
+int sigwait(const sigset_t *mask, int *sig)
+{
+	siginfo_t si;
+	if (sigtimedwait(mask, &si, NULL) < 0)
+		return -1;
+	*sig = si.si_signo;
+	return 0;
+}
diff --git a/src/signal/sigwaitinfo.c b/src/signal/sigwaitinfo.c
new file mode 100644
index 00000000..e79feb91
--- /dev/null
+++ b/src/signal/sigwaitinfo.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include <stddef.h>
+
+int sigwaitinfo(const sigset_t *mask, siginfo_t *si)
+{
+	return sigtimedwait(mask, si, NULL);
+}
diff --git a/src/stat/chmod.c b/src/stat/chmod.c
new file mode 100644
index 00000000..cb310fec
--- /dev/null
+++ b/src/stat/chmod.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int chmod(const char *path, mode_t mode)
+{
+	return syscall2(__NR_chmod, (long)path, mode);
+}
diff --git a/src/stat/fchmod.c b/src/stat/fchmod.c
new file mode 100644
index 00000000..91897383
--- /dev/null
+++ b/src/stat/fchmod.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int fchmod(int fd, mode_t mode)
+{
+	return syscall2(__NR_fchmod, fd, mode);
+}
diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
new file mode 100644
index 00000000..f4f22b2c
--- /dev/null
+++ b/src/stat/fchmodat.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+	return syscall4(__NR_fchmodat, fd, (long)path, mode, flag);
+}
diff --git a/src/stat/fstat.c b/src/stat/fstat.c
new file mode 100644
index 00000000..5f643301
--- /dev/null
+++ b/src/stat/fstat.c
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fstat(int fd, struct stat *buf)
+{
+	return syscall2(__NR_fstat64, fd, (long)buf);
+}
+
+LFS64(fstat);
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
new file mode 100644
index 00000000..22bc2934
--- /dev/null
+++ b/src/stat/fstatat.c
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fstatat(int fd, const char *path, struct stat *buf, int flag)
+{
+	return syscall4(__NR_fstatat64, fd, (long)path, (long)buf, flag);
+}
+
+LFS64(fstatat);
diff --git a/src/stat/fstatvfs.c b/src/stat/fstatvfs.c
new file mode 100644
index 00000000..83bd7486
--- /dev/null
+++ b/src/stat/fstatvfs.c
@@ -0,0 +1,13 @@
+#include <sys/statvfs.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fstatvfs(int fd, struct statvfs *buf)
+{
+	return syscall2(__NR_fstatfs64, fd, (long)buf);
+}
+
+weak_alias(fstatvfs, fstatfs);
+
+LFS64(fstatvfs);
+LFS64(fstatfs);
diff --git a/src/stat/lstat.c b/src/stat/lstat.c
new file mode 100644
index 00000000..afdb5538
--- /dev/null
+++ b/src/stat/lstat.c
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+#include "libc.h"
+
+int lstat(const char *path, struct stat *buf)
+{
+	return syscall2(__NR_lstat64, (long)path, (long)buf);
+}
+
+LFS64(lstat);
diff --git a/src/stat/mkdir.c b/src/stat/mkdir.c
new file mode 100644
index 00000000..8295cad5
--- /dev/null
+++ b/src/stat/mkdir.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mkdir(const char *path, mode_t mode)
+{
+	return syscall2(__NR_mkdir, (long)path, mode);
+}
diff --git a/src/stat/mkdirat.c b/src/stat/mkdirat.c
new file mode 100644
index 00000000..1fb38250
--- /dev/null
+++ b/src/stat/mkdirat.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mkdirat(int fd, const char *path, mode_t mode)
+{
+	return syscall3(__NR_mkdirat, fd, (long)path, mode);
+}
diff --git a/src/stat/mkfifo.c b/src/stat/mkfifo.c
new file mode 100644
index 00000000..60efcf73
--- /dev/null
+++ b/src/stat/mkfifo.c
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifo(const char *path, mode_t mode)
+{
+	return mknod(path, mode | S_IFIFO, 0);
+}
diff --git a/src/stat/mkfifoat.c b/src/stat/mkfifoat.c
new file mode 100644
index 00000000..d3a1f970
--- /dev/null
+++ b/src/stat/mkfifoat.c
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifoat(int fd, const char *path, mode_t mode)
+{
+	return mknodat(fd, path, mode | S_IFIFO, 0);
+}
diff --git a/src/stat/mknod.c b/src/stat/mknod.c
new file mode 100644
index 00000000..0123eeef
--- /dev/null
+++ b/src/stat/mknod.c
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mknod(const char *path, mode_t mode, dev_t dev)
+{
+	/* since dev_t is system-specific anyway we defer to the idiotic
+	 * legacy-compatible bitfield mapping of the type.. at least we've
+	 * made it large enough to leave space for future expansion.. */
+	return syscall3(__NR_mknod, (long)path, mode, dev & 0xffff);
+}
diff --git a/src/stat/mknodat.c b/src/stat/mknodat.c
new file mode 100644
index 00000000..b5687e47
--- /dev/null
+++ b/src/stat/mknodat.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mknodat(int fd, const char *path, mode_t mode, dev_t dev)
+{
+	return syscall4(__NR_mknodat, fd, (long)path, mode, dev & 0xffff);
+}
diff --git a/src/stat/stat.c b/src/stat/stat.c
new file mode 100644
index 00000000..67640cc1
--- /dev/null
+++ b/src/stat/stat.c
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+#include "libc.h"
+
+int stat(const char *path, struct stat *buf)
+{
+	return syscall2(__NR_stat64, (long)path, (long)buf);
+}
+
+LFS64(stat);
diff --git a/src/stat/statvfs.c b/src/stat/statvfs.c
new file mode 100644
index 00000000..55a05d52
--- /dev/null
+++ b/src/stat/statvfs.c
@@ -0,0 +1,13 @@
+#include <sys/statvfs.h>
+#include "syscall.h"
+#include "libc.h"
+
+int statvfs(const char *path, struct statvfs *buf)
+{
+	return syscall2(__NR_statfs64, (long)path, (long)buf);
+}
+
+weak_alias(statvfs, statfs);
+
+LFS64(statvfs);
+LFS64(statfs);
diff --git a/src/stat/umask.c b/src/stat/umask.c
new file mode 100644
index 00000000..49cb48a6
--- /dev/null
+++ b/src/stat/umask.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+mode_t umask(mode_t mode)
+{
+	return syscall1(__NR_umask, mode);
+}
diff --git a/src/stdio/__fclose_ca.c b/src/stdio/__fclose_ca.c
new file mode 100644
index 00000000..e0b12a15
--- /dev/null
+++ b/src/stdio/__fclose_ca.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int __fclose_ca(FILE *f)
+{
+	return f->close(f);
+}
diff --git a/src/stdio/__fdopen.c b/src/stdio/__fdopen.c
new file mode 100644
index 00000000..6ad7c57d
--- /dev/null
+++ b/src/stdio/__fdopen.c
@@ -0,0 +1,52 @@
+#include "stdio_impl.h"
+
+FILE *__fdopen(int fd, const char *mode)
+{
+	FILE *f;
+	struct termios tio;
+	int plus = !!strchr(mode, '+');
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) return 0;
+
+	/* Allocate FILE+buffer or fail */
+	if (!(f=malloc(sizeof *f + UNGET + BUFSIZ))) return 0;
+
+	/* Zero-fill only the struct, not the buffer */
+	memset(f, 0, sizeof *f);
+
+	/* Impose mode restrictions */
+	if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
+
+	/* Set append mode on fd if opened for append */
+	if (*mode == 'a') {
+		int flags = __syscall_fcntl(fd, F_GETFL, 0);
+		__syscall_fcntl(fd, F_SETFL, flags | O_APPEND);
+	}
+
+	f->fd = fd;
+	f->buf = (unsigned char *)f + sizeof *f + UNGET;
+	f->buf_size = BUFSIZ;
+
+	/* Activate line buffered mode for terminals */
+	f->lbf = EOF;
+	if (!(f->flags & F_NOWR) && !__syscall_ioctl(fd, TCGETS, &tio))
+		f->lbf = '\n';
+
+	/* Initialize op ptrs. No problem if some are unneeded. */
+	f->read = __stdio_read;
+	f->write = __stdio_write;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+
+	/* Add new FILE to open file list */
+	OFLLOCK();
+	f->next = ofl_head;
+	if (ofl_head) ofl_head->prev = f;
+	ofl_head = f;
+	OFLUNLOCK();
+
+	return f;
+}
+
+weak_alias(__fdopen, fdopen);
diff --git a/src/stdio/__fopen_rb_ca.c b/src/stdio/__fopen_rb_ca.c
new file mode 100644
index 00000000..57d9b73c
--- /dev/null
+++ b/src/stdio/__fopen_rb_ca.c
@@ -0,0 +1,18 @@
+#include "stdio_impl.h"
+
+FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t len)
+{
+	memset(f, 0, sizeof *f);
+
+	f->fd = __syscall_open(filename, O_RDONLY, 0);
+	if (f->fd < 0) return 0;
+
+	f->flags = F_NOWR | F_PERM;
+	f->buf = buf + UNGET;
+	f->buf_size = len - UNGET;
+	f->read = __stdio_read;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+
+	return f;
+}
diff --git a/src/stdio/__fpending.c b/src/stdio/__fpending.c
new file mode 100644
index 00000000..a4334e23
--- /dev/null
+++ b/src/stdio/__fpending.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+size_t __fpending(FILE *f)
+{
+	return f->wend ? f->wpos - f->wbase : 0;
+}
diff --git a/src/stdio/__ofl.c b/src/stdio/__ofl.c
new file mode 100644
index 00000000..7d9652c8
--- /dev/null
+++ b/src/stdio/__ofl.c
@@ -0,0 +1,3 @@
+#include "stdio_impl.h"
+
+struct ofl __ofl;
diff --git a/src/stdio/__overflow.c b/src/stdio/__overflow.c
new file mode 100644
index 00000000..e35104de
--- /dev/null
+++ b/src/stdio/__overflow.c
@@ -0,0 +1,52 @@
+#include "stdio_impl.h"
+
+static int overflow(FILE *f, int c)
+{
+	/* Initialize if we're not already writing */
+	if (!f->wend) {
+		/* Fail if we're in error state or unwritable. */
+		if (f->flags & (F_ERR|F_NOWR)) return EOF;
+
+		/* Set byte orientation -1,0=>-1; 1=>1 */
+		f->mode |= f->mode-1;
+
+		/* Clear read buffer (easier than summoning nasal demons) */
+		f->rpos = f->rend = f->rstop = 0;
+
+		/* Activate write through the buffer */
+		f->wpos = f->wbase = f->buf;
+		f->wend = f->buf + f->buf_size;
+		f->wstop = (f->lbf < 0) ? f->wend - 1 : 0;
+	}
+
+	/* Buffer can always hold at least 1 byte... */
+	if (c != EOF) {
+		*f->wpos++ = c;
+		if (f->wpos <= f->wstop && c != f->lbf) return c;
+	}
+	/* ...since if the next call fails, buffer is empty. */
+	if (f->write(f, f->wbase, f->wpos - f->wbase) < 0) {
+		f->flags |= F_ERR;
+		f->wpos = f->wbase = f->wend = f->wstop = 0;
+		return EOF;
+	}
+
+	/* Buffer is empty so reset position to beginning */
+	f->wpos = f->wbase;
+
+	return c;
+}
+
+int __overflow(FILE *f, int c)
+{
+	return overflow(f, c & 0xff);
+}
+
+int __oflow(FILE *f)
+{
+	overflow(f, EOF);
+	return (f->flags & F_ERR) ? EOF : 0;
+}
+
+/* Link flush-on-exit code iff any stdio write functions are linked. */
+int (*const __fflush_on_exit)(FILE *) = fflush;
diff --git a/src/stdio/__scanf.c b/src/stdio/__scanf.c
new file mode 100644
index 00000000..185615d3
--- /dev/null
+++ b/src/stdio/__scanf.c
@@ -0,0 +1,487 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <float.h>
+
+#include "__scanf.h"
+
+static int read(rctx_t *r)
+{
+	if (--r->w < 0) return r->w = -1;
+	if (r->u) r->u = 0;
+	else r->read(r);
+	return r->c;
+}
+
+static void unread(rctx_t *r)
+{
+	//if (r->u || r->w < 0) return;
+	if (r->w < 0) return;
+	r->w++;
+	r->u = 1;
+}
+
+#define SIZE_hh -2
+#define SIZE_h  -1
+#define SIZE_def 0
+#define SIZE_l   1
+#define SIZE_ll  2
+#define SIZE_L   3
+
+static void store_int(void *dest, int size, int neg, unsigned long long i)
+{
+	if (!dest) return;
+	if (neg) i = -i;
+	switch (size) {
+	case SIZE_hh:
+		*(char *)dest = i;
+		break;
+	case SIZE_h:
+		*(short *)dest = i;
+		break;
+	case SIZE_def:
+		*(int *)dest = i;
+		break;
+	case SIZE_l:
+		*(long *)dest = i;
+		break;
+	case SIZE_ll:
+		*(long long *)dest = i;
+		break;
+	}
+}
+
+static void *arg_n(va_list ap, unsigned int n)
+{
+	void *p;
+	unsigned int i;
+	va_list ap2;
+	va_copy(ap2, ap);
+	for (i=n; i>1; i--) va_arg(ap2, void *);
+	p = va_arg(ap2, void *);
+	va_end(ap2);
+	return p;
+}
+
+int __scanf(rctx_t *r, const wchar_t *fmt, va_list ap)
+{
+	int mode=0;
+	int width;
+	int size;
+	const wchar_t *p, *z;
+	int c, l, t, m;
+	long long dummy;
+	char *s;
+	wchar_t *wcs;
+	mbstate_t st;
+	int wide = r->wide;
+	void *dest=NULL;
+	int invert;
+	unsigned long long i=0;
+	int neg=0;
+	int matches=0;
+	long double f;
+	int (*is_space)(int) = r->is_space;
+
+	for (p=fmt; *p; ) {
+		if (is_space(*p)) {
+			do p++; while (is_space(*p));
+			do r->w=1; while (is_space(read(r)));
+			unread(r);
+			continue;
+		} else if (*p != '%' || p[1] == '%') {
+			if (*p == '%') p++;
+			r->w = 1;
+			if (*p++ != read(r))
+				goto match_fail;
+			continue;
+		}
+		p++;
+		if (mode != 1) {
+			for (z=p; isdigit(*z); z++);
+			if (*z != '$' && *z != '*') {
+				if (mode == 0) mode = 1;
+				else goto fmt_fail;
+			} else if (*z != '*') {
+				int pos = 0;
+				mode = 2;
+				for (; p<z; p++) {
+					pos = 10*pos + *p - '0';
+				}
+				p++;
+				if (!pos) goto fmt_fail;
+				dest = arg_n(ap, pos);
+			}
+		}
+		if (*p == '*') {
+			dest = NULL;
+			p++;
+		} else if (mode == 1) {
+			dest = va_arg(ap, void *);
+		}
+		
+		if (!*p) goto fmt_fail;
+
+		width = 0;
+		for (; isdigit(*p); p++) {
+			width = 10*width + *p - '0';
+		}
+
+		size = 0;
+		switch (*p++) {
+		case 0:
+			goto fmt_fail;
+		case 'h':
+			if (*p == 'h') p++, size = SIZE_hh;
+			else size = SIZE_h;
+			break;
+		case 'l':
+			if (*p == 'l') p++, size = SIZE_ll;
+			else size = SIZE_l;
+			break;
+		case 'j':
+			size = SIZE_ll;
+			break;
+		case 'z':
+		case 't':
+			size = SIZE_l;
+			break;
+		case 'L':
+			size = SIZE_L;
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 's': case 'c': case '[':
+		case 'S': case 'C':
+		case 'p': case 'n':
+			p--;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		t = *p++;
+
+		switch (t) {
+		case 'C':
+		case 'c':
+			if (width < 1) width = 1;
+		case 's':
+			if (size == SIZE_l) t &= ~0x20;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case '[': case 'S':
+		case 'p': case 'n':
+			if (width < 1) width = INT_MAX;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		r->w = width;
+
+		if (t != 'n') {
+			if (read(r) < 0) goto input_fail;
+			unread(r);
+		}
+
+		switch (t) {
+		case 'n':
+			store_int(dest, size, 0, r->l - r->u);
+			/* do not increment match count, etc! */
+			continue;
+		case 'C':
+			wcs = dest ? dest : (void *)&dummy;
+			st = (mbstate_t){ 0 };
+			while ((c=read(r)) >= 0) {
+				if (wide) {
+					if (dest) *wcs++ = c;
+				} else {
+					char ch = c;
+					switch (mbrtowc(wcs, &ch, 1, &st)) {
+					case -1:
+						goto enc_fail;
+					case -2:
+						break;
+					default:
+						if (dest) wcs++;
+					}
+				}
+			}
+			if (r->w > 0) goto match_fail;
+			break;
+		case 'c':
+			s = dest ? dest : (void *)&dummy;
+			while ((c=read(r)) >= 0) {
+				if (wide) {
+					if ((l=wctomb(s, c)) < 0)
+						goto enc_fail;
+					if (dest) s += l;
+				} else {
+					if (dest) *s++ = c;
+				}
+			}
+			if (r->w > 0) goto match_fail;
+			break;
+		case '[':
+			wcs = dest ? dest : (void *)&dummy;
+			s = dest ? dest : (void *)&dummy;
+			if (!wide && size == SIZE_l) st = (mbstate_t){ 0 };
+
+			if (*p == '^') p++, invert = 1;
+			else invert = 0;
+
+			if (wide) {
+				for (m=0; (c=read(r)) >= 0; m=1) {
+					for (z=p; *z && *z != c && (*z != ']' || z==p); z++);
+					if (!*z) goto fmt_fail;
+					if (*z == c && (*z != ']' || z==p)) {
+						if (invert) break;
+					} else {
+						if (!invert) break;
+					}
+					if (size == SIZE_l) {
+						if (dest) *wcs++ = c;
+					} else {
+						if ((l=wctomb(s, c)) < 0)
+							goto enc_fail;
+						if (dest) s += l;
+					}
+				}
+				for (p++; *p && *p != ']'; p++);
+				p++;
+			} else {
+				unsigned char scanset[257];
+				memset(scanset, invert, sizeof scanset);
+				scanset[0] = 0;
+				for (z=p; *z && (*z != ']' || z==p); z++)
+					scanset[1+*z] = 1-invert;
+				if (!*z) goto fmt_fail;
+				p=z+1;
+				c=0;
+				for (m=0; scanset[(c=read(r))+1]; m=1) {
+					if (size == SIZE_l) {
+						char ch = c;
+						switch (mbrtowc(wcs, &ch, 1, &st)) {
+						case -1:
+							goto enc_fail;
+						case -2:
+							break;
+						default:
+							if (dest) wcs++;
+						}
+					} else {
+						if (dest) *s++ = c;
+					}
+				}
+			}
+			if (!m) goto match_fail;
+			if (dest) {
+				if (size == SIZE_l) *wcs++ = 0;
+				else *s++ = 0;
+			}
+			break;
+		default:
+			/* read unlimited number of spaces, then reset width */
+			do r->w = 1; while (is_space(c = read(r)));
+			if (c < 0) goto input_fail;
+			unread(r);
+			r->w = width;
+		}
+
+		switch (t) {
+		case 'p':
+		case 'X':
+			t = 'x';
+		case 'd':
+		case 'i':
+		case 'o':
+		case 'u':
+		case 'x':
+			i = m = neg = 0;
+			if ((c=read(r)) == '-') neg=1;
+			else if (c != '+') unread(r);
+			switch (t) {
+			case 'i':
+			case 'x':
+				if ((c=read(r)) != '0') {
+					if (t == 'i') t = 'd';
+					unread(r);
+					break;
+				}
+				if (((c=read(r))|0x20) != 'x') {
+					if (t == 'i') {
+						t = 'o';
+						/* lone 0 is valid octal */
+						if ((unsigned)(c-'0') >= 8) {
+							m = 1;
+							goto int_finish;
+						}
+					}
+					unread(r);
+					break;
+				}
+				t = 'x';
+			}
+		}
+		
+		switch (t) {
+		case 'd':
+		case 'u':
+			for (m=0; isdigit(c=read(r)); m=1)
+				i = 10*i + c-'0';
+			goto int_finish;
+		case 'o':
+			for (m=0; (unsigned)(c=read(r))-'0' < 8; m=1)
+				i = (i<<3) + c-'0';
+			goto int_finish;
+		case 'x':
+			for (m=0; ; m=1) {
+				if (isdigit(c=read(r))) {
+					i = (i<<4) + c-'0';
+				} else if ((unsigned)(c|0x20)-'a' < 6) {
+					i = (i<<4) + (c|0x20)-'a'+10;
+				} else break;
+			}
+		int_finish:
+			if (!m) goto match_fail;
+			store_int(dest, size, neg, i);
+			break;
+		case 'a':
+		case 'e':
+		case 'f':
+		case 'g':
+			f = 0.0;
+			neg = m = 0;
+			if ((c=read(r)) == '-') neg=1;
+			else if (c != '+') unread(r);
+			/* FIXME: check for INF/NAN strings here */
+			if (read(r)=='0' && (m=1, (read(r)|0x20) == 'x'))
+				goto hexfloat;
+			else unread(r);
+			for (; isdigit(c=read(r)); m=1)
+				f = 10.0 * f + (c-'0');
+			if (c=='.') {
+				double mag = 10.0;
+				for (; isdigit(c=read(r)); mag*=10.0)
+					f += (c-'0')/mag;
+			}
+			if ((c|0x20)=='e') {
+				int ex=0, en=0;
+				m = 0;
+				if ((c=read(r))=='-') en=1;
+				else if (c!='+') unread(r);
+				for (; isdigit(c=read(r)); m=1)
+					if (ex < LDBL_MAX_10_EXP)
+						ex = 10 * ex + (c-'0');
+				if (ex > LDBL_MAX_10_EXP)
+					f = en ? 0 : INFINITY;
+				else {
+					if (en) while (ex--) f/=10.0;
+					else while (ex--) f*=10.0;
+				}
+			}
+			goto writefloat;
+hexfloat:
+			m = 0;
+			for (; isxdigit(c=read(r)); m=1)
+				if (isdigit(c)) f = 16.0*f + (c-'0');
+				else f = 16.0*f + ((c|32)-'a'+10);
+			if (c=='.') {
+				double mag = 1/16.0;
+				for (; isxdigit(c=read(r)); mag*=1/16.0)
+					if (isdigit(c)) f += (c-'0')*mag;
+					else f += ((c|32)-'a'+10)*mag;
+			}
+			if ((c|0x20)=='p') {
+				int ex=0, en=0;
+				m = 0;
+				if ((c=read(r))=='-') en=1;
+				else if (c!='+') unread(r);
+				for (; isdigit(c=read(r)); m=1)
+					if (ex < LDBL_MAX_EXP)
+						ex = 10 * ex + (c-'0');
+				if (ex > LDBL_MAX_EXP)
+					f = en ? 0 : INFINITY;
+				else {
+					if (en) while (ex--) f*=0.5;
+					else while (ex--) f*=2.0;
+				}
+			}
+writefloat:
+			if (!m) goto match_fail;
+			if (neg) f *= -1.0;
+			if (dest) switch (size) {
+			case SIZE_def:
+				*(float *)dest = f;
+				break;
+			case SIZE_l:
+				*(double *)dest = f;
+				break;
+			case SIZE_L:
+				*(long double *)dest = f;
+				break;
+			}
+			break;
+		case 'S':
+			wcs = dest ? dest : (void *)&dummy;
+			st = (mbstate_t){ 0 };
+			while((c=read(r)) >= 0) {
+				if (wide) {
+					if (is_space(c)) break;
+					if (dest) *wcs++ = c;
+				} else {
+					char ch = c;
+					if (is_space(c)) break;
+					switch (mbrtowc(wcs, &ch, 1, &st)) {
+					case -1:
+						goto enc_fail;
+					case -2:
+						break;
+					default:
+						if (dest) wcs++;
+					}
+				}
+			}
+			if (dest) *wcs++ = 0;
+			break;
+		case 's':
+			s = dest ? dest : (void *)&dummy;
+			while((c=read(r)) >= 0) {
+				if (wide) {
+					if (is_space(c)) break;
+					if ((l=wctomb(s, c)) < 0)
+						goto enc_fail;
+					if (dest) s += l;
+				} else {
+					if (is_space(c)) break;
+					if (dest) *s++ = c;
+				}
+			}
+			if (dest) *s++ = 0;
+			break;
+		}
+
+		/* unread will do nothing if field width was exhausted */
+		unread(r);
+		if (dest) matches++;
+	}
+	return matches;
+enc_fail:
+	errno = EILSEQ;
+fmt_fail:
+input_fail:
+	if (!matches) matches--;
+match_fail:
+	unread(r);
+	return matches;
+}
diff --git a/src/stdio/__scanf.h b/src/stdio/__scanf.h
new file mode 100644
index 00000000..e549b979
--- /dev/null
+++ b/src/stdio/__scanf.h
@@ -0,0 +1,16 @@
+#include <wchar.h>
+
+typedef struct rctx
+{
+	void (*read)(struct rctx *);
+	void *opaque;
+	int wide;
+	int (*is_space)();
+	int l;
+	int e;
+	int c;
+	int u;
+	int w;
+} rctx_t;
+
+int __scanf(rctx_t *, const wchar_t *, va_list);
diff --git a/src/stdio/__stdio_close.c b/src/stdio/__stdio_close.c
new file mode 100644
index 00000000..24fef33f
--- /dev/null
+++ b/src/stdio/__stdio_close.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int __stdio_close(FILE *f)
+{
+	return __syscall_close(f->fd);
+}
diff --git a/src/stdio/__stdio_read.c b/src/stdio/__stdio_read.c
new file mode 100644
index 00000000..ee7e1258
--- /dev/null
+++ b/src/stdio/__stdio_read.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
+{
+	return __syscall_read(f->fd, buf, len);
+}
diff --git a/src/stdio/__stdio_seek.c b/src/stdio/__stdio_seek.c
new file mode 100644
index 00000000..fdb9fe7f
--- /dev/null
+++ b/src/stdio/__stdio_seek.c
@@ -0,0 +1,15 @@
+#include "stdio_impl.h"
+
+static off_t retneg1(FILE *f, off_t off, int whence)
+{
+	return -1;
+}
+
+off_t __stdio_seek(FILE *f, off_t off, int whence)
+{
+	off_t ret = __syscall_lseek(f->fd, off, whence);
+	/* Detect unseekable files and optimize future failures out */
+	if (ret < 0 && off == 0 && whence == SEEK_CUR)
+		f->seek = retneg1;
+	return ret;
+}
diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c
new file mode 100644
index 00000000..78545626
--- /dev/null
+++ b/src/stdio/__stdio_write.c
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	const unsigned char *stop = buf+len;
+	ssize_t cnt = 1;
+	for (; buf<stop && (cnt=__syscall_write(f->fd, buf, len))>0; buf+=cnt);
+	return len-(stop-buf);
+}
diff --git a/src/stdio/__uflow.c b/src/stdio/__uflow.c
new file mode 100644
index 00000000..5a51d610
--- /dev/null
+++ b/src/stdio/__uflow.c
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+
+int __uflow(FILE *f)
+{
+	if (__underflow(f) < 0) return EOF;
+	else return *f->rpos++;
+}
diff --git a/src/stdio/__underflow.c b/src/stdio/__underflow.c
new file mode 100644
index 00000000..b769f4e4
--- /dev/null
+++ b/src/stdio/__underflow.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+
+int __underflow(FILE *f)
+{
+	ssize_t cnt;
+
+	/* Read from buffer (Do we ever get called when this is true??) */
+	if (f->rpos < f->rstop) return *f->rpos;
+
+	/* Initialize if we're not already reading */
+	if (!f->rstop) {
+		/* Fail immediately if unreadable, eof, or error state. */
+		if (f->flags & (F_EOF|F_ERR|F_NORD)) return EOF;
+
+		/* Set byte orientation -1,0=>-1; 1=>1 */
+		f->mode |= f->mode-1;
+
+		/* Flush any unwritten output; fail on error. */
+		if (f->wpos > f->buf && __oflow(f)) return EOF;
+
+		/* Disallow writes to buffer. */
+		f->wstop = 0;
+	}
+
+	/* Perform the underlying read operation */
+	if ((cnt=f->read(f, f->buf, f->buf_size)) + 1 <= 1) {
+		/* Set flags and leave read mode */
+		f->flags |= F_EOF | (cnt & F_ERR);
+		f->rpos = f->rend = f->rstop = 0;
+		return EOF;
+	}
+
+	/* Setup buffer pointers for reading from buffer */
+	f->rpos = f->buf;
+	f->rend = f->rstop = f->buf + cnt;
+
+	return *f->rpos;
+}
diff --git a/src/stdio/asprintf.c b/src/stdio/asprintf.c
new file mode 100644
index 00000000..79e59c2d
--- /dev/null
+++ b/src/stdio/asprintf.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int vasprintf(char **, const char *, va_list);
+
+int asprintf(char **s, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vasprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/clearerr.c b/src/stdio/clearerr.c
new file mode 100644
index 00000000..3bf94d30
--- /dev/null
+++ b/src/stdio/clearerr.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+void clearerr(FILE *f)
+{
+	FLOCK(f);
+	f->flags &= ~(F_EOF|F_ERR);
+	FUNLOCK(f);
+}
+
+weak_alias(clearerr, clearerr_unlocked);
diff --git a/src/stdio/dprintf.c b/src/stdio/dprintf.c
new file mode 100644
index 00000000..fa28322f
--- /dev/null
+++ b/src/stdio/dprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int dprintf(int fd, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vdprintf(fd, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/fclose.c b/src/stdio/fclose.c
new file mode 100644
index 00000000..26bc37e8
--- /dev/null
+++ b/src/stdio/fclose.c
@@ -0,0 +1,21 @@
+#include "stdio_impl.h"
+
+int fclose(FILE *f)
+{
+	int r;
+	int perm = f->flags & F_PERM;
+
+	if (!perm) {
+		OFLLOCK();
+		if (f->prev) f->prev->next = f->next;
+		if (f->next) f->next->prev = f->prev;
+		if (ofl_head == f) ofl_head = f->next;
+		OFLUNLOCK();
+	}
+
+	r = fflush(f) | f->close(f);
+
+	if (!perm) free(f);
+	
+	return r;
+}
diff --git a/src/stdio/feof.c b/src/stdio/feof.c
new file mode 100644
index 00000000..f2b739b5
--- /dev/null
+++ b/src/stdio/feof.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+#undef feof
+
+int feof(FILE *f)
+{
+	return !!(f->flags & F_EOF);
+}
+
+weak_alias(feof, feof_unlocked);
diff --git a/src/stdio/ferror.c b/src/stdio/ferror.c
new file mode 100644
index 00000000..f535fbed
--- /dev/null
+++ b/src/stdio/ferror.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+#undef ferror
+
+int ferror(FILE *f)
+{
+	return !!(f->flags & F_ERR);
+}
+
+weak_alias(ferror, ferror_unlocked);
diff --git a/src/stdio/fflush.c b/src/stdio/fflush.c
new file mode 100644
index 00000000..cf3f5b0e
--- /dev/null
+++ b/src/stdio/fflush.c
@@ -0,0 +1,50 @@
+#include "stdio_impl.h"
+
+static int __fflush_unlocked(FILE *f)
+{
+	/* If writing, flush output. */
+	if (f->wpos > f->buf && __oflow(f)) return -1;
+
+	/* If reading, sync position, per POSIX */
+	if (f->rpos < f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
+	f->rpos = f->rend;
+
+	/* Hook for special behavior on flush */
+	if (f->flush) f->flush(f);
+
+	return (f->flags & F_ERR) ? EOF : 0;
+}
+
+/* stdout.c will override this if linked */
+static FILE *const __dummy = 0;
+weak_alias(__dummy, __stdout_to_flush);
+
+int fflush(FILE *f)
+{
+	int r;
+	FILE *next;
+
+	if (f) {
+		FLOCK(f);
+		r = __fflush_unlocked(f);
+		FUNLOCK(f);
+		return r;
+	}
+
+	r = __stdout_to_flush ? fflush(__stdout_to_flush) : 0;
+
+	OFLLOCK();
+	for (f=ofl_head; f; f=next) {
+		FLOCK(f);
+		OFLUNLOCK();
+		r |= __fflush_unlocked(f);
+		OFLLOCK();
+		next = f->next;
+		FUNLOCK(f);
+	}
+	OFLUNLOCK();
+	
+	return r;
+}
+
+weak_alias(__fflush_unlocked, fflush_unlocked);
diff --git a/src/stdio/fgetc.c b/src/stdio/fgetc.c
new file mode 100644
index 00000000..3a7f1e30
--- /dev/null
+++ b/src/stdio/fgetc.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int fgetc(FILE *f)
+{
+	int c;
+	FLOCK(f);
+	c = f->rpos < f->rstop ? *f->rpos++ : __uflow(f);
+	FUNLOCK(f);
+	return c;
+}
diff --git a/src/stdio/fgetpos.c b/src/stdio/fgetpos.c
new file mode 100644
index 00000000..5b663d1e
--- /dev/null
+++ b/src/stdio/fgetpos.c
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+int fgetpos(FILE *f, fpos_t *pos)
+{
+	off_t off = __ftello(f);
+	if (off < 0) return -1;
+	*(off_t *)pos = off;
+	return 0;
+}
+
+LFS64(fgetpos);
diff --git a/src/stdio/fgets.c b/src/stdio/fgets.c
new file mode 100644
index 00000000..7939303e
--- /dev/null
+++ b/src/stdio/fgets.c
@@ -0,0 +1,34 @@
+#include "stdio_impl.h"
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+char *fgets(char *s, int n, FILE *f)
+{
+	char *p = s;
+	unsigned char *z;
+	size_t k;
+
+	if (!n--) return 0;
+
+	FLOCK(f);
+
+	while (n && !feof(f)) {
+		z = memchr(f->rpos, '\n', f->rend - f->rpos);
+		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+		k = MIN(k, n);
+		memcpy(p, f->rpos, k);
+		f->rpos += k;
+		p += k;
+		n -= k;
+		if (z) break;
+		__underflow(f);
+	}
+	*p = 0;
+	if (ferror(f)) p = s;
+
+	FUNLOCK(f);
+
+	return (p == s) ? 0 : s;
+}
+
+weak_alias(fgets, fgets_unlocked);
diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c
new file mode 100644
index 00000000..c990545f
--- /dev/null
+++ b/src/stdio/fgetwc.c
@@ -0,0 +1,51 @@
+#include "stdio_impl.h"
+
+wint_t __fgetwc_unlocked(FILE *f)
+{
+	mbstate_t st = { 0 };
+	wchar_t wc;
+	int c;
+	unsigned char b;
+	size_t l;
+
+	f->mode |= f->mode+1;
+
+	/* Convert character from buffer if possible */
+	if (f->rpos < f->rend) {
+		l = mbrtowc(&wc, f->rpos, f->rend - f->rpos, &st);
+		if (l+2 >= 2) {
+			f->rpos += l + !l; /* l==0 means 1 byte, null */
+			return wc;
+		}
+		if (l == -1) {
+			f->rpos++;
+			return WEOF;
+		}
+	} else l = -2;
+
+	/* Convert character byte-by-byte from __uflow */
+	while (l == -2) {
+		b = c = __uflow(f);
+		if (c < 0) {
+			if (!mbsinit(&st)) errno = EILSEQ;
+			return WEOF;
+		}
+		l = mbrtowc(&wc, &b, 1, &st);
+		if (l == -1) return WEOF;
+	}
+
+	FUNLOCK(f);
+	return wc;
+}
+
+wint_t fgetwc(FILE *f)
+{
+	wint_t c;
+	FLOCK(f);
+	c = __fgetwc_unlocked(f);
+	FUNLOCK(f);
+	return c;
+}
+
+weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
+weak_alias(__fgetwc_unlocked, getwc_unlocked);
diff --git a/src/stdio/fgetws.c b/src/stdio/fgetws.c
new file mode 100644
index 00000000..2e76b565
--- /dev/null
+++ b/src/stdio/fgetws.c
@@ -0,0 +1,27 @@
+#include "stdio_impl.h"
+
+wint_t __fgetwc_unlocked(FILE *);
+
+wchar_t *fgetws(wchar_t *s, int n, FILE *f)
+{
+	wchar_t *p = s;
+
+	if (!n--) return s;
+
+	FLOCK(f);
+
+	for (; n; n--) {
+		wint_t c = __fgetwc_unlocked(f);
+		if (c == WEOF) break;
+		*p++ = c;
+		if (c == '\n') break;
+	}
+	*p = 0;
+	if (ferror(f)) p = s;
+
+	FUNLOCK(f);
+
+	return (p == s) ? NULL : s;
+}
+
+weak_alias(fgetws, fgetws_unlocked);
diff --git a/src/stdio/fileno.c b/src/stdio/fileno.c
new file mode 100644
index 00000000..9ffb26d5
--- /dev/null
+++ b/src/stdio/fileno.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int fileno(FILE *f)
+{
+	return f->fd;
+}
+
+weak_alias(fileno, fileno_unlocked);
diff --git a/src/stdio/fmemopen.c b/src/stdio/fmemopen.c
new file mode 100644
index 00000000..77a60746
--- /dev/null
+++ b/src/stdio/fmemopen.c
@@ -0,0 +1,16 @@
+#if 0
+#include "stdio_impl.h"
+
+static ssize_t mread(FILE *f, unsigned char *buf, size_t len)
+{
+	memcpy(buf, 
+}
+
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+	FILE *f = calloc(sizeof(FILE), 1);
+	if (!f) return 0;
+	
+	//
+}
+#endif
diff --git a/src/stdio/fopen.c b/src/stdio/fopen.c
new file mode 100644
index 00000000..670cf5f3
--- /dev/null
+++ b/src/stdio/fopen.c
@@ -0,0 +1,34 @@
+#include "stdio_impl.h"
+
+FILE *fopen(const char *filename, const char *mode)
+{
+	FILE *f;
+	int fd;
+	int flags;
+	int plus = !!strchr(mode, '+');
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Compute the flags to pass to open() */
+	if (plus) flags = O_RDWR;
+	else if (*mode == 'r') flags = O_RDONLY;
+	else flags = O_WRONLY;
+	if (*mode != 'r') flags |= O_CREAT;
+	if (*mode == 'w') flags |= O_TRUNC;
+	if (*mode == 'a') flags |= O_APPEND;
+
+	fd = __syscall_open(filename, flags, 0666);
+	if (fd < 0) return 0;
+
+	f = __fdopen(fd, mode);
+	if (f) return f;
+
+	__syscall_close(fd);
+	return 0;
+}
+
+LFS64(fopen);
diff --git a/src/stdio/fprintf.c b/src/stdio/fprintf.c
new file mode 100644
index 00000000..a220cc10
--- /dev/null
+++ b/src/stdio/fprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int fprintf(FILE *f, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/fputc.c b/src/stdio/fputc.c
new file mode 100644
index 00000000..ec859385
--- /dev/null
+++ b/src/stdio/fputc.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int fputc(int c, FILE *f)
+{
+	FLOCK(f);
+	if (c != f->lbf && f->wpos + 1 < f->wend) *f->wpos++ = c;
+	else c = __overflow(f, c);
+	FUNLOCK(f);
+	return c;
+}
diff --git a/src/stdio/fputs.c b/src/stdio/fputs.c
new file mode 100644
index 00000000..e6bdb204
--- /dev/null
+++ b/src/stdio/fputs.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int fputs(const char *s, FILE *f)
+{
+	size_t l = strlen(s);
+	if (!l) return 0;
+	return (int)fwrite(s, l, 1, f) - 1;
+}
+
+weak_alias(fputs, fputs_unlocked);
diff --git a/src/stdio/fputwc.c b/src/stdio/fputwc.c
new file mode 100644
index 00000000..b48bb74d
--- /dev/null
+++ b/src/stdio/fputwc.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+
+wint_t __fputwc_unlocked(wchar_t c, FILE *f)
+{
+	char mbc[MB_LEN_MAX];
+	int l;
+
+	f->mode |= f->mode+1;
+
+	if (isascii(c)) {
+		if (c != f->lbf && f->wpos + 1 < f->wend) *f->wpos++ = c;
+		else c = __overflow(f, c);
+	} else if (f->wpos + MB_LEN_MAX < f->wend) {
+		l = wctomb(f->wpos, c);
+		if (l < 0) c = WEOF;
+		else f->wpos += l;
+	} else {
+		l = wctomb(mbc, c);
+		if (l < 0 || __fwritex(mbc, l, f) < l) c = WEOF;
+	}
+	return c;
+}
+
+wint_t fputwc(wchar_t c, FILE *f)
+{
+	FLOCK(f);
+	c = __fputwc_unlocked(c, f);
+	FUNLOCK(f);
+	return 0;
+}
+
+weak_alias(__fputwc_unlocked, fputwc_unlocked);
+weak_alias(__fputwc_unlocked, putwc_unlocked);
diff --git a/src/stdio/fputws.c b/src/stdio/fputws.c
new file mode 100644
index 00000000..9057853b
--- /dev/null
+++ b/src/stdio/fputws.c
@@ -0,0 +1,23 @@
+#include "stdio_impl.h"
+
+int fputws(const wchar_t *ws, FILE *f)
+{
+	unsigned char buf[BUFSIZ];
+	size_t l=0;
+
+	FLOCK(f);
+
+	f->mode |= f->mode+1;
+
+	while (ws && (l = wcsrtombs(buf, (void*)&ws, sizeof buf, 0))+1 > 1)
+		if (__fwritex(buf, l, f) < l) {
+			FUNLOCK(f);
+			return -1;
+		}
+
+	FUNLOCK(f);
+
+	return l; /* 0 or -1 */
+}
+
+weak_alias(fputws, fputws_unlocked);
diff --git a/src/stdio/fread.c b/src/stdio/fread.c
new file mode 100644
index 00000000..0fa0b2aa
--- /dev/null
+++ b/src/stdio/fread.c
@@ -0,0 +1,49 @@
+#include "stdio_impl.h"
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+size_t fread(void *destv, size_t size, size_t nmemb, FILE *f)
+{
+	unsigned char *dest = destv;
+	size_t len = size*nmemb, l = len, k;
+
+	/* Never touch the file if length is zero.. */
+	if (!l) return 0;
+
+	FLOCK(f);
+
+	for (;;) {
+		/* First exhaust the buffer. */
+		k = MIN(f->rend - f->rpos, l);
+		memcpy(dest, f->rpos, k);
+		f->rpos += k;
+		dest += k;
+		l -= k;
+
+		/* Stop on EOF or errors */
+		if (f->flags & (F_EOF|F_ERR|F_NORD)) goto eof;
+
+		/* Done? Or going unbuffered? */
+		if (!l || l > f->buf_size/2) break;
+
+		/* Otherwise, refill & read thru buffer. */
+		__underflow(f);
+	}
+
+	/* Read the remainder directly */
+	for (; l; l-=k, dest+=k) {
+		k = f->read(f, dest, l);
+		if (k+1<=1) {
+			f->flags |= F_EOF | (F_ERR & k);
+			goto eof;
+		}
+	}
+
+	FUNLOCK(f);
+	return nmemb;
+eof:
+	FUNLOCK(f);
+	return (len-l)/size;
+}
+
+weak_alias(fread, fread_unlocked);
diff --git a/src/stdio/freopen.c b/src/stdio/freopen.c
new file mode 100644
index 00000000..8d3af9fc
--- /dev/null
+++ b/src/stdio/freopen.c
@@ -0,0 +1,47 @@
+#include "stdio_impl.h"
+
+/* The basic idea of this implementation is to open a new FILE,
+ * hack the necessary parts of the new FILE into the old one, then
+ * close the new FILE. */
+
+/* Locking is not necessary because, in the event of failure, the stream
+ * passed to freopen is invalid as soon as freopen is called. */
+
+FILE *freopen(const char *filename, const char *mode, FILE *f)
+{
+	int fl;
+	FILE *f2;
+
+	fflush(f);
+
+	if (!filename) {
+		f2 = fopen("/dev/null", mode);
+		if (!f2) goto fail;
+		fl = __syscall_fcntl(f2->fd, F_GETFL, 0);
+		if (fl < 0 || __syscall_fcntl(f->fd, F_SETFL, fl) < 0)
+			goto fail2;
+	} else {
+		f2 = fopen(filename, mode);
+		if (!f2) goto fail;
+		if (__syscall_dup2(f2->fd, f->fd) < 0)
+			goto fail2;
+	}
+
+	f->flags = (f->flags & F_PERM) | f2->flags;
+	f->read = f2->read;
+	f->write = f2->write;
+	f->seek = f2->seek;
+	f->close = f2->close;
+	f->flush = f2->flush;
+
+	fclose(f2);
+	return f;
+
+fail2:
+	fclose(f2);
+fail:
+	fclose(f);
+	return NULL;
+}
+
+LFS64(freopen);
diff --git a/src/stdio/fscanf.c b/src/stdio/fscanf.c
new file mode 100644
index 00000000..51fc9b30
--- /dev/null
+++ b/src/stdio/fscanf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int fscanf(FILE *f, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/fseek.c b/src/stdio/fseek.c
new file mode 100644
index 00000000..bfaad375
--- /dev/null
+++ b/src/stdio/fseek.c
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+
+int __fseeko_unlocked(FILE *f, off_t off, int whence)
+{
+	/* Adjust relative offset for unread data in buffer, if any. */
+	if (whence == SEEK_CUR) off -= f->rend - f->rpos;
+
+	/* If writing, flush output. */
+	if (f->wpos > f->buf && __oflow(f)) return -1;
+
+	/* Perform the underlying seek operation. */
+	if (f->seek(f, off, whence) < 0) return -1;
+
+	/* If seek succeeded, file is seekable and we discard read buffer. */
+	f->rpos = f->rend = f->rstop = 0;
+	f->flags &= ~F_EOF;
+	
+	FUNLOCK(f);	
+	return 0;
+}
+
+int __fseeko(FILE *f, off_t off, int whence)
+{
+	int result;
+	FLOCK(f);
+	result = __fseeko_unlocked(f, off, whence);
+	FUNLOCK(f);
+	return result;
+}
+
+int fseek(FILE *f, long off, int whence)
+{
+	return __fseeko(f, off, whence);
+}
+
+weak_alias(__fseeko, fseeko);
+
+LFS64(fseeko);
diff --git a/src/stdio/fsetpos.c b/src/stdio/fsetpos.c
new file mode 100644
index 00000000..5d76c8cd
--- /dev/null
+++ b/src/stdio/fsetpos.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int fsetpos(FILE *f, const fpos_t *pos)
+{
+	return __fseeko(f, *(const off_t *)pos, SEEK_SET);
+}
+
+LFS64(fsetpos);
diff --git a/src/stdio/ftell.c b/src/stdio/ftell.c
new file mode 100644
index 00000000..aa1f5381
--- /dev/null
+++ b/src/stdio/ftell.c
@@ -0,0 +1,35 @@
+#include "stdio_impl.h"
+
+off_t __ftello_unlocked(FILE *f)
+{
+	off_t pos = f->seek(f, 0, SEEK_CUR);
+	if (pos < 0) {
+		FUNLOCK(f);
+		return pos;
+	}
+	/* Adjust for data in buffer. */
+	return pos - (f->rend - f->rpos) + (f->wpos - f->wbase);
+}
+
+off_t __ftello(FILE *f)
+{
+	off_t pos;
+	FLOCK(f);
+	pos = __ftello_unlocked(f);
+	FUNLOCK(f);
+	return pos;
+}
+
+long ftell(FILE *f)
+{
+	off_t pos = __ftello(f);
+	if (pos > LONG_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	return pos;
+}
+
+weak_alias(__ftello, ftello);
+
+LFS64(ftello);
diff --git a/src/stdio/fwide.c b/src/stdio/fwide.c
new file mode 100644
index 00000000..f4da47f6
--- /dev/null
+++ b/src/stdio/fwide.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+#define SH (8*sizeof(int)-1)
+#define NORMALIZE(x) ((x)>>SH | -((-(x))>>SH))
+
+int fwide(FILE *f, int mode)
+{
+	if (!f->mode) f->mode = NORMALIZE(mode);
+	return f->mode;
+}
diff --git a/src/stdio/fwrite.c b/src/stdio/fwrite.c
new file mode 100644
index 00000000..23974fe1
--- /dev/null
+++ b/src/stdio/fwrite.c
@@ -0,0 +1,51 @@
+#include "stdio_impl.h"
+
+size_t __fwritex(const unsigned char *s, size_t l, FILE *f)
+{
+	size_t i = 0;
+	size_t k = f->wend - f->wpos;
+
+	/* Handle line-buffered mode by breaking into 2 parts */
+	if (f->lbf >= 0) {
+		/* Match /^(.*\n|)/ */
+		for (i=l; i && s[i-1] != '\n'; i--);
+		if (i) {
+			f->lbf = EOF;
+			__fwritex(s, i, f);
+			f->lbf = '\n';
+			__oflow(f);
+			return ferror(f) ? 0 : i + __fwritex(s+i, l-i, f);
+		}
+	}
+
+	/* Buffer initial segment */
+	if (k > l) k = l;
+	memcpy(f->wpos, s, k);
+	f->wpos += k;
+	if (f->wpos < f->wend) return l;
+
+	/* If there's work left to do, flush buffer */
+	__oflow(f);
+	if (ferror(f)) return 0;
+
+	/* If the remainder will not fit in buffer, write it directly */
+	if (l - k >= f->wend - f->wpos)
+		return k + f->write(f, s+k, l-k);
+
+	/* Otherwise, buffer the remainder */
+	memcpy(f->wpos, s+k, l-k);
+	f->wpos += l-k;
+	return l;
+}
+
+size_t fwrite(const void *src, size_t size, size_t nmemb, FILE *f)
+{
+	size_t l = size*nmemb;
+	if (!l) return l;
+	FLOCK(f);
+	l = __fwritex(src, l, f);
+	FUNLOCK(f);
+	return l/size;
+}
+
+weak_alias(fwrite, fwrite_unlocked);
diff --git a/src/stdio/fwscanf.c b/src/stdio/fwscanf.c
new file mode 100644
index 00000000..a6892cf6
--- /dev/null
+++ b/src/stdio/fwscanf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int fwscanf(FILE *f, const wchar_t *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/getc.c b/src/stdio/getc.c
new file mode 100644
index 00000000..b739b0a5
--- /dev/null
+++ b/src/stdio/getc.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int getc(FILE *f)
+{
+	return fgetc(f);
+}
diff --git a/src/stdio/getc_unlocked.c b/src/stdio/getc_unlocked.c
new file mode 100644
index 00000000..629223ea
--- /dev/null
+++ b/src/stdio/getc_unlocked.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int getc_unlocked(FILE *f)
+{
+	return f->rpos < f->rstop ? *f->rpos++ : __uflow(f);
+}
+
+weak_alias (getc_unlocked, fgetc_unlocked);
diff --git a/src/stdio/getchar.c b/src/stdio/getchar.c
new file mode 100644
index 00000000..c1012658
--- /dev/null
+++ b/src/stdio/getchar.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int getchar(void)
+{
+	return fgetc(stdin);
+}
diff --git a/src/stdio/getchar_unlocked.c b/src/stdio/getchar_unlocked.c
new file mode 100644
index 00000000..299cb958
--- /dev/null
+++ b/src/stdio/getchar_unlocked.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int getchar_unlocked(void)
+{
+	return stdin->rpos < stdin->rstop ? *stdin->rpos++ : __uflow(stdin);
+}
diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c
new file mode 100644
index 00000000..f770d20b
--- /dev/null
+++ b/src/stdio/getdelim.c
@@ -0,0 +1,59 @@
+#include "stdio_impl.h"
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+ssize_t getdelim(char **s, size_t *n, int delim, FILE *f)
+{
+	char *tmp;
+	unsigned char *z;
+	size_t k;
+	size_t i=0;
+
+	if (!n || !s) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (!*s) *n=0;
+
+	FLOCK(f);
+
+	while (!feof(f)) {
+		z = memchr(f->rpos, delim, f->rend - f->rpos);
+		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+		if (i+k >= *n) {
+			if (k >= SIZE_MAX-i) goto oom;
+			*n = i+k+1;
+			if (*n < SIZE_MAX/2) *n *= 2;
+			tmp = realloc(*s, *n);
+			if (!tmp) {
+				*n = i+k+1;
+				tmp = realloc(*s, *n);
+				if (!tmp) goto oom;
+			}
+			*s = tmp;
+		}
+		memcpy(*s+i, f->rpos, k);
+		f->rpos += k;
+		i += k;
+		if (z) break;
+		__underflow(f);
+	}
+	(*s)[i] = 0;
+	if (feof(f) || ferror(f)) {
+		FUNLOCK(f);
+		return -1;
+	}
+
+	FUNLOCK(f);
+
+	if (i > SSIZE_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+
+	return i;
+oom:
+	errno = ENOMEM;
+	return -1;
+}
diff --git a/src/stdio/getline.c b/src/stdio/getline.c
new file mode 100644
index 00000000..a3a6651b
--- /dev/null
+++ b/src/stdio/getline.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+ssize_t getline(char **s, size_t *n, FILE *f)
+{
+	return getdelim(s, n, '\n', f);
+}
diff --git a/src/stdio/gets.c b/src/stdio/gets.c
new file mode 100644
index 00000000..24319eb2
--- /dev/null
+++ b/src/stdio/gets.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+char *gets(char *s)
+{
+	char *ret = fgets(s, INT_MAX, stdin);
+	if (ret && s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0;
+	return ret;
+}
diff --git a/src/stdio/getw.c b/src/stdio/getw.c
new file mode 100644
index 00000000..de9e985a
--- /dev/null
+++ b/src/stdio/getw.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int getw(FILE *f)
+{
+	int x;
+	return fread(&x, sizeof x, 1, f) ? x : EOF;
+}
diff --git a/src/stdio/getwc.c b/src/stdio/getwc.c
new file mode 100644
index 00000000..a2818bc4
--- /dev/null
+++ b/src/stdio/getwc.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+wint_t getwc(FILE *f)
+{
+	return fgetwc(f);
+}
diff --git a/src/stdio/getwchar.c b/src/stdio/getwchar.c
new file mode 100644
index 00000000..2295bd40
--- /dev/null
+++ b/src/stdio/getwchar.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+wint_t getwchar(void)
+{
+	return fgetwc(stdin);
+}
+
+weak_alias(getwchar, getwchar_unlocked);
diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c
new file mode 100644
index 00000000..c2fe7a24
--- /dev/null
+++ b/src/stdio/pclose.c
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int pclose(FILE *f)
+{
+	int status;
+	fclose(f);
+	while (waitpid(f->pipe_pid, &status, 0) == -1)
+		if (errno != EINTR) return -1;
+	return status;
+}
diff --git a/src/stdio/perror.c b/src/stdio/perror.c
new file mode 100644
index 00000000..e4637c8a
--- /dev/null
+++ b/src/stdio/perror.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "stdio_impl.h"
+
+void perror(const char *msg)
+{
+#if 1
+	if (msg) fprintf(stderr, "%s: %m\n", msg, strerror(errno));
+	else fprintf(stderr, "%m\n");
+#else
+	FILE *f = stderr;
+	char *errstr = strerror(errno);
+
+	FLOCK(f);
+	
+	if (msg) {
+		__fwritex(msg, strlen(msg), f);
+		__putc_unlocked(':', f);
+		__putc_unlocked(' ', f);
+	}
+	__fwritex(errstr, strlen(errstr), f);
+	__putc_unlocked('\n', f);
+
+	FUNLOCK(f);
+#endif
+}
diff --git a/src/stdio/popen.c b/src/stdio/popen.c
new file mode 100644
index 00000000..1d33e9d6
--- /dev/null
+++ b/src/stdio/popen.c
@@ -0,0 +1,43 @@
+#include "stdio_impl.h"
+
+FILE *popen(const char *cmd, const char *mode)
+{
+	int p[2];
+	int op;
+	pid_t pid;
+	FILE *f;
+	const char *modes = "rw", *mi = strchr(modes, *mode);
+
+	if (mi) {
+		op = mi-modes;
+	} else {
+		errno = EINVAL;
+		return 0;
+	}
+	
+	if (pipe(p)) return NULL;
+	f = fdopen(p[op], mode);
+	if (!f) {
+		close(p[0]);
+		close(p[1]);
+		return NULL;
+	}
+	
+	pid = fork();
+	switch (pid) {
+	case -1:
+		fclose(f);
+		close(p[0]);
+		close(p[1]);
+		return NULL;
+	case 0:
+		dup2(p[1-op], 1-op);
+		close(p[0]);
+		close(p[1]);
+		execl("/bin/sh", "sh", "-c", cmd, (char *)0);
+		_exit(127);
+	}
+	close(p[1-op]);
+	f->pipe_pid = pid;
+	return f;
+}
diff --git a/src/stdio/printf.c b/src/stdio/printf.c
new file mode 100644
index 00000000..efeb8b33
--- /dev/null
+++ b/src/stdio/printf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int printf(const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vprintf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/putc.c b/src/stdio/putc.c
new file mode 100644
index 00000000..3c9dc11e
--- /dev/null
+++ b/src/stdio/putc.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int putc(int c, FILE *f)
+{
+	return fputc(c, f);
+}
+
+weak_alias(putc, _IO_putc);
diff --git a/src/stdio/putc_unlocked.c b/src/stdio/putc_unlocked.c
new file mode 100644
index 00000000..f01da717
--- /dev/null
+++ b/src/stdio/putc_unlocked.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int putc_unlocked(int c, FILE *f)
+{
+	return f->wpos < f->wstop ? (*f->wpos++ = c) : __overflow(f, c);
+}
+
+weak_alias(putc_unlocked, fputc_unlocked);
diff --git a/src/stdio/putchar.c b/src/stdio/putchar.c
new file mode 100644
index 00000000..945636d5
--- /dev/null
+++ b/src/stdio/putchar.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int putchar(int c)
+{
+	return fputc(c, stdout);
+}
diff --git a/src/stdio/putchar_unlocked.c b/src/stdio/putchar_unlocked.c
new file mode 100644
index 00000000..72d47d15
--- /dev/null
+++ b/src/stdio/putchar_unlocked.c
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+
+int putchar_unlocked(int c)
+{
+	return stdout->wpos < stdout->wstop ?
+		(*stdout->wpos++ = c) : __overflow(stdout, c);
+}
diff --git a/src/stdio/puts.c b/src/stdio/puts.c
new file mode 100644
index 00000000..eb70efdc
--- /dev/null
+++ b/src/stdio/puts.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int puts(const char *s)
+{
+	return -(fputs(s, stdout) < 0 || putchar('\n') < 0);
+}
diff --git a/src/stdio/putw.c b/src/stdio/putw.c
new file mode 100644
index 00000000..137832ee
--- /dev/null
+++ b/src/stdio/putw.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int putw(int x, FILE *f)
+{
+	return fwrite(&x, sizeof x, 1, f) ? x : EOF;
+}
diff --git a/src/stdio/putwc.c b/src/stdio/putwc.c
new file mode 100644
index 00000000..80b54a47
--- /dev/null
+++ b/src/stdio/putwc.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+wint_t putwc(wchar_t c, FILE *f)
+{
+	return fputwc(c, f);
+}
diff --git a/src/stdio/putwchar.c b/src/stdio/putwchar.c
new file mode 100644
index 00000000..3aacc1cf
--- /dev/null
+++ b/src/stdio/putwchar.c
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+wint_t putwchar(wchar_t c)
+{
+	return fputwc(c, stdout);
+}
+
+weak_alias(putwchar, putwchar_unlocked);
diff --git a/src/stdio/remove.c b/src/stdio/remove.c
new file mode 100644
index 00000000..8e338277
--- /dev/null
+++ b/src/stdio/remove.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int remove(const char *path)
+{
+	return __syscall_unlink(path);
+}
diff --git a/src/stdio/rename.c b/src/stdio/rename.c
new file mode 100644
index 00000000..4eced08a
--- /dev/null
+++ b/src/stdio/rename.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int rename(const char *old, const char *new)
+{
+	return syscall2(__NR_rename, (long)old, (long)new);
+}
diff --git a/src/stdio/rewind.c b/src/stdio/rewind.c
new file mode 100644
index 00000000..7944b434
--- /dev/null
+++ b/src/stdio/rewind.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void rewind(FILE *f)
+{
+	fseek(f, 0, SEEK_SET);
+}
diff --git a/src/stdio/scanf.c b/src/stdio/scanf.c
new file mode 100644
index 00000000..a04a4402
--- /dev/null
+++ b/src/stdio/scanf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int scanf(const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/setbuf.c b/src/stdio/setbuf.c
new file mode 100644
index 00000000..205afcfe
--- /dev/null
+++ b/src/stdio/setbuf.c
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+void setbuf(FILE *f, char *buf)
+{
+	setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/src/stdio/setvbuf.c b/src/stdio/setvbuf.c
new file mode 100644
index 00000000..2985d3f1
--- /dev/null
+++ b/src/stdio/setvbuf.c
@@ -0,0 +1,22 @@
+#include "stdio_impl.h"
+
+/* This function makes no attempt to protect the user from his/her own
+ * stupidity. If called any time but when then ISO C standard specifically
+ * allows it, all hell can and will break loose, especially with threads!
+ *
+ * This implementation ignores all arguments except the buffering type,
+ * and uses the existing buffer allocated alongside the FILE object.
+ * In the case of stderr where the preexisting buffer is length 1, it
+ * is not possible to set line buffering or full buffering. */
+
+int setvbuf(FILE *f, char *buf, int type, size_t size)
+{
+	f->lbf = EOF;
+
+	if (type == _IONBF)
+		f->buf_size = 1;
+	else if (type == _IOLBF)
+		f->lbf = '\n';
+
+	return 0;
+}
diff --git a/src/stdio/snprintf.c b/src/stdio/snprintf.c
new file mode 100644
index 00000000..4071c2f6
--- /dev/null
+++ b/src/stdio/snprintf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int snprintf(char *s, size_t n, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsnprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
diff --git a/src/stdio/sprintf.c b/src/stdio/sprintf.c
new file mode 100644
index 00000000..6b225409
--- /dev/null
+++ b/src/stdio/sprintf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sprintf(char *s, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/sscanf.c b/src/stdio/sscanf.c
new file mode 100644
index 00000000..a1cea699
--- /dev/null
+++ b/src/stdio/sscanf.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sscanf(const char *s, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/stderr.c b/src/stdio/stderr.c
new file mode 100644
index 00000000..4a79d4e7
--- /dev/null
+++ b/src/stdio/stderr.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[1+UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = 1,
+	.fd = 2,
+	.flags = F_PERM | F_NORD,
+	.write = __stdio_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+};
+FILE *const stderr = &f;
diff --git a/src/stdio/stdin.c b/src/stdio/stdin.c
new file mode 100644
index 00000000..51c99232
--- /dev/null
+++ b/src/stdio/stdin.c
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[BUFSIZ+UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 0,
+	.flags = F_PERM | F_NOWR,
+	.read = __stdio_read,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+};
+FILE *const stdin = &f;
diff --git a/src/stdio/stdout.c b/src/stdio/stdout.c
new file mode 100644
index 00000000..bf6eea6c
--- /dev/null
+++ b/src/stdio/stdout.c
@@ -0,0 +1,17 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[BUFSIZ+UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 1,
+	.flags = F_PERM | F_NORD,
+	.lbf = '\n',
+	.write = __stdio_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+};
+FILE *const stdout = &f;
+
+/* overrides symbol in fflush.c, used for flushing NULL */
+FILE *const __stdout_to_flush = &f;
diff --git a/src/stdio/swscanf.c b/src/stdio/swscanf.c
new file mode 100644
index 00000000..b66ad03e
--- /dev/null
+++ b/src/stdio/swscanf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int swscanf(const wchar_t *s, const wchar_t *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
new file mode 100644
index 00000000..2cbcb864
--- /dev/null
+++ b/src/stdio/tempnam.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+char *tempnam(const char *dir, const char *pfx)
+{
+	static int lock;
+	static int index;
+	char *s;
+	int pid = getpid();
+	int l;
+
+	if (!dir) dir = P_tmpdir;
+	if (!pfx) pfx = "temp";
+
+	if (access(dir, R_OK|W_OK|X_OK) != 0)
+		return NULL;
+
+	l = strlen(dir) + 1 + strlen(pfx) + 2 + sizeof(int)*3*2 + 1;
+	s = malloc(l);
+	if (!s) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	LOCK(&lock);
+	for (; index < TMP_MAX; index++) {
+		snprintf(s, l, "%s/%s-%d-%d", dir, pfx, pid, index);
+		if (access(s, F_OK) != 0) {
+			UNLOCK(&lock);
+			return s;
+		}
+	}
+	UNLOCK(&lock);
+	free(s);
+	return NULL;	
+}
diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c
new file mode 100644
index 00000000..185025f1
--- /dev/null
+++ b/src/stdio/tmpfile.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "stdio_impl.h"
+
+FILE *tmpfile(void)
+{
+	char buf[L_tmpnam], *s;
+	int fd;
+	FILE *f;
+	for (;;) {
+		s = tmpnam(buf);
+		if (!s) return NULL;
+		fd = __syscall_open(s, O_RDWR | O_CREAT | O_EXCL, 0600);
+		if (fd >= 0) {
+			f = __fdopen(fd, "w+");
+			remove(s);
+			return f;
+		}
+	}
+}
+
+LFS64(tmpfile);
diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
new file mode 100644
index 00000000..14d59220
--- /dev/null
+++ b/src/stdio/tmpnam.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include "libc.h"
+
+char *tmpnam(char *s)
+{
+	static int lock;
+	static int index;
+	static char *s2;
+	int pid = getpid();
+	char *dir = getenv("TMPDIR");
+
+	if (!s) {
+		if (!s2) s2 = malloc(L_tmpnam);
+		s = s2;
+	}
+
+	/* this interface is insecure anyway but at least we can try.. */
+	if (!dir || strlen(dir) > L_tmpnam-32)
+		dir = P_tmpdir;
+
+	if (access(dir, R_OK|W_OK|X_OK) != 0)
+		return NULL;
+
+	LOCK(&lock);
+	for (index++; index < TMP_MAX; index++) {
+		snprintf(s, L_tmpnam, "%s/temp%d-%d", dir, pid, index);
+		if (access(s, F_OK) != 0) {
+			UNLOCK(&lock);
+			return s;
+		}
+	}
+	UNLOCK(&lock);
+	return NULL;
+}
diff --git a/src/stdio/ungetc.c b/src/stdio/ungetc.c
new file mode 100644
index 00000000..07181684
--- /dev/null
+++ b/src/stdio/ungetc.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+
+int ungetc(int c, FILE *f)
+{
+	if (c == EOF) return c;
+
+	FLOCK(f);
+
+	/* Fail if unreadable or writing and unable to flush */
+	if ((f->flags & (F_ERR|F_NORD)) || (f->wpos && __oflow(f))) {
+		FUNLOCK(f);
+		return EOF;
+	}
+
+	/* Clear write mode */
+	f->wbase = f->wpos = f->wstop = f->wend = 0;
+
+	/* Put the file in read mode */
+	if (!f->rpos) f->rpos = f->rend = f->buf;
+
+	/* If unget buffer is already full, fail. */
+	if (f->rpos <= f->buf - UNGET) {
+		FUNLOCK(f);
+		return EOF;
+	}
+
+	/* Put a byte back into the buffer */
+	*--f->rpos = c;
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	return c;
+}
diff --git a/src/stdio/ungetwc.c b/src/stdio/ungetwc.c
new file mode 100644
index 00000000..f7cde2e0
--- /dev/null
+++ b/src/stdio/ungetwc.c
@@ -0,0 +1,45 @@
+#include "stdio_impl.h"
+
+wint_t ungetwc(wint_t c, FILE *f)
+{
+	unsigned char mbc[MB_LEN_MAX];
+	int l=1;
+
+	if (c == WEOF) return c;
+
+	/* Try conversion early so we can fail without locking if invalid */
+	if (!isascii(c) && (l = wctomb(mbc, c)) < 0)
+		return WEOF;
+
+	FLOCK(f);
+
+	f->mode |= f->mode+1;
+
+	/* Fail if unreadable or writing and unable to flush */
+	if ((f->flags & (F_ERR|F_NORD)) || (f->wpos && __oflow(f))) {
+		FUNLOCK(f);
+		return EOF;
+	}
+
+	/* Clear write mode */
+	f->wpos = f->wstop = f->wend = 0;
+
+	/* Put the file in read mode */
+	if (!f->rpos) f->rpos = f->rend = f->buf;
+
+	/* If unget buffer is nonempty, fail. */
+	if (f->rpos < f->buf) {
+		FUNLOCK(f);
+		return WEOF;
+	}
+
+	/* Put character back into the buffer */
+	if (isascii(c)) *--f->rpos = c;
+	else memcpy(f->rpos -= l, mbc, l);
+
+	/* Clear EOF */
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	return c;
+}
diff --git a/src/stdio/vasprintf.c b/src/stdio/vasprintf.c
new file mode 100644
index 00000000..f2bbc7aa
--- /dev/null
+++ b/src/stdio/vasprintf.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#define GUESS 240U
+
+int vasprintf(char **s, const char *fmt, va_list ap)
+{
+	va_list ap2;
+	char *a;
+	int l=GUESS;
+
+	if (!(a=malloc(GUESS))) return -1;
+
+	va_copy(ap2, ap);
+	l=vsnprintf(a, GUESS, fmt, ap2);
+	va_end(ap2);
+
+	if (l<GUESS) {
+		char *b = realloc(a, l+1U);
+		*s = b ? b : a;
+		return l;
+	}
+	free(a);
+	if (l<0 || !(*s=malloc(l+1U))) return -1;
+	return vsnprintf(*s, l+1U, fmt, ap);
+}
diff --git a/src/stdio/vdprintf.c b/src/stdio/vdprintf.c
new file mode 100644
index 00000000..bfb1b0a9
--- /dev/null
+++ b/src/stdio/vdprintf.c
@@ -0,0 +1,14 @@
+#include "stdio_impl.h"
+
+int vdprintf(int fd, const char *fmt, va_list ap)
+{
+	int r;
+	char buf[BUFSIZ];
+	FILE f = {
+		.fd = fd, .lbf = EOF, .write = __stdio_write,
+		.buf = buf+UNGET, .buf_size = sizeof buf - UNGET
+	};
+	r = vfprintf(&f, fmt, ap);
+	__oflow(&f);
+	return r;
+}
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
new file mode 100644
index 00000000..5e19acc5
--- /dev/null
+++ b/src/stdio/vfprintf.c
@@ -0,0 +1,640 @@
+#include "stdio_impl.h"
+
+/* Some useful macros */
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#define CONCAT2(x,y) x ## y
+#define CONCAT(x,y) CONCAT2(x,y)
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+#if UINT_MAX == ULONG_MAX
+#define LONG_IS_INT
+#endif
+
+#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
+#define ODD_TYPES
+#endif
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+#ifndef LONG_IS_INT
+	LONG, ULONG,
+#else
+#define LONG INT
+#define ULONG UINT
+#endif
+	SHORT, USHORT, CHAR, UCHAR,
+#ifdef ODD_TYPES
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+#else
+#define LLONG ULLONG
+#define SIZET ULONG
+#define IMAX LLONG
+#define UMAX ULLONG
+#define PDIFF LONG
+#define UIPTR ULONG
+#endif
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	/* Give the compiler a hint for optimizing the switch. */
+	if ((unsigned)type > MAXSTATE) return;
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+#ifndef LONG_IS_INT
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+#endif
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+#ifdef ODD_TYPES
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+#endif
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const char *s, size_t l)
+{
+	__fwritex(s, l, f);
+}
+
+static void pad(FILE *f, char c, int w, int l, int fl)
+{
+	char pad[256];
+	if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
+	l = w - l;
+	memset(pad, c, l>sizeof pad ? sizeof pad : l);
+	for (; l >= sizeof pad; l -= sizeof pad)
+		out(f, pad, sizeof pad);
+	out(f, pad, l);
+}
+
+static const char xdigits[16] = {
+	"0123456789ABCDEF"
+};
+
+static char *fmt_x(uintmax_t x, char *s, int lower)
+{
+	for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
+	return s;
+}
+
+static char *fmt_o(uintmax_t x, char *s)
+{
+	for (; x; x>>=3) *--s = '0' + (x&7);
+	return s;
+}
+
+static char *fmt_u(uintmax_t x, char *s)
+{
+	unsigned long y;
+	for (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
+	for (y=x;           y; y/=10) *--s = '0' + y%10;
+	return s;
+}
+
+static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
+{
+	uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];
+	uint32_t *a, *d, *r, *z;
+	int e2=0, e, i, j, l;
+	char buf[9+LDBL_MANT_DIG/4], *s;
+	const char *prefix="-+ ";
+	int pl;
+	char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
+
+	pl=1;
+	if (y<0 || 1/y<0) {
+		y=-y;
+	} else if (fl & MARK_POS) {
+		prefix++;
+	} else if (fl & PAD_POS) {
+		prefix+=2;
+	} else pl=0;
+
+	if (!isfinite(y)) {
+		char *s = (t&32)?"inf":"INF";
+		if (y!=y) s=(t&32)?"nan":"NAN", pl=0;
+		pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
+		out(f, prefix, pl);
+		out(f, s, 3);
+		pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+		return MAX(w, 3+pl);
+	}
+
+	y = frexpl(y, &e2) * 2;
+	if (y) e2--;
+
+	if ((t|32)=='a') {
+		long double round = 8.0;
+		int re;
+
+		if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
+		else re=LDBL_MANT_DIG/4-1-p;
+
+		if (re) {
+			if (pl && *prefix=='-') y=-y;
+			while (re--) round*=16;
+			y+=round;
+			y-=round;
+			if (y<0) y=-y;
+		}
+
+		estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
+		if (estr==ebuf) *--estr='0';
+		*--estr = (e2<0 ? '-' : '+');
+		*--estr = t+('p'-'a');
+
+		s=buf;
+		*s++='0';
+		*s++=t+('x'-'a');
+		do {
+			int x=y;
+			*s++=xdigits[x]|(t&32);
+			y=16*(y-x);
+			if (s-buf==3 && (y||p>0||(fl&ALT_FORM))) *s++='.';
+		} while (y);
+
+		if (p<0) p = s-buf-4;
+		l = 1 + p + (p || (fl&ALT_FORM)) + ebuf-estr;
+
+		pad(f, ' ', w, pl+l, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+l, fl^ZERO_PAD);
+		out(f, buf, s-buf);
+		pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
+		out(f, estr, ebuf-estr);
+		pad(f, '0', w, pl+l, fl^LEFT_ADJ);
+		return MAX(w, pl+l);
+	}
+	if (p<0) p=6;
+
+	y *= 0x1p28; e2-=28;
+
+	if (e2<0) a=r=z=big;
+	else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+
+	do {
+		*z = y;
+		y = 1000000000*(y-*z++);
+	} while (y);
+
+	while (e2>0) {
+		uint32_t carry=0;
+		int sh=MIN(29,e2);
+		for (d=z-1; d>=a; d--) {
+			uint64_t x = ((uint64_t)*d<<sh)+carry;
+			*d = x % 1000000000;
+			carry = x / 1000000000;
+		}
+		if (!z[-1] && z>a) z--;
+		if (carry) *--a = carry;
+		e2-=sh;
+	}
+	while (e2<0) {
+		uint32_t carry=0, *z2;
+		int sh=MIN(9,-e2);
+		for (d=a; d<z; d++) {
+			uint32_t rm = *d & (1<<sh)-1;
+			*d = (*d>>sh) + carry;
+			carry = (1000000000>>sh) * rm;
+		}
+		if (!*a) a++;
+		if (carry) *z++ = carry;
+		/* Avoid (slow!) computation past requested precision */
+		z2 = ((t|32)=='f' ? r : a) + 2 + p/9;
+		z = MIN(z, z2);
+		e2+=sh;
+	}
+
+	if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+	else e=0;
+
+	/* Perform rounding: j is precision after the radix (possibly neg) */
+	j = p - ((t|32)!='f')*e - ((t|32)=='g');
+	if (j < 9*(z-r-1)) {
+		uint32_t x;
+		/* We avoid C's broken division of negative numbers */
+		d = r + 1 + (j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP;
+		j += 9*LDBL_MAX_EXP;
+		j %= 9;
+		for (i=10, j++; j<9; i*=10, j++);
+		x = *d % i;
+		/* Are there any significant digits past j? */
+		if (x || d+1!=z) {
+			long double round = CONCAT(0x1p,LDBL_MANT_DIG);
+			long double small;
+			if (x<i/2) small=0x01p-1;
+			else if (i==i/2 && d+1==z) small=0x10p-1;
+			else small=0x11p-1;
+			if (pl && *prefix=='-') round*=-1, small*=-1;
+			/* Decide whether to round by probing round+small */
+			if (round+small != round) {
+				*d = *d - x + i;
+				while (*d > 999999999) {
+					*d--=0;
+					(*d)++;
+				}
+				if (d<a) a=d;
+				for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+			}
+		}
+		for (; !z[-1] && z>a; z--);
+	}
+	
+	if ((t|32)=='g') {
+		if (!p) p++;
+		if (p>e && e>=-4) {
+			t--;
+			p-=e+1;
+		} else {
+			t-=2;
+			p--;
+		}
+		if (!(fl&ALT_FORM)) {
+			/* Count trailing zeros in last place */
+			if (z>a) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
+			else j=9;
+			if ((t|32)=='f')
+				p = MIN(p,MAX(0,9*(z-r-1)-j));
+			else
+				p = MIN(p,MAX(0,9*(z-r-1)+e-j));
+		}
+	}
+	l = 1 + p + (p || (fl&ALT_FORM));
+	if ((t|32)=='f') {
+		if (e>0) l+=e;
+	} else {
+		estr=fmt_u(e<0 ? -e : e, ebuf);
+		while(ebuf-estr<2) *--estr='0';
+		*--estr = (e<0 ? '-' : '+');
+		*--estr = t;
+		l += ebuf-estr;
+	}
+
+	pad(f, ' ', w, pl+l, fl);
+	out(f, prefix, pl);
+	pad(f, '0', w, pl+l, fl^ZERO_PAD);
+
+	if ((t|32)=='f') {
+		if (a>r) a=r;
+		for (d=a; d<=r; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (d!=a) while (s>buf) *--s='0';
+			else if (s==buf+9) *--s='0';
+			out(f, s, buf+9-s);
+		}
+		if (p || (fl&ALT_FORM)) out(f, ".", 1);
+		for (; d<z && p>0; d++, p-=9) {
+			char *s = fmt_u(*d, buf+9);
+			while (s>buf) *--s='0';
+			out(f, s, MIN(9,p));
+		}
+		pad(f, '0', p+9, 9, 0);
+	} else {
+		if (z<=a) z=a+1;
+		for (d=a; d<z && p>=0; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (s==buf+9) *--s='0';
+			if (d!=a) while (s>buf) *--s='0';
+			else {
+				out(f, s++, 1);
+				if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
+			}
+			out(f, s, MIN(buf+9-s, p));
+			p -= buf+9-s;
+		}
+		pad(f, '0', p+18, 18, 0);
+		out(f, estr, ebuf-estr);
+	}
+
+	pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+
+	return MAX(w, pl+l);
+}
+
+static int getint(char **s) {
+	int i;
+	for (i=0; isdigit(**s); (*s)++)
+		i = 10*i + (**s-'0');
+	return i;
+}
+
+static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	char *a, *z, *s=(char *)fmt;
+	unsigned l10n=0, litpct, fl;
+	int w, p;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	int i;
+	char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+	const char *prefix;
+	int t, pl;
+	wchar_t wc[2], *ws;
+	char mb[4];
+
+	for (;;) {
+		/* Update output count, end loop when fmt is exhausted */
+		if (cnt >= 0) {
+			if (l > INT_MAX - cnt) {
+				if (!ferror(f)) errno = EOVERFLOW;
+				cnt = -1;
+			} else cnt += l;
+		}
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		litpct = strspn(s, "%")/2; /* Optimize %%%% runs */
+		z = s+litpct;
+		s += 2*litpct;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (isdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (isdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else return -1;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) return -1;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else return -1;
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+		} else p = -1;
+
+		/* Format specifier state machine */
+		st=0;
+		do {
+			if (OOB(*s)) return -1;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1<STOP);
+		if (!st) return -1;
+
+		/* Check validity of argument type (nl/normal) */
+		if (st==NOARG) {
+			if (argpos>=0) return -1;
+			else if (!f) continue;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+
+		z = buf + sizeof(buf);
+		prefix = "-+   0X0x";
+		pl = 0;
+		t = s[-1];
+
+		/* Transform ls,lc -> S,C */
+		if (ps && (t&15)==3) t&=~32;
+
+		/* - and 0 flags are mutually exclusive */
+		if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+		switch(t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = l;
+			case LPRE: *(long *)arg.p = l;
+			case LLPRE: *(long long *)arg.p = l;
+			case HPRE: *(unsigned short *)arg.p = l;
+			case HHPRE: *(unsigned char *)arg.p = l;
+			case ZTPRE: *(size_t *)arg.p = l;
+			case JPRE: *(uintmax_t *)arg.p = l;
+			}
+			continue;
+		case 'p':
+			p = MAX(p, 2*sizeof(void*));
+			t = 'x';
+			fl |= ALT_FORM;
+		case 'x': case 'X':
+			a = fmt_x(arg.i, z, t&32);
+			if (fl & ALT_FORM) prefix+=(t>>4), pl=2;
+			if (0) {
+		case 'o':
+			a = fmt_o(arg.i, z);
+			if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;
+			} if (0) {
+		case 'd': case 'i':
+			pl=1;
+			if (arg.i>INTMAX_MAX) {
+				arg.i=-arg.i;
+			} else if (fl & MARK_POS) {
+				prefix++;
+			} else if (fl & PAD_POS) {
+				prefix+=2;
+			} else pl=0;
+		case 'u':
+			a = fmt_u(arg.i, z);
+			}
+			if (!arg.i && !p) continue;
+			if (p>=0) fl &= ~ZERO_PAD;
+			p = MAX(p, z-a + !arg.i);
+			break;
+		case 'c':
+			*(a=z-(p=1))=arg.i;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'm':
+			if (1) a = strerror(errno); else
+		case 's':
+			a = arg.p;
+			z = memchr(a, 0, p);
+			if (!z) z=a+p;
+			else p=z-a;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'C':
+			wc[0] = arg.i;
+			wc[1] = 0;
+			arg.p = wc;
+			p = -1;
+		case 'S':
+			ws = arg.p;
+			for (i=0; *ws && (l=wctomb(mb, *ws++))>=0 && l<=0U+p-i; i+=l);
+			if (l<0) return -1;
+			p = i;
+			pad(f, ' ', w, p, fl);
+			ws = arg.p;
+			for (i=0; *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
+				out(f, mb, l);
+			pad(f, ' ', w, p, fl^LEFT_ADJ);
+			l = w>p ? w : p;
+			continue;
+		case 'e': case 'f': case 'g': case 'a':
+		case 'E': case 'F': case 'G': case 'A':
+			l = fmt_fp(f, arg.f, w, p, fl, t);
+			continue;
+		}
+
+		if (p < z-a) p = z-a;
+		if (w < pl+p) w = pl+p;
+
+		pad(f, ' ', w, pl+p, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+p, fl^ZERO_PAD);
+		pad(f, '0', p, z-a, 0);
+		out(f, a, z-a);
+		pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
+
+		l = w;
+	}
+
+	if (f) return cnt;
+	if (!l10n) return 0;
+
+	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+		pop_arg(nl_arg+i, nl_type[i], ap);
+	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+	if (i<=NL_ARGMAX) return -1;
+	return 1;
+}
+
+int vfprintf(FILE *f, const char *fmt, va_list ap)
+{
+	va_list ap2;
+	int nl_type[NL_ARGMAX] = {0};
+	union arg nl_arg[NL_ARGMAX];
+	int ret;
+
+	va_copy(ap2, ap);
+	if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
+
+	FLOCK(f);
+	ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
+	FUNLOCK(f);
+	va_end(ap2);
+	return ret;
+}
diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
new file mode 100644
index 00000000..69f45081
--- /dev/null
+++ b/src/stdio/vfscanf.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "stdio_impl.h"
+#include "__scanf.h"
+
+static void f_read(rctx_t *r)
+{
+	FILE *f = r->opaque;
+	if ((r->c = __uflow(f)) >= 0) r->l++;
+}
+
+int vfscanf(FILE *f, const char *fmt, va_list ap)
+{
+	size_t l = strlen(fmt), i, result;
+	rctx_t r = { f_read, (void *)f, 0, isspace };
+	wchar_t fmt2[l+1];
+
+	if (l > 0x100000) {
+		errno = ENOMEM;
+		return -1;
+	}
+	for (i=0; i<=l; i++) fmt2[i] = (unsigned char)fmt[i];
+
+	FLOCK(f);
+
+	result = __scanf(&r, fmt2, ap);
+
+	if (r.u && r.c >= 0) {
+		/* This code takes care of the case where the caller performs
+		 * a nonmatching scanf to leave a character in the unscan
+		 * buffer, followed by an unget, followed by a scanf that
+		 * matches zero characters. In this case the final 'unread'
+		 * character must be returned to the unget buffer rather than
+		 * the unscan buffer. */
+		 f->rpos--;
+	}
+
+	FUNLOCK(f);
+	return result;
+}
diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c
new file mode 100644
index 00000000..491c1403
--- /dev/null
+++ b/src/stdio/vfwscanf.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "stdio_impl.h"
+#include "__scanf.h"
+
+static void f_read(rctx_t *r)
+{
+	FILE *f = r->opaque;
+	if ((r->c = fgetwc(f)) >= 0) r->l++;
+}
+
+int vfwscanf(FILE *f, const wchar_t *fmt, va_list ap)
+{
+	rctx_t r = { f_read, (void *)f, 1, iswspace };
+	int result;
+
+	result = __scanf(&r, fmt, ap);
+
+	if (r.u && r.c >= 0) {
+		ungetwc(r.c, f);
+	}
+
+	return result;
+}
diff --git a/src/stdio/vprintf.c b/src/stdio/vprintf.c
new file mode 100644
index 00000000..67b38dac
--- /dev/null
+++ b/src/stdio/vprintf.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int vprintf(const char *fmt, va_list ap)
+{
+	return vfprintf(stdout, fmt, ap);
+}
diff --git a/src/stdio/vscanf.c b/src/stdio/vscanf.c
new file mode 100644
index 00000000..6f55b1c3
--- /dev/null
+++ b/src/stdio/vscanf.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int vscanf(const char *fmt, va_list ap)
+{
+	return vfscanf(stdin, fmt, ap);
+}
diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c
new file mode 100644
index 00000000..bda6b49b
--- /dev/null
+++ b/src/stdio/vsnprintf.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+
+static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
+{
+	/* pretend to succeed, but discard data */
+	return l;
+}
+
+int vsnprintf(char *s, size_t n, const char *fmt, va_list ap)
+{
+	int r;
+	FILE f;
+	unsigned char buf[1];
+
+	memset(&f, 0, sizeof(FILE));
+	f.lbf = EOF;
+	f.write = sn_write;
+	f.buf_size = 1;
+	f.buf = buf;
+	if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	} else if (n > 0) {
+		if (n > (char *)0+SIZE_MAX-s) n = (char *)0+SIZE_MAX-s;
+		f.wpos = s;
+		f.wbase = f.wend = s+n-1;
+		f.wstop = f.wend - 1;
+	}
+	r = vfprintf(&f, fmt, ap);
+	/* wpos points just after last byte written, or to s+n-1 (wbase) */
+	*f.wpos = 0;
+	return r;
+}
diff --git a/src/stdio/vsprintf.c b/src/stdio/vsprintf.c
new file mode 100644
index 00000000..7836ccb2
--- /dev/null
+++ b/src/stdio/vsprintf.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <limits.h>
+
+int vsprintf(char *s, const char *fmt, va_list ap)
+{
+	return vsnprintf(s, INT_MAX, fmt, ap);
+}
diff --git a/src/stdio/vsscanf.c b/src/stdio/vsscanf.c
new file mode 100644
index 00000000..fd48f709
--- /dev/null
+++ b/src/stdio/vsscanf.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "__scanf.h"
+
+static void s_read(rctx_t *r)
+{
+	unsigned char *s = r->opaque;
+	if (!s[r->l]) r->c = -1;
+	else r->c = s[r->l++];
+}
+
+int vsscanf(const char *s, const char *fmt, va_list ap)
+{
+	size_t l = strlen(fmt), i;
+	wchar_t fmt2[l+1];
+	rctx_t r = { s_read, (void *)s, 0, isspace };
+	for (i=0; i<=l; i++) fmt2[i] = (unsigned char)fmt[i];
+	return __scanf(&r, fmt2, ap);
+}
diff --git a/src/stdio/vswscanf.c b/src/stdio/vswscanf.c
new file mode 100644
index 00000000..2c4ffbe0
--- /dev/null
+++ b/src/stdio/vswscanf.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include "__scanf.h"
+
+static void s_read(rctx_t *r)
+{
+	wchar_t *s = r->opaque;
+	if (!s[r->l]) r->c = -1;
+	else r->c = s[r->l++];
+}
+
+int vswscanf(const wchar_t *s, const wchar_t *fmt, va_list ap)
+{
+	rctx_t r = { s_read, (void *)s, 1, iswspace };
+	return __scanf(&r, fmt, ap);
+}
diff --git a/src/stdio/vwscanf.c b/src/stdio/vwscanf.c
new file mode 100644
index 00000000..86da0457
--- /dev/null
+++ b/src/stdio/vwscanf.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int vwscanf(const wchar_t *fmt, va_list ap)
+{
+	return vfwscanf(stdin, fmt, ap);
+}
diff --git a/src/stdio/wscanf.c b/src/stdio/wscanf.c
new file mode 100644
index 00000000..34b58846
--- /dev/null
+++ b/src/stdio/wscanf.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int wscanf(const wchar_t *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
diff --git a/src/stdlib/abs.c b/src/stdlib/abs.c
new file mode 100644
index 00000000..4806d629
--- /dev/null
+++ b/src/stdlib/abs.c
@@ -0,0 +1,4 @@
+int abs(int a)
+{
+	return a>0 ? a : -a;
+}
diff --git a/src/stdlib/atof.c b/src/stdlib/atof.c
new file mode 100644
index 00000000..f7fcd826
--- /dev/null
+++ b/src/stdlib/atof.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+double atof(const char *s)
+{
+	return strtod(s, 0);
+}
diff --git a/src/stdlib/atoi.c b/src/stdlib/atoi.c
new file mode 100644
index 00000000..648b154f
--- /dev/null
+++ b/src/stdlib/atoi.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+int atoi(const char *s)
+{
+	int n=0, neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	while (isdigit(*s))
+		n = 10*n + *s++ - '0';
+	return neg ? -n : n;
+}
diff --git a/src/stdlib/atol.c b/src/stdlib/atol.c
new file mode 100644
index 00000000..9c91bba9
--- /dev/null
+++ b/src/stdlib/atol.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long atol(const char *s)
+{
+	long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	while (isdigit(*s))
+		n = 10*n + *s++ - '0';
+	return neg ? -n : n;
+}
diff --git a/src/stdlib/atoll.c b/src/stdlib/atoll.c
new file mode 100644
index 00000000..0e03e0a1
--- /dev/null
+++ b/src/stdlib/atoll.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long long atoll(const char *s)
+{
+	long long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	while (isdigit(*s))
+		n = 10*n + *s++ - '0';
+	return neg ? -n : n;
+}
diff --git a/src/stdlib/bsearch.c b/src/stdlib/bsearch.c
new file mode 100644
index 00000000..61d89367
--- /dev/null
+++ b/src/stdlib/bsearch.c
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
+{
+	void *try;
+	int sign;
+	while (nel > 0) {
+		try = (char *)base + width*(nel/2);
+		sign = cmp(key, try);
+		if (!sign) return try;
+		else if (nel == 1) break;
+		else if (sign < 0)
+			nel /= 2;
+		else {
+			base = try;
+			nel -= nel/2;
+		}
+	}
+	return NULL;
+}
diff --git a/src/stdlib/div.c b/src/stdlib/div.c
new file mode 100644
index 00000000..e42c1f14
--- /dev/null
+++ b/src/stdlib/div.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+div_t div(int num, int den)
+{
+	return (div_t){ num/den, num%den };
+}
diff --git a/src/stdlib/frexp.c b/src/stdlib/frexp.c
new file mode 100644
index 00000000..ae82cb30
--- /dev/null
+++ b/src/stdlib/frexp.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <inttypes.h>
+
+double frexp(double x, int *e)
+{
+	union { double d; uint64_t i; } y = { x };
+	int ee = y.i>>52 & 0x7ff;
+
+	if (!ee) {
+		if (x) {
+			x = frexp(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7ff) {
+		return x;
+	}
+
+	*e = ee - 0x3fe;
+	y.i &= 0x800fffffffffffffull;
+	y.i |= 0x3fe0000000000000ull;
+	return y.d;
+}
diff --git a/src/stdlib/frexpf.c b/src/stdlib/frexpf.c
new file mode 100644
index 00000000..ee5e910a
--- /dev/null
+++ b/src/stdlib/frexpf.c
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <inttypes.h>
+
+float frexpf(float x, int *e)
+{
+	union { float f; uint32_t i; } y = { x };
+	int ee = y.i>>23 & 0xff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpf(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0xff) {
+		return x;
+	}
+
+	*e = ee - 0x7e;
+	y.i &= 0x807ffffful;
+	y.i |= 0x3f000000ul;
+	return y.f;
+}
diff --git a/src/stdlib/frexpl.c b/src/stdlib/frexpl.c
new file mode 100644
index 00000000..ecfff007
--- /dev/null
+++ b/src/stdlib/frexpl.c
@@ -0,0 +1,25 @@
+#include <math.h>
+#include <inttypes.h>
+
+/* This version is for 80-bit little endian long double */
+
+long double frexpl(long double x, int *e)
+{
+	union { long double ld; uint16_t hw[5]; } y = { x };
+	int ee = y.hw[4]&0x7fff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpl(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7fff) {
+		return x;
+	}
+
+	*e = ee - 0x3ffe;
+	y.hw[4] &= 0x8000;
+	y.hw[4] |= 0x3ffe;
+	return y.ld;
+}
diff --git a/src/stdlib/imaxabs.c b/src/stdlib/imaxabs.c
new file mode 100644
index 00000000..81001819
--- /dev/null
+++ b/src/stdlib/imaxabs.c
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+intmax_t imaxabs(intmax_t a)
+{
+	return a>0 ? a : -a;
+}
diff --git a/src/stdlib/imaxdiv.c b/src/stdlib/imaxdiv.c
new file mode 100644
index 00000000..b2ce821f
--- /dev/null
+++ b/src/stdlib/imaxdiv.c
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+imaxdiv_t imaxdiv(intmax_t num, intmax_t den)
+{
+	return (imaxdiv_t){ num/den, num%den };
+}
diff --git a/src/stdlib/labs.c b/src/stdlib/labs.c
new file mode 100644
index 00000000..675b95b8
--- /dev/null
+++ b/src/stdlib/labs.c
@@ -0,0 +1,4 @@
+long labs(long a)
+{
+	return a>0 ? a : -a;
+}
diff --git a/src/stdlib/ldiv.c b/src/stdlib/ldiv.c
new file mode 100644
index 00000000..36eb960b
--- /dev/null
+++ b/src/stdlib/ldiv.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+ldiv_t ldiv(long num, long den)
+{
+	return (ldiv_t){ num/den, num%den };
+}
diff --git a/src/stdlib/llabs.c b/src/stdlib/llabs.c
new file mode 100644
index 00000000..bec4a03d
--- /dev/null
+++ b/src/stdlib/llabs.c
@@ -0,0 +1,4 @@
+long long llabs(long long a)
+{
+	return a>0 ? a : -a;
+}
diff --git a/src/stdlib/lldiv.c b/src/stdlib/lldiv.c
new file mode 100644
index 00000000..7aaf7a0e
--- /dev/null
+++ b/src/stdlib/lldiv.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+lldiv_t lldiv(long long num, long long den)
+{
+	return (lldiv_t){ num/den, num%den };
+}
diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c
new file mode 100644
index 00000000..f5bf3d02
--- /dev/null
+++ b/src/stdlib/qsort.c
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <string.h>
+
+/* A simple heap sort implementation.. only in-place O(nlogn) sort I know. */
+
+#define MIN(a, b) ((a)<(b) ? (a) : (b))
+
+static void swap(char *a, char *b, size_t len)
+{
+	char tmp[256];
+	size_t l;
+	while (len) {
+		l = MIN(sizeof tmp, len);
+		memcpy(tmp, a, l);
+		memcpy(a, b, l);
+		memcpy(b, tmp, l);
+		a += l;
+		b += l;
+		len -= l;
+	}
+}
+
+static void sift(char *base, size_t root, size_t nel, size_t width, int (*cmp)(const void *, const void *))
+{
+	size_t max;
+
+	while (2*root <= nel) {
+		max = 2*root;
+		if (max < nel && cmp(base+max*width, base+(max+1)*width) < 0)
+			max++;
+		if (cmp(base+root*width, base+max*width) < 0) {
+			swap(base+root*width, base+max*width, width);
+			root = max;
+		} else break;
+	}
+}
+
+void qsort(void *_base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
+{
+	char *base = _base;
+	size_t i;
+
+	if (!nel) return;
+	for (i=(nel+1)/2; i; i--)
+		sift(base, i-1, nel-1, width, cmp);
+	for (i=nel-1; i; i--) {
+		swap(base, base+i*width, width);
+		sift(base, 0, i-1, width, cmp);
+	}
+}
diff --git a/src/stdlib/strtod.c b/src/stdlib/strtod.c
new file mode 100644
index 00000000..388058fe
--- /dev/null
+++ b/src/stdlib/strtod.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+double strtod(const char *s, char **p)
+{
+	return strtold(s, p);
+}
diff --git a/src/stdlib/strtof.c b/src/stdlib/strtof.c
new file mode 100644
index 00000000..07b32df4
--- /dev/null
+++ b/src/stdlib/strtof.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+float strtof(const char *s, char **p)
+{
+	return strtold(s, p);
+}
diff --git a/src/stdlib/strtoimax.c b/src/stdlib/strtoimax.c
new file mode 100644
index 00000000..19691091
--- /dev/null
+++ b/src/stdlib/strtoimax.c
@@ -0,0 +1,25 @@
+#include <inttypes.h>
+#include <errno.h>
+#include <ctype.h>
+
+intmax_t strtoimax(const char *s1, char **p, int base)
+{
+	const unsigned char *s = s1;
+	int sign = 0;
+	uintmax_t x;
+
+	/* Initial whitespace */
+	for (; isspace(*s); s++);
+
+	/* Optional sign */
+	if (*s == '-') sign = *s++;
+	else if (*s == '+') s++;
+
+	x = strtoumax(s, p, base);
+	if (x > INTMAX_MAX) {
+		if (!sign || -x != INTMAX_MIN)
+			errno = ERANGE;
+		return sign ? INTMAX_MIN : INTMAX_MAX;
+	}
+	return sign ? -x : x;
+}
diff --git a/src/stdlib/strtol.c b/src/stdlib/strtol.c
new file mode 100644
index 00000000..ace820af
--- /dev/null
+++ b/src/stdlib/strtol.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+long strtol(const char *s, char **p, int base)
+{
+	intmax_t x = strtoimax(s, p, base);
+	if (x > LONG_MAX) {
+		errno = ERANGE;
+		return LONG_MAX;
+	} else if (x < LONG_MIN) {
+		errno = ERANGE;
+		return LONG_MIN;
+	}
+	return x;
+}
diff --git a/src/stdlib/strtold.c b/src/stdlib/strtold.c
new file mode 100644
index 00000000..54f80469
--- /dev/null
+++ b/src/stdlib/strtold.c
@@ -0,0 +1,93 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+
+long double strtold(const char *s1, char **p)
+{
+	const unsigned char *s = s1;
+	long double x = 0;
+	long double frac;
+	int sign = 0;
+	int nonzero = 0;
+	int radix = '.';
+	long e;
+
+	if (!p) p = (char **)&s1;
+
+	/* Initial whitespace */
+	for (; isspace(*s); s++);
+
+	/* Optional sign */
+	if (*s == '-') sign = *s++;
+	else if (*s == '+') s++;
+
+	/* Handle infinities and NaNs. */
+	if ((s[0]|32)=='i' && (s[1]|32)=='n' && (s[2]|32)=='f') {
+		*p = (char *)s + 3;
+		return sign ? -1.0/0.0 : 1.0/0.0;
+	} else if ((s[0]|32)=='n' && (s[1]|32)=='a' && (s[2]|32)=='n') {
+		*p = (char *)s + 3;
+		return 0.0/0.0;
+	}
+
+	/* Possible hex float */
+	if (s[0]=='0' && (s[1]|32)=='x') {
+		/* Mantissa must be non-degenerate */
+		if (!isxdigit(s[2]) && (s[2]!=radix || !isxdigit(s[3]))) {
+			/* Decimal float 0, 'x' extraneous */
+			*p = (char *)++s;
+			return 0;
+		}
+		/* We have a real hex float */
+		s += 2;
+		for (; isxdigit(*s); s++) {
+			x = 16*x + (isdigit(*s)?*s-'0':(*s|32)-'a');
+			if (*s!='0') nonzero=1;
+		}
+		if (*s == radix) {
+			frac = 1.0/16.0;
+			for (s++; isxdigit(*s); s++) {
+				x += frac * (isdigit(*s)?*s-'0':(*s|32)-'a');
+				frac *= 1.0/16.0;
+				if (*s!='0') nonzero=1;
+			}
+		}
+		if ((*s|32) == 'p') {
+			e = strtol(s+1, (void *)&s, 10);
+			for (; e>0; e--) x *= 2.0;
+			for (; e<0; e++) x *= 0.5;
+		}
+		if ((nonzero && !x) || !(1.0/x))
+			errno = ERANGE;
+		*p = (char *)s;
+		return sign ? -x : x;
+	}
+
+	/* Mantissa must be non-degenerate */
+	if (!isdigit(s[0]) && (s[0]!=radix || !isdigit(s[1]))) {
+		*p = (char *)s1;
+		return 0;
+	}
+
+	for (; isdigit(*s); s++) {
+		x = 10*x + *s-'0';
+		if (*s!='0') nonzero=1;
+	}
+	if (*s == radix) {
+		frac = 10.0;
+		for (s++; isdigit(*s); s++) {
+			x += (*s-'0') / frac;
+			frac *= 10.0;
+			if (*s!='0') nonzero=1;
+		}
+	}
+	if ((*s|32)=='e') {
+		e = strtol(++s, (void *)&s, 10);
+		for (; e>0; e--) x *= 10.0;
+		for (; e<0; e++) x /= 10.0;
+	}
+	if ((nonzero && !x) || !(1.0/x))
+		errno = ERANGE;
+	*p = (char*)s;
+	return sign ? -x : x;
+}
diff --git a/src/stdlib/strtoll.c b/src/stdlib/strtoll.c
new file mode 100644
index 00000000..9ab66fd9
--- /dev/null
+++ b/src/stdlib/strtoll.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+long long strtoll(const char *s, char **p, int base)
+{
+	intmax_t x = strtoimax(s, p, base);
+	if (x > LLONG_MAX) {
+		errno = ERANGE;
+		return LLONG_MAX;
+	} else if (x < LLONG_MIN) {
+		errno = ERANGE;
+		return LLONG_MIN;
+	}
+	return x;
+}
diff --git a/src/stdlib/strtoul.c b/src/stdlib/strtoul.c
new file mode 100644
index 00000000..951d5e8c
--- /dev/null
+++ b/src/stdlib/strtoul.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+unsigned long strtoul(const char *s, char **p, int base)
+{
+	uintmax_t x = strtoumax(s, p, base);
+	if (x > ULONG_MAX) {
+		errno = ERANGE;
+		return ULONG_MAX;
+	}
+	return x;
+}
diff --git a/src/stdlib/strtoull.c b/src/stdlib/strtoull.c
new file mode 100644
index 00000000..20aa7bde
--- /dev/null
+++ b/src/stdlib/strtoull.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+unsigned long long strtoull(const char *s, char **p, int base)
+{
+	uintmax_t x = strtoumax(s, p, base);
+	if (x > ULLONG_MAX) {
+		errno = ERANGE;
+		return ULLONG_MAX;
+	}
+	return x;
+}
diff --git a/src/stdlib/strtoumax.c b/src/stdlib/strtoumax.c
new file mode 100644
index 00000000..a529f6e8
--- /dev/null
+++ b/src/stdlib/strtoumax.c
@@ -0,0 +1,123 @@
+#include <inttypes.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+
+/* Lookup table for digit values. -1==255>=36 -> invalid */
+static const unsigned char digits[] = {
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+};
+
+uintmax_t strtoumax(const char *s1, char **p, int base)
+{
+	const unsigned char *s = s1;
+	size_t x1, z1;
+	uintmax_t x, z=0;
+	int sign = 0;
+	int shift;
+
+	if (!p) p = (char **)&s1;
+
+	/* Initial whitespace */
+	for (; isspace(*s); s++);
+
+	/* Optional sign */
+	if (*s == '-') sign = *s++;
+	else if (*s == '+') s++;
+
+	/* Default base 8, 10, or 16 depending on prefix */
+	if (base == 0) {
+		if (s[0] == '0') {
+			if ((s[1]|32) == 'x') base = 16;
+			else base = 8;
+		} else {
+			base = 10;
+		}
+	}
+
+	if ((unsigned)base-2 > 36-2 || digits[*s]>=base) {
+		*p = (char *)s1;
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Main loops. Only use big types if we have to. */
+	if (base == 10) {
+		for (x1=0; isdigit(*s) && x1<=SIZE_MAX/10-10; s++)
+			x1 = 10*x1 + *s-'0';
+		for (x=x1; isdigit(*s) && x<=UINTMAX_MAX/10-10; s++)
+			x = 10*x + *s-'0';
+		if (isdigit(*s)) {
+			if (isdigit(s[1]) || 10*x>UINTMAX_MAX-(*s-'0'))
+				goto overflow;
+			x = 10*x + *s-'0';
+		}
+	} else if (!(base & base/2)) {
+		if (base == 16) {
+			if (s[0]=='0' && (s[1]|32)=='x' && digits[s[2]]<16)
+				s+=2;
+			shift=4;
+			z1 = SIZE_MAX/16;
+			z = UINTMAX_MAX/16;
+		} else if (base == 8) {
+			shift=3;
+			z1 = SIZE_MAX/8;
+			z = UINTMAX_MAX/8;
+		} else if (base == 2) {
+			shift=1;
+			z1 = SIZE_MAX/2;
+			z = UINTMAX_MAX/2;
+		} else if (base == 4) {
+			shift=2;
+			z1 = SIZE_MAX/4;
+			z = UINTMAX_MAX/4;
+		} else /* if (base == 32) */ {
+			shift=5;
+			z1 = SIZE_MAX/32;
+			z = UINTMAX_MAX/32;
+		}
+		for (x1=0; digits[*s]<base && x1<=z1; s++)
+			x1 = (x1<<shift) + digits[*s];
+		for (x=x1; digits[*s]<base && x<=z; s++)
+			x = (x<<shift) + digits[*s];
+		if (digits[*s] < base) goto overflow;
+	} else {
+		z1 = SIZE_MAX/base-base;
+		for (x1=0; digits[*s]<base && x1<=z1; s++)
+			x1 = x1*base + digits[*s];
+		if (digits[*s]<base)
+			z = UINTMAX_MAX/base-base;
+		for (x=x1; digits[*s]<base && x<=z; s++)
+			x = x*base + digits[*s];
+		if (digits[*s] < base) {
+			if (digits[s[1]]<base || x*base>UINTMAX_MAX-digits[*s])
+				goto overflow;
+			x = x*base + digits[*s];
+		}
+	}
+
+	*p = (char *)s;
+	return sign ? -x : x;
+
+overflow:
+	for (; digits[*s] < base; s++);
+	*p = (char *)s;
+	errno = ERANGE;
+	return UINTMAX_MAX;
+}
diff --git a/src/stdlib/wcstoimax.c b/src/stdlib/wcstoimax.c
new file mode 100644
index 00000000..861fcb54
--- /dev/null
+++ b/src/stdlib/wcstoimax.c
@@ -0,0 +1,24 @@
+#include <wchar.h>
+#include <inttypes.h>
+#include <errno.h>
+
+intmax_t wcstoimax(const wchar_t *s, wchar_t **p, int base)
+{
+	int sign = 0;
+	uintmax_t x;
+
+	/* Initial whitespace */
+	for (; iswspace(*s); s++);
+
+	/* Optional sign */
+	if (*s == '-') sign = *s++;
+	else if (*s == '+') s++;
+
+	x = wcstoumax(s, p, base);
+	if (x > INTMAX_MAX) {
+		if (!sign || -x != INTMAX_MIN)
+			errno = ERANGE;
+		return sign ? INTMAX_MIN : INTMAX_MAX;
+	}
+	return sign ? -x : x;
+}
diff --git a/src/stdlib/wcstol.c b/src/stdlib/wcstol.c
new file mode 100644
index 00000000..aad62e5b
--- /dev/null
+++ b/src/stdlib/wcstol.c
@@ -0,0 +1,18 @@
+#include <wchar.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+long wcstol(const wchar_t *s, wchar_t **p, int base)
+{
+	intmax_t x = wcstoimax(s, p, base);
+	if (x > LONG_MAX) {
+		errno = ERANGE;
+		return LONG_MAX;
+	} else if (x < LONG_MIN) {
+		errno = ERANGE;
+		return LONG_MIN;
+	}
+	return x;
+}
diff --git a/src/stdlib/wcstoll.c b/src/stdlib/wcstoll.c
new file mode 100644
index 00000000..ddfea74b
--- /dev/null
+++ b/src/stdlib/wcstoll.c
@@ -0,0 +1,18 @@
+#include <wchar.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+long long wcstoll(const wchar_t *s, wchar_t **p, int base)
+{
+	intmax_t x = wcstoimax(s, p, base);
+	if (x > LLONG_MAX) {
+		errno = ERANGE;
+		return LLONG_MAX;
+	} else if (x < LLONG_MIN) {
+		errno = ERANGE;
+		return LLONG_MIN;
+	}
+	return x;
+}
diff --git a/src/stdlib/wcstoul.c b/src/stdlib/wcstoul.c
new file mode 100644
index 00000000..e39faafe
--- /dev/null
+++ b/src/stdlib/wcstoul.c
@@ -0,0 +1,15 @@
+#include <wchar.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+unsigned long wcstoul(const wchar_t *s, wchar_t **p, int base)
+{
+	uintmax_t x = wcstoumax(s, p, base);
+	if (x > ULONG_MAX) {
+		errno = ERANGE;
+		return ULONG_MAX;
+	}
+	return x;
+}
diff --git a/src/stdlib/wcstoull.c b/src/stdlib/wcstoull.c
new file mode 100644
index 00000000..e324dfb2
--- /dev/null
+++ b/src/stdlib/wcstoull.c
@@ -0,0 +1,15 @@
+#include <wchar.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <limits.h>
+
+unsigned long long wcstoull(const wchar_t *s, wchar_t **p, int base)
+{
+	uintmax_t x = wcstoumax(s, p, base);
+	if (x > ULLONG_MAX) {
+		errno = ERANGE;
+		return ULLONG_MAX;
+	}
+	return x;
+}
diff --git a/src/stdlib/wcstoumax.c b/src/stdlib/wcstoumax.c
new file mode 100644
index 00000000..a8f4680f
--- /dev/null
+++ b/src/stdlib/wcstoumax.c
@@ -0,0 +1,47 @@
+#include <wchar.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+
+uintmax_t wcstoumax(const wchar_t *s, wchar_t **p, int base)
+{
+	/* Large enough for largest value in binary */
+	char buf[sizeof(uintmax_t)*8+2];
+	int sign = 0, skipped=0;
+
+	if (!p) p = (wchar_t **)&s;
+
+	if (base && (unsigned)base-2 > 36-2) {
+		*p = (wchar_t *)s;
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Initial whitespace */
+	for (; iswspace(*s); s++);
+
+	/* Optional sign */
+	if (*s == '-') sign = *s++;
+	else if (*s == '+') s++;
+
+	/* Skip leading zeros but don't allow leading zeros before "0x". */
+	for (; s[0]=='0' && s[1]=='0'; s++) skipped=1;
+	if (skipped && (base==0 || base==16) && (s[1]|32)=='x') {
+		*p = (wchar_t *)(s+1);
+		return 0;
+	}
+
+	/* Convert to normal char string so we can use strtoumax */
+	buf[0] = sign;
+	if (wcstombs(buf+!!sign, s, sizeof buf-1) < 0) return 0;
+	buf[sizeof buf-1]=0;
+
+	/* Compute final position */
+	if (p) {
+		if ((base==0 || base==16) && s[0]=='0' && (s[1]|32)=='x' && iswxdigit(s[2])) s+=2;
+		for(;*s&&((unsigned)*s-'0'<base||((unsigned)*s|32)-'a'<base-10);s++);
+		*p = (wchar_t *)s;
+	}
+
+	return strtoumax(buf, 0, base);
+}
diff --git a/src/string/bcmp.c b/src/string/bcmp.c
new file mode 100644
index 00000000..5d6a388b
--- /dev/null
+++ b/src/string/bcmp.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <strings.h>
+
+int bcmp(const void *s1, const void *s2, size_t n)
+{
+	return memcmp(s1, s2, n);
+}
diff --git a/src/string/bcopy.c b/src/string/bcopy.c
new file mode 100644
index 00000000..e76272fc
--- /dev/null
+++ b/src/string/bcopy.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <strings.h>
+
+void bcopy(const void *s1, void *s2, size_t n)
+{
+	memmove(s2, s1, n);
+}
diff --git a/src/string/bzero.c b/src/string/bzero.c
new file mode 100644
index 00000000..0f98b4a5
--- /dev/null
+++ b/src/string/bzero.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <strings.h>
+
+void bzero(void *s, size_t n)
+{
+	memset(s, 0, n);
+}
diff --git a/src/string/index.c b/src/string/index.c
new file mode 100644
index 00000000..dd611251
--- /dev/null
+++ b/src/string/index.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <strings.h>
+
+char *index(const char *s, int c)
+{
+	return strchr(s, c);
+}
diff --git a/src/string/memchr.c b/src/string/memchr.c
new file mode 100644
index 00000000..a0472f78
--- /dev/null
+++ b/src/string/memchr.c
@@ -0,0 +1,24 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define SS (sizeof(size_t))
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+void *memchr(const void *src, int c, size_t n)
+{
+	const unsigned char *s = src;
+	c = (unsigned char)c;
+	for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
+	if (n && *s != c) {
+		const size_t *w;
+		size_t k = ONES * c;
+		for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
+		for (s = (const void *)w; n && *s != c; s++, n--);
+	}
+	return n ? (void *)s : 0;
+}
diff --git a/src/string/memcmp.c b/src/string/memcmp.c
new file mode 100644
index 00000000..bdbce9f0
--- /dev/null
+++ b/src/string/memcmp.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+int memcmp(const void *vl, const void *vr, size_t n)
+{
+	const unsigned char *l=vl, *r=vr;
+	for (; n && *l == *r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
diff --git a/src/string/memcpy.c b/src/string/memcpy.c
new file mode 100644
index 00000000..02cb4694
--- /dev/null
+++ b/src/string/memcpy.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define SS (sizeof(size_t))
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+	unsigned char *d = dest;
+	const unsigned char *s = src;
+
+	if (((uintptr_t)d & ALIGN) != ((uintptr_t)s & ALIGN))
+		goto misaligned;
+
+	for (; ((uintptr_t)d & ALIGN) && n; n--) *d++ = *s++;
+	if (n) {
+		size_t *wd = (void *)d;
+		const size_t *ws = (const void *)s;
+
+		for (; n>=SS; n-=SS) *wd++ = *ws++;
+		d = (void *)wd;
+		s = (const void *)ws;
+misaligned:
+		for (; n; n--) *d++ = *s++;
+	}
+	return dest;
+}
diff --git a/src/string/memmove.c b/src/string/memmove.c
new file mode 100644
index 00000000..22bb4b35
--- /dev/null
+++ b/src/string/memmove.c
@@ -0,0 +1,14 @@
+#include <string.h>
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+	char *d = dest;
+	const char *s = src;
+	if (d==s) return d;
+	if ((size_t)(d-s) < n) {
+		while (n--) d[n] = s[n];
+		return dest;
+	}
+	/* Assumes memcpy is overlap-safe when dest < src */
+	return memcpy(d, s, n);
+}
diff --git a/src/string/mempcpy.c b/src/string/mempcpy.c
new file mode 100644
index 00000000..e54251cd
--- /dev/null
+++ b/src/string/mempcpy.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+void *mempcpy(void *dest, void *src, size_t n)
+{
+	memcpy(dest, src, n);
+	return (char *)dest + n;
+}
diff --git a/src/string/memset.c b/src/string/memset.c
new file mode 100644
index 00000000..20e47c45
--- /dev/null
+++ b/src/string/memset.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define SS (sizeof(size_t))
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+
+void *memset(void *dest, int c, size_t n)
+{
+	unsigned char *s = dest;
+	c = (unsigned char)c;
+	for (; ((uintptr_t)s & ALIGN) && n; n--) *s++ = c;
+	if (n) {
+		size_t *w, k = ONES * c;
+		for (w = (void *)s; n>=SS; n-=SS, w++) *w = k;
+		for (s = (void *)w; n; n--, s++) *s = c;
+	}
+	return dest;
+}
diff --git a/src/string/rindex.c b/src/string/rindex.c
new file mode 100644
index 00000000..17df2bf2
--- /dev/null
+++ b/src/string/rindex.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <strings.h>
+
+char *rindex(const char *s, int c)
+{
+	return strrchr(s, c);
+}
diff --git a/src/string/stpcpy.c b/src/string/stpcpy.c
new file mode 100644
index 00000000..10ca4933
--- /dev/null
+++ b/src/string/stpcpy.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpcpy(char *d, const char *s)
+{
+	size_t *wd;
+	const size_t *ws;
+
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; (*d=*s) && ((uintptr_t)s & ALIGN); s++, d++);
+		if (!*s) return d;
+		wd=(void *)d; ws=(const void *)s;
+		for (; !HASZERO(*ws); *wd++ = *ws++);
+		d=(void *)wd; s=(const void *)ws;
+	}
+	for (; (*d=*s); s++, d++);
+
+	return d;
+}
+
+weak_alias(__stpcpy, stpcpy);
diff --git a/src/string/stpncpy.c b/src/string/stpncpy.c
new file mode 100644
index 00000000..a877f5fe
--- /dev/null
+++ b/src/string/stpncpy.c
@@ -0,0 +1,32 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpncpy(char *d, const char *s, size_t n)
+{
+	size_t *wd;
+	const size_t *ws;
+
+	if (((uintptr_t)s & ALIGN) != ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (!n || !*s) goto tail;
+		wd=(void *)d; ws=(const void *)s;
+		for (; n>=sizeof(size_t) && !HASZERO(*ws);
+		       n-=sizeof(size_t), ws++, *wd++) *wd = *ws;
+		d=(void *)wd; s=(const void *)ws;
+	}
+	for (; n && (*d=*s); n--, s++, d++);
+tail:
+	memset(d, 0, n);
+	return d;
+}
+
+weak_alias(__stpncpy, stpncpy);
+
diff --git a/src/string/strcasecmp.c b/src/string/strcasecmp.c
new file mode 100644
index 00000000..dd879052
--- /dev/null
+++ b/src/string/strcasecmp.c
@@ -0,0 +1,9 @@
+#include <strings.h>
+#include <ctype.h>
+
+int strcasecmp(const char *_l, const char *_r)
+{
+	const unsigned char *l=_l, *r=_r;
+	for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);
+	return tolower(*l) - tolower(*r);
+}
diff --git a/src/string/strcasestr.c b/src/string/strcasestr.c
new file mode 100644
index 00000000..f1cb0e84
--- /dev/null
+++ b/src/string/strcasestr.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strcasestr(const char *h, const char *n)
+{
+	//FIXME!
+	return strstr(h, n);
+}
diff --git a/src/string/strcat.c b/src/string/strcat.c
new file mode 100644
index 00000000..29fdb611
--- /dev/null
+++ b/src/string/strcat.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strcat(char *dest, const char *src)
+{
+	strcpy(dest + strlen(dest), src);
+	return dest;
+}
diff --git a/src/string/strchr.c b/src/string/strchr.c
new file mode 100644
index 00000000..e606f4fe
--- /dev/null
+++ b/src/string/strchr.c
@@ -0,0 +1,23 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *strchr(const char *s, int c)
+{
+	c = (char)c;
+	if (!c) return (char *)s + strlen(s);
+	for (; ((uintptr_t)s & ALIGN) && *s && *s != c; s++);
+	if (*s && *s != c) {
+		const size_t *w;
+		size_t k = ONES * c;
+		for (w = (const void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
+		for (s = (const void *)w; *s && *s != c; s++);
+	}
+	return *s ? (char *)s : 0;
+}
diff --git a/src/string/strchrnul.c b/src/string/strchrnul.c
new file mode 100644
index 00000000..5e0c1a1a
--- /dev/null
+++ b/src/string/strchrnul.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strchrnul(const char *s, int c)
+{
+	char *p = strchr(s, c);
+	return p ? p : (char *)s + strlen(s);
+}
diff --git a/src/string/strcmp.c b/src/string/strcmp.c
new file mode 100644
index 00000000..91eb7404
--- /dev/null
+++ b/src/string/strcmp.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+int strcmp(const char *l, const char *r)
+{
+	for (; *l==*r && *l && *r; l++, r++);
+	return *(unsigned char *)l - *(unsigned char *)r;
+}
diff --git a/src/string/strcpy.c b/src/string/strcpy.c
new file mode 100644
index 00000000..7675e9ce
--- /dev/null
+++ b/src/string/strcpy.c
@@ -0,0 +1,16 @@
+#include <string.h>
+
+char *__stpcpy(char *, const char *);
+
+char *strcpy(char *dest, const char *src)
+{
+#if 1
+	__stpcpy(dest, src);
+	return dest;
+#else
+	const unsigned char *s = src;
+	unsigned char *d = dest;
+	while ((*d++ = *s++));
+	return dest;
+#endif
+}
diff --git a/src/string/strcspn.c b/src/string/strcspn.c
new file mode 100644
index 00000000..439b7be4
--- /dev/null
+++ b/src/string/strcspn.c
@@ -0,0 +1,20 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+size_t strcspn(const char *_s, const char *_c)
+{
+	const unsigned char *s = _s;
+	const unsigned char *c = _c;
+	const unsigned char *a = s;
+	size_t byteset[32/sizeof(size_t)];
+
+	if (!c[0]) return strlen(s);
+	if (!c[1]) return (s=strchr(s, *c)) ? s-a : strlen(a);
+
+	memset(byteset, 0, sizeof byteset);
+	for (; *c && BITOP(byteset, *c, |=); c++);
+	for (; *s && !BITOP(byteset, *s, &); s++);
+	return s-a;
+}
diff --git a/src/string/strdup.c b/src/string/strdup.c
new file mode 100644
index 00000000..dd5f80c1
--- /dev/null
+++ b/src/string/strdup.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+char *__strdup(const char *s)
+{
+	size_t l = strlen(s);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	return memcpy(d, s, l+1);
+}
+
+weak_alias(__strdup, strdup);
diff --git a/src/string/strerror_r.c b/src/string/strerror_r.c
new file mode 100644
index 00000000..6fdd4ce2
--- /dev/null
+++ b/src/string/strerror_r.c
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <errno.h>
+
+int strerror_r(int err, char *buf, size_t buflen)
+{
+	char *msg = strerror(err);
+	if (strlen(msg) >= buflen)
+		return ERANGE;
+	strcpy(buf, msg);
+	return 0;
+}
diff --git a/src/string/strlcat.c b/src/string/strlcat.c
new file mode 100644
index 00000000..a6b94c4c
--- /dev/null
+++ b/src/string/strlcat.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+size_t strlcat(char *d, const char *s, size_t n)
+{
+	size_t l = strnlen(d, n);
+	if (l == n) return l + strlen(s);
+	return l + strlcpy(d+l, s, n-l);
+}
diff --git a/src/string/strlcpy.c b/src/string/strlcpy.c
new file mode 100644
index 00000000..bbebf1db
--- /dev/null
+++ b/src/string/strlcpy.c
@@ -0,0 +1,32 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlcpy(char *d, const char *s, size_t n)
+{
+	char *d0 = d;
+	size_t *wd;
+	const size_t *ws;
+
+	if (!n--) goto finish;
+	if (((uintptr_t)s & ALIGN) != ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (n && *s) {
+			wd=(void *)d; ws=(const void *)s;
+			for (; n>=sizeof(size_t) && !HASZERO(*ws);
+			       n-=sizeof(size_t), ws++, *wd++) *wd = *ws;
+			d=(void *)wd; s=(const void *)ws;
+		}
+	}
+	for (; n && (*d=*s); n--, s++, d++);
+	*d = 0;
+finish:
+	return d-d0 + strlen(s);
+}
diff --git a/src/string/strlen.c b/src/string/strlen.c
new file mode 100644
index 00000000..936fb5cf
--- /dev/null
+++ b/src/string/strlen.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlen(const char *s)
+{
+	const char *a = s;
+	const size_t *w;
+	for (; ((uintptr_t)s & ALIGN) && *s; s++);
+	if (*s) {
+		for (w = (const void *)s; !HASZERO(*w); w++);
+		for (s = (const void *)w; *s; s++);
+	}
+	return s-a;
+}
diff --git a/src/string/strncasecmp.c b/src/string/strncasecmp.c
new file mode 100644
index 00000000..4f9230e1
--- /dev/null
+++ b/src/string/strncasecmp.c
@@ -0,0 +1,10 @@
+#include <strings.h>
+#include <ctype.h>
+
+int strncasecmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=_l, *r=_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);
+	return tolower(*l) - tolower(*r);
+}
diff --git a/src/string/strncat.c b/src/string/strncat.c
new file mode 100644
index 00000000..255b7a72
--- /dev/null
+++ b/src/string/strncat.c
@@ -0,0 +1,10 @@
+#include <string.h>
+
+char *strncat(char *d, const char *s, size_t n)
+{
+	char *a = d;
+	d += strlen(d);
+	while (n && (*d++ = *s++)) n--;
+	*d++ = 0;
+	return a;
+}
diff --git a/src/string/strncmp.c b/src/string/strncmp.c
new file mode 100644
index 00000000..52ba0323
--- /dev/null
+++ b/src/string/strncmp.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+int strncmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=_l, *r=_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && *l == *r ; l++, r++, n--);
+	return *l - *r;
+}
diff --git a/src/string/strncpy.c b/src/string/strncpy.c
new file mode 100644
index 00000000..c0cd7974
--- /dev/null
+++ b/src/string/strncpy.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+char *__stpncpy(char *, const char *, size_t);
+
+char *strncpy(char *d, const char *s, size_t n)
+{
+	__stpncpy(d, s, n);
+	return d;
+}
diff --git a/src/string/strndup.c b/src/string/strndup.c
new file mode 100644
index 00000000..617d27ba
--- /dev/null
+++ b/src/string/strndup.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <string.h>
+
+char *strndup(const char *s, size_t n)
+{
+	size_t l = strnlen(s, n);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	memcpy(d, s, l);
+	d[l] = 0;
+	return d;
+}
diff --git a/src/string/strnlen.c b/src/string/strnlen.c
new file mode 100644
index 00000000..6442eb79
--- /dev/null
+++ b/src/string/strnlen.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+size_t strnlen(const char *s, size_t n)
+{
+	const char *p = memchr(s, 0, n);
+	return p ? p-s : n;
+}
diff --git a/src/string/strpbrk.c b/src/string/strpbrk.c
new file mode 100644
index 00000000..55947c64
--- /dev/null
+++ b/src/string/strpbrk.c
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strpbrk(const char *s, const char *b)
+{
+	s += strcspn(s, b);
+	return *s ? (char *)s : 0;
+}
diff --git a/src/string/strrchr.c b/src/string/strrchr.c
new file mode 100644
index 00000000..31c8e0b8
--- /dev/null
+++ b/src/string/strrchr.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+char *strrchr(const char *s, int c)
+{
+	const char *p;
+	c = (char)c;
+	for (p=s+strlen(s); p>=s && *p!=c; p--);
+	return p>=s ? (char *)p : 0;
+}
diff --git a/src/string/strsep.c b/src/string/strsep.c
new file mode 100644
index 00000000..1bfe1db1
--- /dev/null
+++ b/src/string/strsep.c
@@ -0,0 +1,12 @@
+#include <string.h>
+
+char *strsep(char **str, const char *sep)
+{
+	char *s = *str, *end;
+	if (!s) return NULL;
+	end = s + strcspn(s, sep);
+	if (*end) *end++ = 0;
+	else end = 0;
+	*str = end;
+	return s;
+}
diff --git a/src/string/strsignal.c b/src/string/strsignal.c
new file mode 100644
index 00000000..72fba8d1
--- /dev/null
+++ b/src/string/strsignal.c
@@ -0,0 +1,98 @@
+#include <signal.h>
+
+#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \
+ && (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \
+ && (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \
+ && (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \
+ && (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \
+ && (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \
+ && (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \
+ && (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)
+
+#define sigmap(x) x
+
+#else
+
+static const char map[] = {
+	[SIGHUP]    = 1,
+	[SIGINT]    = 2,
+	[SIGQUIT]   = 3,
+	[SIGILL]    = 4,
+	[SIGTRAP]   = 5,
+	[SIGABRT]   = 6,
+	[SIGBUS]    = 7,
+	[SIGFPE]    = 8,
+	[SIGKILL]   = 9,
+	[SIGUSR1]   = 10,
+	[SIGSEGV]   = 11,
+	[SIGUSR2]   = 12,
+	[SIGPIPE]   = 13,
+	[SIGALRM]   = 14,
+	[SIGTERM]   = 15,
+	[SIGSTKFLT] = 16,
+	[SIGCHLD]   = 17,
+	[SIGCONT]   = 18,
+	[SIGSTOP]   = 19,
+	[SIGTSTP]   = 20,
+	[SIGTTIN]   = 21,
+	[SIGTTOU]   = 22,
+	[SIGURG]    = 23,
+	[SIGXCPU]   = 24,
+	[SIGXFSZ]   = 25,
+	[SIGVTALRM] = 26,
+	[SIGPROF]   = 27,
+	[SIGWINCH]  = 28,
+	[SIGPOLL]   = 29,
+	[SIGPWR]    = 30,
+	[SIGSYS]    = 31
+};
+
+#define sigmap(x) ((unsigned)(x) > sizeof map ? 0 : map[(unsigned)(x)])
+
+#endif
+
+static const char strings[] =
+	"Unknown signal\0"
+	"Hangup\0"
+	"Interrupt\0"
+	"Quit\0"
+	"Illegal instruction\0"
+	"Trace/breakpoint trap\0"
+	"Aborted\0"
+	"Bus error\0"
+	"Floating point exception\0"
+	"Killed\0"
+	"User defined signal 1\0"
+	"Segmentation fault\0"
+	"User defined signal 2\0"
+	"Broken pipe\0"
+	"Alarm clock\0"
+	"Terminated\0"
+	"Stack fault\0"
+	"Child exited\0"
+	"Continued\0"
+	"Stopped (signal)\0"
+	"Stopped\0"
+	"Stopped (tty input)\0"
+	"Stopped (tty output)\0"
+	"Urgent I/O condition\0"
+	"CPU time limit exceeded\0"
+	"File size limit exceeded\0"
+	"Virtual timer expired\0"
+	"Profiling timer expired\0"
+	"Window changed\0"
+	"I/O possible\0"
+	"Power failure\0"
+	"Bad system call";
+
+char *strsignal(int signum)
+{
+	char *s = (char *)strings;
+
+	signum = sigmap(signum);
+	if ((unsigned)signum - 1 > 31) signum = 0;
+
+	for (; signum--; s++) for (; *s; s++);
+
+	return s;
+}
diff --git a/src/string/strspn.c b/src/string/strspn.c
new file mode 100644
index 00000000..59b063e5
--- /dev/null
+++ b/src/string/strspn.c
@@ -0,0 +1,22 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+size_t strspn(const char *_s, const char *_c)
+{
+	const unsigned char *s = _s;
+	const unsigned char *c = _c;
+	const unsigned char *a = s;
+	size_t byteset[32/sizeof(size_t)] = { 0 };
+
+	if (!c[0]) return 0;
+	if (!c[1]) {
+		for (; *s == *c; s++);
+		return s-a;
+	}
+
+	for (; *c && BITOP(byteset, *c, |=); c++);
+	for (; *s && BITOP(byteset, *s, &); s++);
+	return s-a;
+}
diff --git a/src/string/strstr.c b/src/string/strstr.c
new file mode 100644
index 00000000..4d536a73
--- /dev/null
+++ b/src/string/strstr.c
@@ -0,0 +1,166 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h++; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-1 : 0;
+}
+
+static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
+	return *h ? (char *)h-2 : 0;
+}
+
+static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-3 : 0;
+}
+
+#if 0
+static char *naive_strstr(const char *h, const char *n)
+{
+	size_t i;
+	for (i=0; n[i] && h[i]; i++)
+	for (   ; n[i] != h[i]; h++, i=0);
+	return n[i] ? 0 : (char *)h;
+}
+#endif
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
+{
+	const unsigned char *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (l=0; n[l] && h[l]; l++)
+		BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const char *z2 = memchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			//printf("adv by %zu (on %c) at [%s] (%zu;l=%zu)\n", k, h[l-1], h, shift[h[l-1]], l);
+			if (k) {
+				if (mem0 && mem && k < p) k = l-p;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k == mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+char *strstr(const char *h, const char *n)
+{
+	/* Return immediately on empty needle */
+	if (!n[0]) return (char *)h;
+
+	/* Use faster algorithms for short needles */
+	h = strchr(h, *n);
+	if (!h || !n[1]) return (char *)h;
+	if (!h[1]) return 0;
+	if (!n[2]) return twobyte_strstr(h, n);
+	if (!h[2]) return 0;
+	if (!n[3]) return threebyte_strstr(h, n);
+	if (!h[3]) return 0;
+	if (!n[4]) return fourbyte_strstr(h, n);
+
+	return twoway_strstr(h, n);
+}
diff --git a/src/string/strtok.c b/src/string/strtok.c
new file mode 100644
index 00000000..1ba221cb
--- /dev/null
+++ b/src/string/strtok.c
@@ -0,0 +1,13 @@
+#include <string.h>
+
+char *strtok(char *s, const char *sep)
+{
+	static char *p;
+	if (!s && !(s = p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return p = 0;
+	p = s + strcspn(s, sep);
+	if (*p) *p++ = 0;
+	else p = 0;
+	return s;
+}
diff --git a/src/string/strtok_r.c b/src/string/strtok_r.c
new file mode 100644
index 00000000..c763897a
--- /dev/null
+++ b/src/string/strtok_r.c
@@ -0,0 +1,12 @@
+#include <string.h>
+
+char *strtok_r(char *s, const char *sep, char **p)
+{
+	if (!s && !(s = *p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return *p = 0;
+	*p = s + strcspn(s, sep);
+	if (**p) *(*p)++ = 0;
+	else *p = 0;
+	return s;
+}
diff --git a/src/string/swab.c b/src/string/swab.c
new file mode 100644
index 00000000..b2132884
--- /dev/null
+++ b/src/string/swab.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+
+void swab(const void *_src, void *_dest, ssize_t n)
+{
+	const char *src = _src;
+	char *dest = _dest;
+	for (; n>0; n-=2) {
+		dest[0] = src[1];
+		dest[1] = src[0];
+		dest += 2;
+		src += 2;
+	}
+}
diff --git a/src/string/wcscat.c b/src/string/wcscat.c
new file mode 100644
index 00000000..946f16e2
--- /dev/null
+++ b/src/string/wcscat.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcscat(wchar_t *dest, const wchar_t *src)
+{
+	wcscpy(dest + wcslen(dest), src);
+	return dest;
+}
diff --git a/src/string/wcschr.c b/src/string/wcschr.c
new file mode 100644
index 00000000..8dfc2f31
--- /dev/null
+++ b/src/string/wcschr.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcschr(const wchar_t *s, wchar_t c)
+{
+	if (!c) return (wchar_t *)s + wcslen(s);
+	for (; *s && *s != c; s++);
+	return *s ? (wchar_t *)s : 0;
+}
diff --git a/src/string/wcscmp.c b/src/string/wcscmp.c
new file mode 100644
index 00000000..26eeee70
--- /dev/null
+++ b/src/string/wcscmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcscmp(const wchar_t *l, const wchar_t *r)
+{
+	for (; *l==*r && *l && *r; l++, r++);
+	return *l - *r;
+}
diff --git a/src/string/wcscpy.c b/src/string/wcscpy.c
new file mode 100644
index 00000000..e0ac194f
--- /dev/null
+++ b/src/string/wcscpy.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcscpy(wchar_t *d, const wchar_t *s)
+{
+	wchar_t *a = d;
+	while ((*d++ = *s++));
+	return a;
+}
diff --git a/src/string/wcscspn.c b/src/string/wcscspn.c
new file mode 100644
index 00000000..c4e52722
--- /dev/null
+++ b/src/string/wcscspn.c
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+size_t wcscspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	if (!c[0]) return wcslen(s);
+	if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
+	for (a=s; *s && !wcschr(c, *s); s++);
+	return s-a;
+}
diff --git a/src/string/wcslen.c b/src/string/wcslen.c
new file mode 100644
index 00000000..1b7b6655
--- /dev/null
+++ b/src/string/wcslen.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcslen(const wchar_t *s)
+{
+	const wchar_t *a;
+	for (a=s; *s; s++);
+	return s-a;
+}
diff --git a/src/string/wcsncat.c b/src/string/wcsncat.c
new file mode 100644
index 00000000..b07abe45
--- /dev/null
+++ b/src/string/wcsncat.c
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+wchar_t *wcsncat(wchar_t *d, const wchar_t *s, size_t n)
+{
+	wchar_t *a = d;
+	d += wcslen(d);
+	while (n && (*d++ = *s++)) n--;
+	*d++ = 0;
+	return a;
+}
diff --git a/src/string/wcsncmp.c b/src/string/wcsncmp.c
new file mode 100644
index 00000000..1b159f41
--- /dev/null
+++ b/src/string/wcsncmp.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r && *l && *r; l++, r++);
+	return n ? *l - *r : 0;
+}
diff --git a/src/string/wcsncpy.c b/src/string/wcsncpy.c
new file mode 100644
index 00000000..0164208d
--- /dev/null
+++ b/src/string/wcsncpy.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+
+wchar_t *wcsncpy(wchar_t *d, const wchar_t *s, size_t n)
+{
+	wchar_t *a = d;
+	while (n && (*d++ = *s++)) n--;
+	wmemset(d, 0, n);
+	return a;
+}
diff --git a/src/string/wcspbrk.c b/src/string/wcspbrk.c
new file mode 100644
index 00000000..0c72c197
--- /dev/null
+++ b/src/string/wcspbrk.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
+{
+	s += wcscspn(s, b);
+	return *s ? (wchar_t *)s : NULL;
+}
diff --git a/src/string/wcsrchr.c b/src/string/wcsrchr.c
new file mode 100644
index 00000000..7503475a
--- /dev/null
+++ b/src/string/wcsrchr.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcsrchr(const wchar_t *s, wint_t c)
+{
+	const wchar_t *p;
+	for (p=s+wcslen(s); p>=s && *p!=c; p--);
+	return p>=s ? (wchar_t *)p : 0;
+}
diff --git a/src/string/wcsspn.c b/src/string/wcsspn.c
new file mode 100644
index 00000000..4320d8f6
--- /dev/null
+++ b/src/string/wcsspn.c
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcsspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	for (a=s; *s && wcschr(c, *s); s++);
+	return s-a;
+}
diff --git a/src/string/wcsstr.c b/src/string/wcsstr.c
new file mode 100644
index 00000000..966174f8
--- /dev/null
+++ b/src/string/wcsstr.c
@@ -0,0 +1,117 @@
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+static wchar_t *naive_wcsstr(const wchar_t *h, const wchar_t *n)
+{
+	size_t i;
+	for (i=0; n[i] && h[i]; i++)
+	for (   ; n[i] != h[i]; h++, i=0);
+	return n[i] ? 0 : (wchar_t *)h;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
+{
+	const wchar_t *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+
+	/* Computing length of needle */
+	for (l=0; n[l] && h[l]; l++);
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (wmemcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const wchar_t *z2 = wmemchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k == mem) return (wchar_t *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+wchar_t *wcsstr(const wchar_t *h, const wchar_t *n)
+{
+	/* Return immediately on empty needle or haystack */
+	if (!n[0]) return (wchar_t *)h;
+	if (!h[0]) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = wcschr(h, *n);
+	if (!h || !n[1]) return (wchar_t *)h;
+	if (!h[1]) return 0;
+	if (!n[2] || !n[3] || !n[4]) return naive_wcsstr(h, n);
+
+	return twoway_wcsstr(h, n);
+}
diff --git a/src/string/wcswcs.c b/src/string/wcswcs.c
new file mode 100644
index 00000000..9cfe4ac4
--- /dev/null
+++ b/src/string/wcswcs.c
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
+{
+	return wcsstr(haystack, needle);
+}
diff --git a/src/string/wmemchr.c b/src/string/wmemchr.c
new file mode 100644
index 00000000..a3ee0e61
--- /dev/null
+++ b/src/string/wmemchr.c
@@ -0,0 +1,8 @@
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
+{
+	for (; n && *s != c; s++);
+	return n ? (wchar_t *)s : 0;
+}
diff --git a/src/string/wmemcmp.c b/src/string/wmemcmp.c
new file mode 100644
index 00000000..6788a383
--- /dev/null
+++ b/src/string/wmemcmp.c
@@ -0,0 +1,8 @@
+#include <string.h>
+#include <wchar.h>
+
+int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
diff --git a/src/string/wmemcpy.c b/src/string/wmemcpy.c
new file mode 100644
index 00000000..330e37c7
--- /dev/null
+++ b/src/string/wmemcpy.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *wmemcpy(wchar_t *d, const wchar_t *s, size_t n)
+{
+	wchar_t *a = d;
+	while (n--) *d++ = *s++;
+	return a;
+}
diff --git a/src/string/wmemmove.c b/src/string/wmemmove.c
new file mode 100644
index 00000000..49608cae
--- /dev/null
+++ b/src/string/wmemmove.c
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
+{
+	if ((size_t)(d-s) < n) {
+		while (n--) d[n] = s[n];
+		return d;
+	}
+	return wmemcpy(d, s, n);
+}
diff --git a/src/string/wmemset.c b/src/string/wmemset.c
new file mode 100644
index 00000000..1a2a8618
--- /dev/null
+++ b/src/string/wmemset.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <wchar.h>
+
+wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
+{
+	wchar_t *ret = d;
+	while (n--) *d++ = c;
+	return ret;
+}
diff --git a/src/stub/utmpx.c b/src/stub/utmpx.c
new file mode 100644
index 00000000..32003969
--- /dev/null
+++ b/src/stub/utmpx.c
@@ -0,0 +1,30 @@
+#include <utmpx.h>
+#include <stddef.h>
+
+void endutxent(void)
+{
+}
+
+void setutxent(void)
+{
+}
+
+struct utmpx *getutxent(void)
+{
+	return NULL;
+}
+
+struct utmpx *getutxid(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *getutxline(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *pututxline(const struct utmpx *ut)
+{
+	return NULL;
+}
diff --git a/src/temp/mkdtemp.c b/src/temp/mkdtemp.c
new file mode 100644
index 00000000..f8b067ec
--- /dev/null
+++ b/src/temp/mkdtemp.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include "libc.h"
+
+char *mkdtemp(char *template)
+{
+	for (;;) {
+		if (!mktemp(template)) return 0;
+		if (!mkdir(template, 0700)) return template;
+		if (errno != EEXIST) return 0;
+		/* this is safe because mktemp verified
+		 * that we have a valid template string */
+		strcpy(template+strlen(template)-6, "XXXXXX");
+	}
+}
diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
new file mode 100644
index 00000000..b1567191
--- /dev/null
+++ b/src/temp/mkstemp.c
@@ -0,0 +1,26 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int mkstemp(char *template)
+{
+	int fd;
+retry:
+	if (!mktemp(template)) return -1;
+	fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
+	if (fd >= 0) return fd;
+	if (errno == EEXIST) {
+		/* this is safe because mktemp verified
+		 * that we have a valid template string */
+		strcpy(template+strlen(template)-6, "XXXXXX");
+		goto retry;
+	}
+	return -1;
+}
+
+LFS64(mkstemp);
diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c
new file mode 100644
index 00000000..8638e087
--- /dev/null
+++ b/src/temp/mktemp.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include "libc.h"
+
+char *mktemp(char *template)
+{
+	static int lock;
+	static int index;
+	int l = strlen(template);
+
+	if (l < 6 || strcmp(template+l-6, "XXXXXX")) {
+		errno = EINVAL;
+		return NULL;
+	}
+	LOCK(&lock);
+	for (; index < 1000000; index++) {
+		snprintf(template+l-6, 6, "%06d", index);
+		if (access(template, F_OK) != 0) {
+			UNLOCK(&lock);
+			return template;
+		}
+	}
+	UNLOCK(&lock);
+	return NULL;	
+}
diff --git a/src/termios/cfgetospeed.c b/src/termios/cfgetospeed.c
new file mode 100644
index 00000000..0ebc198c
--- /dev/null
+++ b/src/termios/cfgetospeed.c
@@ -0,0 +1,12 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+speed_t cfgetospeed(const struct termios *tio)
+{
+	return tio->c_cflag & CBAUD;
+}
+
+speed_t cfgetispeed(const struct termios *tio)
+{
+	return cfgetospeed(tio);
+}
diff --git a/src/termios/cfsetospeed.c b/src/termios/cfsetospeed.c
new file mode 100644
index 00000000..80c790f1
--- /dev/null
+++ b/src/termios/cfsetospeed.c
@@ -0,0 +1,22 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "libc.h"
+
+int cfsetospeed(struct termios *tio, speed_t speed)
+{
+	if (speed & ~CBAUD) {
+		errno = EINVAL;
+		return -1;
+	}
+	tio->c_cflag &= ~CBAUD;
+	tio->c_cflag |= speed;
+	return 0;
+}
+
+int cfsetispeed(struct termios *tio, speed_t speed)
+{
+	return speed ? cfsetospeed(tio, speed) : 0;
+}
+
+weak_alias(cfsetospeed, cfsetspeed);
diff --git a/src/termios/tcdrain.c b/src/termios/tcdrain.c
new file mode 100644
index 00000000..c51dd401
--- /dev/null
+++ b/src/termios/tcdrain.c
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcdrain(int fd)
+{
+	return ioctl(fd, TCSBRK, 1);
+}
diff --git a/src/termios/tcflow.c b/src/termios/tcflow.c
new file mode 100644
index 00000000..c7fc3fe2
--- /dev/null
+++ b/src/termios/tcflow.c
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflow(int fd, int action)
+{
+	return ioctl(fd, TCXONC, action);
+}
diff --git a/src/termios/tcflush.c b/src/termios/tcflush.c
new file mode 100644
index 00000000..50222669
--- /dev/null
+++ b/src/termios/tcflush.c
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflush(int fd, int queue)
+{
+	return ioctl(fd, TCFLSH, queue);
+}
diff --git a/src/termios/tcgetattr.c b/src/termios/tcgetattr.c
new file mode 100644
index 00000000..d9ce786e
--- /dev/null
+++ b/src/termios/tcgetattr.c
@@ -0,0 +1,10 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <string.h>
+
+int tcgetattr(int fd, struct termios *tio)
+{
+	if (ioctl(fd, TCGETS, tio))
+		return -1;
+	return 0;
+}
diff --git a/src/termios/tcgetsid.c b/src/termios/tcgetsid.c
new file mode 100644
index 00000000..1053fd64
--- /dev/null
+++ b/src/termios/tcgetsid.c
@@ -0,0 +1,10 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetsid(int fd)
+{
+	int sid;
+	if (ioctl(fd, TIOCGSID, &sid) < 0)
+		return -1;
+	return sid;
+}
diff --git a/src/termios/tcsendbreak.c b/src/termios/tcsendbreak.c
new file mode 100644
index 00000000..b6df0a23
--- /dev/null
+++ b/src/termios/tcsendbreak.c
@@ -0,0 +1,8 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsendbreak(int fd, int dur)
+{
+	/* nonzero duration is implementation-defined, so ignore it */
+	return ioctl(fd, TCSBRK, 0);
+}
diff --git a/src/termios/tcsetattr.c b/src/termios/tcsetattr.c
new file mode 100644
index 00000000..e9a168f3
--- /dev/null
+++ b/src/termios/tcsetattr.c
@@ -0,0 +1,13 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <errno.h>
+
+int tcsetattr(int fd, int act, const struct termios *tio)
+{
+	if (act < 0 || act > 2) {
+		errno = EINVAL;
+		return -1;
+	}
+	return ioctl(fd, TCSETS+act, tio);
+}
diff --git a/src/thread/__futex.c b/src/thread/__futex.c
new file mode 100644
index 00000000..93352fa3
--- /dev/null
+++ b/src/thread/__futex.c
@@ -0,0 +1,8 @@
+#include "futex.h"
+#include "syscall.h"
+
+int __futex(volatile int *addr, int op, int val, void *ts)
+{
+	return syscall4(__NR_futex, (long)addr, op, val, (long)ts);
+}
+
diff --git a/src/thread/__lock.c b/src/thread/__lock.c
new file mode 100644
index 00000000..557c6a62
--- /dev/null
+++ b/src/thread/__lock.c
@@ -0,0 +1,12 @@
+#define SYSCALL_RETURN_ERRNO
+#include "pthread_impl.h"
+
+void __lock(volatile int *l)
+{
+	int spins=100000;
+	/* Do not use futexes because we insist that unlocking is a simple
+	 * assignment to optimize non-pathological code with no contention. */
+	while (a_xchg(l, 1))
+		if (spins) spins--, a_spin();
+		else syscall0(__NR_sched_yield);
+}
diff --git a/src/thread/__set_thread_area.c b/src/thread/__set_thread_area.c
new file mode 100644
index 00000000..576d8b40
--- /dev/null
+++ b/src/thread/__set_thread_area.c
@@ -0,0 +1,9 @@
+#include "syscall.h"
+
+int __set_thread_area(unsigned long *desc)
+{
+	if (syscall1(__NR_set_thread_area, (long)desc) < 0)
+		return -1;
+	__asm__ __volatile__ ( "movw %w0,%%gs" : : "r"(desc[0]*8+3) );
+	return 0;
+}
diff --git a/src/thread/__timedwait.c b/src/thread/__timedwait.c
new file mode 100644
index 00000000..354def2c
--- /dev/null
+++ b/src/thread/__timedwait.c
@@ -0,0 +1,21 @@
+#include <time.h>
+#include <errno.h>
+#include "futex.h"
+#define SYSCALL_RETURN_ERRNO
+#include "syscall.h"
+#include <stdio.h>
+int __timedwait(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv)
+{
+	struct timespec to;
+	if (at) {
+		clock_gettime(clk, &to);
+		to.tv_sec = at->tv_sec - to.tv_sec;
+		if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) {
+			to.tv_sec--;
+			to.tv_nsec += 1000000000;
+		}
+		if (to.tv_sec < 0) return ETIMEDOUT;
+	}
+	if (priv) priv = 128; priv=0;
+	return syscall4(__NR_futex, (long)addr, FUTEX_WAIT | priv, val, at ? (long)&to : 0);
+}
diff --git a/src/thread/__unmapself.c b/src/thread/__unmapself.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/thread/__unmapself.c
diff --git a/src/thread/__wait.c b/src/thread/__wait.c
new file mode 100644
index 00000000..8c249cd3
--- /dev/null
+++ b/src/thread/__wait.c
@@ -0,0 +1,16 @@
+#define SYSCALL_RETURN_ERRNO
+#include "pthread_impl.h"
+
+void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
+{
+	int spins=50000;
+	if (priv) priv = 128; priv=0;
+	while (spins--) {
+		if (*addr==val) a_spin();
+		else return;
+	}
+	if (waiters) a_inc(waiters);
+	while (*addr==val)
+		syscall4(__NR_futex, (long)addr, FUTEX_WAIT|priv, val, 0);
+	if (waiters) a_dec(waiters);
+}
diff --git a/src/thread/__wake.c b/src/thread/__wake.c
new file mode 100644
index 00000000..048ddcc0
--- /dev/null
+++ b/src/thread/__wake.c
@@ -0,0 +1,9 @@
+#define SYSCALL_RETURN_ERRNO
+#include "pthread_impl.h"
+
+void __wake(volatile int *addr, int cnt, int priv)
+{
+	if (priv) priv = 128; priv=0;
+	if (cnt<0) cnt = INT_MAX;
+	syscall3(__NR_futex, (long)addr, FUTEX_WAKE | priv, cnt);
+}
diff --git a/src/thread/cancellation.c b/src/thread/cancellation.c
new file mode 100644
index 00000000..e35ba824
--- /dev/null
+++ b/src/thread/cancellation.c
@@ -0,0 +1,22 @@
+#include "pthread_impl.h"
+
+void __pthread_register_cancel(struct __ptcb *cb)
+{
+	struct pthread *self = pthread_self();
+	cb->__next = self->cancelbuf;
+	self->cancelbuf = cb;
+}
+
+#define pthread_self __pthread_self
+
+void __pthread_unregister_cancel(struct __ptcb *cb)
+{
+	struct pthread *self = pthread_self();
+	self->cancelbuf = self->cancelbuf->__next;
+}
+
+void __pthread_unwind_next(struct __ptcb *cb)
+{
+	if (cb->__next) longjmp((void *)cb->__next->__jb, 1);
+	pthread_exit(PTHREAD_CANCELLED);
+}
diff --git a/src/thread/clone.c b/src/thread/clone.c
new file mode 100644
index 00000000..971bfeed
--- /dev/null
+++ b/src/thread/clone.c
@@ -0,0 +1,26 @@
+#if 0
+
+int clone(int (*start)(void *), void *stack, int flags, void *arg,
+	pid_t *ptid, struct user_desc *tls, pid_t *ctid)
+{
+	int ret;
+	__asm__(
+	        "andl $-16,%%ecx     \n\t"
+		"xchgl %%ebx,%2      \n\t"
+		"movl %%ebx,(%%ecx)  \n\t"
+		"int $0x80           \n\t"
+		"testl %%eax,%%eax   \n\t"
+		"jnz 1f              \n\t"
+		"xorl %%ebp,%%ebp    \n\t"
+		"call *%%ebx         \n\t"
+		"\n1:                \n\t"
+		"xchgl %%ebx,%2      \n\t"
+		: "=a" (ret)
+		: "a" (__NR_clone), "m" (flags), "c"(stack), "d"(ptid),
+		  "S" (tls), "D" (ctid)
+		: "memory"
+	);
+	return __syscall_ret(ret);
+}
+
+#endif
diff --git a/src/thread/i386/__unmapself.s b/src/thread/i386/__unmapself.s
new file mode 100644
index 00000000..5c674966
--- /dev/null
+++ b/src/thread/i386/__unmapself.s
@@ -0,0 +1,22 @@
+.text
+.global __unmapself
+.type   __unmapself,%function
+__unmapself:
+	call 1f
+	.long -1
+	.long -1
+1:	popl %ecx
+	xorl %ebx,%ebx
+	xorl %edx,%edx
+	movl $8,%esi
+	movl $175,%eax
+	int $128
+	movl $91,%eax
+	movl 4(%esp),%ebx
+	movl 8(%esp),%ecx
+	int $128
+	xorl %ebx,%ebx
+	movl $1,%eax
+	int $128
+
+.size __unmapself,.-__unmapself
diff --git a/src/thread/i386/clone.s b/src/thread/i386/clone.s
new file mode 100644
index 00000000..4f33366c
--- /dev/null
+++ b/src/thread/i386/clone.s
@@ -0,0 +1,35 @@
+.text
+.global __clone
+.type   __clone,%function
+__clone:
+	movl	8(%esp),%ecx
+	andl	$0xfffffff0, %ecx
+	subl	$28,%ecx
+	movl	16(%esp),%eax
+	movl	%eax,12(%ecx)
+	movl	4(%esp),%eax
+	movl	%eax,8(%ecx)
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	movl	$120,%eax
+	movl	12+12(%esp),%ebx
+	movl	20+12(%esp),%edx
+	movl	24+12(%esp),%esi
+	movl	28+12(%esp),%edi
+	int	$128
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	test	%eax,%eax
+	jnz	1f
+	xorl	%ebp,%ebp
+	call	*%ebx
+	movl	%eax, %ebx
+	movl	$1, %eax
+	int	$128
+1:	
+	movl %eax, 4(%esp)
+	ret
+
+.size __clone,.-__clone
diff --git a/src/thread/pthread_attr_destroy.c b/src/thread/pthread_attr_destroy.c
new file mode 100644
index 00000000..b5845dd0
--- /dev/null
+++ b/src/thread/pthread_attr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_attr_destroy(pthread_attr_t *a)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_attr_getdetachstate.c b/src/thread/pthread_attr_getdetachstate.c
new file mode 100644
index 00000000..9cd49536
--- /dev/null
+++ b/src/thread/pthread_attr_getdetachstate.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getdetachstate(pthread_attr_t *a, int *state)
+{
+	*state = a->__detach;
+	return 0;
+}
diff --git a/src/thread/pthread_attr_getguardsize.c b/src/thread/pthread_attr_getguardsize.c
new file mode 100644
index 00000000..3f089c8c
--- /dev/null
+++ b/src/thread/pthread_attr_getguardsize.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getguardsize(pthread_attr_t *a, size_t *size)
+{
+	*size = a->__guardsize + DEFAULT_GUARD_SIZE;
+	return 0;
+}
diff --git a/src/thread/pthread_attr_getscope.c b/src/thread/pthread_attr_getscope.c
new file mode 100644
index 00000000..0cb224d3
--- /dev/null
+++ b/src/thread/pthread_attr_getscope.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getscope(pthread_attr_t *a, int *scope)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_attr_getstacksize.c b/src/thread/pthread_attr_getstacksize.c
new file mode 100644
index 00000000..40bbf186
--- /dev/null
+++ b/src/thread/pthread_attr_getstacksize.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getstacksize(pthread_attr_t *a, size_t *size)
+{
+	*size = a->__stacksize + DEFAULT_STACK_SIZE;
+	return 0;
+}
diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c
new file mode 100644
index 00000000..d91bf157
--- /dev/null
+++ b/src/thread/pthread_attr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_init(pthread_attr_t *a)
+{
+	memset(a, 0, sizeof *a);
+	return 0;
+}
diff --git a/src/thread/pthread_attr_setdetachstate.c b/src/thread/pthread_attr_setdetachstate.c
new file mode 100644
index 00000000..d23b4778
--- /dev/null
+++ b/src/thread/pthread_attr_setdetachstate.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
+{
+	a->__detach = state;
+	return 0;
+}
diff --git a/src/thread/pthread_attr_setguardsize.c b/src/thread/pthread_attr_setguardsize.c
new file mode 100644
index 00000000..e0e8d3fb
--- /dev/null
+++ b/src/thread/pthread_attr_setguardsize.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
+{
+	if (size > SIZE_MAX/8) return EINVAL;
+	a->__guardsize = size - DEFAULT_GUARD_SIZE;
+	return 0;
+}
diff --git a/src/thread/pthread_attr_setscope.c b/src/thread/pthread_attr_setscope.c
new file mode 100644
index 00000000..a970a819
--- /dev/null
+++ b/src/thread/pthread_attr_setscope.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setscope(pthread_attr_t *a, int scope)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_attr_setstacksize.c b/src/thread/pthread_attr_setstacksize.c
new file mode 100644
index 00000000..58f4bb18
--- /dev/null
+++ b/src/thread/pthread_attr_setstacksize.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
+{
+	if (size-PAGE_SIZE > SIZE_MAX/4) return EINVAL;
+	a->__stacksize = size - DEFAULT_STACK_SIZE;
+	return 0;
+}
diff --git a/src/thread/pthread_barrier_destroy.c b/src/thread/pthread_barrier_destroy.c
new file mode 100644
index 00000000..2898c41a
--- /dev/null
+++ b/src/thread/pthread_barrier_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_destroy(pthread_barrier_t *b)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_barrier_init.c b/src/thread/pthread_barrier_init.c
new file mode 100644
index 00000000..2cc67ed5
--- /dev/null
+++ b/src/thread/pthread_barrier_init.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_init(pthread_barrier_t *b, const pthread_barrierattr_t *a, unsigned count)
+{
+	if (!count) return EINVAL;
+	*b = (pthread_barrier_t){ .__limit = count-1 };
+	return 0;
+}
diff --git a/src/thread/pthread_barrier_wait.c b/src/thread/pthread_barrier_wait.c
new file mode 100644
index 00000000..02c252ad
--- /dev/null
+++ b/src/thread/pthread_barrier_wait.c
@@ -0,0 +1,31 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_wait(pthread_barrier_t *b)
+{
+	int cur;
+
+	/* Trivial case: count was set at 1 */
+	if (!b->__limit) return PTHREAD_BARRIER_SERIAL_THREAD;
+
+	/* Wait for anyone still suspended at previous use of barrier */
+	while ((cur=b->__left))
+		__wait(&b->__left, &b->__waiters, cur, 0);
+
+	/* If we are the last to reach barrier, reset it and wake others */
+	if (a_fetch_add(&b->__count, 1) == b->__limit) {
+		b->__left = b->__limit;
+		b->__count = 0;
+		__wake(&b->__count, -1, 0);
+		return PTHREAD_BARRIER_SERIAL_THREAD;
+	}
+
+	/* Wait for our peers to reach the barrier */
+	while ((cur=b->__count))
+		__wait(&b->__count, 0, cur, 0);
+
+	/* If we're the last to wake up and barrier is awaiting reuse */
+	if (a_fetch_add(&b->__left, -1) == 1 && b->__waiters)
+		__wake(&b->__left, -1, 0);
+
+	return 0;
+}
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
new file mode 100644
index 00000000..9397ffe9
--- /dev/null
+++ b/src/thread/pthread_cancel.c
@@ -0,0 +1,7 @@
+#define SYSCALL_RETURN_ERRNO
+#include "pthread_impl.h"
+
+int pthread_cancel(pthread_t t)
+{
+	return syscall3(__NR_tgkill, t->pid, t->tid, SIGCANCEL);
+}
diff --git a/src/thread/pthread_cond_broadcast.c b/src/thread/pthread_cond_broadcast.c
new file mode 100644
index 00000000..7a023b85
--- /dev/null
+++ b/src/thread/pthread_cond_broadcast.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_cond_broadcast(pthread_cond_t *c)
+{
+	c->__block = 0;
+	__wake(&c->__block, -1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_cond_destroy.c b/src/thread/pthread_cond_destroy.c
new file mode 100644
index 00000000..1d21a5a8
--- /dev/null
+++ b/src/thread/pthread_cond_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_cond_destroy(pthread_cond_t *c)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_cond_init.c b/src/thread/pthread_cond_init.c
new file mode 100644
index 00000000..33948606
--- /dev/null
+++ b/src/thread/pthread_cond_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a)
+{
+	memset(c, 0, sizeof *c);
+	return 0;
+}
diff --git a/src/thread/pthread_cond_signal.c b/src/thread/pthread_cond_signal.c
new file mode 100644
index 00000000..0dd9416b
--- /dev/null
+++ b/src/thread/pthread_cond_signal.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_cond_signal(pthread_cond_t *c)
+{
+	c->__block = 0;
+	__wake(&c->__block, 1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c
new file mode 100644
index 00000000..b67dded4
--- /dev/null
+++ b/src/thread/pthread_cond_timedwait.c
@@ -0,0 +1,26 @@
+#include "pthread_impl.h"
+
+static void relock(void *m)
+{
+	pthread_mutex_lock(m);
+}
+
+int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, const struct timespec *ts)
+{
+	int r, e=0;
+	CANCELPT(0);
+
+	pthread_cleanup_push(relock, m);
+	c->__block = 1;
+	if ((r=pthread_mutex_unlock(m))) return r;
+
+	CANCELPT(1);
+	e = __timedwait(&c->__block, 1, CLOCK_REALTIME, ts, 0);
+	CANCELPT(0);
+
+	pthread_cleanup_pop(0);
+	if ((r=pthread_mutex_lock(m))) return r;
+
+	CANCELPT(0);
+	return e;
+}
diff --git a/src/thread/pthread_cond_wait.c b/src/thread/pthread_cond_wait.c
new file mode 100644
index 00000000..eb70e5f7
--- /dev/null
+++ b/src/thread/pthread_cond_wait.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
+{
+	return pthread_cond_timedwait(c, m, 0);
+}
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
new file mode 100644
index 00000000..6fa484c7
--- /dev/null
+++ b/src/thread/pthread_create.c
@@ -0,0 +1,189 @@
+#include "pthread_impl.h"
+
+#define pthread_self __pthread_self
+
+static void docancel(struct pthread *self)
+{
+	struct __ptcb cb = { .__next = self->cancelbuf };
+	__pthread_unwind_next(&cb);
+}
+
+static void cancel_handler(int sig, siginfo_t *si, void *ctx)
+{
+	struct pthread *self = pthread_self();
+	self->cancel = 1;
+	if (self->canceldisable || (!self->cancelasync && !self->cancelpoint))
+		return;
+	docancel(self);
+}
+
+/* "rsyscall" is a mechanism by which a thread can synchronously force all
+ * other threads to perform an arbitrary syscall. It is necessary to work
+ * around the non-conformant implementation of setuid() et al on Linux,
+ * which affect only the calling thread and not the whole process. This
+ * implementation performs some tricks with signal delivery to work around
+ * the fact that it does not keep any list of threads in userspace. */
+
+static struct {
+	volatile int lock, hold, blocks, cnt;
+	unsigned long arg[6];
+	int nr;
+	int err;
+} rs;
+
+static void rsyscall_handler(int sig, siginfo_t *si, void *ctx)
+{
+	if (rs.cnt == libc.threads_minus_1) return;
+
+	if (syscall6(rs.nr, rs.arg[0], rs.arg[1], rs.arg[2],
+		rs.arg[3], rs.arg[4], rs.arg[5]) < 0 && !rs.err) rs.err=errno;
+
+	a_inc(&rs.cnt);
+	__wake(&rs.cnt, 1, 1);
+	while(rs.hold)
+		__wait(&rs.hold, 0, 1, 1);
+	a_dec(&rs.cnt);
+	if (!rs.cnt) __wake(&rs.cnt, 1, 1);
+}
+
+static int rsyscall(int nr, long a, long b, long c, long d, long e, long f)
+{
+	int i, ret;
+	sigset_t set = { 0 };
+	struct pthread *self = pthread_self();
+	sigaddset(&set, SIGSYSCALL);
+
+	LOCK(&rs.lock);
+	while ((i=rs.blocks))
+		__wait(&rs.blocks, 0, i, 1);
+
+	__libc_sigprocmask(SIG_BLOCK, &set, 0);
+
+	rs.nr = nr;
+	rs.arg[0] = a; rs.arg[1] = b;
+	rs.arg[2] = c; rs.arg[3] = d;
+	rs.arg[4] = d; rs.arg[5] = f;
+	rs.hold = 1;
+	rs.err = 0;
+	rs.cnt = 0;
+
+	/* Dispatch signals until all threads respond */
+	for (i=libc.threads_minus_1; i; i--)
+		sigqueue(self->pid, SIGSYSCALL, (union sigval){0});
+	while ((i=rs.cnt) < libc.threads_minus_1) {
+		sigqueue(self->pid, SIGSYSCALL, (union sigval){0});
+		__wait(&rs.cnt, 0, i, 1);
+	}
+
+	/* Handle any lingering signals with no-op */
+	__libc_sigprocmask(SIG_UNBLOCK, &set, 0);
+
+	/* Resume other threads' signal handlers and wait for them */
+	rs.hold = 0;
+	__wake(&rs.hold, -1, 0);
+	while((i=rs.cnt)) __wait(&rs.cnt, 0, i, 1);
+
+	if (rs.err) errno = rs.err, ret = -1;
+	else ret = syscall6(nr, a, b, c, d, e, f);
+
+	UNLOCK(&rs.lock);
+	return ret;
+}
+
+static void cancelpt(int x)
+{
+	struct pthread *self = pthread_self();
+	if (self->canceldisable) return;
+	self->cancelpoint = x;
+	if (self->cancel) docancel(self);
+}
+
+static void init_threads()
+{
+	struct sigaction sa = { .sa_flags = SA_SIGINFO | SA_RESTART };
+	libc.lock = __lock;
+	libc.cancelpt = cancelpt;
+	libc.rsyscall = rsyscall;
+	sa.sa_sigaction = cancel_handler;
+	__libc_sigaction(SIGCANCEL, &sa, 0);
+	sigaddset(&sa.sa_mask, SIGSYSCALL);
+	sigaddset(&sa.sa_mask, SIGCANCEL);
+	sa.sa_sigaction = rsyscall_handler;
+	__libc_sigaction(SIGSYSCALL, &sa, 0);
+	sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
+}
+
+static int start(void *p)
+{
+	struct pthread *self = p;
+	pthread_exit(self->start(self->start_arg));
+	return 0;
+}
+
+#undef pthread_self
+
+#define CLONE_MAGIC 0x7d0f00
+int __clone(int (*)(void *), void *, int, void *, pid_t *, void *, pid_t *);
+
+#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)
+
+/* pthread_key_create.c overrides this */
+static const size_t dummy = 0;
+weak_alias(dummy, __pthread_tsd_size);
+
+int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(void *), void *arg)
+{
+	static int init;
+	int ret;
+	size_t size, guard;
+	struct pthread *self = pthread_self(), *new;
+	unsigned char *map, *stack, *tsd;
+	static const pthread_attr_t default_attr;
+
+	if (!self) return errno = ENOSYS;
+	if (!init && ++init) init_threads();
+
+	if (!attr) attr = &default_attr;
+	guard = ROUND(attr->__guardsize + DEFAULT_GUARD_SIZE);
+	size = guard + ROUND(attr->__stacksize + DEFAULT_STACK_SIZE);
+	size += __pthread_tsd_size;
+	map = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
+	if (!map) return EAGAIN;
+	mprotect(map, guard, PROT_NONE);
+
+	tsd = map + size - __pthread_tsd_size;
+	new = (void *)(tsd - sizeof *new - PAGE_SIZE%sizeof *new);
+	new->map_base = map;
+	new->map_size = size;
+	new->pid = self->pid;
+	new->errno_ptr = &new->errno_val;
+	new->start = entry;
+	new->start_arg = arg;
+	new->self = new;
+	new->tsd = (void *)tsd;
+	new->detached = attr->__detach;
+	new->attr = *attr;
+	memcpy(new->tlsdesc, self->tlsdesc, sizeof new->tlsdesc);
+	new->tlsdesc[1] = (uintptr_t)new;
+	stack = (void *)((uintptr_t)new-1 & ~(uintptr_t)15);
+
+	/* We must synchronize new thread creation with rsyscall
+	 * delivery. This looks to be the least expensive way: */
+	a_inc(&rs.blocks);
+	while (rs.lock) __wait(&rs.lock, 0, 1, 1);
+
+	a_inc(&libc.threads_minus_1);
+	ret = __clone(start, stack, CLONE_MAGIC, new,
+		&new->tid, &new->tlsdesc, &new->tid);
+
+	a_dec(&rs.blocks);
+	if (rs.lock) __wake(&rs.blocks, 1, 1);
+
+	if (ret < 0) {
+		a_dec(&libc.threads_minus_1);
+		munmap(map, size);
+		return -ret;
+	}
+	*res = new;
+	return 0;
+}
diff --git a/src/thread/pthread_detach.c b/src/thread/pthread_detach.c
new file mode 100644
index 00000000..f0eae3e8
--- /dev/null
+++ b/src/thread/pthread_detach.c
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_detach(pthread_t t)
+{
+	/* Cannot detach a thread that's already exiting */
+	if (a_xchg(&t->exitlock, 1))
+		return pthread_join(t, 0);
+	t->detached = 1;
+	t->exitlock = 0;
+	return 0;
+}
diff --git a/src/thread/pthread_equal.c b/src/thread/pthread_equal.c
new file mode 100644
index 00000000..a55d280c
--- /dev/null
+++ b/src/thread/pthread_equal.c
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_equal(pthread_t a, pthread_t b)
+{
+	return a==b;
+}
diff --git a/src/thread/pthread_exit.c b/src/thread/pthread_exit.c
new file mode 100644
index 00000000..4966e234
--- /dev/null
+++ b/src/thread/pthread_exit.c
@@ -0,0 +1,25 @@
+#include "pthread_impl.h"
+
+#undef pthread_self
+
+void pthread_exit(void *result)
+{
+	int i;
+	struct pthread *self = pthread_self();
+	self->result = result;
+
+	a_dec(&libc.threads_minus_1);
+	if (libc.threads_minus_1 < 0)
+		exit(0);
+
+	LOCK(&self->exitlock);
+
+	if (self->tsd_used) for (i=0; i<PTHREAD_KEYS_MAX; i++)
+		if (self->tsd[i] && libc.tsd_keys[i])
+			libc.tsd_keys[i](self->tsd[i]);
+
+	if (self->detached && self->map_base)
+		__unmapself(self->map_base, self->map_size);
+
+	__syscall_exit(0);
+}
diff --git a/src/thread/pthread_getspecific.c b/src/thread/pthread_getspecific.c
new file mode 100644
index 00000000..a6ca27d0
--- /dev/null
+++ b/src/thread/pthread_getspecific.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+void *pthread_getspecific(pthread_key_t k)
+{
+	struct pthread *self = pthread_self();
+	if (!self->tsd) return 0;
+	return self->tsd[k];
+}
diff --git a/src/thread/pthread_join.c b/src/thread/pthread_join.c
new file mode 100644
index 00000000..5210ed48
--- /dev/null
+++ b/src/thread/pthread_join.c
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int pthread_join(pthread_t t, void **res)
+{
+	int tmp = t->tid;
+	CANCELPT_BEGIN;
+	if (tmp) __wait(&t->tid, 0, tmp, 1);
+	CANCELPT_END;
+	if (res) *res = t->result;
+	if (t->map_base) munmap(t->map_base, t->map_size);
+	return 0;
+}
diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c
new file mode 100644
index 00000000..efc38046
--- /dev/null
+++ b/src/thread/pthread_key_create.c
@@ -0,0 +1,25 @@
+#include "pthread_impl.h"
+
+const size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
+
+static void nodtor(void *dummy)
+{
+}
+
+int pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
+{
+	static void (*keys[PTHREAD_KEYS_MAX])(void *);
+	int i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
+	int j = i;
+
+	libc.tsd_keys = keys;
+	if (!dtor) dtor = nodtor;
+	/* Cheap trick - &k cannot match any destructor pointer */
+	while (a_cas_p(keys+j, 0, &k)
+		&& (j=(j+1)%PTHREAD_KEYS_MAX) != i);
+	if (keys[j] != (void (*)(void *))&k)
+		return EAGAIN;
+	keys[j] = dtor;
+	*k = j;
+	return 0;
+}
diff --git a/src/thread/pthread_key_delete.c b/src/thread/pthread_key_delete.c
new file mode 100644
index 00000000..4914ebb4
--- /dev/null
+++ b/src/thread/pthread_key_delete.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_key_delete(pthread_key_t k)
+{
+	if (libc.tsd_keys) libc.tsd_keys[k] = 0;
+	return 0;
+}
diff --git a/src/thread/pthread_kill.c b/src/thread/pthread_kill.c
new file mode 100644
index 00000000..9d85fa5b
--- /dev/null
+++ b/src/thread/pthread_kill.c
@@ -0,0 +1,7 @@
+#define SYSCALL_RETURN_ERRNO
+#include "pthread_impl.h"
+
+int pthread_kill(pthread_t t, int sig)
+{
+	return syscall3(__NR_tgkill, t->pid, t->tid, sig);
+}
diff --git a/src/thread/pthread_mutex_destroy.c b/src/thread/pthread_mutex_destroy.c
new file mode 100644
index 00000000..6d49e689
--- /dev/null
+++ b/src/thread/pthread_mutex_destroy.c
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_mutex_init.c b/src/thread/pthread_mutex_init.c
new file mode 100644
index 00000000..d453543d
--- /dev/null
+++ b/src/thread/pthread_mutex_init.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a)
+{
+	memset(m, 0, sizeof *m);
+	if (a) {
+	}
+	return 0;
+}
diff --git a/src/thread/pthread_mutex_lock.c b/src/thread/pthread_mutex_lock.c
new file mode 100644
index 00000000..6696f17a
--- /dev/null
+++ b/src/thread/pthread_mutex_lock.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_lock(pthread_mutex_t *m)
+{
+	int r;
+	while ((r=pthread_mutex_trylock(m)) == EBUSY)
+		__wait(&m->__lock, &m->__waiters, 1, 0);
+	return r;
+}
diff --git a/src/thread/pthread_mutex_timedlock.c b/src/thread/pthread_mutex_timedlock.c
new file mode 100644
index 00000000..5dfad94f
--- /dev/null
+++ b/src/thread/pthread_mutex_timedlock.c
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *at)
+{
+	int r, w=0;
+	while ((r=pthread_mutex_trylock(m)) == EBUSY) {
+		if (!w) a_inc(&m->__waiters), w++;
+		if (__timedwait(&m->__lock, 1, CLOCK_REALTIME, at, 0) == ETIMEDOUT) {
+			if (w) a_dec(&m->__waiters);
+			return ETIMEDOUT;
+		}
+	}
+	if (w) a_dec(&m->__waiters);
+	return r;
+}
diff --git a/src/thread/pthread_mutex_trylock.c b/src/thread/pthread_mutex_trylock.c
new file mode 100644
index 00000000..1e3817bb
--- /dev/null
+++ b/src/thread/pthread_mutex_trylock.c
@@ -0,0 +1,28 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_trylock(pthread_mutex_t *m)
+{
+	if (m->__type == PTHREAD_MUTEX_RECURSIVE) {
+		pthread_t self = pthread_self();
+		if (m->__owner == self) {
+			if ((unsigned)m->__lock >= INT_MAX) return EAGAIN;
+			a_inc(&m->__lock);
+			return 0;
+		}
+		if (a_fetch_add(&m->__lock, 1)) {
+			if (a_fetch_add(&m->__lock, -1)==1 && m->__waiters)
+				__wake(&m->__lock, 1, 0);
+			return EBUSY;
+		}
+		m->__owner = self;
+		return 0;
+	}
+
+	if (a_xchg(&m->__lock, 1))
+		if (m->__type == PTHREAD_MUTEX_ERRORCHECK
+		 && m->__owner == pthread_self()) return EDEADLK;
+		else return EBUSY;
+	if (m->__type == PTHREAD_MUTEX_ERRORCHECK)
+		m->__owner = pthread_self();
+	return 0;
+}
diff --git a/src/thread/pthread_mutex_unlock.c b/src/thread/pthread_mutex_unlock.c
new file mode 100644
index 00000000..23e64ac8
--- /dev/null
+++ b/src/thread/pthread_mutex_unlock.c
@@ -0,0 +1,19 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_unlock(pthread_mutex_t *m)
+{
+	if (m->__type == PTHREAD_MUTEX_RECURSIVE) {
+		if (a_fetch_add(&m->__lock, -1)==1 && m->__waiters)
+			__wake(&m->__lock, 1, 0);
+		return 0;
+	}
+
+	if (m->__type == PTHREAD_MUTEX_ERRORCHECK
+	 && m->__owner != pthread_self())
+	 	return EPERM;
+
+	m->__owner = 0;
+	m->__lock = 0;
+	if (m->__waiters) __wake(&m->__lock, 1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_mutexattr_destroy.c b/src/thread/pthread_mutexattr_destroy.c
new file mode 100644
index 00000000..9fd69747
--- /dev/null
+++ b/src/thread/pthread_mutexattr_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_mutexattr_gettype.c b/src/thread/pthread_mutexattr_gettype.c
new file mode 100644
index 00000000..9edb16c6
--- /dev/null
+++ b/src/thread/pthread_mutexattr_gettype.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *a, int *type)
+{
+	*type = *a & 3;
+	return 0;
+}
diff --git a/src/thread/pthread_mutexattr_init.c b/src/thread/pthread_mutexattr_init.c
new file mode 100644
index 00000000..ea631069
--- /dev/null
+++ b/src/thread/pthread_mutexattr_init.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_init(pthread_mutexattr_t *a)
+{
+	memset(a, 0, sizeof *a);
+	return 0;
+}
diff --git a/src/thread/pthread_mutexattr_settype.c b/src/thread/pthread_mutexattr_settype.c
new file mode 100644
index 00000000..4e85950e
--- /dev/null
+++ b/src/thread/pthread_mutexattr_settype.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
+{
+	if ((unsigned)type > 2) return EINVAL;
+	*a = (*a & ~3) | type;
+	return 0;
+}
diff --git a/src/thread/pthread_once.c b/src/thread/pthread_once.c
new file mode 100644
index 00000000..72230054
--- /dev/null
+++ b/src/thread/pthread_once.c
@@ -0,0 +1,38 @@
+#include "pthread_impl.h"
+
+static void undo(void *control)
+{
+	a_store(control, 0);
+	__wake(control, 1, 0);
+}
+
+int pthread_once(pthread_once_t *control, void (*init)(void))
+{
+	static int waiters;
+
+	/* Return immediately if init finished before */
+	if (*control == 2) return 0;
+
+	/* Try to enter initializing state. Three possibilities:
+	 *  0 - we're the first or the other cancelled; run init
+	 *  1 - another thread is running init; wait
+	 *  2 - another thread finished running init; just return */
+
+	for (;;) switch (a_swap(control, 1)) {
+	case 0:
+		break;
+	case 1:
+		__wait(control, &waiters, 1, 0);
+		continue;
+	case 2:
+		a_store(control, 2);
+		return 0;
+	}
+
+	pthread_cleanup_push(undo, control);
+	init();
+	pthread_cleanup_pop(0);
+
+	if (waiters) __wake(control, -1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_destroy.c b/src/thread/pthread_rwlock_destroy.c
new file mode 100644
index 00000000..49ecfbd0
--- /dev/null
+++ b/src/thread/pthread_rwlock_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rw)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_init.c b/src/thread/pthread_rwlock_init.c
new file mode 100644
index 00000000..f87d566c
--- /dev/null
+++ b/src/thread/pthread_rwlock_init.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_init(pthread_rwlock_t *rw, const pthread_rwlockattr_t *a)
+{
+	memset(rw, 0, sizeof *rw);
+	if (a) {
+	}
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_rdlock.c b/src/thread/pthread_rwlock_rdlock.c
new file mode 100644
index 00000000..6bcdb815
--- /dev/null
+++ b/src/thread/pthread_rwlock_rdlock.c
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
+{
+	while (pthread_rwlock_tryrdlock(rw))
+		__wait(&rw->__wrlock, &rw->__waiters, 1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_timedrdlock.c b/src/thread/pthread_rwlock_timedrdlock.c
new file mode 100644
index 00000000..290327de
--- /dev/null
+++ b/src/thread/pthread_rwlock_timedrdlock.c
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *rw, const struct timespec *at)
+{
+	int w=0;
+	while (pthread_rwlock_tryrdlock(rw)) {
+		if (!w) a_inc(&rw->__waiters), w++;
+		if (__timedwait(&rw->__wrlock, 1, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
+			if (w) a_dec(&rw->__waiters);
+			return ETIMEDOUT;
+		}
+	}
+	if (w) a_dec(&rw->__waiters);
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_timedwrlock.c b/src/thread/pthread_rwlock_timedwrlock.c
new file mode 100644
index 00000000..9f749648
--- /dev/null
+++ b/src/thread/pthread_rwlock_timedwrlock.c
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *rw, const struct timespec *at)
+{
+	int nr, *p, w=0;
+	while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
+		if (!w) a_inc(&rw->__waiters), w++;
+		if ((nr=rw->__readers)) p = &rw->__readers;
+		else nr=1, p = &rw->__wrlock;
+		if (__timedwait(p, nr, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
+			if (w) a_dec(&rw->__waiters);
+			return ETIMEDOUT;
+		}
+	}
+	if (w) a_dec(&rw->__waiters);
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_tryrdlock.c b/src/thread/pthread_rwlock_tryrdlock.c
new file mode 100644
index 00000000..f59fbbdd
--- /dev/null
+++ b/src/thread/pthread_rwlock_tryrdlock.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
+{
+	a_inc(&rw->__readers);
+	if (rw->__wrlock) {
+		a_dec(&rw->__readers);
+		if (rw->__waiters && !rw->__readers)
+			__wake(&rw->__readers, 1, 0);
+		return EAGAIN;
+	}
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_trywrlock.c b/src/thread/pthread_rwlock_trywrlock.c
new file mode 100644
index 00000000..c029b874
--- /dev/null
+++ b/src/thread/pthread_rwlock_trywrlock.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
+{
+	if (a_xchg(&rw->__wrlock, 1))
+		return EAGAIN;
+	if (rw->__readers) {
+		a_store(&rw->__wrlock, 0);
+		return EAGAIN;
+	}
+	rw->__owner = pthread_self()->tid;
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_unlock.c b/src/thread/pthread_rwlock_unlock.c
new file mode 100644
index 00000000..f39117e7
--- /dev/null
+++ b/src/thread/pthread_rwlock_unlock.c
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rw)
+{
+	struct pthread *self = pthread_self();
+	if (rw->__owner == self->tid) {
+		rw->__owner = 0;
+		a_store(&rw->__wrlock, 0);
+		if (rw->__waiters)
+			__wake(&rw->__wrlock, -1, 0);
+		return 0;
+	}
+	a_dec(&rw->__readers);
+	if (rw->__waiters && !rw->__readers)
+		__wake(&rw->__readers, 1, 0);
+	return 0;
+}
diff --git a/src/thread/pthread_rwlock_wrlock.c b/src/thread/pthread_rwlock_wrlock.c
new file mode 100644
index 00000000..219e924a
--- /dev/null
+++ b/src/thread/pthread_rwlock_wrlock.c
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rw)
+{
+	int nr;
+	while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
+		if ((nr=rw->__readers))
+			__wait(&rw->__readers, &rw->__waiters, nr, 0);
+		else
+			__wait(&rw->__wrlock, &rw->__waiters, 1, 0);
+	}
+	return 0;
+}
diff --git a/src/thread/pthread_self.c b/src/thread/pthread_self.c
new file mode 100644
index 00000000..686d73d5
--- /dev/null
+++ b/src/thread/pthread_self.c
@@ -0,0 +1,39 @@
+#include "pthread_impl.h"
+
+static struct pthread main_thread;
+
+#undef errno
+static int *errno_location()
+{
+	return pthread_self()->errno_ptr;
+}
+
+static int init_main_thread()
+{
+	main_thread.tlsdesc[0] = -1;
+	main_thread.tlsdesc[1] = (long)&main_thread;
+	main_thread.tlsdesc[2] = SIZE_MAX/PAGE_SIZE;
+	main_thread.tlsdesc[3] = 0x51;
+	main_thread.self = &main_thread;
+	main_thread.errno_ptr = __errno_location();
+	if (__set_thread_area(main_thread.tlsdesc) < 0)
+		return -1;
+	syscall1(__NR_set_tid_address, (long)&main_thread.tid);
+	libc.errno_location = errno_location;
+	main_thread.tid = main_thread.pid = getpid();
+	return 0;
+}
+
+#undef pthread_self
+
+pthread_t pthread_self()
+{
+	static int init, failed;
+	if (!init) {
+		if (failed) return 0;
+		if (init_main_thread() < 0) failed = 1;
+		if (failed) return 0;
+		init = 1;
+	}
+	return __pthread_self();
+}
diff --git a/src/thread/pthread_setcancelstate.c b/src/thread/pthread_setcancelstate.c
new file mode 100644
index 00000000..23c38851
--- /dev/null
+++ b/src/thread/pthread_setcancelstate.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_setcancelstate(int new, int *old)
+{
+	struct pthread *self = pthread_self();
+	if (old) *old = self->canceldisable;
+	if ((unsigned)new > 1) return EINVAL;
+	self->canceldisable = new;
+	return 0;
+}
diff --git a/src/thread/pthread_setcanceltype.c b/src/thread/pthread_setcanceltype.c
new file mode 100644
index 00000000..c73db22f
--- /dev/null
+++ b/src/thread/pthread_setcanceltype.c
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_setcanceltype(int new, int *old)
+{
+	struct pthread *self = pthread_self();
+	if (old) *old = self->cancelasync;
+	if ((unsigned)new > 1) return EINVAL;
+	self->cancelasync = new;
+	return 0;
+}
diff --git a/src/thread/pthread_setspecific.c b/src/thread/pthread_setspecific.c
new file mode 100644
index 00000000..171cef41
--- /dev/null
+++ b/src/thread/pthread_setspecific.c
@@ -0,0 +1,18 @@
+#include "pthread_impl.h"
+
+int pthread_setspecific(pthread_key_t k, const void *x)
+{
+	struct pthread *self = pthread_self();
+	/* Handle the case of the main thread */
+	if (!self->tsd) {
+		if (!x) return 0;
+		if (!(self->tsd = calloc(sizeof(void *), PTHREAD_KEYS_MAX)))
+			return ENOMEM;
+	}
+	/* Avoid unnecessary COW */
+	if (self->tsd[k] != x) {
+		self->tsd[k] = (void *)x;
+		self->tsd_used = 1;
+	}
+	return 0;
+}
diff --git a/src/thread/pthread_spin_destroy.c b/src/thread/pthread_spin_destroy.c
new file mode 100644
index 00000000..e65a820c
--- /dev/null
+++ b/src/thread/pthread_spin_destroy.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_destroy(pthread_spinlock_t *s)
+{
+	return 0;
+}
diff --git a/src/thread/pthread_spin_init.c b/src/thread/pthread_spin_init.c
new file mode 100644
index 00000000..681881cf
--- /dev/null
+++ b/src/thread/pthread_spin_init.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_init(pthread_spinlock_t *s, int shared)
+{
+	return *s = 0;
+}
diff --git a/src/thread/pthread_spin_lock.c b/src/thread/pthread_spin_lock.c
new file mode 100644
index 00000000..59fa6ea8
--- /dev/null
+++ b/src/thread/pthread_spin_lock.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_spin_lock(pthread_spinlock_t *s)
+{
+	while (a_xchg(s, 1));
+	return 0;
+}
diff --git a/src/thread/pthread_spin_trylock.c b/src/thread/pthread_spin_trylock.c
new file mode 100644
index 00000000..c12696b3
--- /dev/null
+++ b/src/thread/pthread_spin_trylock.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_trylock(pthread_spinlock_t *s)
+{
+	return -a_xchg(s, 1) & EBUSY;
+}
diff --git a/src/thread/pthread_spin_unlock.c b/src/thread/pthread_spin_unlock.c
new file mode 100644
index 00000000..a7eab334
--- /dev/null
+++ b/src/thread/pthread_spin_unlock.c
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_unlock(pthread_spinlock_t *s)
+{
+	return *s = 0;
+}
diff --git a/src/thread/pthread_testcancel.c b/src/thread/pthread_testcancel.c
new file mode 100644
index 00000000..774b7068
--- /dev/null
+++ b/src/thread/pthread_testcancel.c
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+void pthread_testcancel()
+{
+	CANCELPT_BEGIN;
+	CANCELPT_END;
+}
diff --git a/src/time/__asctime.c b/src/time/__asctime.c
new file mode 100644
index 00000000..18535802
--- /dev/null
+++ b/src/time/__asctime.c
@@ -0,0 +1,27 @@
+#include <time.h>
+#include <stdio.h>
+#include <langinfo.h>
+
+const char *__langinfo(nl_item);
+
+char *__asctime(const struct tm *tm, char *buf)
+{
+	/* FIXME: change __langinfo to __C_langinfo once we have locales */
+	if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+		__langinfo(ABDAY_1+tm->tm_wday),
+		__langinfo(ABMON_1+tm->tm_mon),
+		tm->tm_mday, tm->tm_hour,
+		tm->tm_min, tm->tm_sec,
+		1900 + tm->tm_year) >= 26)
+	{
+		/* ISO C requires us to use the above format string,
+		 * even if it will not fit in the buffer. Thus asctime_r
+		 * is _supposed_ to crash if the fields in tm are too large.
+		 * We follow this behavior and crash "gracefully" to warn
+		 * application developers that they may not be so lucky
+		 * on other implementations (e.g. stack smashing..).
+		 */
+		*(int*)0 = 0;
+	}
+	return buf;
+}
diff --git a/src/time/__time.h b/src/time/__time.h
new file mode 100644
index 00000000..967e5180
--- /dev/null
+++ b/src/time/__time.h
@@ -0,0 +1,9 @@
+time_t __tm_to_time(struct tm *);
+struct tm *__time_to_tm(time_t, struct tm *);
+void __tzset(void);
+struct tm *__dst_adjust(struct tm *tm);
+
+extern long __timezone;
+extern int __daylight;
+extern int __dst_offset;
+extern char *__tzname[2];
diff --git a/src/time/__time_to_tm.c b/src/time/__time_to_tm.c
new file mode 100644
index 00000000..a1ebc452
--- /dev/null
+++ b/src/time/__time_to_tm.c
@@ -0,0 +1,81 @@
+#include <time.h>
+
+/* C defines the rounding for division in a nonsensical way */
+#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+/* FIXME: use lldiv once it's fixed to compute quot,rem together */
+struct tm *__time_to_tm(time_t t, struct tm *tm)
+{
+	/* months are march-based */
+	static const int days_thru_month[] = {31,61,92,122,153,184,214,245,275,306,337,366};
+	long long bigday;
+	unsigned int day, year4, year100;
+	int year, year400;
+	int month;
+	int leap;
+	int hour, min, sec;
+	int wday, mday, yday;
+
+	/* start from 2000-03-01 (multiple of 400 years) */
+	t += -946684800 - 86400*(31+29);
+
+	bigday = Q(t, 86400);
+	sec = t-bigday*86400;
+
+	hour = sec/3600;
+	sec -= hour*3600;
+	min = sec/60;
+	sec -= min*60;
+
+	/* 2000-03-01 was a wednesday */
+	wday = (3+bigday)%7;
+	if (wday < 0) wday += 7;
+
+	t = -946684800LL - 86400*(31+29) + 9000000;
+	
+	year400 = Q(bigday, DAYS_PER_400Y);
+	day = bigday-year400*DAYS_PER_400Y;
+
+	year100 = day/DAYS_PER_100Y;
+	if (year100 == 4) year100--;
+	day -= year100*DAYS_PER_100Y;
+
+	year4 = day/DAYS_PER_4Y;
+	if (year4 == 25) year4--;
+	day -= year4*DAYS_PER_4Y;
+
+	year = day/365;
+	if (year == 4) year--;
+	day -= year*365;
+
+	leap = !year && (year4 || !year100);
+	yday = day + 31+28 + leap;
+	if (yday >= 365+leap) yday -= 365+leap;
+
+	year += 4*year4 + 100*year100 + 400*year400 + 2000-1900;
+
+	for (month=0; days_thru_month[month] <= day; month++);
+	if (month) day -= days_thru_month[month-1];
+	month += 2;
+	if (month >= 12) {
+		month -= 12;
+		year++;
+	}
+
+	mday = day+1;
+
+	tm->tm_sec = sec;
+	tm->tm_min = min;
+	tm->tm_hour= hour;
+	tm->tm_mday= mday;
+	tm->tm_mon = month;
+	tm->tm_year= year;
+	tm->tm_wday= wday;
+	tm->tm_yday= yday;
+
+	return tm;
+}
diff --git a/src/time/__tm_to_time.c b/src/time/__tm_to_time.c
new file mode 100644
index 00000000..3fa15fad
--- /dev/null
+++ b/src/time/__tm_to_time.c
@@ -0,0 +1,33 @@
+#include <time.h>
+
+/* C defines the rounding for division in a nonsensical way */
+#define Q(a,b) ((a)>0 ? (a)/(b) : -(((b)-(a)-1)/(b)))
+
+time_t __tm_to_time(struct tm *tm)
+{
+	time_t year  = tm->tm_year + -100;
+	int    month = tm->tm_mon;
+	int    day   = tm->tm_mday;
+	int z4, z100, z400;
+
+	/* normalize month */
+	if (month >= 12) {
+		year += month/12;
+		month %= 12;
+	} else if (month < 0) {
+		year += month/12;
+		month %= 12;
+		if (month) {
+			month += 12;
+			year--;
+		}
+	}
+	z4 = Q(year - (month < 2), 4);
+	z100 = Q(z4, 25);
+	z400 = Q(z100, 4);
+	day += year*365 + z4 - z100 + z400 +
+		month[(int []){0,31,59,90,120,151,181,212,243,273,304,335}];
+	return (long long)day*86400
+		+ tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec
+		- -946684800; /* the dawn of time :) */
+}
diff --git a/src/time/asctime.c b/src/time/asctime.c
new file mode 100644
index 00000000..3102eb87
--- /dev/null
+++ b/src/time/asctime.c
@@ -0,0 +1,9 @@
+#include <time.h>
+
+char *__asctime(const struct tm *, char *);
+
+char *asctime(const struct tm *tm)
+{
+	static char buf[26];
+	return __asctime(tm, buf);
+}
diff --git a/src/time/asctime_r.c b/src/time/asctime_r.c
new file mode 100644
index 00000000..e51b8804
--- /dev/null
+++ b/src/time/asctime_r.c
@@ -0,0 +1,8 @@
+#include <time.h>
+
+char *__asctime(const struct tm *, char *);
+
+char *asctime_r(const struct tm *tm, char *buf)
+{
+	return __asctime(tm, buf);
+}
diff --git a/src/time/clock.c b/src/time/clock.c
new file mode 100644
index 00000000..2feddb36
--- /dev/null
+++ b/src/time/clock.c
@@ -0,0 +1,9 @@
+#include <time.h>
+#include <sys/times.h>
+
+/* this function assumes 100 hz linux and corrects for it */
+clock_t clock()
+{
+	struct tms tms;
+	return (unsigned long)times(&tms)*10000;
+}
diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c
new file mode 100644
index 00000000..dab09d50
--- /dev/null
+++ b/src/time/clock_gettime.c
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int clock_gettime(clockid_t clk, struct timespec *ts)
+{
+	return syscall2(__NR_clock_gettime, clk, (long)ts);
+}
diff --git a/src/time/ctime.c b/src/time/ctime.c
new file mode 100644
index 00000000..185ec554
--- /dev/null
+++ b/src/time/ctime.c
@@ -0,0 +1,6 @@
+#include <time.h>
+
+char *ctime(const time_t *t)
+{
+	return asctime(localtime(t));
+}
diff --git a/src/time/ctime_r.c b/src/time/ctime_r.c
new file mode 100644
index 00000000..d2260a16
--- /dev/null
+++ b/src/time/ctime_r.c
@@ -0,0 +1,8 @@
+#include <time.h>
+
+char *ctime_r(const time_t *t, char *buf)
+{
+	struct tm tm;
+	localtime_r(t, &tm);
+	return asctime_r(&tm, buf);
+}
diff --git a/src/time/difftime.c b/src/time/difftime.c
new file mode 100644
index 00000000..80a18cc0
--- /dev/null
+++ b/src/time/difftime.c
@@ -0,0 +1,6 @@
+#include <time.h>
+
+double difftime(time_t t1, time_t t0)
+{
+	return t1-t0;
+}
diff --git a/src/time/gettimeofday.c b/src/time/gettimeofday.c
new file mode 100644
index 00000000..2b8a287d
--- /dev/null
+++ b/src/time/gettimeofday.c
@@ -0,0 +1,9 @@
+#define SYSCALL_RETURN_ERRNO
+#include <sys/time.h>
+#include "syscall.h"
+
+int gettimeofday(struct timeval *tv, void *tz)
+{
+	syscall2(__NR_gettimeofday, (long)tv, 0);
+	return 0;
+}
diff --git a/src/time/gmtime.c b/src/time/gmtime.c
new file mode 100644
index 00000000..d4d5d1f1
--- /dev/null
+++ b/src/time/gmtime.c
@@ -0,0 +1,11 @@
+#include <time.h>
+
+#include "__time.h"
+
+struct tm *gmtime(const time_t *t)
+{
+	static struct tm tm;
+	__time_to_tm(*t, &tm);
+	tm.tm_isdst = 0;
+	return &tm;
+}
diff --git a/src/time/gmtime_r.c b/src/time/gmtime_r.c
new file mode 100644
index 00000000..5b565a65
--- /dev/null
+++ b/src/time/gmtime_r.c
@@ -0,0 +1,10 @@
+#include <time.h>
+
+#include "__time.h"
+
+struct tm *gmtime_r(const time_t *t, struct tm *result)
+{
+	__time_to_tm(*t, result);
+	result->tm_isdst = 0;
+	return result;
+}
diff --git a/src/time/localtime.c b/src/time/localtime.c
new file mode 100644
index 00000000..abd5e84d
--- /dev/null
+++ b/src/time/localtime.c
@@ -0,0 +1,12 @@
+#include <time.h>
+
+#include "__time.h"
+
+struct tm *localtime(const time_t *t)
+{
+	static struct tm tm;
+	__tzset();
+	__time_to_tm(*t - __timezone, &tm);
+	tm.tm_isdst = -1;
+	return __dst_adjust(&tm);
+}
diff --git a/src/time/localtime_r.c b/src/time/localtime_r.c
new file mode 100644
index 00000000..2bf10378
--- /dev/null
+++ b/src/time/localtime_r.c
@@ -0,0 +1,11 @@
+#include <time.h>
+
+#include "__time.h"
+
+struct tm *localtime_r(const time_t *t, struct tm *result)
+{
+	__tzset();
+	__time_to_tm(*t - __timezone, result);
+	result->tm_isdst = -1;
+	return __dst_adjust(result);
+}
diff --git a/src/time/mktime.c b/src/time/mktime.c
new file mode 100644
index 00000000..858cd50d
--- /dev/null
+++ b/src/time/mktime.c
@@ -0,0 +1,24 @@
+#include <time.h>
+
+#include "__time.h"
+
+time_t mktime(struct tm *tm)
+{
+	int isdst = tm->tm_isdst;
+	time_t t, lt;
+
+	__tzset();
+
+	tm->tm_sec += __timezone;
+	if (isdst > 0) tm->tm_sec += __dst_offset;
+
+	t = __tm_to_time(tm);
+	
+	lt = t - __timezone;
+	if (isdst > 0) lt -= __dst_offset;
+	__time_to_tm(lt, tm);
+
+	__dst_adjust(tm);
+	
+	return t;
+}
diff --git a/src/time/nanosleep.c b/src/time/nanosleep.c
new file mode 100644
index 00000000..5ac4c359
--- /dev/null
+++ b/src/time/nanosleep.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <time.h>
+#include "syscall.h"
+#include "libc.h"
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+	int ret;
+	CANCELPT_BEGIN;
+	ret = syscall2(__NR_nanosleep, (long)req, (long)rem);
+	CANCELPT_END;
+	return ret;
+}
diff --git a/src/time/strftime.c b/src/time/strftime.c
new file mode 100644
index 00000000..f1b94631
--- /dev/null
+++ b/src/time/strftime.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <langinfo.h>
+#include <time.h>
+#include "__time.h"
+
+// FIXME: integer overflows
+
+const char *__langinfo(nl_item);
+
+size_t strftime(char *s, size_t n, const char *f, const struct tm *tm)
+{
+	nl_item item;
+	int val;
+	const char *fmt;
+	size_t l;
+	for (l=0; *f && l<n; f++) {
+		if (*f == '%') {
+do_fmt:
+		switch (*++f) {
+		case '%':
+			goto literal;
+		case 'E':
+		case 'O':
+			goto do_fmt;
+		case 'a':
+			item = ABDAY_1 + tm->tm_wday;
+			goto nl_strcat;
+		case 'A':
+			item = DAY_1 + tm->tm_wday;
+			goto nl_strcat;
+		case 'h':
+		case 'b':
+			item = ABMON_1 + tm->tm_mon;
+			goto nl_strcat;
+		case 'B':
+			item = MON_1 + tm->tm_mon;
+			goto nl_strcat;
+		case 'c':
+			item = D_T_FMT;
+			goto nl_strftime;
+		case 'C':
+			val = (1900+tm->tm_year) / 100;
+			fmt = "%02d";
+			goto number;
+		case 'd':
+			val = tm->tm_mday;
+			fmt = "%02d";
+			goto number;
+		case 'D':
+			fmt = "%m/%d/%y";
+			goto recu_strftime;
+		case 'e':
+			val = tm->tm_mday;
+			fmt = "%2d";
+			goto number;
+		case 'F':
+			fmt = "%Y-%m-%d";
+			goto recu_strftime;
+		case 'g':
+			// FIXME
+			val = 0; //week_based_year(tm)%100;
+			fmt = "%02d";
+			goto number;
+		case 'G':
+			// FIXME
+			val = 0; //week_based_year(tm);
+			fmt = "%04d";
+			goto number;
+		case 'H':
+			val = tm->tm_hour;
+			fmt = "%02d";
+			goto number;
+		case 'I':
+			val = tm->tm_hour;
+			if (!val) val = 12;
+			else if (val > 12) val -= 12;
+			fmt = "%02d";
+			goto number;
+		case 'j':
+			val = tm->tm_yday+1;
+			fmt = "%03d";
+			goto number;
+		case 'm':
+			val = tm->tm_mon+1;
+			fmt = "%02d";
+			goto number;
+		case 'M':
+			val = tm->tm_min;
+			fmt = "%02d";
+			goto number;
+		case 'n':
+			s[l++] = '\n';
+			continue;
+		case 'p':
+			item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
+			goto nl_strcat;
+		case 'r':
+			item = T_FMT_AMPM;
+			goto nl_strftime;
+		case 'R':
+			fmt = "%H:%M";
+			goto recu_strftime;
+		case 'S':
+			val = tm->tm_sec;
+			fmt = "%02d";
+			goto number;
+		case 't':
+			s[l++] = '\t';
+			continue;
+		case 'T':
+			fmt = "%H:%M:%S";
+			goto recu_strftime;
+		case 'u':
+			val = tm->tm_wday ? tm->tm_wday : 7;
+			fmt = "%d";
+			goto number;
+		case 'U':
+		case 'V':
+		case 'W':
+			// FIXME: week number mess..
+			continue;
+		case 'w':
+			val = tm->tm_wday;
+			fmt = "%d";
+			goto number;
+		case 'x':
+			item = D_FMT;
+			goto nl_strftime;
+		case 'X':
+			item = T_FMT;
+			goto nl_strftime;
+		case 'y':
+			val = tm->tm_year % 100;
+			fmt = "%02d";
+			goto number;
+		case 'Y':
+			val = tm->tm_year + 1900;
+			fmt = "%04d";
+			goto number;
+		case 'z':
+			if (tm->tm_isdst < 0) continue;
+			val = -__timezone - (tm->tm_isdst ? __dst_offset : 0);
+			l += snprintf(s+l, n-l, "%+.2d%.2d", val/3600, abs(val%3600)/60);
+			continue;
+		case 'Z':
+			if (tm->tm_isdst < 0 || !__tzname[0] || !__tzname[0][0])
+				continue;
+			l += snprintf(s+l, n-l, "%s", __tzname[!!tm->tm_isdst]);
+			continue;
+		default:
+			return 0;
+		}
+		}
+literal:
+		s[l++] = *f;
+		continue;
+number:
+		l += snprintf(s+l, n-l, fmt, val);
+		continue;
+nl_strcat:
+		l += snprintf(s+l, n-l, "%s", __langinfo(item));
+		continue;
+nl_strftime:
+		fmt = __langinfo(item);
+recu_strftime:
+		l += strftime(s+l, n-l, fmt, tm);
+	}
+	if (l >= n) return 0;
+	s[l] = 0;
+	return l;
+}
diff --git a/src/time/strptime.c b/src/time/strptime.c
new file mode 100644
index 00000000..db72e610
--- /dev/null
+++ b/src/time/strptime.c
@@ -0,0 +1,178 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <langinfo.h>
+#include <time.h>
+
+const char *__langinfo(nl_item);
+
+char *strptime(const char *s, const char *f, struct tm *tm)
+{
+	return NULL;
+}
+
+#if 0
+
+char *strptime(const char *s, const char *f, struct tm *tm)
+{
+	nl_item item;
+	int *dest;
+	const char *fmt;
+	for (; *f; f++) {
+		if (isspace(*f)) goto whitespace;
+		if (*f == '%') {
+do_fmt:
+		switch (*++f) {
+		case '%':
+			goto literal;
+		case 'E':
+		case 'O':
+			goto do_fmt;
+		case 'a':
+			item = ABDAY_1 + tm->tm_wday;
+			goto nl_strcat;
+		case 'A':
+			item = DAY_1 + tm->tm_wday;
+			goto nl_strcat;
+		case 'h':
+		case 'b':
+			item = ABMON_1 + tm->tm_mon;
+			goto nl_strcat;
+		case 'B':
+			item = MON_1 + tm->tm_mon;
+			goto nl_strcat;
+		case 'c':
+			item = D_T_FMT;
+			goto nl_strftime;
+		case 'C':
+			val = (1900+tm->tm_year) / 100;
+			fmt = "%02d";
+			goto number;
+		case 'd':
+			val = tm->tm_mday;
+			fmt = "%02d";
+			goto number;
+		case 'D':
+			fmt = "%m/%d/%y";
+			goto recu_strftime;
+		case 'e':
+			val = tm->tm_mday;
+			fmt = "%2d";
+			goto number;
+		case 'F':
+			fmt = "%Y-%m-%d";
+			goto recu_strftime;
+		case 'g':
+			// FIXME
+			val = 0; //week_based_year(tm)%100;
+			fmt = "%02d";
+			goto number;
+		case 'G':
+			// FIXME
+			val = 0; //week_based_year(tm);
+			fmt = "%04d";
+			goto number;
+		case 'H':
+			val = tm->tm_hour;
+			fmt = "%02d";
+			goto number;
+		case 'I':
+			val = tm->tm_hour;
+			if (!val) val = 12;
+			else if (val > 12) val -= 12;
+			fmt = "%02d";
+			goto number;
+		case 'j':
+			val = tm->tm_yday+1;
+			fmt = "%03d";
+			goto number;
+		case 'm':
+			val = tm->tm_mon+1;
+			fmt = "%02d";
+			goto number;
+		case 'M':
+			val = tm->tm_min;
+			fmt = "%02d";
+			goto number;
+		case 'n':
+		case 't':
+			goto whitespace;
+		case 'p':
+			item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
+			goto nl_strcat;
+		case 'r':
+			item = T_FMT_AMPM;
+			goto nl_strftime;
+		case 'R':
+			fmt = "%H:%M";
+			goto recu_strftime;
+		case 'S':
+			val = tm->tm_sec;
+			fmt = "%02d";
+			goto number;
+		case 'T':
+			fmt = "%H:%M:%S";
+			goto recu_strftime;
+		case 'u':
+			val = tm->tm_wday ? tm->tm_wday : 7;
+			fmt = "%d";
+			goto number;
+		case 'U':
+		case 'V':
+		case 'W':
+			// FIXME: week number mess..
+			continue;
+		case 'w':
+			val = tm->tm_wday;
+			fmt = "%d";
+			goto number;
+		case 'x':
+			item = D_FMT;
+			goto nl_strftime;
+		case 'X':
+			item = T_FMT;
+			goto nl_strftime;
+		case 'y':
+			val = tm->tm_year % 100;
+			fmt = "%02d";
+			goto number;
+		case 'Y':
+			val = tm->tm_year + 1900;
+			fmt = "%04d";
+			goto number;
+		case 'z':
+			if (tm->tm_isdst < 0) continue;
+			val = timezone + (tm->tm_isdst) ? __dst_offset : 0;
+			l += snprintf(s+l, n-l, "%+02d%02d", val/60, abs(val%60));
+			continue;
+		case 'Z':
+			if (tm->tm_isdst < 0 || !tzname[0] || !tzname[0][0])
+				continue;
+			l += snprintf(s+l, n-l, "%s", tzname[!!tm->tm_isdst]);
+			continue;
+		}
+		default:
+			return NULL;
+		}
+literal:
+		if (*s++ != *f) return NULL;
+		continue;
+whitespace:
+		while(isspace(*s)) s++;
+		continue;
+number:
+		l += snprintf(s+l, n-l, fmt, val);
+		continue;
+nl_strcat:
+		l += snprintf(s+l, n-l, "%s", __langinfo(item));
+		continue;
+nl_strftime:
+		fmt = __langinfo(item);
+recu_strftime:
+		l += strftime(s+l, n-l, fmt, tm);
+	}
+	if (l >= n) return 0;
+	s[l] = 0;
+	return l;
+}
+
+#endif
diff --git a/src/time/time.c b/src/time/time.c
new file mode 100644
index 00000000..3457dade
--- /dev/null
+++ b/src/time/time.c
@@ -0,0 +1,12 @@
+#define SYSCALL_RETURN_ERRNO
+#include <time.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+time_t time(time_t *t)
+{
+	struct timeval tv;
+	syscall2(__NR_gettimeofday, (long)&tv, 0);
+	if (t) *t = tv.tv_sec;
+	return tv.tv_sec;
+}
diff --git a/src/time/times.c b/src/time/times.c
new file mode 100644
index 00000000..e9b5a823
--- /dev/null
+++ b/src/time/times.c
@@ -0,0 +1,7 @@
+#include <sys/times.h>
+#include "syscall.h"
+
+clock_t times(struct tms *tms)
+{
+	return syscall1(__NR_times, (long)&tms);
+}
diff --git a/src/time/timezone.s b/src/time/timezone.s
new file mode 100644
index 00000000..4e167b0b
--- /dev/null
+++ b/src/time/timezone.s
@@ -0,0 +1,27 @@
+.data
+
+.global timezone
+.global __timezone
+.global daylight
+.global __daylight
+.global tzname
+.global __tzname
+
+__timezone:
+timezone:
+	.long 0
+.size timezone,.-timezone
+.size __timezone,.-__timezone
+
+__daylight:
+daylight:
+	.long 0
+.size daylight,.-daylight
+.size __daylight,.-__daylight
+
+__tzname:
+tzname:
+	.long 0
+	.long 0
+.size tzname,.-tzname
+.size __tzname,.-__tzname
diff --git a/src/time/tzset.c b/src/time/tzset.c
new file mode 100644
index 00000000..6d69957e
--- /dev/null
+++ b/src/time/tzset.c
@@ -0,0 +1,173 @@
+#include <time.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+#include "__time.h"
+
+long  __timezone = 0;
+int   __daylight = 0;
+char *__tzname[2] = { 0, 0 };
+int   __dst_offset = 0;
+
+weak_alias(__timezone, timezone);
+weak_alias(__daylight, daylight);
+weak_alias(__tzname, tzname);
+weak_alias(__dst_offset, dst_offset);
+
+static char std_name[TZNAME_MAX+1];
+static char dst_name[TZNAME_MAX+1];
+
+/* all elements are zero-based */
+static struct rule {
+	char month;
+	char week;
+	short day;
+	int time;
+} __dst_start, __dst_end;
+
+static void zname(char *d, char **s)
+{
+	int i;
+	for (i=0; i<TZNAME_MAX && isalpha(d[i]=**s); i++, (*s)++);
+	d[i] = 0;
+}
+
+static int hhmmss(char **s)
+{
+	int ofs = strtol(*s, s, 10)*3600;
+	if (ofs >= 0) {
+		if (**s == ':') ofs += strtol(*s+1, s, 10)*60;
+		if (**s == ':') ofs += strtol(*s+1, s, 10);
+	} else {
+		if (**s == ':') ofs -= strtol(*s+1, s, 10)*60;
+		if (**s == ':') ofs -= strtol(*s+1, s, 10);
+	}
+	return ofs;
+}
+
+static int dstrule(struct rule *rule, char **s)
+{
+	if (**s != ',') return -1;
+	switch (*++*s) {
+	case 'J':
+		rule->month = 'J';
+		rule->day = strtol(*s+1, s, 10)-1;
+		break;
+	case 'M':
+		rule->month = strtol(*s+1, s, 10)-1;
+		if (**s != '.' || rule->month < 0 || rule->month > 11)
+			return -1;
+		rule->week = strtol(*s+1, s, 10)-1;
+		if (**s != '.' || rule->week < 0 || rule->week > 4)
+			return -1;
+		rule->day = strtol(*s+1, s, 10);
+		if (rule->day < 0 || rule->day > 6)
+			return -1;
+		break;
+	default:
+		rule->month = 'L';
+		rule->day = strtol(*s+1, s, 10);
+		break;
+	}
+	if (**s == '/') {
+		(*s)++;
+		rule->time = hhmmss(s);
+	} else rule->time = 7200;
+	return 0;
+}
+
+void tzset(void)
+{
+	char *z, *a;
+	
+	strcpy(std_name, "GMT");
+	strcpy(dst_name, "GMT");
+	__tzname[0] = std_name;
+	__tzname[1] = dst_name;
+	__timezone = 0;
+	__daylight = 0;
+	
+	if (!(z = getenv("TZ")) || !isalpha(*z)) return;
+
+	zname(std_name, &z);
+	__timezone = hhmmss(&z);
+
+	zname(dst_name, &z);
+	if (dst_name[0]) __daylight=1;
+	a = z;
+	__dst_offset = hhmmss(&z) - __timezone;
+	if (z==a) __dst_offset = -3600;
+
+	if (dstrule(&__dst_start, &z) || dstrule(&__dst_end, &z))
+		__daylight = 0;
+}
+
+void __tzset(void)
+{
+	static int lock, init;
+	if (init) return;
+	LOCK(&lock);
+	if (!init) tzset();
+	init=1;
+	UNLOCK(&lock);
+}
+
+static int is_leap(int year)
+{
+	year -= 100;
+	return !(year&3) && ((year%100) || !(year%400));
+}
+
+static int cutoff_yday(struct tm *tm, struct rule *rule)
+{
+	static const char days_in_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
+	static const int first_day[] = {0,31,59,90,120,151,181,212,243,273,304,335};
+	int yday, mday, leap;
+	
+	switch (rule->month) {
+	case 'J':
+		return rule->day + (tm->tm_mon > 1 && is_leap(tm->tm_year));
+	case 'L':
+		return rule->day;
+	default:
+		yday = first_day[rule->month];
+		leap = is_leap(tm->tm_year);
+		if (rule->month > 1 && leap) yday++;
+		mday = (rule->day - (yday + tm->tm_wday - tm->tm_yday) + 1400)%7 + 7*rule->week;
+		if (mday >= days_in_month[rule->month] + (leap && rule->month == 1))
+			mday -= 7;
+		return mday + yday;
+	}
+}
+
+struct tm *__dst_adjust(struct tm *tm)
+{
+	time_t t;
+	int start, end, secs;
+	int after_start, before_end;
+
+	if (tm->tm_isdst >= 0) return tm;
+	if (!__daylight) {
+		tm->tm_isdst = 0;
+		return tm;
+	}
+	
+	secs = tm->tm_hour*3600 + tm->tm_min*60 + tm->tm_sec;
+	start = cutoff_yday(tm, &__dst_start);
+	end = cutoff_yday(tm, &__dst_end);
+
+	after_start = (tm->tm_yday > start || (tm->tm_yday == start && secs >= __dst_start.time));
+	before_end = (tm->tm_yday < end || (tm->tm_yday == end && secs < __dst_end.time));
+
+	if ((after_start && before_end) || ((end < start) && (after_start || before_end))) {
+		tm->tm_sec -= __dst_offset;
+		tm->tm_isdst = 1;
+		t = __tm_to_time(tm);
+		return __time_to_tm(t, tm);
+	} else tm->tm_isdst = 0;
+
+	return tm;
+}
diff --git a/src/time/utime.c b/src/time/utime.c
new file mode 100644
index 00000000..56e9e13a
--- /dev/null
+++ b/src/time/utime.c
@@ -0,0 +1,12 @@
+#include <utime.h>
+#include "syscall.h"
+
+int utime(const char *path, const struct utimbuf *times)
+{
+	long ktimes[2];
+	if (times) {
+		ktimes[0] = times->actime;
+		ktimes[1] = times->modtime;
+	}
+	return syscall2(__NR_utime, (long)path, times ? (long)ktimes : 0);
+}
diff --git a/src/unistd/_exit.c b/src/unistd/_exit.c
new file mode 100644
index 00000000..d2e84c4c
--- /dev/null
+++ b/src/unistd/_exit.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+void _exit(int status)
+{
+	_Exit(status);
+}
diff --git a/src/unistd/access.c b/src/unistd/access.c
new file mode 100644
index 00000000..2c10e58c
--- /dev/null
+++ b/src/unistd/access.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int access(const char *filename, int amode)
+{
+	return syscall2(__NR_access, (long)filename, amode);
+}
diff --git a/src/unistd/alarm.c b/src/unistd/alarm.c
new file mode 100644
index 00000000..bba444d8
--- /dev/null
+++ b/src/unistd/alarm.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+unsigned alarm(unsigned seconds)
+{
+	return syscall1(__NR_alarm, seconds);
+}
diff --git a/src/unistd/chdir.c b/src/unistd/chdir.c
new file mode 100644
index 00000000..c89bda38
--- /dev/null
+++ b/src/unistd/chdir.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int chdir(const char *path)
+{
+	return syscall1(__NR_chdir, (long)path);
+}
diff --git a/src/unistd/chown.c b/src/unistd/chown.c
new file mode 100644
index 00000000..6069a2fe
--- /dev/null
+++ b/src/unistd/chown.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int chown(const char *path, uid_t uid, gid_t gid)
+{
+	return syscall3(__NR_chown32, (long)path, uid, gid);
+}
diff --git a/src/unistd/close.c b/src/unistd/close.c
new file mode 100644
index 00000000..97302f67
--- /dev/null
+++ b/src/unistd/close.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int close(int fd)
+{
+	int ret = __syscall_close(fd);
+	CANCELPT_BEGIN;
+	CANCELPT_END;
+	return ret;
+}
diff --git a/src/unistd/confstr.c b/src/unistd/confstr.c
new file mode 100644
index 00000000..4332f726
--- /dev/null
+++ b/src/unistd/confstr.c
@@ -0,0 +1,17 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+size_t confstr(int name, char *buf, size_t len)
+{
+	const char *s = "";
+	if (!name) {
+		s = "/bin:/usr/bin";
+	} else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>31U) {
+		errno = EINVAL;
+		return 0;
+	}
+	// snprintf is overkill but avoid wasting code size to implement
+	// this completely useless function and its truncation semantics
+	return snprintf(buf, len, "%s", s);
+}
diff --git a/src/unistd/ctermid.c b/src/unistd/ctermid.c
new file mode 100644
index 00000000..21b44ec8
--- /dev/null
+++ b/src/unistd/ctermid.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+char *ctermid(char *s)
+{
+	static char *s2;
+	int fd;
+	if (!s) {
+		if (!s2) s2 = malloc(L_ctermid);
+		s = s2;
+	}
+	fd = open("/dev/tty", O_WRONLY | O_NOCTTY);
+	if (fd < 0)
+		return strcpy(s, "");
+	if (ttyname_r(fd, s, L_ctermid))
+		strcpy(s, "");
+	close(fd);
+	return s;
+}
diff --git a/src/unistd/dup.c b/src/unistd/dup.c
new file mode 100644
index 00000000..b11cd715
--- /dev/null
+++ b/src/unistd/dup.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int dup(int fd)
+{
+	return syscall1(__NR_dup, fd);
+}
diff --git a/src/unistd/dup2.c b/src/unistd/dup2.c
new file mode 100644
index 00000000..93325446
--- /dev/null
+++ b/src/unistd/dup2.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int dup2(int old, int new)
+{
+	return __syscall_dup2(old, new);
+}
diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
new file mode 100644
index 00000000..99a93785
--- /dev/null
+++ b/src/unistd/faccessat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int faccessat(int fd, const char *filename, int amode, int flag)
+{
+	return syscall4(__NR_faccessat, fd, (long)filename, amode, flag);
+}
diff --git a/src/unistd/fchdir.c b/src/unistd/fchdir.c
new file mode 100644
index 00000000..b2acbc29
--- /dev/null
+++ b/src/unistd/fchdir.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchdir(int fd)
+{
+	return syscall1(__NR_fchdir, fd);
+}
diff --git a/src/unistd/fchown.c b/src/unistd/fchown.c
new file mode 100644
index 00000000..990f006d
--- /dev/null
+++ b/src/unistd/fchown.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchown(int fd, uid_t uid, gid_t gid)
+{
+	return syscall3(__NR_fchown32, fd, uid, gid);
+}
diff --git a/src/unistd/fchownat.c b/src/unistd/fchownat.c
new file mode 100644
index 00000000..70626428
--- /dev/null
+++ b/src/unistd/fchownat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag)
+{
+	return syscall5(__NR_fchownat, fd, (long)path, uid, gid, flag);
+}
diff --git a/src/unistd/fdatasync.c b/src/unistd/fdatasync.c
new file mode 100644
index 00000000..ef7c9a9d
--- /dev/null
+++ b/src/unistd/fdatasync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fdatasync(int fd)
+{
+	return 0;
+}
diff --git a/src/unistd/fsync.c b/src/unistd/fsync.c
new file mode 100644
index 00000000..7cfedc98
--- /dev/null
+++ b/src/unistd/fsync.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fsync(int fd)
+{
+	//return syscall1(__NR_fsync, fd);
+	return 0;
+}
diff --git a/src/unistd/ftruncate.c b/src/unistd/ftruncate.c
new file mode 100644
index 00000000..e0b2f4bb
--- /dev/null
+++ b/src/unistd/ftruncate.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int ftruncate(int fd, off_t length)
+{
+	if (sizeof(long) == 8)
+		return syscall2(__NR_ftruncate, fd, length);
+	else {
+		union { long long ll; long l[2]; } u = { length };
+		return syscall3(__NR_ftruncate64, fd, u.l[0], u.l[1]);
+	}
+}
+
+LFS64(ftruncate);
diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c
new file mode 100644
index 00000000..4910f42c
--- /dev/null
+++ b/src/unistd/getcwd.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+char *getcwd(char *buf, size_t size)
+{
+	return syscall2(__NR_getcwd, (long)buf, size) < 0 ? NULL : buf;
+}
diff --git a/src/unistd/getegid.c b/src/unistd/getegid.c
new file mode 100644
index 00000000..0e626b75
--- /dev/null
+++ b/src/unistd/getegid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getegid(void)
+{
+	return syscall0(__NR_getegid32);
+}
diff --git a/src/unistd/geteuid.c b/src/unistd/geteuid.c
new file mode 100644
index 00000000..39d6ac7b
--- /dev/null
+++ b/src/unistd/geteuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t geteuid(void)
+{
+	return syscall0(__NR_geteuid32);
+}
diff --git a/src/unistd/getgid.c b/src/unistd/getgid.c
new file mode 100644
index 00000000..186635a2
--- /dev/null
+++ b/src/unistd/getgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getgid(void)
+{
+	return syscall0(__NR_getgid32);
+}
diff --git a/src/unistd/getgroups.c b/src/unistd/getgroups.c
new file mode 100644
index 00000000..6f19870e
--- /dev/null
+++ b/src/unistd/getgroups.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int getgroups(int count, gid_t list[])
+{
+	/* this depends on our gid_t being 32bit */
+	return syscall2(__NR_getgroups32, count, (long)list);
+}
diff --git a/src/unistd/gethostname.c b/src/unistd/gethostname.c
new file mode 100644
index 00000000..a406c4eb
--- /dev/null
+++ b/src/unistd/gethostname.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <string.h>
+
+int gethostname(char *name, size_t len)
+{
+	size_t i;
+	struct utsname uts;
+	if (uname(&uts)) return -1;
+	if (len > sizeof uts.nodename) len = sizeof uts.nodename;
+	for (i=0; i<len && (name[i] = uts.nodename[i]); i++);
+	if (i==len) name[i-1] = 0;
+	return 0;
+}
diff --git a/src/unistd/getlogin.c b/src/unistd/getlogin.c
new file mode 100644
index 00000000..06011913
--- /dev/null
+++ b/src/unistd/getlogin.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+char *getlogin(void)
+{
+	return getenv("LOGNAME");
+}
diff --git a/src/unistd/getlogin_r.c b/src/unistd/getlogin_r.c
new file mode 100644
index 00000000..f04f71e5
--- /dev/null
+++ b/src/unistd/getlogin_r.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int getlogin_r(char *name, size_t size)
+{
+	char *logname = getlogin();
+	if (!logname) return ENXIO; /* or...? */
+	if (strlen(name) >= size) return ERANGE;
+	strcpy(name, logname);
+	return 0;
+}
diff --git a/src/unistd/getpgid.c b/src/unistd/getpgid.c
new file mode 100644
index 00000000..50d716b5
--- /dev/null
+++ b/src/unistd/getpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgid(pid_t pid)
+{
+	return syscall1(__NR_getpgid, pid);
+}
diff --git a/src/unistd/getpgrp.c b/src/unistd/getpgrp.c
new file mode 100644
index 00000000..2004630a
--- /dev/null
+++ b/src/unistd/getpgrp.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgrp(void)
+{
+	return syscall0(__NR_getpgrp);
+}
diff --git a/src/unistd/getpid.c b/src/unistd/getpid.c
new file mode 100644
index 00000000..31cbe1cb
--- /dev/null
+++ b/src/unistd/getpid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpid(void)
+{
+	return syscall0(__NR_getpid);
+}
diff --git a/src/unistd/getppid.c b/src/unistd/getppid.c
new file mode 100644
index 00000000..a3241829
--- /dev/null
+++ b/src/unistd/getppid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getppid(void)
+{
+	return syscall0(__NR_getppid);
+}
diff --git a/src/unistd/getsid.c b/src/unistd/getsid.c
new file mode 100644
index 00000000..064229cf
--- /dev/null
+++ b/src/unistd/getsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getsid(pid_t pid)
+{
+	return syscall1(__NR_getsid, pid);
+}
diff --git a/src/unistd/getuid.c b/src/unistd/getuid.c
new file mode 100644
index 00000000..9d4e53f5
--- /dev/null
+++ b/src/unistd/getuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t getuid(void)
+{
+	return syscall0(__NR_getuid32);
+}
diff --git a/src/unistd/isatty.c b/src/unistd/isatty.c
new file mode 100644
index 00000000..cff6e9fe
--- /dev/null
+++ b/src/unistd/isatty.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <termios.h>
+
+int isatty(int fd)
+{
+	struct termios t;
+	return tcgetattr(fd, &t) == 0;
+}
diff --git a/src/unistd/lchown.c b/src/unistd/lchown.c
new file mode 100644
index 00000000..30e83916
--- /dev/null
+++ b/src/unistd/lchown.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int lchown(const char *path, uid_t uid, gid_t gid)
+{
+	return syscall3(__NR_lchown32, (long)path, uid, gid);
+}
diff --git a/src/unistd/link.c b/src/unistd/link.c
new file mode 100644
index 00000000..f121bb9e
--- /dev/null
+++ b/src/unistd/link.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int link(const char *existing, const char *new)
+{
+	return syscall2(__NR_link, (long)existing, (long)new);
+}
diff --git a/src/unistd/linkat.c b/src/unistd/linkat.c
new file mode 100644
index 00000000..0eb51221
--- /dev/null
+++ b/src/unistd/linkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int linkat(int fd1, const char *existing, int fd2, const char *new, int flag)
+{
+	return syscall5(__NR_linkat, fd1, (long)existing, fd2, (long)new, flag);
+}
diff --git a/src/unistd/lseek.c b/src/unistd/lseek.c
new file mode 100644
index 00000000..0dab2679
--- /dev/null
+++ b/src/unistd/lseek.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+	/* optimized away at compiletime */
+	if (sizeof(long) == 8)
+		return syscall3(__NR_lseek, fd, offset, whence);
+	else {
+		off_t result;
+		return syscall5(__NR__llseek, fd, offset>>32, offset, (long)&result, whence) ? -1 : result;
+	}
+}
+
+LFS64(lseek);
diff --git a/src/unistd/nice.c b/src/unistd/nice.c
new file mode 100644
index 00000000..4b28ef41
--- /dev/null
+++ b/src/unistd/nice.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int nice(int inc)
+{
+	return syscall1(__NR_nice, inc);
+}
diff --git a/src/unistd/pause.c b/src/unistd/pause.c
new file mode 100644
index 00000000..14720651
--- /dev/null
+++ b/src/unistd/pause.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int pause(void)
+{
+	int r;
+	CANCELPT_BEGIN;
+	r = syscall0(__NR_pause);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/unistd/pipe.c b/src/unistd/pipe.c
new file mode 100644
index 00000000..2dfc9c99
--- /dev/null
+++ b/src/unistd/pipe.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pipe(int fd[2])
+{
+	return syscall1(__NR_pipe, (long)fd);
+}
diff --git a/src/unistd/pread.c b/src/unistd/pread.c
new file mode 100644
index 00000000..029ba3d1
--- /dev/null
+++ b/src/unistd/pread.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
+{
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall5(__NR_pread64, fd, (long)buf, size, SYSCALL_LL(ofs));
+	CANCELPT_END;
+	return r;
+}
+
+LFS64(pread);
diff --git a/src/unistd/pwrite.c b/src/unistd/pwrite.c
new file mode 100644
index 00000000..8f23d1b9
--- /dev/null
+++ b/src/unistd/pwrite.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
+{
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall5(__NR_pwrite64, fd, (long)buf, size, SYSCALL_LL(ofs));
+	CANCELPT_END;
+	return r;
+}
+
+LFS64(pwrite);
diff --git a/src/unistd/read.c b/src/unistd/read.c
new file mode 100644
index 00000000..87ff1f10
--- /dev/null
+++ b/src/unistd/read.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = __syscall_read(fd, buf, count);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/unistd/readlink.c b/src/unistd/readlink.c
new file mode 100644
index 00000000..f6b1635c
--- /dev/null
+++ b/src/unistd/readlink.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int readlink(const char *path, char *buf, size_t bufsize)
+{
+	return syscall3(__NR_readlink, (long)path, (long)buf, bufsize);
+}
diff --git a/src/unistd/readlinkat.c b/src/unistd/readlinkat.c
new file mode 100644
index 00000000..8171050d
--- /dev/null
+++ b/src/unistd/readlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int readlinkat(int fd, const char *path, char *buf, size_t bufsize)
+{
+	return syscall4(__NR_readlinkat, fd, (long)path, (long)buf, bufsize);
+}
diff --git a/src/unistd/readv.c b/src/unistd/readv.c
new file mode 100644
index 00000000..e311f9de
--- /dev/null
+++ b/src/unistd/readv.c
@@ -0,0 +1,12 @@
+#include <sys/uio.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t readv(int fd, const struct iovec *iov, int count)
+{
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall3(__NR_readv, fd, (long)iov, count);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
new file mode 100644
index 00000000..0dae9f11
--- /dev/null
+++ b/src/unistd/renameat.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int renameat(int oldfd, const char *old, int newfd, const char *new)
+{
+	return syscall4(__NR_renameat, oldfd, (long)old, newfd, (long)new);
+}
diff --git a/src/unistd/rmdir.c b/src/unistd/rmdir.c
new file mode 100644
index 00000000..8e18c7a8
--- /dev/null
+++ b/src/unistd/rmdir.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int rmdir(const char *path)
+{
+	return syscall1(__NR_rmdir, (long)path);
+}
diff --git a/src/unistd/setegid.c b/src/unistd/setegid.c
new file mode 100644
index 00000000..85348842
--- /dev/null
+++ b/src/unistd/setegid.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+int setegid(gid_t egid)
+{
+	return setregid(-1, egid);
+}
diff --git a/src/unistd/seteuid.c b/src/unistd/seteuid.c
new file mode 100644
index 00000000..0aaa86e0
--- /dev/null
+++ b/src/unistd/seteuid.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+int seteuid(uid_t euid)
+{
+	return setreuid(-1, euid);
+}
diff --git a/src/unistd/setgid.c b/src/unistd/setgid.c
new file mode 100644
index 00000000..00c7a03a
--- /dev/null
+++ b/src/unistd/setgid.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setgid(gid_t gid)
+{
+	if (libc.rsyscall) return libc.rsyscall(__NR_setgid32, gid, 0, 0, 0, 0, 0);
+	return syscall1(__NR_setgid32, gid);
+}
diff --git a/src/unistd/setpgid.c b/src/unistd/setpgid.c
new file mode 100644
index 00000000..748d2907
--- /dev/null
+++ b/src/unistd/setpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t setpgid(pid_t pid, pid_t pgid)
+{
+	return syscall2(__NR_setpgid, pid, pgid);
+}
diff --git a/src/unistd/setpgrp.c b/src/unistd/setpgrp.c
new file mode 100644
index 00000000..a2a37f65
--- /dev/null
+++ b/src/unistd/setpgrp.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+pid_t setpgrp(void)
+{
+	return setpgid(0, 0);
+}
diff --git a/src/unistd/setregid.c b/src/unistd/setregid.c
new file mode 100644
index 00000000..d25dab76
--- /dev/null
+++ b/src/unistd/setregid.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setregid(gid_t rgid, gid_t egid)
+{
+	if (libc.rsyscall) return libc.rsyscall(__NR_setregid32, rgid, egid, 0, 0, 0, 0);
+	return syscall2(__NR_setregid32, rgid, egid);
+}
diff --git a/src/unistd/setreuid.c b/src/unistd/setreuid.c
new file mode 100644
index 00000000..0ba2277b
--- /dev/null
+++ b/src/unistd/setreuid.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setreuid(uid_t ruid, uid_t euid)
+{
+	if (libc.rsyscall) return libc.rsyscall(__NR_setreuid32, ruid, euid, 0, 0, 0, 0);
+	return syscall2(__NR_setreuid32, ruid, euid);
+}
diff --git a/src/unistd/setsid.c b/src/unistd/setsid.c
new file mode 100644
index 00000000..e2c5690c
--- /dev/null
+++ b/src/unistd/setsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t setsid(void)
+{
+	return syscall0(__NR_setsid);
+}
diff --git a/src/unistd/setuid.c b/src/unistd/setuid.c
new file mode 100644
index 00000000..53b74d88
--- /dev/null
+++ b/src/unistd/setuid.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setuid(uid_t uid)
+{
+	if (libc.rsyscall) return libc.rsyscall(__NR_setuid32, uid, 0, 0, 0, 0, 0);
+	return syscall1(__NR_setuid32, uid);
+}
diff --git a/src/unistd/sleep.c b/src/unistd/sleep.c
new file mode 100644
index 00000000..d6450941
--- /dev/null
+++ b/src/unistd/sleep.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <time.h>
+
+unsigned sleep(unsigned seconds)
+{
+	struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
+	if (nanosleep(&tv, &tv))
+		return tv.tv_sec;
+	return 0;
+}
diff --git a/src/unistd/symlink.c b/src/unistd/symlink.c
new file mode 100644
index 00000000..8d380d85
--- /dev/null
+++ b/src/unistd/symlink.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int symlink(const char *existing, const char *new)
+{
+	return syscall2(__NR_symlink, (long)existing, (long)new);
+}
diff --git a/src/unistd/symlinkat.c b/src/unistd/symlinkat.c
new file mode 100644
index 00000000..9693b226
--- /dev/null
+++ b/src/unistd/symlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int symlinkat(const char *existing, int fd, const char *new)
+{
+	return syscall3(__NR_symlinkat, (long)existing, fd, (long)new);
+}
diff --git a/src/unistd/sync.c b/src/unistd/sync.c
new file mode 100644
index 00000000..a49808fd
--- /dev/null
+++ b/src/unistd/sync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+void sync(void)
+{
+	syscall0(__NR_sync);
+}
diff --git a/src/unistd/tcgetpgrp.c b/src/unistd/tcgetpgrp.c
new file mode 100644
index 00000000..50080c7e
--- /dev/null
+++ b/src/unistd/tcgetpgrp.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetpgrp(int fd)
+{
+	int pgrp;
+	if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
+		return -1;
+	return pgrp;
+}
diff --git a/src/unistd/tcsetpgrp.c b/src/unistd/tcsetpgrp.c
new file mode 100644
index 00000000..67c38cb4
--- /dev/null
+++ b/src/unistd/tcsetpgrp.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsetpgrp(int fd, pid_t pgrp)
+{
+	int pgrp_int = pgrp;
+	return ioctl(fd, TIOCSPGRP, &pgrp_int);
+}
diff --git a/src/unistd/truncate.c b/src/unistd/truncate.c
new file mode 100644
index 00000000..f75e824e
--- /dev/null
+++ b/src/unistd/truncate.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int truncate(const char *path, off_t length)
+{
+	if (sizeof(long) == 8)
+		return syscall2(__NR_truncate, (long)path, length);
+	else {
+		union { long long ll; long l[2]; } u = { length };
+		return syscall3(__NR_truncate64, (long)path, u.l[0], u.l[1]);
+	}
+}
+
+LFS64(truncate);
diff --git a/src/unistd/ttyname.c b/src/unistd/ttyname.c
new file mode 100644
index 00000000..0f3e1141
--- /dev/null
+++ b/src/unistd/ttyname.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+char *ttyname(int fd)
+{
+	static char buf[TTY_NAME_MAX];
+	int result;
+	if ((result = ttyname_r(fd, buf, sizeof buf))) {
+		errno = result;
+		return NULL;
+	}
+	return buf;
+}
diff --git a/src/unistd/ttyname_r.c b/src/unistd/ttyname_r.c
new file mode 100644
index 00000000..f86fbd9c
--- /dev/null
+++ b/src/unistd/ttyname_r.c
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+int ttyname_r(int fd, char *name, size_t size)
+{
+	char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
+	ssize_t l;
+
+	if (!isatty(fd)) return ENOTTY;
+
+	snprintf(procname, sizeof procname, "/proc/self/fd/%d", fd);
+	l = readlink(procname, name, size);
+
+	if (l < 0) return errno;
+	else if (l == size) return ERANGE;
+	else return 0;
+}
diff --git a/src/unistd/ualarm.c b/src/unistd/ualarm.c
new file mode 100644
index 00000000..be853035
--- /dev/null
+++ b/src/unistd/ualarm.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+/* FIXME: ?? */
+useconds_t ualarm(useconds_t useconds, useconds_t interval)
+{
+	return -1;
+}
diff --git a/src/unistd/unlink.c b/src/unistd/unlink.c
new file mode 100644
index 00000000..fb577920
--- /dev/null
+++ b/src/unistd/unlink.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int unlink(const char *path)
+{
+	return __syscall_unlink(path);
+}
diff --git a/src/unistd/unlinkat.c b/src/unistd/unlinkat.c
new file mode 100644
index 00000000..47fccc17
--- /dev/null
+++ b/src/unistd/unlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int unlinkat(int fd, const char *path, int flag)
+{
+	return syscall3(__NR_unlinkat, fd, (long)path, flag);
+}
diff --git a/src/unistd/usleep.c b/src/unistd/usleep.c
new file mode 100644
index 00000000..e3869017
--- /dev/null
+++ b/src/unistd/usleep.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <time.h>
+
+int usleep(useconds_t useconds)
+{
+	struct timespec tv = {
+		.tv_sec = useconds/1000000,
+		.tv_nsec = (useconds%1000000)*1000
+	};
+	return nanosleep(&tv, &tv);
+}
diff --git a/src/unistd/write.c b/src/unistd/write.c
new file mode 100644
index 00000000..426cfc5b
--- /dev/null
+++ b/src/unistd/write.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	int r;
+	CANCELPT_BEGIN;
+	r = __syscall_write(fd, buf, count);
+	CANCELPT_END;
+	return r;
+}
diff --git a/src/unistd/writev.c b/src/unistd/writev.c
new file mode 100644
index 00000000..a6a118af
--- /dev/null
+++ b/src/unistd/writev.c
@@ -0,0 +1,12 @@
+#include <sys/uio.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t writev(int fd, const struct iovec *iov, int count)
+{
+	ssize_t r;
+	CANCELPT_BEGIN;
+	r = syscall3(__NR_writev, fd, (long)iov, count);
+	CANCELPT_END;
+	return r;
+}
diff --git a/tools/gen-musl-gcc.sh b/tools/gen-musl-gcc.sh
new file mode 100644
index 00000000..89f7f4d9
--- /dev/null
+++ b/tools/gen-musl-gcc.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+printf '#!/bin/sh\n\nlibc_prefix="%s"\n' "$1"
+
+cat <<"EOF"
+libc_lib=$libc_prefix/lib
+libc_inc=$libc_prefix/include
+libc_crt="$libc_lib/crt1.o"
+libc_start="$libc_lib/crti.o"
+libc_end="$libc_lib/crtn.o"
+
+gcc_inc=$libc_inc
+libgcc="`gcc \"$@\" -print-file-name=libgcc.a`"
+
+gcc -wrapper sh,-c,'
+x= ; y= ; z= ; s= ; for i ; do
+  [ "$z" ] || set -- ; z=1
+  case "$i" in
+    -shared) s=1 ; set -- "$@" -shared ;;
+    -Lxxxxxx) x=1 ;;
+    -xxxxxx) x= ; [ "$s" ] || set -- "$@" "'"$libc_start"'" "'"$libc_crt"'" ;;
+    -l*) [ "$y" ] || set -- "$@" '"$libc_end"' ; set -- "$@" "$i" ; y=1 ;;
+    *) [ "$x" ] || set -- "$@" "$i" ;;
+  esac
+done
+exec "$0" "$@"
+' -std=gnu99 -nostdinc -nostdlib \
+  -isystem "$libc_inc" -isystem "$gcc_inc" \
+  -Wl,-xxxxxx "$@" -L"$libc_lib" -lc "$libgcc" -Lxxxxxx -Wl,-nostdlib
+EOF