This patch upgrades OSv to musl 1.1.24 - last release of musl from 1.1 series.
All unit tests are passing but some other tests like couple of httpserver-api
ones are still failing.

Please note that in order to build besides applying this patch
you have to change musl directory and symlink it to a copy
of musl@1.1.24.

This patch is pretty large (most changes are actually removals of some files)
and it is not clear how it can be divided into smaller pieces where each
of those builds and works independently of other ones.

Outstanding:
- finish updating stdio and stdlib files to new musl - it is what most likely 
causes problems
  with httpserver-api tests
- finish updating networking (can be done after initial upgrade I think)
- potentially reconcile locale changes in new musl with OSv side (OSv
  implements subset of glibc (how much?) flavor of locale functionality)
  [can be done after initial upgrade I think]
- TEST, TEST, TEST

Changes:

1. Add new include folder 'include/api/internal_musl_headers' that has copies
  of some internal musl headers from musl src/include folder that need to point
  to OSv versions of files from include/api
  (see musl commit - 
https://github.com/ifduyue/musl/commit/13d1afa46f8098df290008c681816c9eb89ffbdb#diff-df98b91173dc037aba8877d9a33d2f49)

2. Replace __rand48_step.c with musl as the bug reported by Nadav and fixed on 
musl side
  is part of the commit 571744447c23f91feb6439948f3a619aca850dfb in musl.

3. Replace execle.c with musl copy

4. Replace network/inet* with musl copies

5. Update 4 files in libc/stdio with the latest version from 1.1.24.
    
   libc/stdio/__fdopen.c
   libc/stdio/fmemopen.c
   libc/stdio/open_memstream.c
   libc/stdio/open_wmemstream.c
    
   All of those use new __ofl_add() locking mechanism and have
   to be reconciled with other files from musl - fopen.c, etc.
    
   Also removed lines like these:
   if (!libc.threaded) f->lock = -1;

6. Replace couple of setjmp assembly file with musl ones.

7. Temporarily copied 4 files from locale 0.9.12 until we address issues arisen 
by 1.1.24 changes

8. Copied network/freeaddrinfo.c from musl 0.9.12 for now

9. For now add getchar.c and putchar.c from 0.9.12 musl

   This temporarily deals with changes made on musl side:
   
https://github.com/ifduyue/musl/commit/dd8f02b7dce53d6b1c4282439f1636a2d63bee01
   
https://github.com/ifduyue/musl/commit/9dd19122565c70bc6e0fff35724c91a61209a629 
(later)

10.Locale: added UTF8_LOCALE pointing to C_LOCALE and added locale to FILE
    
   Addresses changes related to 
https://github.com/ifduyue/musl/commit/16f18d036d9a7bf590ee6eb86785c0a9658220b6

11.Fixed LCTRANS_CUR and LCTRANS errors

12 Fixed CURRENT_LOCALE problem and couple of other ones

13.Fixed stdio/ftell.c

14.Updated __tz.c with latest musl and dlfcn.c

15.Replaced encrypt.c with latest musl.

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
---
 Makefile                                      |  133 ++-
 fs/vfs/main.cc                                |    2 +-
 include/api/internal_musl_headers/arpa/inet.h |    8 +
 include/api/internal_musl_headers/errno.h     |   14 +
 include/api/internal_musl_headers/pthread.h   |   29 +
 include/api/internal_musl_headers/stdio.h     |    8 +
 include/api/internal_musl_headers/stdlib.h    |   13 +
 include/api/internal_musl_headers/string.h    |   12 +
 .../api/internal_musl_headers/sys/sysinfo.h   |    9 +
 include/api/internal_musl_headers/sys/time.h  |    9 +
 include/api/internal_musl_headers/unistd.h    |   14 +
 include/api/internal_musl_headers/wchar.h     |    9 +
 include/api/link.h                            |   52 +-
 include/api/netinet/in.h                      |    1 +
 include/api/stdlib.h                          |    1 +
 include/api/sys/inotify.h                     |   58 +-
 include/api/sys/timeb.h                       |    1 +
 include/api/time.h                            |  140 +--
 include/api/x64/bits/errno.h                  |    2 +-
 include/api/x64/bits/ipc.h                    |    2 +-
 include/api/x64/bits/ipcstat.h                |    1 +
 include/api/x64/bits/link.h                   |    1 +
 include/api/x64/bits/msg.h                    |    2 +-
 include/api/x64/bits/shm.h                    |    2 +-
 include/api/x64/bits/statfs.h                 |    2 +-
 include/api/x64/bits/stdarg.h                 |    1 -
 include/api/x64/bits/termios.h                |    2 +-
 include/glibc-compat/features.h               |    2 +
 libc/aliases.ld                               |    5 +
 libc/arch/aarch64/setjmp/longjmp.s            |   14 -
 libc/arch/aarch64/setjmp/setjmp.s             |   17 -
 libc/arch/x64/setjmp/longjmp.s                |   22 -
 libc/arch/x64/setjmp/setjmp.s                 |   22 -
 libc/crypt/encrypt.c                          | 1028 -----------------
 libc/dlfcn.cc                                 |    2 +-
 libc/include/sys/timeb.h                      |   22 -
 libc/internal/fp_arch.h                       |    1 +
 libc/internal/libc.h                          |    2 +-
 libc/internal/locale_impl.h                   |   11 +
 libc/internal/lock.h                          |    4 +
 libc/libc.cc                                  |    6 +
 libc/locale/catopen.c                         |    6 +
 libc/locale/duplocale.c                       |   14 +
 libc/locale/intl.c                            |   67 ++
 libc/locale/langinfo.c                        |   74 ++
 libc/locale/setlocale.c                       |    9 +
 libc/locale/uselocale.c                       |    6 +-
 libc/network/freeaddrinfo.c                   |    7 +
 libc/network/inet_addr.c                      |   13 -
 libc/network/inet_aton.c                      |   44 -
 libc/network/inet_ntop.c                      |   50 -
 libc/prng/__rand48_step.c                     |   14 -
 libc/process/execle.c                         |   24 -
 libc/pthread.cc                               |    3 +
 libc/stdio/__fdopen.c                         |   22 +-
 libc/stdio/fmemopen.c                         |   64 +-
 libc/stdio/getchar.c                          |    6 +
 libc/stdio/ofl.c                              |   16 +
 libc/stdio/open_memstream.c                   |   57 +-
 libc/stdio/open_wmemstream.c                  |   57 +-
 libc/stdio/putchar.c                          |    6 +
 libc/stdio/stdio_impl.h                       |    7 +
 libc/syscall_to_function.h                    |    4 +
 libc/time/__tz.c                              |  126 +-
 libc/time/ftime.c                             |   12 -
 65 files changed, 657 insertions(+), 1737 deletions(-)
 create mode 100644 include/api/internal_musl_headers/arpa/inet.h
 create mode 100644 include/api/internal_musl_headers/errno.h
 create mode 100644 include/api/internal_musl_headers/pthread.h
 create mode 100644 include/api/internal_musl_headers/stdio.h
 create mode 100644 include/api/internal_musl_headers/stdlib.h
 create mode 100644 include/api/internal_musl_headers/string.h
 create mode 100644 include/api/internal_musl_headers/sys/sysinfo.h
 create mode 100644 include/api/internal_musl_headers/sys/time.h
 create mode 100644 include/api/internal_musl_headers/unistd.h
 create mode 100644 include/api/internal_musl_headers/wchar.h
 mode change 100644 => 120000 include/api/link.h
 mode change 100644 => 120000 include/api/sys/inotify.h
 create mode 120000 include/api/sys/timeb.h
 mode change 100644 => 120000 include/api/time.h
 create mode 120000 include/api/x64/bits/ipcstat.h
 create mode 120000 include/api/x64/bits/link.h
 delete mode 120000 include/api/x64/bits/stdarg.h
 delete mode 100644 libc/arch/aarch64/setjmp/longjmp.s
 delete mode 100644 libc/arch/aarch64/setjmp/setjmp.s
 delete mode 100644 libc/arch/x64/setjmp/longjmp.s
 delete mode 100644 libc/arch/x64/setjmp/setjmp.s
 delete mode 100644 libc/crypt/encrypt.c
 delete mode 100644 libc/include/sys/timeb.h
 create mode 120000 libc/internal/fp_arch.h
 create mode 100644 libc/internal/lock.h
 create mode 100644 libc/locale/catopen.c
 create mode 100644 libc/locale/duplocale.c
 create mode 100644 libc/locale/intl.c
 create mode 100644 libc/locale/langinfo.c
 create mode 100644 libc/locale/setlocale.c
 create mode 100644 libc/network/freeaddrinfo.c
 delete mode 100644 libc/network/inet_addr.c
 delete mode 100644 libc/network/inet_aton.c
 delete mode 100644 libc/network/inet_ntop.c
 delete mode 100644 libc/prng/__rand48_step.c
 delete mode 100644 libc/process/execle.c
 create mode 100644 libc/stdio/getchar.c
 create mode 100644 libc/stdio/ofl.c
 create mode 100644 libc/stdio/putchar.c
 delete mode 100644 libc/time/ftime.c

diff --git a/Makefile b/Makefile
index fb91e62a..5baf7d71 100644
--- a/Makefile
+++ b/Makefile
@@ -229,6 +229,7 @@ ifeq ($(arch),x64)
 # C++ include directories, though they are already in the default search path.
 INCLUDES += $(shell $(CXX) -E -xc++ - -v </dev/null 2>&1 | awk '/^End/ {exit} 
/^ .*c\+\+/ {print "-isystem" $$0}')
 endif
+INCLUDES += $(pre-include-api)
 INCLUDES += -isystem include/api
 INCLUDES += -isystem include/api/$(arch)
 ifeq ($(arch),aarch64)
@@ -244,6 +245,8 @@ post-includes-bsd += -isystem bsd/sys
 post-includes-bsd += -isystem bsd/
 post-includes-bsd += -isystem bsd/$(arch)
 
+$(out)/musl/%.o: pre-include-api = -isystem include/api/internal_musl_headers 
-isystem musl/src/include
+
 ifneq ($(werror),0)
        CFLAGS_WERROR = -Werror
 endif
@@ -936,7 +939,7 @@ environ_musl =
 ifeq ($(arch),x64)
 musl_arch = x86_64
 else
-musl_arch = notsup
+musl_arch = aarch64
 endif
 
 libc += internal/_chk_fail.o
@@ -1000,6 +1003,7 @@ environ_libc += env/secure_getenv.c
 environ_musl += env/putenv.c
 environ_musl += env/setenv.c
 environ_musl += env/unsetenv.c
+environ_musl += string/strchrnul.c
 
 musl += ctype/__ctype_b_loc.o
 
@@ -1007,59 +1011,33 @@ musl += errno/strerror.o
 libc += errno/strerror.o
 
 musl += locale/catclose.o
+# These files in 1.1.24 more less map to what intl.c used to be
+#musl += locale/c_locale.o
+#musl += locale/__lctrans.o
+#musl += locale/bind_textdomain_codeset.o
+#musl += locale/dcngettext.o -> Fails to compile (old musl does not have it)
+#musl += locale/textdomain.o
+musl += locale/__mo_lookup.o
+musl += locale/pleval.o
 musl += locale/catgets.o
-musl += locale/catopen.o
-musl += locale/duplocale.o
+libc += locale/catopen.o # 1.1.24 has completely new implementation that does 
not compile; for now just copy from 0.9.12
+libc += locale/duplocale.o # 1.1.24 LC_GLOBAL_LOCALE) old = 
&libc.global_locale ADN does not compile; for now just copy from 0.9.12
 libc += locale/freelocale.o
 musl += locale/iconv.o
-musl += locale/intl.o
-musl += locale/isalnum_l.o
-musl += locale/isalpha_l.o
-musl += locale/isblank_l.o
-musl += locale/iscntrl_l.o
-musl += locale/isdigit_l.o
-musl += locale/isgraph_l.o
-musl += locale/islower_l.o
-musl += locale/isprint_l.o
-musl += locale/ispunct_l.o
-musl += locale/isspace_l.o
-musl += locale/isupper_l.o
-musl += locale/iswalnum_l.o
-musl += locale/iswalpha_l.o
-musl += locale/iswblank_l.o
-musl += locale/iswcntrl_l.o
-musl += locale/iswctype_l.o
-musl += locale/iswdigit_l.o
-musl += locale/iswgraph_l.o
-musl += locale/iswlower_l.o
-musl += locale/iswprint_l.o
-musl += locale/iswpunct_l.o
-musl += locale/iswspace_l.o
-musl += locale/iswupper_l.o
-musl += locale/iswxdigit_l.o
-musl += locale/isxdigit_l.o
-musl += locale/langinfo.o
+musl += locale/iconv_close.o
+libc += locale/intl.o #-> got split into many other files in new musl; for now 
copy intl.c from 0.9.12
+libc += locale/langinfo.o #-> ‘struct __locale_struct’ has no member named 
‘cat’; for now copied from 1.1.24 and changed to drop references to cat field 
in __locale_struct
 musl += locale/localeconv.o
-musl += locale/setlocale.o
-musl += locale/strcasecmp_l.o
+libc += locale/setlocale.o # 1.1.24 has completely new implementation that 
does not compile; for now just copy from 0.9.12
 musl += locale/strcoll.o
-musl += locale/strerror_l.o
 musl += locale/strfmon.o
-musl += locale/strncasecmp_l.o
 libc += locale/strtod_l.o
 libc += locale/strtof_l.o
 libc += locale/strtold_l.o
 musl += locale/strxfrm.o
-musl += locale/tolower_l.o
-musl += locale/toupper_l.o
-musl += locale/towctrans_l.o
-musl += locale/towlower_l.o
-musl += locale/towupper_l.o
 libc += locale/uselocale.o
 musl += locale/wcscoll.o
 musl += locale/wcsxfrm.o
-musl += locale/wctrans_l.o
-musl += locale/wctype_l.o
 
 musl += math/__cos.o
 musl += math/__cosdf.o
@@ -1084,6 +1062,16 @@ musl += math/__sinl.o
 musl += math/__tan.o
 musl += math/__tandf.o
 musl += math/__tanl.o
+musl += math/__math_oflow.o
+musl += math/__math_oflowf.o
+musl += math/__math_xflow.o
+musl += math/__math_xflowf.o
+musl += math/__math_uflow.o
+musl += math/__math_uflowf.o
+musl += math/__math_divzero.o
+musl += math/__math_divzerof.o
+musl += math/__math_invalid.o
+musl += math/__math_invalidf.o
 musl += math/acos.o
 musl += math/acosf.o
 musl += math/acosh.o
@@ -1124,11 +1112,13 @@ musl += math/erf.o
 musl += math/erff.o
 musl += math/erfl.o
 musl += math/exp.o
+musl += math/exp_data.o
 musl += math/exp10.o
 musl += math/exp10f.o
 musl += math/exp10l.o
 musl += math/exp2.o
 musl += math/exp2f.o
+musl += math/exp2f_data.o
 musl += math/exp2l.o
 $(out)/musl/src/math/exp2l.o: CFLAGS += -Wno-unused-variable
 musl += math/expf.o
@@ -1167,8 +1157,11 @@ musl += math/hypot.o
 musl += math/hypotf.o
 musl += math/hypotl.o
 musl += math/ilogb.o
+$(out)/musl/src/math/ilogb.o: CFLAGS += -Wno-unknown-pragmas
 musl += math/ilogbf.o
+$(out)/musl/src/math/ilogbf.o: CFLAGS += -Wno-unknown-pragmas
 musl += math/ilogbl.o
+$(out)/musl/src/math/ilogbl.o: CFLAGS += -Wno-unknown-pragmas
 musl += math/j0.o
 musl += math/j0f.o
 musl += math/j1.o
@@ -1193,6 +1186,7 @@ musl += math/llround.o
 musl += math/llroundf.o
 musl += math/llroundl.o
 musl += math/log.o
+musl += math/log_data.o
 musl += math/log10.o
 musl += math/log10f.o
 musl += math/log10l.o
@@ -1200,12 +1194,15 @@ musl += math/log1p.o
 musl += math/log1pf.o
 musl += math/log1pl.o
 musl += math/log2.o
+musl += math/log2_data.o
 musl += math/log2f.o
+musl += math/log2f_data.o
 musl += math/log2l.o
 musl += math/logb.o
 musl += math/logbf.o
 musl += math/logbl.o
 musl += math/logf.o
+musl += math/logf_data.o
 musl += math/logl.o
 musl += math/lrint.o
 #musl += math/lrintf.o
@@ -1232,7 +1229,9 @@ musl += math/nexttoward.o
 musl += math/nexttowardf.o
 musl += math/nexttowardl.o
 musl += math/pow.o
+musl += math/pow_data.o
 musl += math/powf.o
+musl += math/powf_data.o
 musl += math/powl.o
 musl += math/remainder.o
 musl += math/remainderf.o
@@ -1316,6 +1315,8 @@ libc += misc/__longjmp_chk.o
 
 musl += signal/killpg.o
 musl += signal/siginterrupt.o
+musl += signal/sigrtmin.o
+musl += signal/sigrtmax.o
 
 musl += multibyte/btowc.o
 musl += multibyte/internal.o
@@ -1344,17 +1345,27 @@ libc += network/gethostbyname_r.o
 musl += network/gethostbyname2_r.o
 musl += network/gethostbyaddr_r.o
 musl += network/gethostbyaddr.o
+musl += network/resolvconf.o
+musl += network/res_msend.o #For now copy from musl 1.1.24 and uncomment 
_pthread_cleanup_push/_pthread_cleanup_pop (deal later with it)
+$(out)/musl/src/network/res_msend.o: CFLAGS += -Wno-maybe-uninitialized 
--include libc/syscall_to_function.h --include libc/internal/pthread_stubs.h
+$(out)/libc/multibyte/mbsrtowcs.o: CFLAGS += -Imusl/src/multibyte
+musl += network/lookup_ipliteral.o
 libc += network/getaddrinfo.o
-musl += network/freeaddrinfo.o
+libc += network/freeaddrinfo.o #copied from musl 0.9.12, in 1.1.24 more than 
LOCK, mess with changes to ai_buf struct -> affects our getaddrinfo.c
+musl += network/dn_expand.o
+musl += network/res_mkquery.o
+musl += network/dns_parse.o
 musl += network/in6addr_any.o
 musl += network/in6addr_loopback.o
+musl += network/lookup_name.o
+musl += network/lookup_serv.o
 libc += network/getnameinfo.o
 libc += network/__dns.o
 libc += network/__ipparse.o
-libc += network/inet_addr.o
-libc += network/inet_aton.o
+musl += network/inet_addr.o
+musl += network/inet_aton.o
 musl += network/inet_pton.o
-libc += network/inet_ntop.o
+musl += network/inet_ntop.o
 musl += network/proto.o
 libc += network/if_indextoname.o
 libc += network/if_nametoindex.o
@@ -1372,7 +1383,7 @@ musl += network/res_init.o
 musl += prng/rand.o
 musl += prng/rand_r.o
 libc += prng/random.o
-libc += prng/__rand48_step.o
+musl += prng/__rand48_step.o
 musl += prng/__seed48.o
 musl += prng/drand48.o
 musl += prng/lcong48.o
@@ -1383,16 +1394,14 @@ musl += prng/srand48.o
 libc += random.o
 
 libc += process/execve.o
-libc += process/execle.o
+musl += process/execle.o
 musl += process/execv.o
 musl += process/execl.o
 libc += process/waitpid.o
 musl += process/wait.o
 
-libc += arch/$(arch)/setjmp/setjmp.o
-libc += arch/$(arch)/setjmp/longjmp.o
-libc += arch/$(arch)/setjmp/sigrtmax.o
-libc += arch/$(arch)/setjmp/sigrtmin.o
+musl += setjmp/$(musl_arch)/setjmp.o
+musl += setjmp/$(musl_arch)/longjmp.o
 libc += arch/$(arch)/setjmp/siglongjmp.o
 libc += arch/$(arch)/setjmp/sigsetjmp.o
 libc += arch/$(arch)/setjmp/block.o
@@ -1405,6 +1414,7 @@ endif
 
 musl += stdio/__fclose_ca.o
 libc += stdio/__fdopen.o
+$(out)/libc/stdio/__fdopen.o: CFLAGS += --include libc/syscall_to_function.h
 musl += stdio/__fmodeflags.o
 libc += stdio/__fopen_rb_ca.o
 libc += stdio/__fprintf_chk.o
@@ -1423,6 +1433,8 @@ musl += stdio/__toread.o
 musl += stdio/__towrite.o
 musl += stdio/__uflow.o
 libc += stdio/__vfprintf_chk.o
+libc += stdio/ofl.o
+musl += stdio/ofl_add.o
 musl += stdio/asprintf.o
 musl += stdio/clearerr.o
 musl += stdio/dprintf.o
@@ -1464,7 +1476,7 @@ musl += stdio/fwrite.o
 musl += stdio/fwscanf.o
 libc += stdio/getc.o
 musl += stdio/getc_unlocked.o
-musl += stdio/getchar.o
+libc += stdio/getchar.o #Taken verbatim 0.9.12
 musl += stdio/getchar_unlocked.o
 musl += stdio/getdelim.o
 musl += stdio/getline.o
@@ -1478,7 +1490,7 @@ musl += stdio/perror.o
 musl += stdio/printf.o
 libc += stdio/putc.o
 musl += stdio/putc_unlocked.o
-musl += stdio/putchar.o
+libc += stdio/putchar.o #Taken verbatim 0.9.12
 musl += stdio/putchar_unlocked.o
 musl += stdio/puts.o
 musl += stdio/putw.o
@@ -1500,6 +1512,7 @@ libc += stdio/stdout.o
 musl += stdio/swprintf.o
 musl += stdio/swscanf.o
 musl += stdio/tempnam.o
+$(out)/musl/src/stdio/tempnam.o: CFLAGS += --include libc/syscall_to_function.h
 musl += stdio/tmpfile.o
 $(out)/musl/src/stdio/tmpfile.o: CFLAGS += --include libc/syscall_to_function.h
 musl += stdio/tmpnam.o
@@ -1641,13 +1654,13 @@ musl += temp/mktemp.o
 musl += temp/mkostemp.o
 musl += temp/mkostemps.o
 
-musl += time/__asctime.o
 musl += time/__map_file.o
 $(out)/musl/src/time/__map_file.o: CFLAGS += --include 
libc/syscall_to_function.h
 musl += time/__month_to_secs.o
 musl += time/__secs_to_tm.o
 musl += time/__tm_to_secs.o
 libc += time/__tz.o
+$(out)/libc/time/__tz.o: pre-include-api = -isystem 
include/api/internal_musl_headers -isystem musl/src/include
 musl += time/__year_to_secs.o
 musl += time/asctime.o
 musl += time/asctime_r.o
@@ -1665,7 +1678,7 @@ musl += time/strptime.o
 musl += time/time.o
 musl += time/timegm.o
 musl += time/wcsftime.o
-libc += time/ftime.o # verbatim copy of the file as in 4b15d9f46a2b@musl
+musl += time/ftime.o
 $(out)/libc/time/ftime.o: CFLAGS += -Ilibc/include
 
 musl += termios/tcflow.o
@@ -1724,14 +1737,11 @@ libc += mallopt.o
 
 libc += linux/makedev.o
 
-ifneq ($(musl_arch), notsup)
 musl += fenv/fegetexceptflag.o
 musl += fenv/feholdexcept.o
 musl += fenv/fesetexceptflag.o
+musl += fenv/fesetround.o
 musl += fenv/$(musl_arch)/fenv.o
-else
-musl += fenv/fenv.o
-endif
 
 musl += crypt/crypt_blowfish.o
 musl += crypt/crypt.o
@@ -1740,7 +1750,7 @@ musl += crypt/crypt_md5.o
 musl += crypt/crypt_r.o
 musl += crypt/crypt_sha256.o
 musl += crypt/crypt_sha512.o
-libc += crypt/encrypt.o
+musl += crypt/encrypt.o
 
 #include $(src)/fs/build.mk:
 
@@ -1894,6 +1904,9 @@ $(out)/bsd/%.o: COMMON += -DSMP 
-D'__FBSDID(__str__)=extern int __bogus__'
 environ_sources = $(addprefix libc/, $(environ_libc))
 environ_sources += $(addprefix musl/src/, $(environ_musl))
 
+$(out)/libenviron.so: pre-include-api = -isystem 
include/api/internal_musl_headers -isystem musl/src/include
+$(out)/libenviron.so: source-dialects =
+
 $(out)/libenviron.so: $(environ_sources)
        $(makedir)
         $(call quiet, $(CC) $(CFLAGS) -shared -o $(out)/libenviron.so 
$(environ_sources), CC libenviron.so)
diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
index d20e1a57..ae63f06d 100644
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -2096,7 +2096,7 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *_offset, 
size_t count)
         return -1;
     }
 
-    auto ret = write(out_fd, src + (offset % PAGESIZE), count);
+    auto ret = write(out_fd, src + (offset % PAGE_SIZE), count);
 
     if (ret < 0) {
         return libc_error(errno);
diff --git a/include/api/internal_musl_headers/arpa/inet.h 
b/include/api/internal_musl_headers/arpa/inet.h
new file mode 100644
index 00000000..3054f380
--- /dev/null
+++ b/include/api/internal_musl_headers/arpa/inet.h
@@ -0,0 +1,8 @@
+#ifndef ARPA_INET_H
+#define ARPA_INET_H
+
+#include "../../arpa/inet.h"
+
+hidden int __inet_aton(const char *, struct in_addr *);
+
+#endif
diff --git a/include/api/internal_musl_headers/errno.h 
b/include/api/internal_musl_headers/errno.h
new file mode 100644
index 00000000..643c88a0
--- /dev/null
+++ b/include/api/internal_musl_headers/errno.h
@@ -0,0 +1,14 @@
+#ifndef ERRNO_H
+#define ERRNO_H
+
+#include "../errno.h"
+
+#ifdef __GNUC__
+__attribute__((const))
+#endif
+int *___errno_location(void);
+
+#undef errno
+#define errno (*___errno_location())
+
+#endif
diff --git a/include/api/internal_musl_headers/pthread.h 
b/include/api/internal_musl_headers/pthread.h
new file mode 100644
index 00000000..33d0b87e
--- /dev/null
+++ b/include/api/internal_musl_headers/pthread.h
@@ -0,0 +1,29 @@
+#ifndef PTHREAD_H
+#define PTHREAD_H
+
+#include "../pthread.h"
+
+hidden int __pthread_once(pthread_once_t *, void (*)(void));
+hidden void __pthread_testcancel(void);
+hidden int __pthread_setcancelstate(int, int *);
+hidden int __pthread_create(pthread_t *restrict, const pthread_attr_t 
*restrict, void *(*)(void *), void *restrict);
+hidden _Noreturn void __pthread_exit(void *);
+hidden int __pthread_join(pthread_t, void **);
+hidden int __pthread_mutex_lock(pthread_mutex_t *);
+hidden int __pthread_mutex_trylock(pthread_mutex_t *);
+hidden int __pthread_mutex_trylock_owner(pthread_mutex_t *);
+hidden int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct 
timespec *restrict);
+hidden int __pthread_mutex_unlock(pthread_mutex_t *);
+hidden int __private_cond_signal(pthread_cond_t *, int);
+hidden int __pthread_cond_timedwait(pthread_cond_t *restrict, pthread_mutex_t 
*restrict, const struct timespec *restrict);
+hidden int __pthread_key_create(pthread_key_t *, void (*)(void *));
+hidden int __pthread_key_delete(pthread_key_t);
+hidden int __pthread_rwlock_rdlock(pthread_rwlock_t *);
+hidden int __pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+hidden int __pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const 
struct timespec *__restrict);
+hidden int __pthread_rwlock_wrlock(pthread_rwlock_t *);
+hidden int __pthread_rwlock_trywrlock(pthread_rwlock_t *);
+hidden int __pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const 
struct timespec *__restrict);
+hidden int __pthread_rwlock_unlock(pthread_rwlock_t *);
+
+#endif
diff --git a/include/api/internal_musl_headers/stdio.h 
b/include/api/internal_musl_headers/stdio.h
new file mode 100644
index 00000000..dc702d39
--- /dev/null
+++ b/include/api/internal_musl_headers/stdio.h
@@ -0,0 +1,8 @@
+#ifndef STDIO_H
+#define STDIO_H
+
+#define __DEFINED_struct__IO_FILE
+
+#include "../stdio.h"
+
+#endif
diff --git a/include/api/internal_musl_headers/stdlib.h 
b/include/api/internal_musl_headers/stdlib.h
new file mode 100644
index 00000000..eaf6651e
--- /dev/null
+++ b/include/api/internal_musl_headers/stdlib.h
@@ -0,0 +1,13 @@
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include "../stdlib.h"
+
+hidden int __putenv(char *, size_t, char *);
+hidden void __env_rm_add(char *, char *);
+hidden int __mkostemps(char *, int, int);
+hidden int __ptsname_r(int, char *, size_t);
+hidden char *__randname(char *);
+
+#endif
+
diff --git a/include/api/internal_musl_headers/string.h 
b/include/api/internal_musl_headers/string.h
new file mode 100644
index 00000000..65315b93
--- /dev/null
+++ b/include/api/internal_musl_headers/string.h
@@ -0,0 +1,12 @@
+#ifndef STRING_H
+#define STRING_H
+
+#include "../string.h"
+
+hidden void *__memrchr(const void *, int, size_t);
+hidden char *__stpcpy(char *, const char *);
+hidden char *__stpncpy(char *, const char *, size_t);
+hidden char *__strchrnul(const char *, int);
+
+#endif
+
diff --git a/include/api/internal_musl_headers/sys/sysinfo.h 
b/include/api/internal_musl_headers/sys/sysinfo.h
new file mode 100644
index 00000000..d5a7702a
--- /dev/null
+++ b/include/api/internal_musl_headers/sys/sysinfo.h
@@ -0,0 +1,9 @@
+#ifndef SYS_SYSINFO_H
+#define SYS_SYSINFO_H
+
+#include "../../sys/sysinfo.h"
+#include <features.h>
+
+hidden int __lsysinfo(struct sysinfo *);
+
+#endif
diff --git a/include/api/internal_musl_headers/sys/time.h 
b/include/api/internal_musl_headers/sys/time.h
new file mode 100644
index 00000000..ad820d4d
--- /dev/null
+++ b/include/api/internal_musl_headers/sys/time.h
@@ -0,0 +1,9 @@
+#ifndef SYS_TIME_H
+#define SYS_TIME_H
+
+#include "../../sys/time.h"
+
+hidden int __futimesat(int, const char *, const struct timeval [2]);
+
+#endif
+
diff --git a/include/api/internal_musl_headers/unistd.h 
b/include/api/internal_musl_headers/unistd.h
new file mode 100644
index 00000000..deed1f71
--- /dev/null
+++ b/include/api/internal_musl_headers/unistd.h
@@ -0,0 +1,14 @@
+#ifndef UNISTD_H
+#define UNISTD_H
+
+#include "../unistd.h"
+
+extern char **__environ;
+
+hidden int __dup3(int, int, int);
+hidden int __mkostemps(char *, int, int);
+hidden int __execvpe(const char *, char *const *, char *const *);
+hidden int __aio_close(int);
+hidden off_t __lseek(int, off_t, int);
+
+#endif
diff --git a/include/api/internal_musl_headers/wchar.h 
b/include/api/internal_musl_headers/wchar.h
new file mode 100644
index 00000000..567c9969
--- /dev/null
+++ b/include/api/internal_musl_headers/wchar.h
@@ -0,0 +1,9 @@
+#ifndef WCHAR_H
+#define WCHAR_H
+
+#define __DEFINED_struct__IO_FILE
+
+#include "../wchar.h"
+
+#endif
+
diff --git a/include/api/link.h b/include/api/link.h
deleted file mode 100644
index a813cbe1..00000000
--- a/include/api/link.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _LINK_H
-#define _LINK_H
-
-#include <elf.h>
-#define __NEED_size_t
-#define __NEED_uint32_t
-#include <bits/alltypes.h>
-
-#if UINTPTR_MAX > 0xffffffff
-#define ElfW(type) Elf64_ ## type
-#else
-#define ElfW(type) Elf32_ ## type
-#endif
-
-#include <sys/cdefs.h>
-__BEGIN_DECLS
-
-/* this is the same everywhere except alpha and s390 */
-typedef uint32_t Elf_Symndx;
-
-struct dl_phdr_info {
-       ElfW(Addr) dlpi_addr;
-       const char *dlpi_name;
-       const ElfW(Phdr) *dlpi_phdr;
-       ElfW(Half) dlpi_phnum;
-       unsigned long long int dlpi_adds;
-       unsigned long long int dlpi_subs;
-       size_t dlpi_tls_modid;
-       void *dlpi_tls_data;
-};
-
-struct link_map {
-       ElfW(Addr) l_addr;
-       char *l_name;
-       ElfW(Dyn) *l_ld;
-       struct link_map *l_next, *l_prev;
-};
-
-struct r_debug {
-       int r_version;
-       struct link_map *r_map;
-       ElfW(Addr) r_brk;
-       enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
-       ElfW(Addr) r_ldbase;
-};
-
-int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), void *);
-
-__END_DECLS
-
-#endif
diff --git a/include/api/link.h b/include/api/link.h
new file mode 120000
index 00000000..b163099a
--- /dev/null
+++ b/include/api/link.h
@@ -0,0 +1 @@
+../../musl/include/link.h
\ No newline at end of file
diff --git a/include/api/netinet/in.h b/include/api/netinet/in.h
index 18fa77f7..54d7b73a 100644
--- a/include/api/netinet/in.h
+++ b/include/api/netinet/in.h
@@ -6,6 +6,7 @@ extern "C" {
 #endif
 
 #include <features.h>
+#include <sys/socket.h>
 
 #define __NEED_in_addr_t
 #define __NEED_in_port_t
diff --git a/include/api/stdlib.h b/include/api/stdlib.h
index 8cfb1b23..834ed3fa 100644
--- a/include/api/stdlib.h
+++ b/include/api/stdlib.h
@@ -69,6 +69,7 @@ int mbtowc (wchar_t *__restrict, const char *__restrict, 
size_t);
 int wctomb (char *, wchar_t);
 size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
 size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
+size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
 
 #define EXIT_FAILURE 1
 #define EXIT_SUCCESS 0
diff --git a/include/api/sys/inotify.h b/include/api/sys/inotify.h
deleted file mode 100644
index 46638cac..00000000
--- a/include/api/sys/inotify.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _SYS_INOTIFY_H
-#define _SYS_INOTIFY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <fcntl.h>
-
-struct inotify_event {
-       int wd;
-       uint32_t mask, cookie, len;
-       char name[];
-};
-
-#define IN_CLOEXEC O_CLOEXEC
-#define IN_NONBLOCK O_NONBLOCK
-
-#define IN_ACCESS        0x00000001
-#define IN_MODIFY        0x00000002
-#define IN_ATTRIB        0x00000004
-#define IN_CLOSE_WRITE   0x00000008
-#define IN_CLOSE_NOWRITE 0x00000010
-#define IN_CLOSE         (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
-#define IN_OPEN          0x00000020
-#define IN_MOVED_FROM    0x00000040
-#define IN_MOVED_TO      0x00000080
-#define IN_MOVE          (IN_MOVED_FROM | IN_MOVED_TO)
-#define IN_CREATE        0x00000100
-#define IN_DELETE        0x00000200
-#define IN_DELETE_SELF   0x00000400
-#define IN_MOVE_SELF     0x00000800
-#define IN_ALL_EVENTS    0x00000fff
-
-#define IN_UNMOUNT       0x00002000
-#define IN_Q_OVERFLOW    0x00004000
-#define IN_IGNORED       0x00008000
-
-#define IN_ONLYDIR       0x01000000
-#define IN_DONT_FOLLOW   0x02000000
-#define IN_EXCL_UNLINK   0x04000000
-#define IN_MASK_ADD      0x20000000
-
-#define IN_ISDIR         0x40000000
-#define IN_ONESHOT       0x80000000
-
-int inotify_init(void);
-int inotify_init1(int);
-int inotify_add_watch(int, const char *, uint32_t);
-int inotify_rm_watch(int, int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/api/sys/inotify.h b/include/api/sys/inotify.h
new file mode 120000
index 00000000..9143407e
--- /dev/null
+++ b/include/api/sys/inotify.h
@@ -0,0 +1 @@
+../../../musl/include/sys/inotify.h
\ No newline at end of file
diff --git a/include/api/sys/timeb.h b/include/api/sys/timeb.h
new file mode 120000
index 00000000..c946af6a
--- /dev/null
+++ b/include/api/sys/timeb.h
@@ -0,0 +1 @@
+../../../musl/include/sys/timeb.h
\ No newline at end of file
diff --git a/include/api/time.h b/include/api/time.h
deleted file mode 100644
index 16ec08ae..00000000
--- a/include/api/time.h
+++ /dev/null
@@ -1,139 +0,0 @@
-#ifndef        _TIME_H
-#define _TIME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <features.h>
-
-#ifdef __cplusplus
-#define NULL 0L
-#else
-#define NULL ((void*)0)
-#endif
-
-
-#define __NEED_size_t
-#define __NEED_time_t
-#define __NEED_clock_t
-#define __NEED_struct_timespec
-
-#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
- || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
- || defined(_BSD_SOURCE)
-#define __NEED_clockid_t
-#define __NEED_timer_t
-#define __NEED_pid_t
-#define __NEED_locale_t
-#endif
-
-#include <bits/alltypes.h>
-
-#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
-#define __tm_gmtoff tm_gmtoff
-#define __tm_zone tm_zone
-#endif
-
-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;
-};
-
-clock_t clock (void);
-time_t time (time_t *);
-double difftime (time_t, time_t);
-time_t mktime (struct tm *);
-size_t strftime (char *__restrict, size_t, const char *__restrict, const 
struct tm *__restrict);
-struct tm *gmtime (const time_t *);
-struct tm *localtime (const time_t *);
-char *asctime (const struct tm *);
-char *ctime (const time_t *);
-int timespec_get(struct timespec *, int);
-
-#define CLOCKS_PER_SEC 1000000L
-
-#define TIME_UTC 1
-
-#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
- || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
- || defined(_BSD_SOURCE)
-
-size_t strftime_l (char *  __restrict, size_t, const char *  __restrict, const 
struct tm *  __restrict, locale_t);
-
-struct tm *gmtime_r (const time_t *__restrict, struct tm *__restrict);
-struct tm *localtime_r (const time_t *__restrict, struct tm *__restrict);
-char *asctime_r (const struct tm *__restrict, char *__restrict);
-char *ctime_r (const time_t *, char *);
-
-void tzset (void);
-
-struct itimerspec
-{
-       struct timespec it_interval;
-       struct timespec it_value;
-};
-
-#define CLOCK_REALTIME           0
-#define CLOCK_MONOTONIC          1
-#define CLOCK_PROCESS_CPUTIME_ID 2
-#define CLOCK_THREAD_CPUTIME_ID  3
-#define CLOCK_MONOTONIC_RAW      4
-#define CLOCK_REALTIME_COARSE    5
-#define CLOCK_MONOTONIC_COARSE   6
-#define CLOCK_BOOTTIME           7
-#define CLOCK_REALTIME_ALARM     8
-#define CLOCK_BOOTTIME_ALARM     9
-#define CLOCK_SGI_CYCLE         10
-#define CLOCK_TAI               11
-
-#define TIMER_ABSTIME 1
-
-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 *);
-
-struct sigevent;
-int timer_create (clockid_t, struct sigevent *__restrict, timer_t *__restrict);
-int timer_delete (timer_t);
-int timer_settime (timer_t, int, const struct itimerspec *__restrict, struct 
itimerspec *__restrict);
-int timer_gettime (timer_t, struct itimerspec *);
-int timer_getoverrun (timer_t);
-
-#endif
-
-
-#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
-char *strptime (const char *__restrict, const char *__restrict, struct tm 
*__restrict);
-extern int daylight;
-extern long timezone;
-extern char *tzname[2];
-extern int getdate_err;
-struct tm *getdate (const char *);
-#endif
-
-
-#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
-int stime(const time_t *);
-time_t timegm(struct tm *);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/include/api/time.h b/include/api/time.h
new file mode 120000
index 00000000..f2c2b9ea
--- /dev/null
+++ b/include/api/time.h
@@ -0,0 +1 @@
+../../musl/include/time.h
\ No newline at end of file
diff --git a/include/api/x64/bits/errno.h b/include/api/x64/bits/errno.h
index babb760a..aa3382d9 120000
--- a/include/api/x64/bits/errno.h
+++ b/include/api/x64/bits/errno.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/errno.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/errno.h
\ No newline at end of file
diff --git a/include/api/x64/bits/ipc.h b/include/api/x64/bits/ipc.h
index 4d58823e..c7955297 120000
--- a/include/api/x64/bits/ipc.h
+++ b/include/api/x64/bits/ipc.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/ipc.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/ipc.h
\ No newline at end of file
diff --git a/include/api/x64/bits/ipcstat.h b/include/api/x64/bits/ipcstat.h
new file mode 120000
index 00000000..57e8cb3f
--- /dev/null
+++ b/include/api/x64/bits/ipcstat.h
@@ -0,0 +1 @@
+../../../../musl/arch/generic/bits/ipcstat.h
\ No newline at end of file
diff --git a/include/api/x64/bits/link.h b/include/api/x64/bits/link.h
new file mode 120000
index 00000000..96bd2402
--- /dev/null
+++ b/include/api/x64/bits/link.h
@@ -0,0 +1 @@
+../../../../musl/arch/generic/bits/link.h
\ No newline at end of file
diff --git a/include/api/x64/bits/msg.h b/include/api/x64/bits/msg.h
index 3d200408..caaec5d7 120000
--- a/include/api/x64/bits/msg.h
+++ b/include/api/x64/bits/msg.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/msg.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/msg.h
\ No newline at end of file
diff --git a/include/api/x64/bits/shm.h b/include/api/x64/bits/shm.h
index 877cd1b9..1315f22f 120000
--- a/include/api/x64/bits/shm.h
+++ b/include/api/x64/bits/shm.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/shm.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/shm.h
\ No newline at end of file
diff --git a/include/api/x64/bits/statfs.h b/include/api/x64/bits/statfs.h
index d08749fc..cd92eaf4 120000
--- a/include/api/x64/bits/statfs.h
+++ b/include/api/x64/bits/statfs.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/statfs.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/statfs.h
\ No newline at end of file
diff --git a/include/api/x64/bits/stdarg.h b/include/api/x64/bits/stdarg.h
deleted file mode 120000
index 133456b3..00000000
--- a/include/api/x64/bits/stdarg.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../musl/arch/x86_64/bits/stdarg.h
\ No newline at end of file
diff --git a/include/api/x64/bits/termios.h b/include/api/x64/bits/termios.h
index 639f866f..41b9b61d 120000
--- a/include/api/x64/bits/termios.h
+++ b/include/api/x64/bits/termios.h
@@ -1 +1 @@
-../../../../musl/arch/x86_64/bits/termios.h
\ No newline at end of file
+../../../../musl/arch/generic/bits/termios.h
\ No newline at end of file
diff --git a/include/glibc-compat/features.h b/include/glibc-compat/features.h
index 094a0fad..7f5c4ee7 100644
--- a/include/glibc-compat/features.h
+++ b/include/glibc-compat/features.h
@@ -10,6 +10,8 @@
 
 #include_next <features.h>
 
+#define hidden __attribute__((__visibility__("hidden")))
+
 #define __GNU_LIBRARY__ 6
 #define __GLIBC__       2
 #define __GLIBC_MINOR__ 20
diff --git a/libc/aliases.ld b/libc/aliases.ld
index 4ce216ad..f6adf5d3 100644
--- a/libc/aliases.ld
+++ b/libc/aliases.ld
@@ -9,6 +9,9 @@
  * address.
  */
 
+/* errno */
+___errno_location = __errno_location;
+
 /* network */
 __res_init = res_init;
 
@@ -54,3 +57,5 @@ stat64 = stat;
 fstat64 = fstat;
 lstat64 = lstat;
 fstatat64 = fstatat;
+
+__lseek = lseek;
diff --git a/libc/arch/aarch64/setjmp/longjmp.s 
b/libc/arch/aarch64/setjmp/longjmp.s
deleted file mode 100644
index cf73028e..00000000
--- a/libc/arch/aarch64/setjmp/longjmp.s
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2014 Huawei Technologies Duesseldorf GmbH
- *
- * This work is open source software, licensed under the terms of the
- * BSD license as described in the LICENSE file in the top-level directory.
- */
-
-.global _longjmp
-.global longjmp
-.type _longjmp,@function
-.type longjmp,@function
-_longjmp:
-longjmp:
-        wfi
-        b longjmp
diff --git a/libc/arch/aarch64/setjmp/setjmp.s 
b/libc/arch/aarch64/setjmp/setjmp.s
deleted file mode 100644
index 654ecb26..00000000
--- a/libc/arch/aarch64/setjmp/setjmp.s
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright 2014 Huawei Technologies Duesseldorf GmbH
- *
- * This work is open source software, licensed under the terms of the
- * BSD license as described in the LICENSE file in the top-level directory.
- */
-
-.global __setjmp
-.global _setjmp
-.global setjmp
-.type __setjmp,@function
-.type _setjmp,@function
-.type setjmp,@function
-__setjmp:
-_setjmp:
-setjmp:
-        wfi
-        b setjmp
diff --git a/libc/arch/x64/setjmp/longjmp.s b/libc/arch/x64/setjmp/longjmp.s
deleted file mode 100644
index e175a4b9..00000000
--- a/libc/arch/x64/setjmp/longjmp.s
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
-.global _longjmp
-.global longjmp
-.type _longjmp,@function
-.type longjmp,@function
-_longjmp:
-longjmp:
-       mov %rsi,%rax           /* val will be longjmp return */
-       test %rax,%rax
-       jnz 1f
-       inc %rax                /* if val==0, val=1 per longjmp semantics */
-1:
-       mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
-       mov 8(%rdi),%rbp
-       mov 16(%rdi),%r12
-       mov 24(%rdi),%r13
-       mov 32(%rdi),%r14
-       mov 40(%rdi),%r15
-       mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
-       mov %rdx,%rsp
-       mov 56(%rdi),%rdx       /* this is the instruction pointer */
-       jmp *%rdx               /* goto saved address without altering rsp */
diff --git a/libc/arch/x64/setjmp/setjmp.s b/libc/arch/x64/setjmp/setjmp.s
deleted file mode 100644
index 98f58b8d..00000000
--- a/libc/arch/x64/setjmp/setjmp.s
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
-.global __setjmp
-.global _setjmp
-.global setjmp
-.type __setjmp,@function
-.type _setjmp,@function
-.type setjmp,@function
-__setjmp:
-_setjmp:
-setjmp:
-       mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
-       mov %rbp,8(%rdi)
-       mov %r12,16(%rdi)
-       mov %r13,24(%rdi)
-       mov %r14,32(%rdi)
-       mov %r15,40(%rdi)
-       lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
-       mov %rdx,48(%rdi)
-       mov (%rsp),%rdx         /* save return addr ptr for new rip */
-       mov %rdx,56(%rdi)
-       xor %rax,%rax           /* always return 0 */
-       ret
diff --git a/libc/crypt/encrypt.c b/libc/crypt/encrypt.c
deleted file mode 100644
index 27424921..00000000
--- a/libc/crypt/encrypt.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
-
-merge of musl 1.1.19 crypt_des.c and encrypt.c
-
-https://git.musl-libc.org/cgit/musl/plain/src/crypt/crypt_des.c
-https://git.musl-libc.org/cgit/musl/plain/src/crypt/encrypt.c
-
-*/
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-struct expanded_key {
-       uint32_t l[16], r[16];
-};
-
-
-void __des_enc_setkey(const unsigned char *key, struct expanded_key *ekey);
-void __enc_do_des(uint32_t l_in, uint32_t r_in,
-    uint32_t *l_out, uint32_t *r_out,
-    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey);
-
-#define _PASSWORD_EFMT1 '_'
-
-static const unsigned char key_shifts[16] = {
-       1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
-};
-
-static const uint32_t psbox[8][64] = {
-       {
-               0x00808200,0x00000000,0x00008000,0x00808202,
-               0x00808002,0x00008202,0x00000002,0x00008000,
-               0x00000200,0x00808200,0x00808202,0x00000200,
-               0x00800202,0x00808002,0x00800000,0x00000002,
-               0x00000202,0x00800200,0x00800200,0x00008200,
-               0x00008200,0x00808000,0x00808000,0x00800202,
-               0x00008002,0x00800002,0x00800002,0x00008002,
-               0x00000000,0x00000202,0x00008202,0x00800000,
-               0x00008000,0x00808202,0x00000002,0x00808000,
-               0x00808200,0x00800000,0x00800000,0x00000200,
-               0x00808002,0x00008000,0x00008200,0x00800002,
-               0x00000200,0x00000002,0x00800202,0x00008202,
-               0x00808202,0x00008002,0x00808000,0x00800202,
-               0x00800002,0x00000202,0x00008202,0x00808200,
-               0x00000202,0x00800200,0x00800200,0x00000000,
-               0x00008002,0x00008200,0x00000000,0x00808002,
-       },{
-               0x40084010,0x40004000,0x00004000,0x00084010,
-               0x00080000,0x00000010,0x40080010,0x40004010,
-               0x40000010,0x40084010,0x40084000,0x40000000,
-               0x40004000,0x00080000,0x00000010,0x40080010,
-               0x00084000,0x00080010,0x40004010,0x00000000,
-               0x40000000,0x00004000,0x00084010,0x40080000,
-               0x00080010,0x40000010,0x00000000,0x00084000,
-               0x00004010,0x40084000,0x40080000,0x00004010,
-               0x00000000,0x00084010,0x40080010,0x00080000,
-               0x40004010,0x40080000,0x40084000,0x00004000,
-               0x40080000,0x40004000,0x00000010,0x40084010,
-               0x00084010,0x00000010,0x00004000,0x40000000,
-               0x00004010,0x40084000,0x00080000,0x40000010,
-               0x00080010,0x40004010,0x40000010,0x00080010,
-               0x00084000,0x00000000,0x40004000,0x00004010,
-               0x40000000,0x40080010,0x40084010,0x00084000,
-       },{
-               0x00000104,0x04010100,0x00000000,0x04010004,
-               0x04000100,0x00000000,0x00010104,0x04000100,
-               0x00010004,0x04000004,0x04000004,0x00010000,
-               0x04010104,0x00010004,0x04010000,0x00000104,
-               0x04000000,0x00000004,0x04010100,0x00000100,
-               0x00010100,0x04010000,0x04010004,0x00010104,
-               0x04000104,0x00010100,0x00010000,0x04000104,
-               0x00000004,0x04010104,0x00000100,0x04000000,
-               0x04010100,0x04000000,0x00010004,0x00000104,
-               0x00010000,0x04010100,0x04000100,0x00000000,
-               0x00000100,0x00010004,0x04010104,0x04000100,
-               0x04000004,0x00000100,0x00000000,0x04010004,
-               0x04000104,0x00010000,0x04000000,0x04010104,
-               0x00000004,0x00010104,0x00010100,0x04000004,
-               0x04010000,0x04000104,0x00000104,0x04010000,
-               0x00010104,0x00000004,0x04010004,0x00010100,
-       },{
-               0x80401000,0x80001040,0x80001040,0x00000040,
-               0x00401040,0x80400040,0x80400000,0x80001000,
-               0x00000000,0x00401000,0x00401000,0x80401040,
-               0x80000040,0x00000000,0x00400040,0x80400000,
-               0x80000000,0x00001000,0x00400000,0x80401000,
-               0x00000040,0x00400000,0x80001000,0x00001040,
-               0x80400040,0x80000000,0x00001040,0x00400040,
-               0x00001000,0x00401040,0x80401040,0x80000040,
-               0x00400040,0x80400000,0x00401000,0x80401040,
-               0x80000040,0x00000000,0x00000000,0x00401000,
-               0x00001040,0x00400040,0x80400040,0x80000000,
-               0x80401000,0x80001040,0x80001040,0x00000040,
-               0x80401040,0x80000040,0x80000000,0x00001000,
-               0x80400000,0x80001000,0x00401040,0x80400040,
-               0x80001000,0x00001040,0x00400000,0x80401000,
-               0x00000040,0x00400000,0x00001000,0x00401040,
-       },{
-               0x00000080,0x01040080,0x01040000,0x21000080,
-               0x00040000,0x00000080,0x20000000,0x01040000,
-               0x20040080,0x00040000,0x01000080,0x20040080,
-               0x21000080,0x21040000,0x00040080,0x20000000,
-               0x01000000,0x20040000,0x20040000,0x00000000,
-               0x20000080,0x21040080,0x21040080,0x01000080,
-               0x21040000,0x20000080,0x00000000,0x21000000,
-               0x01040080,0x01000000,0x21000000,0x00040080,
-               0x00040000,0x21000080,0x00000080,0x01000000,
-               0x20000000,0x01040000,0x21000080,0x20040080,
-               0x01000080,0x20000000,0x21040000,0x01040080,
-               0x20040080,0x00000080,0x01000000,0x21040000,
-               0x21040080,0x00040080,0x21000000,0x21040080,
-               0x01040000,0x00000000,0x20040000,0x21000000,
-               0x00040080,0x01000080,0x20000080,0x00040000,
-               0x00000000,0x20040000,0x01040080,0x20000080,
-       },{
-               0x10000008,0x10200000,0x00002000,0x10202008,
-               0x10200000,0x00000008,0x10202008,0x00200000,
-               0x10002000,0x00202008,0x00200000,0x10000008,
-               0x00200008,0x10002000,0x10000000,0x00002008,
-               0x00000000,0x00200008,0x10002008,0x00002000,
-               0x00202000,0x10002008,0x00000008,0x10200008,
-               0x10200008,0x00000000,0x00202008,0x10202000,
-               0x00002008,0x00202000,0x10202000,0x10000000,
-               0x10002000,0x00000008,0x10200008,0x00202000,
-               0x10202008,0x00200000,0x00002008,0x10000008,
-               0x00200000,0x10002000,0x10000000,0x00002008,
-               0x10000008,0x10202008,0x00202000,0x10200000,
-               0x00202008,0x10202000,0x00000000,0x10200008,
-               0x00000008,0x00002000,0x10200000,0x00202008,
-               0x00002000,0x00200008,0x10002008,0x00000000,
-               0x10202000,0x10000000,0x00200008,0x10002008,
-       },{
-               0x00100000,0x02100001,0x02000401,0x00000000,
-               0x00000400,0x02000401,0x00100401,0x02100400,
-               0x02100401,0x00100000,0x00000000,0x02000001,
-               0x00000001,0x02000000,0x02100001,0x00000401,
-               0x02000400,0x00100401,0x00100001,0x02000400,
-               0x02000001,0x02100000,0x02100400,0x00100001,
-               0x02100000,0x00000400,0x00000401,0x02100401,
-               0x00100400,0x00000001,0x02000000,0x00100400,
-               0x02000000,0x00100400,0x00100000,0x02000401,
-               0x02000401,0x02100001,0x02100001,0x00000001,
-               0x00100001,0x02000000,0x02000400,0x00100000,
-               0x02100400,0x00000401,0x00100401,0x02100400,
-               0x00000401,0x02000001,0x02100401,0x02100000,
-               0x00100400,0x00000000,0x00000001,0x02100401,
-               0x00000000,0x00100401,0x02100000,0x00000400,
-               0x02000001,0x02000400,0x00000400,0x00100001,
-       },{
-               0x08000820,0x00000800,0x00020000,0x08020820,
-               0x08000000,0x08000820,0x00000020,0x08000000,
-               0x00020020,0x08020000,0x08020820,0x00020800,
-               0x08020800,0x00020820,0x00000800,0x00000020,
-               0x08020000,0x08000020,0x08000800,0x00000820,
-               0x00020800,0x00020020,0x08020020,0x08020800,
-               0x00000820,0x00000000,0x00000000,0x08020020,
-               0x08000020,0x08000800,0x00020820,0x00020000,
-               0x00020820,0x00020000,0x08020800,0x00000800,
-               0x00000020,0x08020020,0x00000800,0x00020820,
-               0x08000800,0x00000020,0x08000020,0x08020000,
-               0x08020020,0x08000000,0x00020000,0x08000820,
-               0x00000000,0x08020820,0x00020020,0x08000020,
-               0x08020000,0x08000800,0x08000820,0x00000000,
-               0x08020820,0x00020800,0x00020800,0x00000820,
-               0x00000820,0x00020020,0x08000000,0x08020800,
-       },
-};
-static const uint32_t ip_maskl[16][16] = {
-       {
-               0x00000000,0x00010000,0x00000000,0x00010000,
-               0x01000000,0x01010000,0x01000000,0x01010000,
-               0x00000000,0x00010000,0x00000000,0x00010000,
-               0x01000000,0x01010000,0x01000000,0x01010000,
-       },{
-               0x00000000,0x00000001,0x00000000,0x00000001,
-               0x00000100,0x00000101,0x00000100,0x00000101,
-               0x00000000,0x00000001,0x00000000,0x00000001,
-               0x00000100,0x00000101,0x00000100,0x00000101,
-       },{
-               0x00000000,0x00020000,0x00000000,0x00020000,
-               0x02000000,0x02020000,0x02000000,0x02020000,
-               0x00000000,0x00020000,0x00000000,0x00020000,
-               0x02000000,0x02020000,0x02000000,0x02020000,
-       },{
-               0x00000000,0x00000002,0x00000000,0x00000002,
-               0x00000200,0x00000202,0x00000200,0x00000202,
-               0x00000000,0x00000002,0x00000000,0x00000002,
-               0x00000200,0x00000202,0x00000200,0x00000202,
-       },{
-               0x00000000,0x00040000,0x00000000,0x00040000,
-               0x04000000,0x04040000,0x04000000,0x04040000,
-               0x00000000,0x00040000,0x00000000,0x00040000,
-               0x04000000,0x04040000,0x04000000,0x04040000,
-       },{
-               0x00000000,0x00000004,0x00000000,0x00000004,
-               0x00000400,0x00000404,0x00000400,0x00000404,
-               0x00000000,0x00000004,0x00000000,0x00000004,
-               0x00000400,0x00000404,0x00000400,0x00000404,
-       },{
-               0x00000000,0x00080000,0x00000000,0x00080000,
-               0x08000000,0x08080000,0x08000000,0x08080000,
-               0x00000000,0x00080000,0x00000000,0x00080000,
-               0x08000000,0x08080000,0x08000000,0x08080000,
-       },{
-               0x00000000,0x00000008,0x00000000,0x00000008,
-               0x00000800,0x00000808,0x00000800,0x00000808,
-               0x00000000,0x00000008,0x00000000,0x00000008,
-               0x00000800,0x00000808,0x00000800,0x00000808,
-       },{
-               0x00000000,0x00100000,0x00000000,0x00100000,
-               0x10000000,0x10100000,0x10000000,0x10100000,
-               0x00000000,0x00100000,0x00000000,0x00100000,
-               0x10000000,0x10100000,0x10000000,0x10100000,
-       },{
-               0x00000000,0x00000010,0x00000000,0x00000010,
-               0x00001000,0x00001010,0x00001000,0x00001010,
-               0x00000000,0x00000010,0x00000000,0x00000010,
-               0x00001000,0x00001010,0x00001000,0x00001010,
-       },{
-               0x00000000,0x00200000,0x00000000,0x00200000,
-               0x20000000,0x20200000,0x20000000,0x20200000,
-               0x00000000,0x00200000,0x00000000,0x00200000,
-               0x20000000,0x20200000,0x20000000,0x20200000,
-       },{
-               0x00000000,0x00000020,0x00000000,0x00000020,
-               0x00002000,0x00002020,0x00002000,0x00002020,
-               0x00000000,0x00000020,0x00000000,0x00000020,
-               0x00002000,0x00002020,0x00002000,0x00002020,
-       },{
-               0x00000000,0x00400000,0x00000000,0x00400000,
-               0x40000000,0x40400000,0x40000000,0x40400000,
-               0x00000000,0x00400000,0x00000000,0x00400000,
-               0x40000000,0x40400000,0x40000000,0x40400000,
-       },{
-               0x00000000,0x00000040,0x00000000,0x00000040,
-               0x00004000,0x00004040,0x00004000,0x00004040,
-               0x00000000,0x00000040,0x00000000,0x00000040,
-               0x00004000,0x00004040,0x00004000,0x00004040,
-       },{
-               0x00000000,0x00800000,0x00000000,0x00800000,
-               0x80000000,0x80800000,0x80000000,0x80800000,
-               0x00000000,0x00800000,0x00000000,0x00800000,
-               0x80000000,0x80800000,0x80000000,0x80800000,
-       },{
-               0x00000000,0x00000080,0x00000000,0x00000080,
-               0x00008000,0x00008080,0x00008000,0x00008080,
-               0x00000000,0x00000080,0x00000000,0x00000080,
-               0x00008000,0x00008080,0x00008000,0x00008080,
-       },
-};
-static const uint32_t ip_maskr[16][16] = {
-       {
-               0x00000000,0x00000000,0x00010000,0x00010000,
-               0x00000000,0x00000000,0x00010000,0x00010000,
-               0x01000000,0x01000000,0x01010000,0x01010000,
-               0x01000000,0x01000000,0x01010000,0x01010000,
-       },{
-               0x00000000,0x00000000,0x00000001,0x00000001,
-               0x00000000,0x00000000,0x00000001,0x00000001,
-               0x00000100,0x00000100,0x00000101,0x00000101,
-               0x00000100,0x00000100,0x00000101,0x00000101,
-       },{
-               0x00000000,0x00000000,0x00020000,0x00020000,
-               0x00000000,0x00000000,0x00020000,0x00020000,
-               0x02000000,0x02000000,0x02020000,0x02020000,
-               0x02000000,0x02000000,0x02020000,0x02020000,
-       },{
-               0x00000000,0x00000000,0x00000002,0x00000002,
-               0x00000000,0x00000000,0x00000002,0x00000002,
-               0x00000200,0x00000200,0x00000202,0x00000202,
-               0x00000200,0x00000200,0x00000202,0x00000202,
-       },{
-               0x00000000,0x00000000,0x00040000,0x00040000,
-               0x00000000,0x00000000,0x00040000,0x00040000,
-               0x04000000,0x04000000,0x04040000,0x04040000,
-               0x04000000,0x04000000,0x04040000,0x04040000,
-       },{
-               0x00000000,0x00000000,0x00000004,0x00000004,
-               0x00000000,0x00000000,0x00000004,0x00000004,
-               0x00000400,0x00000400,0x00000404,0x00000404,
-               0x00000400,0x00000400,0x00000404,0x00000404,
-       },{
-               0x00000000,0x00000000,0x00080000,0x00080000,
-               0x00000000,0x00000000,0x00080000,0x00080000,
-               0x08000000,0x08000000,0x08080000,0x08080000,
-               0x08000000,0x08000000,0x08080000,0x08080000,
-       },{
-               0x00000000,0x00000000,0x00000008,0x00000008,
-               0x00000000,0x00000000,0x00000008,0x00000008,
-               0x00000800,0x00000800,0x00000808,0x00000808,
-               0x00000800,0x00000800,0x00000808,0x00000808,
-       },{
-               0x00000000,0x00000000,0x00100000,0x00100000,
-               0x00000000,0x00000000,0x00100000,0x00100000,
-               0x10000000,0x10000000,0x10100000,0x10100000,
-               0x10000000,0x10000000,0x10100000,0x10100000,
-       },{
-               0x00000000,0x00000000,0x00000010,0x00000010,
-               0x00000000,0x00000000,0x00000010,0x00000010,
-               0x00001000,0x00001000,0x00001010,0x00001010,
-               0x00001000,0x00001000,0x00001010,0x00001010,
-       },{
-               0x00000000,0x00000000,0x00200000,0x00200000,
-               0x00000000,0x00000000,0x00200000,0x00200000,
-               0x20000000,0x20000000,0x20200000,0x20200000,
-               0x20000000,0x20000000,0x20200000,0x20200000,
-       },{
-               0x00000000,0x00000000,0x00000020,0x00000020,
-               0x00000000,0x00000000,0x00000020,0x00000020,
-               0x00002000,0x00002000,0x00002020,0x00002020,
-               0x00002000,0x00002000,0x00002020,0x00002020,
-       },{
-               0x00000000,0x00000000,0x00400000,0x00400000,
-               0x00000000,0x00000000,0x00400000,0x00400000,
-               0x40000000,0x40000000,0x40400000,0x40400000,
-               0x40000000,0x40000000,0x40400000,0x40400000,
-       },{
-               0x00000000,0x00000000,0x00000040,0x00000040,
-               0x00000000,0x00000000,0x00000040,0x00000040,
-               0x00004000,0x00004000,0x00004040,0x00004040,
-               0x00004000,0x00004000,0x00004040,0x00004040,
-       },{
-               0x00000000,0x00000000,0x00800000,0x00800000,
-               0x00000000,0x00000000,0x00800000,0x00800000,
-               0x80000000,0x80000000,0x80800000,0x80800000,
-               0x80000000,0x80000000,0x80800000,0x80800000,
-       },{
-               0x00000000,0x00000000,0x00000080,0x00000080,
-               0x00000000,0x00000000,0x00000080,0x00000080,
-               0x00008000,0x00008000,0x00008080,0x00008080,
-               0x00008000,0x00008000,0x00008080,0x00008080,
-       },
-};
-static const uint32_t fp_maskl[8][16] = {
-       {
-               0x00000000,0x40000000,0x00400000,0x40400000,
-               0x00004000,0x40004000,0x00404000,0x40404000,
-               0x00000040,0x40000040,0x00400040,0x40400040,
-               0x00004040,0x40004040,0x00404040,0x40404040,
-       },{
-               0x00000000,0x10000000,0x00100000,0x10100000,
-               0x00001000,0x10001000,0x00101000,0x10101000,
-               0x00000010,0x10000010,0x00100010,0x10100010,
-               0x00001010,0x10001010,0x00101010,0x10101010,
-       },{
-               0x00000000,0x04000000,0x00040000,0x04040000,
-               0x00000400,0x04000400,0x00040400,0x04040400,
-               0x00000004,0x04000004,0x00040004,0x04040004,
-               0x00000404,0x04000404,0x00040404,0x04040404,
-       },{
-               0x00000000,0x01000000,0x00010000,0x01010000,
-               0x00000100,0x01000100,0x00010100,0x01010100,
-               0x00000001,0x01000001,0x00010001,0x01010001,
-               0x00000101,0x01000101,0x00010101,0x01010101,
-       },{
-               0x00000000,0x80000000,0x00800000,0x80800000,
-               0x00008000,0x80008000,0x00808000,0x80808000,
-               0x00000080,0x80000080,0x00800080,0x80800080,
-               0x00008080,0x80008080,0x00808080,0x80808080,
-       },{
-               0x00000000,0x20000000,0x00200000,0x20200000,
-               0x00002000,0x20002000,0x00202000,0x20202000,
-               0x00000020,0x20000020,0x00200020,0x20200020,
-               0x00002020,0x20002020,0x00202020,0x20202020,
-       },{
-               0x00000000,0x08000000,0x00080000,0x08080000,
-               0x00000800,0x08000800,0x00080800,0x08080800,
-               0x00000008,0x08000008,0x00080008,0x08080008,
-               0x00000808,0x08000808,0x00080808,0x08080808,
-       },{
-               0x00000000,0x02000000,0x00020000,0x02020000,
-               0x00000200,0x02000200,0x00020200,0x02020200,
-               0x00000002,0x02000002,0x00020002,0x02020002,
-               0x00000202,0x02000202,0x00020202,0x02020202,
-       },
-};
-static const uint32_t fp_maskr[8][16] = {
-       {
-               0x00000000,0x40000000,0x00400000,0x40400000,
-               0x00004000,0x40004000,0x00404000,0x40404000,
-               0x00000040,0x40000040,0x00400040,0x40400040,
-               0x00004040,0x40004040,0x00404040,0x40404040,
-       },{
-               0x00000000,0x10000000,0x00100000,0x10100000,
-               0x00001000,0x10001000,0x00101000,0x10101000,
-               0x00000010,0x10000010,0x00100010,0x10100010,
-               0x00001010,0x10001010,0x00101010,0x10101010,
-       },{
-               0x00000000,0x04000000,0x00040000,0x04040000,
-               0x00000400,0x04000400,0x00040400,0x04040400,
-               0x00000004,0x04000004,0x00040004,0x04040004,
-               0x00000404,0x04000404,0x00040404,0x04040404,
-       },{
-               0x00000000,0x01000000,0x00010000,0x01010000,
-               0x00000100,0x01000100,0x00010100,0x01010100,
-               0x00000001,0x01000001,0x00010001,0x01010001,
-               0x00000101,0x01000101,0x00010101,0x01010101,
-       },{
-               0x00000000,0x80000000,0x00800000,0x80800000,
-               0x00008000,0x80008000,0x00808000,0x80808000,
-               0x00000080,0x80000080,0x00800080,0x80800080,
-               0x00008080,0x80008080,0x00808080,0x80808080,
-       },{
-               0x00000000,0x20000000,0x00200000,0x20200000,
-               0x00002000,0x20002000,0x00202000,0x20202000,
-               0x00000020,0x20000020,0x00200020,0x20200020,
-               0x00002020,0x20002020,0x00202020,0x20202020,
-       },{
-               0x00000000,0x08000000,0x00080000,0x08080000,
-               0x00000800,0x08000800,0x00080800,0x08080800,
-               0x00000008,0x08000008,0x00080008,0x08080008,
-               0x00000808,0x08000808,0x00080808,0x08080808,
-       },{
-               0x00000000,0x02000000,0x00020000,0x02020000,
-               0x00000200,0x02000200,0x00020200,0x02020200,
-               0x00000002,0x02000002,0x00020002,0x02020002,
-               0x00000202,0x02000202,0x00020202,0x02020202,
-       },
-};
-static const uint32_t key_perm_maskl[8][16] = {
-       {
-               0x00000000,0x00000000,0x00000010,0x00000010,
-               0x00001000,0x00001000,0x00001010,0x00001010,
-               0x00100000,0x00100000,0x00100010,0x00100010,
-               0x00101000,0x00101000,0x00101010,0x00101010,
-       },{
-               0x00000000,0x00000000,0x00000020,0x00000020,
-               0x00002000,0x00002000,0x00002020,0x00002020,
-               0x00200000,0x00200000,0x00200020,0x00200020,
-               0x00202000,0x00202000,0x00202020,0x00202020,
-       },{
-               0x00000000,0x00000000,0x00000040,0x00000040,
-               0x00004000,0x00004000,0x00004040,0x00004040,
-               0x00400000,0x00400000,0x00400040,0x00400040,
-               0x00404000,0x00404000,0x00404040,0x00404040,
-       },{
-               0x00000000,0x00000000,0x00000080,0x00000080,
-               0x00008000,0x00008000,0x00008080,0x00008080,
-               0x00800000,0x00800000,0x00800080,0x00800080,
-               0x00808000,0x00808000,0x00808080,0x00808080,
-       },{
-               0x00000000,0x00000001,0x00000100,0x00000101,
-               0x00010000,0x00010001,0x00010100,0x00010101,
-               0x01000000,0x01000001,0x01000100,0x01000101,
-               0x01010000,0x01010001,0x01010100,0x01010101,
-       },{
-               0x00000000,0x00000002,0x00000200,0x00000202,
-               0x00020000,0x00020002,0x00020200,0x00020202,
-               0x02000000,0x02000002,0x02000200,0x02000202,
-               0x02020000,0x02020002,0x02020200,0x02020202,
-       },{
-               0x00000000,0x00000004,0x00000400,0x00000404,
-               0x00040000,0x00040004,0x00040400,0x00040404,
-               0x04000000,0x04000004,0x04000400,0x04000404,
-               0x04040000,0x04040004,0x04040400,0x04040404,
-       },{
-               0x00000000,0x00000008,0x00000800,0x00000808,
-               0x00080000,0x00080008,0x00080800,0x00080808,
-               0x08000000,0x08000008,0x08000800,0x08000808,
-               0x08080000,0x08080008,0x08080800,0x08080808,
-       },
-};
-static const uint32_t key_perm_maskr[12][16] = {
-       {
-               0x00000000,0x00000001,0x00000000,0x00000001,
-               0x00000000,0x00000001,0x00000000,0x00000001,
-               0x00000000,0x00000001,0x00000000,0x00000001,
-               0x00000000,0x00000001,0x00000000,0x00000001,
-       },{
-               0x00000000,0x00000000,0x00100000,0x00100000,
-               0x00001000,0x00001000,0x00101000,0x00101000,
-               0x00000010,0x00000010,0x00100010,0x00100010,
-               0x00001010,0x00001010,0x00101010,0x00101010,
-       },{
-               0x00000000,0x00000002,0x00000000,0x00000002,
-               0x00000000,0x00000002,0x00000000,0x00000002,
-               0x00000000,0x00000002,0x00000000,0x00000002,
-               0x00000000,0x00000002,0x00000000,0x00000002,
-       },{
-               0x00000000,0x00000000,0x00200000,0x00200000,
-               0x00002000,0x00002000,0x00202000,0x00202000,
-               0x00000020,0x00000020,0x00200020,0x00200020,
-               0x00002020,0x00002020,0x00202020,0x00202020,
-       },{
-               0x00000000,0x00000004,0x00000000,0x00000004,
-               0x00000000,0x00000004,0x00000000,0x00000004,
-               0x00000000,0x00000004,0x00000000,0x00000004,
-               0x00000000,0x00000004,0x00000000,0x00000004,
-       },{
-               0x00000000,0x00000000,0x00400000,0x00400000,
-               0x00004000,0x00004000,0x00404000,0x00404000,
-               0x00000040,0x00000040,0x00400040,0x00400040,
-               0x00004040,0x00004040,0x00404040,0x00404040,
-       },{
-               0x00000000,0x00000008,0x00000000,0x00000008,
-               0x00000000,0x00000008,0x00000000,0x00000008,
-               0x00000000,0x00000008,0x00000000,0x00000008,
-               0x00000000,0x00000008,0x00000000,0x00000008,
-       },{
-               0x00000000,0x00000000,0x00800000,0x00800000,
-               0x00008000,0x00008000,0x00808000,0x00808000,
-               0x00000080,0x00000080,0x00800080,0x00800080,
-               0x00008080,0x00008080,0x00808080,0x00808080,
-       },{
-               0x00000000,0x00000000,0x01000000,0x01000000,
-               0x00010000,0x00010000,0x01010000,0x01010000,
-               0x00000100,0x00000100,0x01000100,0x01000100,
-               0x00010100,0x00010100,0x01010100,0x01010100,
-       },{
-               0x00000000,0x00000000,0x02000000,0x02000000,
-               0x00020000,0x00020000,0x02020000,0x02020000,
-               0x00000200,0x00000200,0x02000200,0x02000200,
-               0x00020200,0x00020200,0x02020200,0x02020200,
-       },{
-               0x00000000,0x00000000,0x04000000,0x04000000,
-               0x00040000,0x00040000,0x04040000,0x04040000,
-               0x00000400,0x00000400,0x04000400,0x04000400,
-               0x00040400,0x00040400,0x04040400,0x04040400,
-       },{
-               0x00000000,0x00000000,0x08000000,0x08000000,
-               0x00080000,0x00080000,0x08080000,0x08080000,
-               0x00000800,0x00000800,0x08000800,0x08000800,
-               0x00080800,0x00080800,0x08080800,0x08080800,
-       },
-};
-static const uint32_t comp_maskl0[4][8] = {
-       {
-               0x00000000,0x00020000,0x00000001,0x00020001,
-               0x00080000,0x000a0000,0x00080001,0x000a0001,
-       },{
-               0x00000000,0x00001000,0x00000000,0x00001000,
-               0x00000040,0x00001040,0x00000040,0x00001040,
-       },{
-               0x00000000,0x00400000,0x00000020,0x00400020,
-               0x00008000,0x00408000,0x00008020,0x00408020,
-       },{
-               0x00000000,0x00100000,0x00000800,0x00100800,
-               0x00000000,0x00100000,0x00000800,0x00100800,
-       },
-};
-static const uint32_t comp_maskr0[4][8] = {
-       {
-               0x00000000,0x00200000,0x00020000,0x00220000,
-               0x00000002,0x00200002,0x00020002,0x00220002,
-       },{
-               0x00000000,0x00000000,0x00100000,0x00100000,
-               0x00000004,0x00000004,0x00100004,0x00100004,
-       },{
-               0x00000000,0x00004000,0x00000800,0x00004800,
-               0x00000000,0x00004000,0x00000800,0x00004800,
-       },{
-               0x00000000,0x00400000,0x00008000,0x00408000,
-               0x00000008,0x00400008,0x00008008,0x00408008,
-       },
-};
-static const uint32_t comp_maskl1[4][16] = {
-       {
-               0x00000000,0x00000010,0x00004000,0x00004010,
-               0x00040000,0x00040010,0x00044000,0x00044010,
-               0x00000100,0x00000110,0x00004100,0x00004110,
-               0x00040100,0x00040110,0x00044100,0x00044110,
-       },{
-               0x00000000,0x00800000,0x00000002,0x00800002,
-               0x00000200,0x00800200,0x00000202,0x00800202,
-               0x00200000,0x00a00000,0x00200002,0x00a00002,
-               0x00200200,0x00a00200,0x00200202,0x00a00202,
-       },{
-               0x00000000,0x00002000,0x00000004,0x00002004,
-               0x00000400,0x00002400,0x00000404,0x00002404,
-               0x00000000,0x00002000,0x00000004,0x00002004,
-               0x00000400,0x00002400,0x00000404,0x00002404,
-       },{
-               0x00000000,0x00010000,0x00000008,0x00010008,
-               0x00000080,0x00010080,0x00000088,0x00010088,
-               0x00000000,0x00010000,0x00000008,0x00010008,
-               0x00000080,0x00010080,0x00000088,0x00010088,
-       },
-};
-static const uint32_t comp_maskr1[4][16] = {
-       {
-               0x00000000,0x00000000,0x00000080,0x00000080,
-               0x00002000,0x00002000,0x00002080,0x00002080,
-               0x00000001,0x00000001,0x00000081,0x00000081,
-               0x00002001,0x00002001,0x00002081,0x00002081,
-       },{
-               0x00000000,0x00000010,0x00800000,0x00800010,
-               0x00010000,0x00010010,0x00810000,0x00810010,
-               0x00000200,0x00000210,0x00800200,0x00800210,
-               0x00010200,0x00010210,0x00810200,0x00810210,
-       },{
-               0x00000000,0x00000400,0x00001000,0x00001400,
-               0x00080000,0x00080400,0x00081000,0x00081400,
-               0x00000020,0x00000420,0x00001020,0x00001420,
-               0x00080020,0x00080420,0x00081020,0x00081420,
-       },{
-               0x00000000,0x00000100,0x00040000,0x00040100,
-               0x00000000,0x00000100,0x00040000,0x00040100,
-               0x00000040,0x00000140,0x00040040,0x00040140,
-               0x00000040,0x00000140,0x00040040,0x00040140,
-       },
-};
-
-static const unsigned char ascii64[] =
-    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-/*   0000000000111111111122222222223333333333444444444455555555556666 */
-/*   0123456789012345678901234567890123456789012345678901234567890123 */
-
-/*
- * We match the behavior of UFC-crypt on systems where "char" is signed by
- * default (the majority), regardless of char's signedness on our system.
- */
-static uint32_t ascii_to_bin(int ch)
-{
-       int sch = (ch < 0x80) ? ch : -(0x100 - ch);
-       int retval;
-
-       retval = sch - '.';
-       if (sch >= 'A') {
-               retval = sch - ('A' - 12);
-               if (sch >= 'a')
-                       retval = sch - ('a' - 38);
-       }
-       retval &= 0x3f;
-
-       return retval;
-}
-
-/*
- * When we choose to "support" invalid salts, nevertheless disallow those
- * containing characters that would violate the passwd file format.
- */
-static inline int ascii_is_unsafe(unsigned char ch)
-{
-       return !ch || ch == '\n' || ch == ':';
-}
-
-static uint32_t setup_salt(uint32_t salt)
-{
-       uint32_t obit, saltbit, saltbits;
-       unsigned int i;
-
-       saltbits = 0;
-       saltbit = 1;
-       obit = 0x800000;
-       for (i = 0; i < 24; i++) {
-               if (salt & saltbit)
-                       saltbits |= obit;
-               saltbit <<= 1;
-               obit >>= 1;
-       }
-
-       return saltbits;
-}
-
-void __des_enc_setkey(const unsigned char *key, struct expanded_key *ekey)
-{
-       uint32_t k0, k1, rawkey0, rawkey1;
-       unsigned int shifts, round, i, ibit;
-
-       rawkey0 =
-           (uint32_t)key[3] |
-           ((uint32_t)key[2] << 8) |
-           ((uint32_t)key[1] << 16) |
-           ((uint32_t)key[0] << 24);
-       rawkey1 =
-           (uint32_t)key[7] |
-           ((uint32_t)key[6] << 8) |
-           ((uint32_t)key[5] << 16) |
-           ((uint32_t)key[4] << 24);
-
-       /*
-        * Do key permutation and split into two 28-bit subkeys.
-        */
-       k0 = k1 = 0;
-       for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
-               unsigned int j = i << 1;
-               k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] |
-                     key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf];
-               k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf];
-               ibit -= 4;
-               k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] |
-                     key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf];
-       }
-
-       /*
-        * Rotate subkeys and do compression permutation.
-        */
-       shifts = 0;
-       for (round = 0; round < 16; round++) {
-               uint32_t t0, t1;
-               uint32_t kl, kr;
-
-               shifts += key_shifts[round];
-
-               t0 = (k0 << shifts) | (k0 >> (28 - shifts));
-               t1 = (k1 << shifts) | (k1 >> (28 - shifts));
-
-               kl = kr = 0;
-               ibit = 25;
-               for (i = 0; i < 4; i++) {
-                       kl |= comp_maskl0[i][(t0 >> ibit) & 7];
-                       kr |= comp_maskr0[i][(t1 >> ibit) & 7];
-                       ibit -= 4;
-                       kl |= comp_maskl1[i][(t0 >> ibit) & 0xf];
-                       kr |= comp_maskr1[i][(t1 >> ibit) & 0xf];
-                       ibit -= 3;
-               }
-               ekey->l[round] = kl;
-               ekey->r[round] = kr;
-       }
-}
-
-/*
- * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
- */
-void __enc_do_des(uint32_t l_in, uint32_t r_in,
-    uint32_t *l_out, uint32_t *r_out,
-    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
-{
-       uint32_t l, r;
-
-       /*
-        * Do initial permutation (IP).
-        */
-       l = r = 0;
-       if (l_in | r_in) {
-               unsigned int i, ibit;
-               for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) {
-                       l |= ip_maskl[i][(l_in >> ibit) & 0xf] |
-                            ip_maskl[i + 8][(r_in >> ibit) & 0xf];
-                       r |= ip_maskr[i][(l_in >> ibit) & 0xf] |
-                            ip_maskr[i + 8][(r_in >> ibit) & 0xf];
-               }
-       }
-
-       while (count--) {
-               /*
-                * Do each round.
-                */
-               unsigned int round = 16;
-               const uint32_t *kl = ekey->l;
-               const uint32_t *kr = ekey->r;
-               uint32_t f;
-               while (round--) {
-                       uint32_t r48l, r48r;
-                       /*
-                        * 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 S-box lookups (which shrink it back to 32 bits)
-                        * and do the P-box permutation at the same time.
-                        */
-                       f = psbox[0][r48l >> 18]
-                         | psbox[1][(r48l >> 12) & 0x3f]
-                         | psbox[2][(r48l >> 6) & 0x3f]
-                         | psbox[3][r48l & 0x3f]
-                         | psbox[4][r48r >> 18]
-                         | psbox[5][(r48r >> 12) & 0x3f]
-                         | psbox[6][(r48r >> 6) & 0x3f]
-                         | psbox[7][r48r & 0x3f];
-                       /*
-                        * Now that we've permuted things, complete f().
-                        */
-                       f ^= l;
-                       l = r;
-                       r = f;
-               }
-               r = l;
-               l = f;
-       }
-
-       /*
-        * Do final permutation (inverse of IP).
-        */
-       {
-               unsigned int i, ibit;
-               uint32_t lo, ro;
-               lo = ro = 0;
-               for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
-                       ro |= fp_maskr[i][(l >> ibit) & 0xf] |
-                             fp_maskr[i + 4][(r >> ibit) & 0xf];
-                       ibit -= 4;
-                       lo |= fp_maskl[i][(l >> ibit) & 0xf] |
-                             fp_maskl[i + 4][(r >> ibit) & 0xf];
-               }
-               *l_out = lo;
-               *r_out = ro;
-       }
-}
-
-static void des_cipher(const unsigned char *in, unsigned char *out,
-    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
-{
-       uint32_t l_out, r_out, rawl, rawr;
-
-       rawl =
-           (uint32_t)in[3] |
-           ((uint32_t)in[2] << 8) |
-           ((uint32_t)in[1] << 16) |
-           ((uint32_t)in[0] << 24);
-       rawr =
-           (uint32_t)in[7] |
-           ((uint32_t)in[6] << 8) |
-           ((uint32_t)in[5] << 16) |
-           ((uint32_t)in[4] << 24);
-
-       __enc_do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey);
-
-       out[0] = l_out >> 24;
-       out[1] = l_out >> 16;
-       out[2] = l_out >> 8;
-       out[3] = l_out;
-       out[4] = r_out >> 24;
-       out[5] = r_out >> 16;
-       out[6] = r_out >> 8;
-       out[7] = r_out;
-}
-
-static char *_crypt_extended_r_uut(const char *_key, const char *_setting, 
char *output)
-{
-       const unsigned char *key = (const unsigned char *)_key;
-       const unsigned char *setting = (const unsigned char *)_setting;
-       struct expanded_key ekey;
-       unsigned char keybuf[8];
-       unsigned char *p, *q;
-       uint32_t count, salt, l, r0, r1;
-       unsigned int i;
-
-       /*
-        * Copy the key, shifting each character left by one bit and padding
-        * with zeroes.
-        */
-       q = keybuf;
-       while (q <= &keybuf[sizeof(keybuf) - 1]) {
-               *q++ = *key << 1;
-               if (*key)
-                       key++;
-       }
-       __des_enc_setkey(keybuf, &ekey);
-
-       if (*setting == _PASSWORD_EFMT1) {
-               /*
-                * "new"-style:
-                *      setting - underscore, 4 chars of count, 4 chars of salt
-                *      key - unlimited characters
-                */
-               for (i = 1, count = 0; i < 5; i++) {
-                       uint32_t value = ascii_to_bin(setting[i]);
-                       if (ascii64[value] != setting[i])
-                               return NULL;
-                       count |= value << (i - 1) * 6;
-               }
-               if (!count)
-                       return NULL;
-
-               for (i = 5, salt = 0; i < 9; i++) {
-                       uint32_t value = ascii_to_bin(setting[i]);
-                       if (ascii64[value] != setting[i])
-                               return NULL;
-                       salt |= value << (i - 5) * 6;
-               }
-
-               while (*key) {
-                       /*
-                        * Encrypt the key with itself.
-                        */
-                       des_cipher(keybuf, keybuf, 1, 0, &ekey);
-                       /*
-                        * And XOR with the next 8 characters of the key.
-                        */
-                       q = keybuf;
-                       while (q <= &keybuf[sizeof(keybuf) - 1] && *key)
-                               *q++ ^= *key++ << 1;
-                       __des_enc_setkey(keybuf, &ekey);
-               }
-
-               memcpy(output, setting, 9);
-               output[9] = '\0';
-               p = (unsigned char *)output + 9;
-       } else {
-               /*
-                * "old"-style:
-                *      setting - 2 chars of salt
-                *      key - up to 8 characters
-                */
-               count = 25;
-
-               if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
-                       return NULL;
-
-               salt = (ascii_to_bin(setting[1]) << 6)
-                    |  ascii_to_bin(setting[0]);
-
-               output[0] = setting[0];
-               output[1] = setting[1];
-               p = (unsigned char *)output + 2;
-       }
-
-       /*
-        * Do it.
-        */
-       __enc_do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey);
-
-       /*
-        * Now encode the result...
-        */
-       l = (r0 >> 8);
-       *p++ = ascii64[(l >> 18) & 0x3f];
-       *p++ = ascii64[(l >> 12) & 0x3f];
-       *p++ = ascii64[(l >> 6) & 0x3f];
-       *p++ = ascii64[l & 0x3f];
-
-       l = (r0 << 16) | ((r1 >> 16) & 0xffff);
-       *p++ = ascii64[(l >> 18) & 0x3f];
-       *p++ = ascii64[(l >> 12) & 0x3f];
-       *p++ = ascii64[(l >> 6) & 0x3f];
-       *p++ = ascii64[l & 0x3f];
-
-       l = r1 << 2;
-       *p++ = ascii64[(l >> 12) & 0x3f];
-       *p++ = ascii64[(l >> 6) & 0x3f];
-       *p++ = ascii64[l & 0x3f];
-       *p = 0;
-
-       return output;
-}
-
-char *__crypt_enc_des(const char *key, const char *setting, char *output)
-{
-       const char *test_key = "\x80\xff\x80\x01 "
-           "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test";
-       const char *test_setting = "_0.../9Zz";
-       const char *test_hash = "_0.../9ZzX7iSJNd21sU";
-       char test_buf[21];
-       char *retval;
-       const char *p;
-
-       if (*setting != _PASSWORD_EFMT1) {
-               test_setting = "\x80x";
-               test_hash = "\x80x22/wK52ZKGA";
-       }
-
-       /*
-        * Hash the supplied password.
-        */
-       retval = _crypt_extended_r_uut(key, setting, output);
-
-       /*
-        * Perform a quick self-test.  It is important that we make both calls
-        * to _crypt_extended_r_uut() from the same scope such that they likely
-        * use the same stack locations, which makes the second call overwrite
-        * the first call's sensitive data on the stack and makes it more
-        * likely that any alignment related issues would be detected.
-        */
-       p = _crypt_extended_r_uut(test_key, test_setting, test_buf);
-       if (p && !strcmp(p, test_hash) && retval)
-               return retval;
-
-       return (setting[0]=='*') ? "x" : "*";
-}
-
-static struct expanded_key __encrypt_key;
-
-void setkey(const char *key)
-{
-       unsigned char bkey[8];
-       int i, j;
-
-       for (i = 0; i < 8; i++) {
-               bkey[i] = 0;
-               for (j = 7; j >= 0; j--, key++)
-                       bkey[i] |= (uint32_t)(*key & 1) << j;
-       }
-
-       __des_enc_setkey(bkey, &__encrypt_key);
-}
-
-void encrypt(char *block, int edflag)
-{
-       struct expanded_key decrypt_key, *key;
-       uint32_t b[2];
-       int i, j;
-       char *p;
-
-       p = block;
-       for (i = 0; i < 2; i++) {
-               b[i] = 0;
-               for (j = 31; j >= 0; j--, p++)
-                       b[i] |= (uint32_t)(*p & 1) << j;
-       }
-
-       key = &__encrypt_key;
-       if (edflag) {
-               key = &decrypt_key;
-               for (i = 0; i < 16; i++) {
-                       decrypt_key.l[i] = __encrypt_key.l[15-i];
-                       decrypt_key.r[i] = __encrypt_key.r[15-i];
-               }
-       }
-
-       __enc_do_des(b[0], b[1], b, b + 1, 1, 0, key);
-
-       p = block;
-       for (i = 0; i < 2; i++)
-               for (j = 31; j >= 0; j--)
-                       *p++ = b[i]>>j & 1;
-}
-
diff --git a/libc/dlfcn.cc b/libc/dlfcn.cc
index 108a78ed..fa496e4e 100644
--- a/libc/dlfcn.cc
+++ b/libc/dlfcn.cc
@@ -124,7 +124,7 @@ int dl_iterate_phdr(int (*callback)(struct dl_phdr_info 
*info,
     return ret;
 }
 
-extern "C" int dladdr(void *addr, Dl_info *info)
+extern "C" int dladdr(const void *addr, Dl_info *info)
 {
     auto ei = elf::get_program()->lookup_addr(addr);
     info->dli_fname = ei.fname;
diff --git a/libc/include/sys/timeb.h b/libc/include/sys/timeb.h
deleted file mode 100644
index 108c1f5c..00000000
--- a/libc/include/sys/timeb.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _SYS_TIMEB_H
-#define _SYS_TIMEB_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define __NEED_time_t
-
-#include <bits/alltypes.h>
-
-struct timeb {
-       time_t time;
-       unsigned short millitm;
-       short timezone, dstflag;
-};
-
-int ftime(struct timeb *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/internal/fp_arch.h b/libc/internal/fp_arch.h
new file mode 120000
index 00000000..4bcf330c
--- /dev/null
+++ b/libc/internal/fp_arch.h
@@ -0,0 +1 @@
+../../musl/arch/generic/fp_arch.h
\ No newline at end of file
diff --git a/libc/internal/libc.h b/libc/internal/libc.h
index e3f2687d..bb2d7f6b 100644
--- a/libc/internal/libc.h
+++ b/libc/internal/libc.h
@@ -41,7 +41,7 @@ extern char **__environ;
 
 #undef weak_alias
 #define __weak_alias(old, new) \
-       __typeof(old) new __attribute__((weak, alias(#old)))
+       __typeof(old) new __attribute__((__weak__, alias(#old)))
 #ifdef __cplusplus
 #define weak_alias(old, new) extern "C" __weak_alias(old, new)
 #else
diff --git a/libc/internal/locale_impl.h b/libc/internal/locale_impl.h
index faf24aee..d9fed2c7 100644
--- a/libc/internal/locale_impl.h
+++ b/libc/internal/locale_impl.h
@@ -2,6 +2,7 @@
 #define LOCALE_IMPL_H
 
 #include <locale.h>
+#include <stdlib.h>
 
 struct __locale_struct {
     struct __locale_data *__locales[13];
@@ -15,4 +16,14 @@ typedef struct __locale_struct *__locale_t;
 
 typedef __locale_t locale_t;
 
+extern __thread locale_t __current_locale;
+#define CURRENT_LOCALE (__current_locale)
+
+#define LCTRANS(msg, lc, loc) (msg) // We are not translating anything
+#define LCTRANS_CUR(msg) (msg)
+
+extern locale_t __c_locale_ptr;
+#define C_LOCALE (__c_locale_ptr)
+#define UTF8_LOCALE (__c_locale_ptr) // This should point to different locale 
struct but for now to get things going
+
 #endif
diff --git a/libc/internal/lock.h b/libc/internal/lock.h
new file mode 100644
index 00000000..d1258987
--- /dev/null
+++ b/libc/internal/lock.h
@@ -0,0 +1,4 @@
+#include <osv/mutex.h>
+
+#define LOCK(x) mutex_lock(&(x))
+#define UNLOCK(x) mutex_unlock(&(x))
diff --git a/libc/libc.cc b/libc/libc.cc
index 559db019..b65d7f7d 100644
--- a/libc/libc.cc
+++ b/libc/libc.cc
@@ -34,6 +34,7 @@ char *program_invocation_short_name;
 
 weak_alias(program_invocation_name, __progname_full);
 weak_alias(program_invocation_short_name, __progname);
+//weak_alias(__errno_location, ___errno_location) 
__attribute__((__visibility__("hidden")));
 
 int libc_error(int err)
 {
@@ -50,6 +51,11 @@ int* __errno_location()
     return &errno;
 }
 
+extern "C" int* ___errno_location() //TODO: Get rid of it
+{
+    return &errno;
+}
+
 int getrlimit(int resource, struct rlimit *rlim)
 {
     auto set = [=] (rlim_t r) { rlim->rlim_cur = rlim->rlim_max = r; };
diff --git a/libc/locale/catopen.c b/libc/locale/catopen.c
new file mode 100644
index 00000000..4423c4d9
--- /dev/null
+++ b/libc/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/libc/locale/duplocale.c b/libc/locale/duplocale.c
new file mode 100644
index 00000000..f9fc1ffa
--- /dev/null
+++ b/libc/locale/duplocale.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+locale_t duplocale(locale_t old)
+{
+       locale_t new;
+       new = calloc(1, sizeof *new);
+       if (new && old != LC_GLOBAL_LOCALE) memcpy(new, old, sizeof *new);
+       return new;
+}
+
+weak_alias(duplocale, __duplocale);
diff --git a/libc/locale/intl.c b/libc/locale/intl.c
new file mode 100644
index 00000000..964f7da1
--- /dev/null
+++ b/libc/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/libc/locale/langinfo.c b/libc/locale/langinfo.c
new file mode 100644
index 00000000..dde95656
--- /dev/null
+++ b/libc/locale/langinfo.c
@@ -0,0 +1,74 @@
+#include <locale.h>
+#include <langinfo.h>
+#include "locale_impl.h"
+#include "libc.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"
+       "\0"
+       "%m/%d/%y\0"
+       "0123456789\0"
+       "%a %b %e %T %Y\0"
+       "%H:%M:%S";
+
+static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no";
+static const char c_numeric[] = ".\0" "";
+
+char *__nl_langinfo_l(nl_item item, locale_t loc)
+{
+       int cat = item >> 16;
+       int idx = item & 65535;
+       const char *str;
+
+       if (item == CODESET) return "ASCII";
+
+       /* _NL_LOCALE_NAME extension */
+       if (idx == 65535 && cat < LC_ALL)
+               return "C";
+       
+       switch (cat) {
+       case LC_NUMERIC:
+               if (idx > 1) return "";
+               str = c_numeric;
+               break;
+       case LC_TIME:
+               if (idx > 0x31) return "";
+               str = c_time;
+               break;
+       case LC_MONETARY:
+               if (idx > 0) return "";
+               str = "";
+               break;
+       case LC_MESSAGES:
+               if (idx > 3) return "";
+               str = c_messages;
+               break;
+       default:
+               return "";
+       }
+
+       for (; idx; idx--, str++) for (; *str; str++);
+       if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);
+       return (char *)str;
+}
+
+char *__nl_langinfo(nl_item item)
+{
+       return __nl_langinfo_l(item, CURRENT_LOCALE);
+}
+
+weak_alias(__nl_langinfo, nl_langinfo);
+weak_alias(__nl_langinfo_l, nl_langinfo_l);
diff --git a/libc/locale/setlocale.c b/libc/locale/setlocale.c
new file mode 100644
index 00000000..28f29b80
--- /dev/null
+++ b/libc/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/libc/locale/uselocale.c b/libc/locale/uselocale.c
index 26f9a164..93e65e21 100644
--- a/libc/locale/uselocale.c
+++ b/libc/locale/uselocale.c
@@ -1,12 +1,12 @@
 #include "locale_impl.h"
 #include "libc.h"
 
-static __thread locale_t __locale;
+__thread locale_t __current_locale;
 
 locale_t __uselocale(locale_t l)
 {
-       locale_t old = __locale;
-       if (l) __locale = l;
+       locale_t old = __current_locale;
+       if (l) __current_locale = l;
        return old;
 }
 
diff --git a/libc/network/freeaddrinfo.c b/libc/network/freeaddrinfo.c
new file mode 100644
index 00000000..df3798ae
--- /dev/null
+++ b/libc/network/freeaddrinfo.c
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <netdb.h>
+
+void freeaddrinfo(struct addrinfo *p)
+{
+       free(p);
+}
diff --git a/libc/network/inet_addr.c b/libc/network/inet_addr.c
deleted file mode 100644
index 63556a20..00000000
--- a/libc/network/inet_addr.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-int __inet_aton(const char *, struct in_addr *);
-
-in_addr_t inet_addr(const char *p)
-{
-    struct in_addr a;
-    if (!__inet_aton(p, &a))
-        return -1;
-    return a.s_addr;
-}
diff --git a/libc/network/inet_aton.c b/libc/network/inet_aton.c
deleted file mode 100644
index bc2adbec..00000000
--- a/libc/network/inet_aton.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <ctype.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "libc.h"
-
-int __inet_aton(const char *s0, struct in_addr *dest)
-{
-    const char *s = s0;
-    unsigned char *d = (void *)dest;
-    unsigned long a[4] = { 0 };
-    char *z;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        a[i] = strtoul(s, &z, 0);
-        if (z == s || (*z && *z != '.') || !isdigit(*s))
-            return 0;
-        if (!*z)
-            break;
-        s = z + 1;
-    }
-    if (i == 4)
-        return 0;
-    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;
-    }
-    for (i = 0; i < 4; i++) {
-        if (a[i] > 255)
-            return 0;
-        d[i] = a[i];
-    }
-    return 1;
-}
-
-weak_alias(__inet_aton, inet_aton);
diff --git a/libc/network/inet_ntop.c b/libc/network/inet_ntop.c
deleted file mode 100644
index 76ae556c..00000000
--- a/libc/network/inet_ntop.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#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 *restrict a0, char *restrict 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,
-                       "%x:%x:%x:%x:%x:%x:%x:%x",
-                       256*a[0]+a[1],256*a[2]+a[3],
-                       256*a[4]+a[5],256*a[6]+a[7],
-                       256*a[8]+a[9],256*a[10]+a[11],
-                       256*a[12]+a[13],256*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/libc/prng/__rand48_step.c b/libc/prng/__rand48_step.c
deleted file mode 100644
index f5bc27ff..00000000
--- a/libc/prng/__rand48_step.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-
-uint64_t __rand48_step(unsigned short *xi, unsigned short *lc)
-{
-       uint64_t a, x;
-       x = xi[0] | xi[1]+0ULL<<16 | xi[2]+0ULL<<32;
-       a = lc[0] | lc[1]+0ULL<<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/libc/process/execle.c b/libc/process/execle.c
deleted file mode 100644
index df28c441..00000000
--- a/libc/process/execle.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <unistd.h>
-#include <stdarg.h>
-
-int execle(const char *path, const char *argv0, ...)
-{
-    int argc;
-    va_list ap;
-
-    va_start(ap, argv0);
-    for(argc=1; va_arg(ap, const char*); argc++);
-    va_end(ap);
-    {
-        int i;
-        char *argv[argc+1];
-        char **envp;
-        va_start(ap, argv0);
-        argv[0] = (char *)argv0;
-        for (i=1; i<=argc; i++)
-            argv[i] = va_arg(ap, char *);
-        envp = va_arg(ap, char **);
-        va_end(ap);
-        return execve(path, argv, envp);
-    }
-}
diff --git a/libc/pthread.cc b/libc/pthread.cc
index 60158b31..a9a31eaf 100644
--- a/libc/pthread.cc
+++ b/libc/pthread.cc
@@ -1181,3 +1181,6 @@ int pthread_attr_getaffinity_np(const pthread_attr_t 
*attr, size_t cpusetsize,
 
     return 0;
 }
+
+extern "C" void _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), 
void *x) {} //TODO: Check if it can be stubbed like this
+extern "C" void _pthread_cleanup_pop(struct __ptcb *cb, int run) {} //TODO: 
Check if it can be stubbed like this
diff --git a/libc/stdio/__fdopen.c b/libc/stdio/__fdopen.c
index dc4deb5b..187a86bc 100644
--- a/libc/stdio/__fdopen.c
+++ b/libc/stdio/__fdopen.c
@@ -1,15 +1,15 @@
 #include "stdio_impl.h"
 #include <stdlib.h>
-#include <termios.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
+#include "libc.h"
 
 FILE *__fdopen(int fd, const char *mode)
 {
        FILE *f;
-       struct termios tio;
+       struct winsize wsz;
 
        /* Check for valid initial mode character */
        if (!strchr("rwa", *mode)) {
@@ -27,12 +27,14 @@ FILE *__fdopen(int fd, const char *mode)
        if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
 
        /* Apply close-on-exec flag */
-       if (strchr(mode, 'e')) fcntl(fd, F_SETFD, FD_CLOEXEC);
+       if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
 
        /* Set append mode on fd if opened for append */
        if (*mode == 'a') {
-               int flags = fcntl(fd, F_GETFL);
-               fcntl(fd, F_SETFL, flags | O_APPEND);
+               int flags = __syscall(SYS_fcntl, fd, F_GETFL);
+               if (!(flags & O_APPEND))
+                       __syscall(SYS_fcntl, fd, F_SETFL, flags | O_APPEND);
+               f->flags |= F_APP;
        }
 
        f->fd = fd;
@@ -41,7 +43,7 @@ FILE *__fdopen(int fd, const char *mode)
 
        /* Activate line buffered mode for terminals */
        f->lbf = EOF;
-       if (!(f->flags & F_NOWR) && !ioctl(fd, TCGETS, &tio))
+       if (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz))
                f->lbf = '\n';
 
        /* Initialize op ptrs. No problem if some are unneeded. */
@@ -51,13 +53,7 @@ FILE *__fdopen(int fd, const char *mode)
        f->close = __stdio_close;
 
        /* Add new FILE to open file list */
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
-
-       return f;
+       return __ofl_add(f);
 }
 
 weak_alias(__fdopen, fdopen);
diff --git a/libc/stdio/fmemopen.c b/libc/stdio/fmemopen.c
index 4a649f85..1a776b90 100644
--- a/libc/stdio/fmemopen.c
+++ b/libc/stdio/fmemopen.c
@@ -1,8 +1,9 @@
 #include "stdio_impl.h"
 #include <errno.h>
-#include <stdlib.h>
 #include <string.h>
+#include <stdlib.h>
 #include <inttypes.h>
+#include "libc.h"
 
 struct cookie {
        size_t pos, len, size;
@@ -10,6 +11,12 @@ struct cookie {
        int mode;
 };
 
+struct mem_FILE {
+       FILE f;
+       struct cookie c;
+       unsigned char buf[UNGET+BUFSIZ], buf2[];
+};
+
 static off_t mseek(FILE *f, off_t off, int whence)
 {
        ssize_t base;
@@ -73,47 +80,46 @@ static int mclose(FILE *m)
 
 FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
 {
-       FILE *f;
-       struct cookie *c;
+       struct mem_FILE *f;
        int plus = !!strchr(mode, '+');
        
-       if (!size || !strchr("rwa", *mode)) {
+       if (!strchr("rwa", *mode)) {
                errno = EINVAL;
                return 0;
        }
 
-       if (!buf && size > SIZE_MAX-sizeof(FILE)-BUFSIZ-UNGET) {
+       if (!buf && size > PTRDIFF_MAX) {
                errno = ENOMEM;
                return 0;
        }
 
-       f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf?0:size), 1);
+       f = malloc(sizeof *f + (buf?0:size));
        if (!f) return 0;
-       f->cookie = c = (void *)(f+1);
-       f->fd = -1;
-       f->lbf = EOF;
-       f->buf = (unsigned char *)(c+1) + UNGET;
-       f->buf_size = BUFSIZ;
-       if (!buf) buf = f->buf + BUFSIZ;
+       memset(&f->f, 0, sizeof f->f);
+       f->f.cookie = &f->c;
+       f->f.fd = -1;
+       f->f.lbf = EOF;
+       f->f.buf = f->buf + UNGET;
+       f->f.buf_size = sizeof f->buf - UNGET;
+       if (!buf) {
+               buf = f->buf2;;
+               memset(buf, 0, size);
+       }
 
-       c->buf = buf;
-       c->size = size;
-       c->mode = *mode;
+       memset(&f->c, 0, sizeof f->c);
+       f->c.buf = buf;
+       f->c.size = size;
+       f->c.mode = *mode;
        
-       if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
-       if (*mode == 'r') c->len = size;
-       else if (*mode == 'a') c->len = c->pos = strnlen(buf, size);
-
-       f->read = mread;
-       f->write = mwrite;
-       f->seek = mseek;
-       f->close = mclose;
+       if (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
+       if (*mode == 'r') f->c.len = size;
+       else if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size);
+       else if (plus) *f->c.buf = 0;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
+       f->f.read = mread;
+       f->f.write = mwrite;
+       f->f.seek = mseek;
+       f->f.close = mclose;
 
-       return f;
+       return __ofl_add(&f->f);
 }
diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c
new file mode 100644
index 00000000..c1012658
--- /dev/null
+++ b/libc/stdio/getchar.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int getchar(void)
+{
+       return fgetc(stdin);
+}
diff --git a/libc/stdio/ofl.c b/libc/stdio/ofl.c
new file mode 100644
index 00000000..0ee6c2f2
--- /dev/null
+++ b/libc/stdio/ofl.c
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include "lock.h"
+
+static FILE *ofl_head;
+static mutex_t ofl_lock;
+
+FILE **__ofl_lock()
+{
+       LOCK(ofl_lock);
+       return &ofl_head;
+}
+
+void __ofl_unlock()
+{
+       UNLOCK(ofl_lock);
+}
diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c
index 3d659cce..7914795f 100644
--- a/libc/stdio/open_memstream.c
+++ b/libc/stdio/open_memstream.c
@@ -1,8 +1,9 @@
 #include "stdio_impl.h"
 #include <errno.h>
 #include <limits.h>
-#include <stdlib.h>
 #include <string.h>
+#include <stdlib.h>
+#include "libc.h"
 
 struct cookie {
        char **bufp;
@@ -13,6 +14,12 @@ struct cookie {
        size_t space;
 };
 
+struct ms_FILE {
+       FILE f;
+       struct cookie c;
+       unsigned char buf[BUFSIZ];
+};
+
 static off_t ms_seek(FILE *f, off_t off, int whence)
 {
        ssize_t base;
@@ -58,31 +65,33 @@ static int ms_close(FILE *f)
 
 FILE *open_memstream(char **bufp, size_t *sizep)
 {
-       FILE *f;
-       struct cookie *c;
-       if (!(f=malloc(sizeof *f + sizeof *c + BUFSIZ))) return 0;
-       memset(f, 0, sizeof *f + sizeof *c);
-       f->cookie = c = (void *)(f+1);
+       struct ms_FILE *f;
+       char *buf;
 
-       c->bufp = bufp;
-       c->sizep = sizep;
-       c->pos = c->len = c->space = 0;
-       c->buf = 0;
+       if (!(f=malloc(sizeof *f))) return 0;
+       if (!(buf=malloc(sizeof *buf))) {
+               free(f);
+               return 0;
+       }
+       memset(&f->f, 0, sizeof f->f);
+       memset(&f->c, 0, sizeof f->c);
+       f->f.cookie = &f->c;
 
-       f->flags = F_NORD;
-       f->fd = -1;
-       f->buf = (void *)(c+1);
-       f->buf_size = BUFSIZ;
-       f->lbf = EOF;
-       f->write = ms_write;
-       f->seek = ms_seek;
-       f->close = ms_close;
+       f->c.bufp = bufp;
+       f->c.sizep = sizep;
+       f->c.pos = f->c.len = f->c.space = *sizep = 0;
+       f->c.buf = *bufp = buf;
+       *buf = 0;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
+       f->f.flags = F_NORD;
+       f->f.fd = -1;
+       f->f.buf = f->buf;
+       f->f.buf_size = sizeof f->buf;
+       f->f.lbf = EOF;
+       f->f.write = ms_write;
+       f->f.seek = ms_seek;
+       f->f.close = ms_close;
+       f->f.mode = -1;
 
-       return f;
+       return __ofl_add(&f->f);
 }
diff --git a/libc/stdio/open_wmemstream.c b/libc/stdio/open_wmemstream.c
index 1984c7e1..54b85098 100644
--- a/libc/stdio/open_wmemstream.c
+++ b/libc/stdio/open_wmemstream.c
@@ -3,6 +3,8 @@
 #include <errno.h>
 #include <limits.h>
 #include <string.h>
+#include <stdlib.h>
+#include "libc.h"
 
 struct cookie {
        wchar_t **bufp;
@@ -14,6 +16,12 @@ struct cookie {
        mbstate_t mbs;
 };
 
+struct wms_FILE {
+       FILE f;
+       struct cookie c;
+       unsigned char buf[1];
+};
+
 static off_t wms_seek(FILE *f, off_t off, int whence)
 {
        ssize_t base;
@@ -59,31 +67,34 @@ static int wms_close(FILE *f)
 
 FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
 {
-       FILE *f;
-       struct cookie *c;
-       if (!(f=malloc(sizeof *f + sizeof *c))) return 0;
-       memset(f, 0, sizeof *f + sizeof *c);
-       f->cookie = c = (void *)(f+1);
+       struct wms_FILE *f;
+       wchar_t *buf;
+
+       if (!(f=malloc(sizeof *f))) return 0;
+       if (!(buf=malloc(sizeof *buf))) {
+               free(f);
+               return 0;
+       }
+       memset(&f->f, 0, sizeof f->f);
+       memset(&f->c, 0, sizeof f->c);
+       f->f.cookie = &f->c;
 
-       c->bufp = bufp;
-       c->sizep = sizep;
-       c->pos = c->len = c->space = 0;
-       c->buf = 0;
+       f->c.bufp = bufp;
+       f->c.sizep = sizep;
+       f->c.pos = f->c.len = f->c.space = *sizep = 0;
+       f->c.buf = *bufp = buf;
+       *buf = 0;
 
-       f->flags = F_NORD;
-       f->fd = -1;
-       f->buf = (void *)(c+1);
-       f->buf_size = 0;
-       f->lbf = EOF;
-       f->write = wms_write;
-       f->seek = wms_seek;
-       f->close = wms_close;
+       f->f.flags = F_NORD;
+       f->f.fd = -1;
+       f->f.buf = f->buf;
+       f->f.buf_size = 0;
+       f->f.lbf = EOF;
+       f->f.write = wms_write;
+       f->f.seek = wms_seek;
+       f->f.close = wms_close;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
+       fwide(&f->f, 1);
 
-       return f;
+       return __ofl_add(&f->f);
 }
diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c
new file mode 100644
index 00000000..945636d5
--- /dev/null
+++ b/libc/stdio/putchar.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int putchar(int c)
+{
+       return fputc(c, stdout);
+}
diff --git a/libc/stdio/stdio_impl.h b/libc/stdio/stdio_impl.h
index 19eee155..fa7a7e53 100644
--- a/libc/stdio/stdio_impl.h
+++ b/libc/stdio/stdio_impl.h
@@ -21,6 +21,7 @@ __BEGIN_DECLS
 #define F_EOF 16
 #define F_ERR 32
 #define F_SVB 64
+#define F_APP 128
 
 /*
  * Note: this structure is layed out so that the fields which are accessed
@@ -61,8 +62,14 @@ struct __FILE_s {
 
        bool no_locking;
        mutex_t mutex;
+       locale_t locale;
 };
 
+hidden FILE **__ofl_lock(void);
+hidden void __ofl_unlock(void);
+hidden void __stdio_exit_needed(void);
+hidden FILE *__ofl_add(FILE *f);
+
 size_t __stdio_read(FILE *, unsigned char *, size_t);
 size_t __stdio_write(FILE *, const unsigned char *, size_t);
 size_t __stdout_write(FILE *, const unsigned char *, size_t);
diff --git a/libc/syscall_to_function.h b/libc/syscall_to_function.h
index a58b4222..f24788cb 100644
--- a/libc/syscall_to_function.h
+++ b/libc/syscall_to_function.h
@@ -1,6 +1,8 @@
 #include <bits/syscall.h>
 #include <unistd.h>
 
+#define sys_open(filename, flags, ...) (open(filename, flags __VA_OPT__(,) 
__VA_ARGS__))
+
 #define __OSV_TO_FUNCTION_SYS_open(filename, flags, ...) (open(filename, flags 
__VA_OPT__(,) __VA_ARGS__))
 
 #define __OSV_TO_FUNCTION_SYS_close(fd) (close(fd))
@@ -17,6 +19,8 @@
 
 #define __OSV_TO_FUNCTION_SYS_fstat(fd, st) (fstat(fd, st))
 
+#define __OSV_TO_FUNCTION_SYS_lstat(fd, st) (lstat(fd, st))
+
 #define __OSV_TO_FUNCTION_SYS_unlink(path) (unlink(path))
 
 #define __OSV_TO_FUNCTION_SYS_rmdir(path) (rmdir(path))
diff --git a/libc/time/__tz.c b/libc/time/__tz.c
index cadece11..2901413b 100644
--- a/libc/time/__tz.c
+++ b/libc/time/__tz.c
@@ -4,7 +4,10 @@
 #include <stdlib.h>
 #undef _BSD_SOURCE // avoid conflict of static index variable with index() 
function in include/api/strings.h
 #include <string.h>
+#define _BSD_SOURCE
+#include <sys/mman.h>
 #include "libc.h"
+#include "lock.h"
 
 long  __timezone = 0;
 int   __daylight = 0;
@@ -21,13 +24,14 @@ const char __utc[] = "UTC";
 static int dst_off;
 static int r0[5], r1[5];
 
-static const unsigned char *zi, *trans, *index, *types, *abbrevs;
+static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
 static size_t map_size;
 
 static char old_tz_buf[32];
 static char *old_tz = old_tz_buf;
 static size_t old_tz_size = sizeof old_tz_buf;
 
+//static volatile int lock[1];
 static mutex_t lock;
 
 static int getint(const char **p)
@@ -37,19 +41,16 @@ static int getint(const char **p)
        return x;
 }
 
-static int getsigned(const char **p)
+static int getoff(const char **p)
 {
+       int neg = 0;
        if (**p == '-') {
                ++*p;
-               return -getint(p);
+               neg = 1;
+       } else if (**p == '+') {
+               ++*p;
        }
-       if (**p == '+') ++*p;
-       return getint(p);
-}
-
-static int getoff(const char **p)
-{
-       int off = 3600*getsigned(p);
+       int off = 3600*getint(p);
        if (**p == ':') {
                ++*p;
                off += 60*getint(p);
@@ -58,7 +59,7 @@ static int getoff(const char **p)
                        off += getint(p);
                }
        }
-       return off;
+       return neg ? -off : off;
 }
 
 static void getrule(const char **p, int rule[5])
@@ -88,7 +89,7 @@ static void getname(char *d, const char **p)
        int i;
        if (**p == '<') {
                ++*p;
-               for (i=0; **p!='>' && i<TZNAME_MAX; i++)
+               for (i=0; (*p)[i]!='>' && i<TZNAME_MAX; i++)
                        d[i] = (*p)[i];
                ++*p;
        } else {
@@ -117,29 +118,30 @@ static size_t zi_dotprod(const unsigned char *z, const 
unsigned char *v, size_t
        return y;
 }
 
-int __munmap(void *, size_t);
-
 static void do_tzset()
 {
        char buf[NAME_MAX+25], *pathname=buf+24;
-       const char *try, *s;
+       const char *try, *s, *p;
        const unsigned char *map = 0;
        size_t i;
        static const char search[] =
                "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
 
        s = getenv("TZ");
-       if (!s) s = __utc;
+       if (!s) s = "/etc/localtime";
+       if (!*s) s = __utc;
 
        if (old_tz && !strcmp(s, old_tz)) return;
 
+       for (i=0; i<5; i++) r0[i] = r1[i] = 0;
+
        if (zi) __munmap((void *)zi, map_size);
 
        /* Cache the old value of TZ to check if it has changed. Avoid
         * free so as not to pull it into static programs. Growth
         * strategy makes it so free would have minimal benefit anyway. */
        i = strlen(s);
-       if (i > PATH_MAX+1) s = __utc, i = 0;
+       if (i > PATH_MAX+1) s = __utc, i = 3;
        if (i >= old_tz_size) {
                old_tz_size *= 2;
                if (i >= old_tz_size) old_tz_size = i+1;
@@ -148,29 +150,32 @@ static void do_tzset()
        }
        if (old_tz) memcpy(old_tz, s, i+1);
 
-       if (*s == ':') s++;
-
        /* Non-suid can use an absolute tzfile pathname or a relative
         * pathame beginning with "."; in secure mode, only the
         * standard path will be searched. */
-       if (*s == '/' || *s == '.') {
-               map = __map_file(s, &map_size);
-       } else {
-               for (i=0; s[i] && s[i]!=','; i++) {
-                       if (s[i]=='/') {
-                               size_t l = strlen(s);
-                               if (l > NAME_MAX || strchr(s, '.'))
-                                       break;
+       if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
+               if (*s == ':') s++;
+               if (*s == '/' || *s == '.') {
+                       if (!strcmp(s, "/etc/localtime"))
+                               map = __map_file(s, &map_size);
+               } else {
+                       size_t l = strlen(s);
+                       if (l <= NAME_MAX && !strchr(s, '.')) {
                                memcpy(pathname, s, l+1);
                                pathname[l] = 0;
-                               for (try=search; !map && *try; try+=l) {
+                               for (try=search; !map && *try; try+=l+1) {
                                        l = strlen(try);
                                        memcpy(pathname-l, try, l);
                                        map = __map_file(pathname-l, &map_size);
                                }
-                               break;
                        }
                }
+               if (!map) s = __utc;
+       }
+       if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
+               __munmap((void *)map, map_size);
+               map = 0;
+               s = __utc;
        }
 
        zi = map;
@@ -186,11 +191,32 @@ static void do_tzset()
                index = trans + (zi_read32(trans-12) << scale);
                types = index + zi_read32(trans-12);
                abbrevs = types + 6*zi_read32(trans-8);
+               abbrevs_end = abbrevs + zi_read32(trans-4);
                if (zi[map_size-1] == '\n') {
                        for (s = (const char *)zi+map_size-2; *s!='\n'; s--);
                        s++;
                } else {
-                       s = 0;
+                       const unsigned char *p;
+                       __tzname[0] = __tzname[1] = 0;
+                       __daylight = __timezone = dst_off = 0;
+                       for (p=types; p<abbrevs; p+=6) {
+                               if (!p[4] && !__tzname[0]) {
+                                       __tzname[0] = (char *)abbrevs + p[5];
+                                       __timezone = -zi_read32(p);
+                               }
+                               if (p[4] && !__tzname[1]) {
+                                       __tzname[1] = (char *)abbrevs + p[5];
+                                       dst_off = -zi_read32(p);
+                                       __daylight = 1;
+                               }
+                       }
+                       if (!__tzname[0]) __tzname[0] = __tzname[1];
+                       if (!__tzname[0]) __tzname[0] = (char *)__utc;
+                       if (!__daylight) {
+                               __tzname[1] = __tzname[0];
+                               dst_off = __timezone;
+                       }
+                       return;
                }
        }
 
@@ -208,7 +234,7 @@ static void do_tzset()
                        dst_off = __timezone - 3600;
        } else {
                __daylight = 0;
-               dst_off = 0;
+               dst_off = __timezone;
        }
 
        if (*s == ',') s++, getrule(&s, r0);
@@ -332,9 +358,9 @@ void __secs_to_zone(long long t, int local, int *isdst, 
long *offset, long *oppo
                size_t alt, i = scan_trans(t, local, &alt);
                if (i != -1) {
                        *isdst = types[6*i+4];
-                       *offset = -(int32_t)zi_read32(types+6*i);
+                       *offset = (int32_t)zi_read32(types+6*i);
                        *zonename = (const char *)abbrevs + types[6*i+5];
-                       if (oppoff) *oppoff = -(int32_t)zi_read32(types+6*alt);
+                       if (oppoff) *oppoff = (int32_t)zi_read32(types+6*alt);
                        UNLOCK(lock);
                        return;
                }
@@ -351,37 +377,33 @@ void __secs_to_zone(long long t, int local, int *isdst, 
long *offset, long *oppo
        long long t0 = rule_to_secs(r0, y);
        long long t1 = rule_to_secs(r1, y);
 
+       if (!local) {
+               t0 += __timezone;
+               t1 += dst_off;
+       }
        if (t0 < t1) {
-               if (!local) {
-                       t0 += __timezone;
-                       t1 += dst_off;
-               }
                if (t >= t0 && t < t1) goto dst;
                goto std;
        } else {
-               if (!local) {
-                       t1 += __timezone;
-                       t0 += dst_off;
-               }
                if (t >= t1 && t < t0) goto std;
                goto dst;
        }
 std:
        *isdst = 0;
-       *offset = __timezone;
-       if (oppoff) *oppoff = dst_off;
+       *offset = -__timezone;
+       if (oppoff) *oppoff = -dst_off;
        *zonename = __tzname[0];
        UNLOCK(lock);
        return;
 dst:
        *isdst = 1;
-       *offset = dst_off;
-       if (oppoff) *oppoff = __timezone;
+       *offset = -dst_off;
+       if (oppoff) *oppoff = -__timezone;
        *zonename = __tzname[1];
        UNLOCK(lock);
 }
 
-void __tzset()
+static void __tzset()
 {
        LOCK(lock);
        do_tzset();
@@ -389,3 +411,15 @@ void __tzset()
 }
 
 weak_alias(__tzset, tzset);
+
+const char *__tm_to_tzname(const struct tm *tm)
+{
+       const void *p = tm->__tm_zone;
+       LOCK(lock);
+       do_tzset();
+       if (p != __utc && p != __tzname[0] && p != __tzname[1] &&
+           (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs))
+               p = "";
+       UNLOCK(lock);
+       return p;
+}
diff --git a/libc/time/ftime.c b/libc/time/ftime.c
deleted file mode 100644
index a1734d0f..00000000
--- a/libc/time/ftime.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <sys/timeb.h>
-#include <time.h>
-
-int ftime(struct timeb *tp)
-{
-       struct timespec ts;
-       clock_gettime(CLOCK_REALTIME, &ts);
-       tp->time = ts.tv_sec;
-       tp->millitm = ts.tv_nsec / 1000000;
-       tp->timezone = tp->dstflag = 0;
-       return 0;
-}
-- 
2.26.2

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20200906154028.4441-1-jwkozaczuk%40gmail.com.

Reply via email to