Merge "Revert "[MIPS] Link .dex or .oat code lacking .MIPS.abiflags segment""
diff --git a/libc/Android.bp b/libc/Android.bp
index ca8a4d5..8ec2b92 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1279,6 +1279,7 @@
         "bionic/ftruncate.cpp",
         "bionic/futimens.cpp",
         "bionic/getcwd.cpp",
+        "bionic/getdomainname.cpp",
         "bionic/gethostname.cpp",
         "bionic/getpgrp.cpp",
         "bionic/getpid.cpp",
diff --git a/libc/Android.mk b/libc/Android.mk
index 828a227..e9ee7fc 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -109,6 +109,7 @@
     bionic/ftruncate.cpp \
     bionic/futimens.cpp \
     bionic/getcwd.cpp \
+    bionic/getdomainname.cpp \
     bionic/gethostname.cpp \
     bionic/getpgrp.cpp \
     bionic/getpid.cpp \
@@ -574,18 +575,15 @@
 libc_common_cflags := \
     -D_LIBC=1 \
     -Wall -Wextra -Wunused \
+    -Wno-deprecated-declarations \
 
-use_clang := $(USE_CLANG_PLATFORM_BUILD)
+use_clang := true
 
 # b/25291096, Clang/llvm compiled libc.so for mips/mips64 failed to boot.
 ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
   use_clang := false
 endif
 
-ifeq ($(use_clang),)
-  use_clang := true
-endif
-
 # Try to catch typical 32-bit assumptions that break with 64-bit pointers.
 libc_common_cflags += \
     -Werror=pointer-to-int-cast \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index d5dd206..b774dbc 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -327,6 +327,7 @@
 int setfsgid(gid_t)  all
 int setfsuid(uid_t)  all
 
+int setdomainname(const char*, size_t)  all
 int sethostname(const char*, size_t)  all
 
 pid_t wait4(pid_t, int*, int, struct rusage*)  all
diff --git a/libc/arch-arm/syscalls/setdomainname.S b/libc/arch-arm/syscalls/setdomainname.S
new file mode 100644
index 0000000..20f1f6f
--- /dev/null
+++ b/libc/arch-arm/syscalls/setdomainname.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    mov     ip, r7
+    ldr     r7, =__NR_setdomainname
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(setdomainname)
diff --git a/libc/arch-arm64/syscalls/setdomainname.S b/libc/arch-arm64/syscalls/setdomainname.S
new file mode 100644
index 0000000..18f8d4b
--- /dev/null
+++ b/libc/arch-arm64/syscalls/setdomainname.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    mov     x8, __NR_setdomainname
+    svc     #0
+
+    cmn     x0, #(MAX_ERRNO + 1)
+    cneg    x0, x0, hi
+    b.hi    __set_errno_internal
+
+    ret
+END(setdomainname)
diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S
index 73002e8..3b4ff55 100644
--- a/libc/arch-mips/bionic/setjmp.S
+++ b/libc/arch-mips/bionic/setjmp.S
@@ -136,7 +136,7 @@
 /* following fields are 8-byte aligned */
 #define	SC_FLAG_OFFSET	(2*4)		/* 8 bytes, cookie and savesigs flag, first actual field  */
 #define	SC_MASK_OFFSET	(4*4)		/* 16 bytes, mips32/mips64 version of sigset_t */
-#define	SC_SPARE_OFFSET	(8*4)		/* 8 bytes, reserved for future uses */
+#define	SC_CKSUM_OFFSET	(8*4)		/* 8 bytes, used for checksum */
 
 /* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */
 #define	SC_REGS_OFFSET	(10*4)		/* SC_REGS_BYTES */
@@ -165,6 +165,8 @@
 #error _JBLEN is too small
 #endif
 
+#define USE_CHECKSUM 1
+
 .macro m_mangle_reg_and_store reg, cookie, temp, offset
 	xor	\temp, \reg, \cookie
 	REG_S	\temp, \offset
@@ -175,6 +177,20 @@
 	xor	\reg, \temp, \cookie
 .endm
 
+.macro m_calculate_checksum dst, src, scratch
+	REG_L \dst, REGSZ(\src)
+#ifdef __LP64__
+	/* 64 bit: checksum offset is 4 (actual _JBLEN is 25) */
+	.irp i,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
+#else
+	/* 32 bit: checksum offset is 8 (actual _JBLEN is 34) */
+	.irp i,2,3,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33
+#endif
+		REG_L \scratch, \i*REGSZ(\src)
+		xor \dst, \dst, \scratch
+	.endr
+.endm
+
 /*
  *
  *  GPOFF and FRAMESIZE must be the same for all setjmp/longjmp routines
@@ -263,6 +279,10 @@
 	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 #endif
 	sw	v0, SC_FPSR_OFFSET(a0)
+#if USE_CHECKSUM
+	m_calculate_checksum t0, a0, t1
+	REG_S t0, SC_CKSUM_OFFSET(a0)
+#endif
 	move	v0, zero
 	RESTORE_GP64
 	PTR_ADDU sp, FRAMESZ
@@ -311,6 +331,16 @@
 	move	s1, a1				# temp spill
 	move	s0, a0
 
+#if USE_CHECKSUM
+	m_calculate_checksum t0, s0, s2
+	REG_L	s2, SC_CKSUM_OFFSET(s0)
+	beq	t0, s2, 0f
+	nop
+	jal	__bionic_setjmp_checksum_mismatch
+	nop
+0:
+#endif
+
 	# extract savesigs flag
 	REG_L	s2, SC_FLAG_OFFSET(s0)
 	andi	t0, s2, 1
diff --git a/libc/arch-mips/string/memset.S b/libc/arch-mips/string/memset.S
index dd94f3b..6344af1 100644
--- a/libc/arch-mips/string/memset.S
+++ b/libc/arch-mips/string/memset.S
@@ -208,7 +208,10 @@
 #else
 LEAF(__memset_chk)
 #endif
+	.set	noreorder
   bgtu   a2, a3, __memset_chk_fail
+  la     t9, __memset_chk_fail
+	.set	reorder
 
   // Fall through to memset...
 END(__memset_chk)
diff --git a/libc/arch-mips/syscalls/setdomainname.S b/libc/arch-mips/syscalls/setdomainname.S
new file mode 100644
index 0000000..ec0504c
--- /dev/null
+++ b/libc/arch-mips/syscalls/setdomainname.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    .set noreorder
+    .cpload t9
+    li v0, __NR_setdomainname
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    la t9,__set_errno_internal
+    j t9
+    nop
+    .set reorder
+END(setdomainname)
diff --git a/libc/arch-mips64/syscalls/setdomainname.S b/libc/arch-mips64/syscalls/setdomainname.S
new file mode 100644
index 0000000..6cee88e
--- /dev/null
+++ b/libc/arch-mips64/syscalls/setdomainname.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    .set push
+    .set noreorder
+    li v0, __NR_setdomainname
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    move t0, ra
+    bal     2f
+    nop
+2:
+    .cpsetup ra, t1, 2b
+    LA t9,__set_errno_internal
+    .cpreturn
+    j t9
+    move ra, t0
+    .set pop
+END(setdomainname)
diff --git a/libc/arch-x86/atom/string/sse2-memset-atom.S b/libc/arch-x86/atom/string/sse2-memset-atom.S
index 30fb3f1..e03cd1a 100644
--- a/libc/arch-x86/atom/string/sse2-memset-atom.S
+++ b/libc/arch-x86/atom/string/sse2-memset-atom.S
@@ -113,11 +113,12 @@
 #endif
 
 ENTRY(__memset_chk)
-  movl LEN(%esp), %ecx
-  cmpl %ecx, CHK_DST_LEN(%esp)
-  jbe memset
+  ENTRANCE
 
-  jmp __memset_chk_fail
+  movl LEN(%esp), %ecx
+  cmpl CHK_DST_LEN(%esp), %ecx
+  ja __memset_chk_fail
+  jmp L(memset_length_loaded)
 END(__memset_chk)
 
 	.section .text.sse2,"ax",@progbits
@@ -126,6 +127,7 @@
 	ENTRANCE
 
 	movl	LEN(%esp), %ecx
+L(memset_length_loaded):
 	movzbl	CHR(%esp), %eax
 	movb	%al, %ah
 	/* Fill the whole EAX with pattern.  */
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index 86e6e3c..efb6459 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -32,6 +32,21 @@
 
 #include <private/bionic_asm.h>
 
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      edx             registers
+// 1      ebx
+// 2      esp
+// 3      ebp
+// 4      esi
+// 5      edi
+// 6      sigmask         signal mask (not used with _setjmp / _longjmp)
+// 7      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 8      checksum        checksum of the core registers, to give better error messages.
+// 9      reserved
+
 #define _JB_EDX 0
 #define _JB_EBX 1
 #define _JB_ESP 2
@@ -40,6 +55,7 @@
 #define _JB_EDI 5
 #define _JB_SIGMASK 6
 #define _JB_SIGFLAG 7
+#define _JB_CHECKSUM 8
 
 .macro m_mangle_registers reg
   xorl \reg,%edx
@@ -54,6 +70,13 @@
   m_mangle_registers \reg
 .endm
 
+.macro m_calculate_checksum dst, src
+  movl $0, \dst
+  .irp i,0,1,2,3,4,5
+    xorl (\i*4)(\src), \dst
+  .endr
+.endm
+
 ENTRY(setjmp)
   movl 4(%esp),%ecx
   mov $1,%eax
@@ -111,13 +134,22 @@
   movl %edi,(_JB_EDI * 4)(%ecx)
   m_unmangle_registers %eax
 
+  m_calculate_checksum %eax, %ecx
+  movl %eax, (_JB_CHECKSUM * 4)(%ecx)
+
   xorl %eax,%eax
   ret
 END(sigsetjmp)
 
 ENTRY(siglongjmp)
-  // Do we have a signal mask to restore?
   movl 4(%esp),%edx
+
+  // Check the checksum before doing anything.
+  m_calculate_checksum %eax, %edx
+  xorl (_JB_CHECKSUM * 4)(%edx), %eax
+  jnz 3f
+
+  // Do we have a signal mask to restore?
   movl (_JB_SIGFLAG * 4)(%edx), %eax
   testl $1,%eax
   jz 1f
@@ -165,6 +197,11 @@
 2:
   movl %ecx,0(%esp)
   ret
+
+3:
+  PIC_PROLOGUE
+  pushl (_JB_SIGMASK * 4)(%edx)
+  call PIC_PLT(__bionic_setjmp_checksum_mismatch)
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
diff --git a/libc/arch-x86/bionic/syscall.S b/libc/arch-x86/bionic/syscall.S
index 2a15102..12402ac 100644
--- a/libc/arch-x86/bionic/syscall.S
+++ b/libc/arch-x86/bionic/syscall.S
@@ -27,18 +27,25 @@
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
 
+    # Get and save the system call entry address.
+    call    __kernel_syscall
+    push    %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     # Load all the arguments from the calling frame.
     # (Not all will be valid, depending on the syscall.)
-    mov     20(%esp),%eax
-    mov     24(%esp),%ebx
-    mov     28(%esp),%ecx
-    mov     32(%esp),%edx
-    mov     36(%esp),%esi
-    mov     40(%esp),%edi
-    mov     44(%esp),%ebp
+    mov     24(%esp),%eax
+    mov     28(%esp),%ebx
+    mov     32(%esp),%ecx
+    mov     36(%esp),%edx
+    mov     40(%esp),%esi
+    mov     44(%esp),%edi
+    mov     48(%esp),%ebp
 
     # Make the system call.
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
 
     # Error?
     cmpl    $-MAX_ERRNO, %eax
diff --git a/libc/arch-x86/silvermont/string/sse2-memset-slm.S b/libc/arch-x86/silvermont/string/sse2-memset-slm.S
index 0718fa7..f5182ba 100644
--- a/libc/arch-x86/silvermont/string/sse2-memset-slm.S
+++ b/libc/arch-x86/silvermont/string/sse2-memset-slm.S
@@ -113,11 +113,12 @@
 #endif
 
 ENTRY(__memset_chk)
-  movl LEN(%esp), %ecx
-  cmpl %ecx, CHK_DST_LEN(%esp)
-  jbe memset
+  ENTRANCE
 
-  jmp __memset_chk_fail
+  movl LEN(%esp), %ecx
+  cmpl CHK_DST_LEN(%esp), %ecx
+  ja __memset_chk_fail
+  jmp L(memset_length_loaded)
 END(__memset_chk)
 
 	.section .text.sse2,"ax",@progbits
@@ -126,6 +127,7 @@
 	ENTRANCE
 
 	movl	LEN(%esp), %ecx
+L(memset_length_loaded):
 	cmp	$0, %ecx
 	ja	L(1byteormore)
 	SETRTNVAL
diff --git a/libc/arch-x86/syscalls/___clock_nanosleep.S b/libc/arch-x86/syscalls/___clock_nanosleep.S
index 088a92e..6998749 100644
--- a/libc/arch-x86/syscalls/___clock_nanosleep.S
+++ b/libc/arch-x86/syscalls/___clock_nanosleep.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_clock_nanosleep, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___close.S b/libc/arch-x86/syscalls/___close.S
index 796944b..b9ebdaa 100644
--- a/libc/arch-x86/syscalls/___close.S
+++ b/libc/arch-x86/syscalls/___close.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_close, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___faccessat.S b/libc/arch-x86/syscalls/___faccessat.S
index 361a6ea..b92b03d 100644
--- a/libc/arch-x86/syscalls/___faccessat.S
+++ b/libc/arch-x86/syscalls/___faccessat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_faccessat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fchmod.S b/libc/arch-x86/syscalls/___fchmod.S
index 119a695..92e864c 100644
--- a/libc/arch-x86/syscalls/___fchmod.S
+++ b/libc/arch-x86/syscalls/___fchmod.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fchmod, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fchmodat.S b/libc/arch-x86/syscalls/___fchmodat.S
index b15bb64..81edf96 100644
--- a/libc/arch-x86/syscalls/___fchmodat.S
+++ b/libc/arch-x86/syscalls/___fchmodat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_fchmodat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fgetxattr.S b/libc/arch-x86/syscalls/___fgetxattr.S
index 2891511..712728d 100644
--- a/libc/arch-x86/syscalls/___fgetxattr.S
+++ b/libc/arch-x86/syscalls/___fgetxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_fgetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___flistxattr.S b/libc/arch-x86/syscalls/___flistxattr.S
index a67967b..a22ef35 100644
--- a/libc/arch-x86/syscalls/___flistxattr.S
+++ b/libc/arch-x86/syscalls/___flistxattr.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_flistxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fsetxattr.S b/libc/arch-x86/syscalls/___fsetxattr.S
index 287dafc..b90c972 100644
--- a/libc/arch-x86/syscalls/___fsetxattr.S
+++ b/libc/arch-x86/syscalls/___fsetxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_fsetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___mremap.S b/libc/arch-x86/syscalls/___mremap.S
index e5e9c54..9d9bfcb 100644
--- a/libc/arch-x86/syscalls/___mremap.S
+++ b/libc/arch-x86/syscalls/___mremap.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_mremap, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___rt_sigqueueinfo.S b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
index 97d167f..e299707 100644
--- a/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
+++ b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_rt_sigqueueinfo, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__accept4.S b/libc/arch-x86/syscalls/__accept4.S
index 7b16dd4..112a8a7 100644
--- a/libc/arch-x86/syscalls/__accept4.S
+++ b/libc/arch-x86/syscalls/__accept4.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $18, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__brk.S b/libc/arch-x86/syscalls/__brk.S
index 22acdad..bf2f1d2 100644
--- a/libc/arch-x86/syscalls/__brk.S
+++ b/libc/arch-x86/syscalls/__brk.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_brk, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__clock_gettime.S b/libc/arch-x86/syscalls/__clock_gettime.S
index 61eadc8..0c0c1c4 100644
--- a/libc/arch-x86/syscalls/__clock_gettime.S
+++ b/libc/arch-x86/syscalls/__clock_gettime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_gettime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__connect.S b/libc/arch-x86/syscalls/__connect.S
index 475d452..5ea160c 100644
--- a/libc/arch-x86/syscalls/__connect.S
+++ b/libc/arch-x86/syscalls/__connect.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $3, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__epoll_pwait.S b/libc/arch-x86/syscalls/__epoll_pwait.S
index 171caa5..3750760 100644
--- a/libc/arch-x86/syscalls/__epoll_pwait.S
+++ b/libc/arch-x86/syscalls/__epoll_pwait.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_epoll_pwait, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__exit.S b/libc/arch-x86/syscalls/__exit.S
index 8cf3663..841c8cf 100644
--- a/libc/arch-x86/syscalls/__exit.S
+++ b/libc/arch-x86/syscalls/__exit.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_exit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fadvise64.S b/libc/arch-x86/syscalls/__fadvise64.S
index 6e4298a..d580a61 100644
--- a/libc/arch-x86/syscalls/__fadvise64.S
+++ b/libc/arch-x86/syscalls/__fadvise64.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_fadvise64_64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fcntl64.S b/libc/arch-x86/syscalls/__fcntl64.S
index d900a52..c886411 100644
--- a/libc/arch-x86/syscalls/__fcntl64.S
+++ b/libc/arch-x86/syscalls/__fcntl64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_fcntl64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fstatfs64.S b/libc/arch-x86/syscalls/__fstatfs64.S
index 9b44743..2c97435 100644
--- a/libc/arch-x86/syscalls/__fstatfs64.S
+++ b/libc/arch-x86/syscalls/__fstatfs64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_fstatfs64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getcpu.S b/libc/arch-x86/syscalls/__getcpu.S
index bb4c41f..fde7306 100644
--- a/libc/arch-x86/syscalls/__getcpu.S
+++ b/libc/arch-x86/syscalls/__getcpu.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_getcpu, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getcwd.S b/libc/arch-x86/syscalls/__getcwd.S
index 8decd99..dc0bded 100644
--- a/libc/arch-x86/syscalls/__getcwd.S
+++ b/libc/arch-x86/syscalls/__getcwd.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getcwd, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getdents64.S b/libc/arch-x86/syscalls/__getdents64.S
index 5190a68..4228da2 100644
--- a/libc/arch-x86/syscalls/__getdents64.S
+++ b/libc/arch-x86/syscalls/__getdents64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_getdents64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getpid.S b/libc/arch-x86/syscalls/__getpid.S
index 197202c..aa5d343 100644
--- a/libc/arch-x86/syscalls/__getpid.S
+++ b/libc/arch-x86/syscalls/__getpid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(__getpid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getpid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getpriority.S b/libc/arch-x86/syscalls/__getpriority.S
index dd5591f..cf2fbc3 100644
--- a/libc/arch-x86/syscalls/__getpriority.S
+++ b/libc/arch-x86/syscalls/__getpriority.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getpriority, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__gettimeofday.S b/libc/arch-x86/syscalls/__gettimeofday.S
index 90f3f91..4e24cdd 100644
--- a/libc/arch-x86/syscalls/__gettimeofday.S
+++ b/libc/arch-x86/syscalls/__gettimeofday.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_gettimeofday, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__ioctl.S b/libc/arch-x86/syscalls/__ioctl.S
index b6ee9f2..2189638 100644
--- a/libc/arch-x86/syscalls/__ioctl.S
+++ b/libc/arch-x86/syscalls/__ioctl.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_ioctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__llseek.S b/libc/arch-x86/syscalls/__llseek.S
index 5cc907a..9213891 100644
--- a/libc/arch-x86/syscalls/__llseek.S
+++ b/libc/arch-x86/syscalls/__llseek.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR__llseek, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__mmap2.S b/libc/arch-x86/syscalls/__mmap2.S
index 08314c8..0904a3d 100644
--- a/libc/arch-x86/syscalls/__mmap2.S
+++ b/libc/arch-x86/syscalls/__mmap2.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_mmap2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__openat.S b/libc/arch-x86/syscalls/__openat.S
index 4c11709..03c03bd 100644
--- a/libc/arch-x86/syscalls/__openat.S
+++ b/libc/arch-x86/syscalls/__openat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_openat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__ppoll.S b/libc/arch-x86/syscalls/__ppoll.S
index 2a1f76e..1a55b03 100644
--- a/libc/arch-x86/syscalls/__ppoll.S
+++ b/libc/arch-x86/syscalls/__ppoll.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_ppoll, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__preadv64.S b/libc/arch-x86/syscalls/__preadv64.S
index 3ce4fc3..5db22a3 100644
--- a/libc/arch-x86/syscalls/__preadv64.S
+++ b/libc/arch-x86/syscalls/__preadv64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_preadv, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__pselect6.S b/libc/arch-x86/syscalls/__pselect6.S
index 8ff102a..18327fd 100644
--- a/libc/arch-x86/syscalls/__pselect6.S
+++ b/libc/arch-x86/syscalls/__pselect6.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_pselect6, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__ptrace.S b/libc/arch-x86/syscalls/__ptrace.S
index d982cec..a522e95 100644
--- a/libc/arch-x86/syscalls/__ptrace.S
+++ b/libc/arch-x86/syscalls/__ptrace.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_ptrace, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__pwritev64.S b/libc/arch-x86/syscalls/__pwritev64.S
index 2ce5b0e..19f1865 100644
--- a/libc/arch-x86/syscalls/__pwritev64.S
+++ b/libc/arch-x86/syscalls/__pwritev64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_pwritev, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__reboot.S b/libc/arch-x86/syscalls/__reboot.S
index 3d169bf..711a4e6 100644
--- a/libc/arch-x86/syscalls/__reboot.S
+++ b/libc/arch-x86/syscalls/__reboot.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_reboot, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigaction.S b/libc/arch-x86/syscalls/__rt_sigaction.S
index 59c3882..ebc431d 100644
--- a/libc/arch-x86/syscalls/__rt_sigaction.S
+++ b/libc/arch-x86/syscalls/__rt_sigaction.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigaction, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigpending.S b/libc/arch-x86/syscalls/__rt_sigpending.S
index 9c6a106..ecf2945 100644
--- a/libc/arch-x86/syscalls/__rt_sigpending.S
+++ b/libc/arch-x86/syscalls/__rt_sigpending.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_rt_sigpending, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigprocmask.S b/libc/arch-x86/syscalls/__rt_sigprocmask.S
index 9b1532f..cdd0f10 100644
--- a/libc/arch-x86/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-x86/syscalls/__rt_sigprocmask.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigprocmask, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigsuspend.S b/libc/arch-x86/syscalls/__rt_sigsuspend.S
index b05acd8..ef96949 100644
--- a/libc/arch-x86/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-x86/syscalls/__rt_sigsuspend.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_rt_sigsuspend, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigtimedwait.S b/libc/arch-x86/syscalls/__rt_sigtimedwait.S
index 14cb70f..8205221 100644
--- a/libc/arch-x86/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-x86/syscalls/__rt_sigtimedwait.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigtimedwait, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__sched_getaffinity.S b/libc/arch-x86/syscalls/__sched_getaffinity.S
index 0b0a970..ba658af 100644
--- a/libc/arch-x86/syscalls/__sched_getaffinity.S
+++ b/libc/arch-x86/syscalls/__sched_getaffinity.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_sched_getaffinity, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__set_thread_area.S b/libc/arch-x86/syscalls/__set_thread_area.S
index 8cd6880..7fc04bd 100644
--- a/libc/arch-x86/syscalls/__set_thread_area.S
+++ b/libc/arch-x86/syscalls/__set_thread_area.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_set_thread_area, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__set_tid_address.S b/libc/arch-x86/syscalls/__set_tid_address.S
index 08acce9..4301156 100644
--- a/libc/arch-x86/syscalls/__set_tid_address.S
+++ b/libc/arch-x86/syscalls/__set_tid_address.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_set_tid_address, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__sigaction.S b/libc/arch-x86/syscalls/__sigaction.S
index 0238247..6b2b7f3 100644
--- a/libc/arch-x86/syscalls/__sigaction.S
+++ b/libc/arch-x86/syscalls/__sigaction.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_sigaction, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__signalfd4.S b/libc/arch-x86/syscalls/__signalfd4.S
index 02ddc73..ea817cf 100644
--- a/libc/arch-x86/syscalls/__signalfd4.S
+++ b/libc/arch-x86/syscalls/__signalfd4.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_signalfd4, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__socket.S b/libc/arch-x86/syscalls/__socket.S
index 75952ee..06d1f1f 100644
--- a/libc/arch-x86/syscalls/__socket.S
+++ b/libc/arch-x86/syscalls/__socket.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $1, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__statfs64.S b/libc/arch-x86/syscalls/__statfs64.S
index b9bccb0..79e1f4b 100644
--- a/libc/arch-x86/syscalls/__statfs64.S
+++ b/libc/arch-x86/syscalls/__statfs64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_statfs64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_create.S b/libc/arch-x86/syscalls/__timer_create.S
index b22f408..4e16b1c 100644
--- a/libc/arch-x86/syscalls/__timer_create.S
+++ b/libc/arch-x86/syscalls/__timer_create.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_timer_create, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_delete.S b/libc/arch-x86/syscalls/__timer_delete.S
index d77ae3e..fea422e 100644
--- a/libc/arch-x86/syscalls/__timer_delete.S
+++ b/libc/arch-x86/syscalls/__timer_delete.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_timer_delete, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_getoverrun.S b/libc/arch-x86/syscalls/__timer_getoverrun.S
index f21b08f..e921073 100644
--- a/libc/arch-x86/syscalls/__timer_getoverrun.S
+++ b/libc/arch-x86/syscalls/__timer_getoverrun.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_timer_getoverrun, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_gettime.S b/libc/arch-x86/syscalls/__timer_gettime.S
index 73c8539..4e20356 100644
--- a/libc/arch-x86/syscalls/__timer_gettime.S
+++ b/libc/arch-x86/syscalls/__timer_gettime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timer_gettime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_settime.S b/libc/arch-x86/syscalls/__timer_settime.S
index 1a6a8ec..9b8af34 100644
--- a/libc/arch-x86/syscalls/__timer_settime.S
+++ b/libc/arch-x86/syscalls/__timer_settime.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_timer_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__waitid.S b/libc/arch-x86/syscalls/__waitid.S
index 2061abc..f134b42 100644
--- a/libc/arch-x86/syscalls/__waitid.S
+++ b/libc/arch-x86/syscalls/__waitid.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_waitid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/_exit.S b/libc/arch-x86/syscalls/_exit.S
index 9945b35..1e89261 100644
--- a/libc/arch-x86/syscalls/_exit.S
+++ b/libc/arch-x86/syscalls/_exit.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_exit_group, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/acct.S b/libc/arch-x86/syscalls/acct.S
index d831771..48c4c5c 100644
--- a/libc/arch-x86/syscalls/acct.S
+++ b/libc/arch-x86/syscalls/acct.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_acct, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/adjtimex.S b/libc/arch-x86/syscalls/adjtimex.S
index 2a91f90..1b0d8b1 100644
--- a/libc/arch-x86/syscalls/adjtimex.S
+++ b/libc/arch-x86/syscalls/adjtimex.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_adjtimex, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/bind.S b/libc/arch-x86/syscalls/bind.S
index 9ef817e..c1f84da 100644
--- a/libc/arch-x86/syscalls/bind.S
+++ b/libc/arch-x86/syscalls/bind.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $2, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/capget.S b/libc/arch-x86/syscalls/capget.S
index 81c24e8..fafde37 100644
--- a/libc/arch-x86/syscalls/capget.S
+++ b/libc/arch-x86/syscalls/capget.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_capget, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/capset.S b/libc/arch-x86/syscalls/capset.S
index 4e311e9..28e5338 100644
--- a/libc/arch-x86/syscalls/capset.S
+++ b/libc/arch-x86/syscalls/capset.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_capset, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/chdir.S b/libc/arch-x86/syscalls/chdir.S
index 2226a1a..4b639eb 100644
--- a/libc/arch-x86/syscalls/chdir.S
+++ b/libc/arch-x86/syscalls/chdir.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_chdir, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/chroot.S b/libc/arch-x86/syscalls/chroot.S
index 95ed0b5..8887f86 100644
--- a/libc/arch-x86/syscalls/chroot.S
+++ b/libc/arch-x86/syscalls/chroot.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_chroot, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/clock_adjtime.S b/libc/arch-x86/syscalls/clock_adjtime.S
index b6e0ac4..4ccf1a6 100644
--- a/libc/arch-x86/syscalls/clock_adjtime.S
+++ b/libc/arch-x86/syscalls/clock_adjtime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_adjtime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/clock_getres.S b/libc/arch-x86/syscalls/clock_getres.S
index 9501799..9466e08 100644
--- a/libc/arch-x86/syscalls/clock_getres.S
+++ b/libc/arch-x86/syscalls/clock_getres.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_getres, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/clock_settime.S b/libc/arch-x86/syscalls/clock_settime.S
index 96fafed..62dc021 100644
--- a/libc/arch-x86/syscalls/clock_settime.S
+++ b/libc/arch-x86/syscalls/clock_settime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/delete_module.S b/libc/arch-x86/syscalls/delete_module.S
index 58b8d6b..b0c8ff9 100644
--- a/libc/arch-x86/syscalls/delete_module.S
+++ b/libc/arch-x86/syscalls/delete_module.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_delete_module, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/dup.S b/libc/arch-x86/syscalls/dup.S
index 0fd9cce..637cfae 100644
--- a/libc/arch-x86/syscalls/dup.S
+++ b/libc/arch-x86/syscalls/dup.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_dup, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/dup3.S b/libc/arch-x86/syscalls/dup3.S
index 8348660..4d08eab 100644
--- a/libc/arch-x86/syscalls/dup3.S
+++ b/libc/arch-x86/syscalls/dup3.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_dup3, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/epoll_create1.S b/libc/arch-x86/syscalls/epoll_create1.S
index 0fcd09c..93d1c00 100644
--- a/libc/arch-x86/syscalls/epoll_create1.S
+++ b/libc/arch-x86/syscalls/epoll_create1.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_epoll_create1, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/epoll_ctl.S b/libc/arch-x86/syscalls/epoll_ctl.S
index 092c1e0..a2d8d27 100644
--- a/libc/arch-x86/syscalls/epoll_ctl.S
+++ b/libc/arch-x86/syscalls/epoll_ctl.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_epoll_ctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/eventfd.S b/libc/arch-x86/syscalls/eventfd.S
index cc165e5..89f9442 100644
--- a/libc/arch-x86/syscalls/eventfd.S
+++ b/libc/arch-x86/syscalls/eventfd.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_eventfd2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/execve.S b/libc/arch-x86/syscalls/execve.S
index e1c0253..7695635 100644
--- a/libc/arch-x86/syscalls/execve.S
+++ b/libc/arch-x86/syscalls/execve.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_execve, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fallocate64.S b/libc/arch-x86/syscalls/fallocate64.S
index e2a7c3e..eabc642 100644
--- a/libc/arch-x86/syscalls/fallocate64.S
+++ b/libc/arch-x86/syscalls/fallocate64.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_fallocate, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchdir.S b/libc/arch-x86/syscalls/fchdir.S
index c40c2c1..5701644 100644
--- a/libc/arch-x86/syscalls/fchdir.S
+++ b/libc/arch-x86/syscalls/fchdir.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fchdir, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchown.S b/libc/arch-x86/syscalls/fchown.S
index 1a4f749..0d41389 100644
--- a/libc/arch-x86/syscalls/fchown.S
+++ b/libc/arch-x86/syscalls/fchown.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_fchown32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchownat.S b/libc/arch-x86/syscalls/fchownat.S
index c2b358e..56b7777 100644
--- a/libc/arch-x86/syscalls/fchownat.S
+++ b/libc/arch-x86/syscalls/fchownat.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_fchownat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fdatasync.S b/libc/arch-x86/syscalls/fdatasync.S
index debd4e3..6ee9e15 100644
--- a/libc/arch-x86/syscalls/fdatasync.S
+++ b/libc/arch-x86/syscalls/fdatasync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fdatasync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/flock.S b/libc/arch-x86/syscalls/flock.S
index 0fc76a8..b65543d 100644
--- a/libc/arch-x86/syscalls/flock.S
+++ b/libc/arch-x86/syscalls/flock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_flock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fremovexattr.S b/libc/arch-x86/syscalls/fremovexattr.S
index 2053a9a..3511d5d 100644
--- a/libc/arch-x86/syscalls/fremovexattr.S
+++ b/libc/arch-x86/syscalls/fremovexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fremovexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fstat64.S b/libc/arch-x86/syscalls/fstat64.S
index ba385a4..16eca69 100644
--- a/libc/arch-x86/syscalls/fstat64.S
+++ b/libc/arch-x86/syscalls/fstat64.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fstat64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fstatat64.S b/libc/arch-x86/syscalls/fstatat64.S
index 90e87b6..402cf60 100644
--- a/libc/arch-x86/syscalls/fstatat64.S
+++ b/libc/arch-x86/syscalls/fstatat64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_fstatat64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fsync.S b/libc/arch-x86/syscalls/fsync.S
index b19a3ab..53aeee6 100644
--- a/libc/arch-x86/syscalls/fsync.S
+++ b/libc/arch-x86/syscalls/fsync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fsync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/ftruncate64.S b/libc/arch-x86/syscalls/ftruncate64.S
index 7233447..2fa792f 100644
--- a/libc/arch-x86/syscalls/ftruncate64.S
+++ b/libc/arch-x86/syscalls/ftruncate64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_ftruncate64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getegid.S b/libc/arch-x86/syscalls/getegid.S
index 729b7ad..cb1921e 100644
--- a/libc/arch-x86/syscalls/getegid.S
+++ b/libc/arch-x86/syscalls/getegid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getegid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getegid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/geteuid.S b/libc/arch-x86/syscalls/geteuid.S
index dcc76b1..c08d3ae 100644
--- a/libc/arch-x86/syscalls/geteuid.S
+++ b/libc/arch-x86/syscalls/geteuid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(geteuid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_geteuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getgid.S b/libc/arch-x86/syscalls/getgid.S
index b36a2c9..9189ae9 100644
--- a/libc/arch-x86/syscalls/getgid.S
+++ b/libc/arch-x86/syscalls/getgid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getgid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getgroups.S b/libc/arch-x86/syscalls/getgroups.S
index 0a5de35..8737d51 100644
--- a/libc/arch-x86/syscalls/getgroups.S
+++ b/libc/arch-x86/syscalls/getgroups.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getgroups32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getitimer.S b/libc/arch-x86/syscalls/getitimer.S
index a0cb761..e088114 100644
--- a/libc/arch-x86/syscalls/getitimer.S
+++ b/libc/arch-x86/syscalls/getitimer.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getitimer, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getpeername.S b/libc/arch-x86/syscalls/getpeername.S
index 6773e6a..40bb814 100644
--- a/libc/arch-x86/syscalls/getpeername.S
+++ b/libc/arch-x86/syscalls/getpeername.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $7, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getpgid.S b/libc/arch-x86/syscalls/getpgid.S
index f702cfd..9d362e8 100644
--- a/libc/arch-x86/syscalls/getpgid.S
+++ b/libc/arch-x86/syscalls/getpgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_getpgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getppid.S b/libc/arch-x86/syscalls/getppid.S
index edbe384..afb40a1 100644
--- a/libc/arch-x86/syscalls/getppid.S
+++ b/libc/arch-x86/syscalls/getppid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getppid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getppid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getresgid.S b/libc/arch-x86/syscalls/getresgid.S
index 9f1a9dd..131c101 100644
--- a/libc/arch-x86/syscalls/getresgid.S
+++ b/libc/arch-x86/syscalls/getresgid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_getresgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getresuid.S b/libc/arch-x86/syscalls/getresuid.S
index 61e1370..94a8767 100644
--- a/libc/arch-x86/syscalls/getresuid.S
+++ b/libc/arch-x86/syscalls/getresuid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_getresuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getrlimit.S b/libc/arch-x86/syscalls/getrlimit.S
index c3acff3..c686f7c 100644
--- a/libc/arch-x86/syscalls/getrlimit.S
+++ b/libc/arch-x86/syscalls/getrlimit.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_ugetrlimit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getrusage.S b/libc/arch-x86/syscalls/getrusage.S
index 0d715cd..51d1df1 100644
--- a/libc/arch-x86/syscalls/getrusage.S
+++ b/libc/arch-x86/syscalls/getrusage.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getrusage, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsid.S b/libc/arch-x86/syscalls/getsid.S
index e142c05..a4568e6 100644
--- a/libc/arch-x86/syscalls/getsid.S
+++ b/libc/arch-x86/syscalls/getsid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_getsid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsockname.S b/libc/arch-x86/syscalls/getsockname.S
index 6050190..0fd5836 100644
--- a/libc/arch-x86/syscalls/getsockname.S
+++ b/libc/arch-x86/syscalls/getsockname.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $6, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsockopt.S b/libc/arch-x86/syscalls/getsockopt.S
index aec40cf..fa6fccf 100644
--- a/libc/arch-x86/syscalls/getsockopt.S
+++ b/libc/arch-x86/syscalls/getsockopt.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $15, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getuid.S b/libc/arch-x86/syscalls/getuid.S
index cc62884..11cc0c6 100644
--- a/libc/arch-x86/syscalls/getuid.S
+++ b/libc/arch-x86/syscalls/getuid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getuid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getxattr.S b/libc/arch-x86/syscalls/getxattr.S
index a2cf137..871362e 100644
--- a/libc/arch-x86/syscalls/getxattr.S
+++ b/libc/arch-x86/syscalls/getxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_getxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/init_module.S b/libc/arch-x86/syscalls/init_module.S
index 1d0f111..0147eee 100644
--- a/libc/arch-x86/syscalls/init_module.S
+++ b/libc/arch-x86/syscalls/init_module.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_init_module, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_add_watch.S b/libc/arch-x86/syscalls/inotify_add_watch.S
index 8cadc6e..f196440 100644
--- a/libc/arch-x86/syscalls/inotify_add_watch.S
+++ b/libc/arch-x86/syscalls/inotify_add_watch.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_inotify_add_watch, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_init1.S b/libc/arch-x86/syscalls/inotify_init1.S
index 23671e0..7f0dcfb 100644
--- a/libc/arch-x86/syscalls/inotify_init1.S
+++ b/libc/arch-x86/syscalls/inotify_init1.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_inotify_init1, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_rm_watch.S b/libc/arch-x86/syscalls/inotify_rm_watch.S
index c246c00..595e053 100644
--- a/libc/arch-x86/syscalls/inotify_rm_watch.S
+++ b/libc/arch-x86/syscalls/inotify_rm_watch.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_inotify_rm_watch, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/kill.S b/libc/arch-x86/syscalls/kill.S
index edc9cde..4ee56e6 100644
--- a/libc/arch-x86/syscalls/kill.S
+++ b/libc/arch-x86/syscalls/kill.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_kill, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/klogctl.S b/libc/arch-x86/syscalls/klogctl.S
index 5de9a31e..3d07942 100644
--- a/libc/arch-x86/syscalls/klogctl.S
+++ b/libc/arch-x86/syscalls/klogctl.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_syslog, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lgetxattr.S b/libc/arch-x86/syscalls/lgetxattr.S
index 55697a0..659b088 100644
--- a/libc/arch-x86/syscalls/lgetxattr.S
+++ b/libc/arch-x86/syscalls/lgetxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_lgetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/linkat.S b/libc/arch-x86/syscalls/linkat.S
index 8b2646d..644172d 100644
--- a/libc/arch-x86/syscalls/linkat.S
+++ b/libc/arch-x86/syscalls/linkat.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_linkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/listen.S b/libc/arch-x86/syscalls/listen.S
index 8ae4186..ce7c3a9 100644
--- a/libc/arch-x86/syscalls/listen.S
+++ b/libc/arch-x86/syscalls/listen.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $4, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/listxattr.S b/libc/arch-x86/syscalls/listxattr.S
index a73dc1a..2fe799e 100644
--- a/libc/arch-x86/syscalls/listxattr.S
+++ b/libc/arch-x86/syscalls/listxattr.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_listxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/llistxattr.S b/libc/arch-x86/syscalls/llistxattr.S
index 63d4489..666d87e 100644
--- a/libc/arch-x86/syscalls/llistxattr.S
+++ b/libc/arch-x86/syscalls/llistxattr.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_llistxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lremovexattr.S b/libc/arch-x86/syscalls/lremovexattr.S
index 42c7e0f..bda772b 100644
--- a/libc/arch-x86/syscalls/lremovexattr.S
+++ b/libc/arch-x86/syscalls/lremovexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_lremovexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lseek.S b/libc/arch-x86/syscalls/lseek.S
index bfe9e63..9142b5c 100644
--- a/libc/arch-x86/syscalls/lseek.S
+++ b/libc/arch-x86/syscalls/lseek.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_lseek, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lsetxattr.S b/libc/arch-x86/syscalls/lsetxattr.S
index f36fc6a..fa977b3 100644
--- a/libc/arch-x86/syscalls/lsetxattr.S
+++ b/libc/arch-x86/syscalls/lsetxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_lsetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/madvise.S b/libc/arch-x86/syscalls/madvise.S
index b69f5d4..21f472e 100644
--- a/libc/arch-x86/syscalls/madvise.S
+++ b/libc/arch-x86/syscalls/madvise.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_madvise, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mincore.S b/libc/arch-x86/syscalls/mincore.S
index 6d1df67..4179c9a 100644
--- a/libc/arch-x86/syscalls/mincore.S
+++ b/libc/arch-x86/syscalls/mincore.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_mincore, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mkdirat.S b/libc/arch-x86/syscalls/mkdirat.S
index 5b6ae18..6a9d94c 100644
--- a/libc/arch-x86/syscalls/mkdirat.S
+++ b/libc/arch-x86/syscalls/mkdirat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_mkdirat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mknodat.S b/libc/arch-x86/syscalls/mknodat.S
index b19d972..a1fae7f 100644
--- a/libc/arch-x86/syscalls/mknodat.S
+++ b/libc/arch-x86/syscalls/mknodat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_mknodat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mlock.S b/libc/arch-x86/syscalls/mlock.S
index 517e5a5..1c57ac0 100644
--- a/libc/arch-x86/syscalls/mlock.S
+++ b/libc/arch-x86/syscalls/mlock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_mlock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mlockall.S b/libc/arch-x86/syscalls/mlockall.S
index 756ca16..9f54de3 100644
--- a/libc/arch-x86/syscalls/mlockall.S
+++ b/libc/arch-x86/syscalls/mlockall.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_mlockall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mount.S b/libc/arch-x86/syscalls/mount.S
index 0537528..4a9f91a 100644
--- a/libc/arch-x86/syscalls/mount.S
+++ b/libc/arch-x86/syscalls/mount.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_mount, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mprotect.S b/libc/arch-x86/syscalls/mprotect.S
index 1ba186c..5eec550 100644
--- a/libc/arch-x86/syscalls/mprotect.S
+++ b/libc/arch-x86/syscalls/mprotect.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_mprotect, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/msync.S b/libc/arch-x86/syscalls/msync.S
index 81bd598..7754da6 100644
--- a/libc/arch-x86/syscalls/msync.S
+++ b/libc/arch-x86/syscalls/msync.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_msync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munlock.S b/libc/arch-x86/syscalls/munlock.S
index 67ca3fe..d2ae9f0 100644
--- a/libc/arch-x86/syscalls/munlock.S
+++ b/libc/arch-x86/syscalls/munlock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_munlock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munlockall.S b/libc/arch-x86/syscalls/munlockall.S
index bf0bfa1..e709b8c 100644
--- a/libc/arch-x86/syscalls/munlockall.S
+++ b/libc/arch-x86/syscalls/munlockall.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(munlockall)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_munlockall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munmap.S b/libc/arch-x86/syscalls/munmap.S
index 272cb52..7ddc5aa 100644
--- a/libc/arch-x86/syscalls/munmap.S
+++ b/libc/arch-x86/syscalls/munmap.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_munmap, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/nanosleep.S b/libc/arch-x86/syscalls/nanosleep.S
index 5c46a4a..580f5e1 100644
--- a/libc/arch-x86/syscalls/nanosleep.S
+++ b/libc/arch-x86/syscalls/nanosleep.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_nanosleep, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/personality.S b/libc/arch-x86/syscalls/personality.S
index d60ced1..3e003c4 100644
--- a/libc/arch-x86/syscalls/personality.S
+++ b/libc/arch-x86/syscalls/personality.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_personality, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pipe2.S b/libc/arch-x86/syscalls/pipe2.S
index ee49ff8..8a93281 100644
--- a/libc/arch-x86/syscalls/pipe2.S
+++ b/libc/arch-x86/syscalls/pipe2.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_pipe2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/prctl.S b/libc/arch-x86/syscalls/prctl.S
index 496591e..22b4a83 100644
--- a/libc/arch-x86/syscalls/prctl.S
+++ b/libc/arch-x86/syscalls/prctl.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_prctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pread64.S b/libc/arch-x86/syscalls/pread64.S
index 42e54ec..9002f17 100644
--- a/libc/arch-x86/syscalls/pread64.S
+++ b/libc/arch-x86/syscalls/pread64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_pread64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/prlimit64.S b/libc/arch-x86/syscalls/prlimit64.S
index 07b5585..13f6682 100644
--- a/libc/arch-x86/syscalls/prlimit64.S
+++ b/libc/arch-x86/syscalls/prlimit64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_prlimit64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/process_vm_readv.S b/libc/arch-x86/syscalls/process_vm_readv.S
index 64965f6..e2cd044 100644
--- a/libc/arch-x86/syscalls/process_vm_readv.S
+++ b/libc/arch-x86/syscalls/process_vm_readv.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_process_vm_readv, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/process_vm_writev.S b/libc/arch-x86/syscalls/process_vm_writev.S
index 555c822..de0d218 100644
--- a/libc/arch-x86/syscalls/process_vm_writev.S
+++ b/libc/arch-x86/syscalls/process_vm_writev.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_process_vm_writev, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pwrite64.S b/libc/arch-x86/syscalls/pwrite64.S
index d5c9b31..7532729 100644
--- a/libc/arch-x86/syscalls/pwrite64.S
+++ b/libc/arch-x86/syscalls/pwrite64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_pwrite64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/read.S b/libc/arch-x86/syscalls/read.S
index c10a83b..d4b69b5 100644
--- a/libc/arch-x86/syscalls/read.S
+++ b/libc/arch-x86/syscalls/read.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_read, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readahead.S b/libc/arch-x86/syscalls/readahead.S
index 1c0ccfc..8ce22bb 100644
--- a/libc/arch-x86/syscalls/readahead.S
+++ b/libc/arch-x86/syscalls/readahead.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_readahead, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readlinkat.S b/libc/arch-x86/syscalls/readlinkat.S
index 4a24c2c..8b74a4e 100644
--- a/libc/arch-x86/syscalls/readlinkat.S
+++ b/libc/arch-x86/syscalls/readlinkat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_readlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readv.S b/libc/arch-x86/syscalls/readv.S
index c18c1b1..a1cb08f 100644
--- a/libc/arch-x86/syscalls/readv.S
+++ b/libc/arch-x86/syscalls/readv.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_readv, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvfrom.S b/libc/arch-x86/syscalls/recvfrom.S
index 88c9d0a..cedd703 100644
--- a/libc/arch-x86/syscalls/recvfrom.S
+++ b/libc/arch-x86/syscalls/recvfrom.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $12, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvmmsg.S b/libc/arch-x86/syscalls/recvmmsg.S
index 09404d4..130332a 100644
--- a/libc/arch-x86/syscalls/recvmmsg.S
+++ b/libc/arch-x86/syscalls/recvmmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $19, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvmsg.S b/libc/arch-x86/syscalls/recvmsg.S
index 6cfcd63..c8d2a08 100644
--- a/libc/arch-x86/syscalls/recvmsg.S
+++ b/libc/arch-x86/syscalls/recvmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $17, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/removexattr.S b/libc/arch-x86/syscalls/removexattr.S
index b067a9f..ab7891e 100644
--- a/libc/arch-x86/syscalls/removexattr.S
+++ b/libc/arch-x86/syscalls/removexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_removexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/renameat.S b/libc/arch-x86/syscalls/renameat.S
index bb2181e..40caaaf 100644
--- a/libc/arch-x86/syscalls/renameat.S
+++ b/libc/arch-x86/syscalls/renameat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_renameat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_get_priority_max.S b/libc/arch-x86/syscalls/sched_get_priority_max.S
index be66cfb..637c9dd 100644
--- a/libc/arch-x86/syscalls/sched_get_priority_max.S
+++ b/libc/arch-x86/syscalls/sched_get_priority_max.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_get_priority_max, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_get_priority_min.S b/libc/arch-x86/syscalls/sched_get_priority_min.S
index 8dde67b..c38a3aa 100644
--- a/libc/arch-x86/syscalls/sched_get_priority_min.S
+++ b/libc/arch-x86/syscalls/sched_get_priority_min.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_get_priority_min, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_getparam.S b/libc/arch-x86/syscalls/sched_getparam.S
index d0551ef..09901bd 100644
--- a/libc/arch-x86/syscalls/sched_getparam.S
+++ b/libc/arch-x86/syscalls/sched_getparam.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_getparam, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_getscheduler.S b/libc/arch-x86/syscalls/sched_getscheduler.S
index 5b7c817..adc4023 100644
--- a/libc/arch-x86/syscalls/sched_getscheduler.S
+++ b/libc/arch-x86/syscalls/sched_getscheduler.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_getscheduler, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_rr_get_interval.S b/libc/arch-x86/syscalls/sched_rr_get_interval.S
index 073f3c7..818f62e 100644
--- a/libc/arch-x86/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-x86/syscalls/sched_rr_get_interval.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_rr_get_interval, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setaffinity.S b/libc/arch-x86/syscalls/sched_setaffinity.S
index 79ec113..b06d778 100644
--- a/libc/arch-x86/syscalls/sched_setaffinity.S
+++ b/libc/arch-x86/syscalls/sched_setaffinity.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_sched_setaffinity, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setparam.S b/libc/arch-x86/syscalls/sched_setparam.S
index 970747d..dba5bc2 100644
--- a/libc/arch-x86/syscalls/sched_setparam.S
+++ b/libc/arch-x86/syscalls/sched_setparam.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_setparam, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setscheduler.S b/libc/arch-x86/syscalls/sched_setscheduler.S
index da50aaf..466a425 100644
--- a/libc/arch-x86/syscalls/sched_setscheduler.S
+++ b/libc/arch-x86/syscalls/sched_setscheduler.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_sched_setscheduler, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_yield.S b/libc/arch-x86/syscalls/sched_yield.S
index e3878e3..b17b14e 100644
--- a/libc/arch-x86/syscalls/sched_yield.S
+++ b/libc/arch-x86/syscalls/sched_yield.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_yield, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendfile.S b/libc/arch-x86/syscalls/sendfile.S
index c5f9a2d..e091706 100644
--- a/libc/arch-x86/syscalls/sendfile.S
+++ b/libc/arch-x86/syscalls/sendfile.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_sendfile, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendfile64.S b/libc/arch-x86/syscalls/sendfile64.S
index bc5d0dd..317c4f4 100644
--- a/libc/arch-x86/syscalls/sendfile64.S
+++ b/libc/arch-x86/syscalls/sendfile64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_sendfile64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendmmsg.S b/libc/arch-x86/syscalls/sendmmsg.S
index 784c6b6..c0097f8 100644
--- a/libc/arch-x86/syscalls/sendmmsg.S
+++ b/libc/arch-x86/syscalls/sendmmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $20, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendmsg.S b/libc/arch-x86/syscalls/sendmsg.S
index bf0d1fb..775ebee 100644
--- a/libc/arch-x86/syscalls/sendmsg.S
+++ b/libc/arch-x86/syscalls/sendmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $16, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendto.S b/libc/arch-x86/syscalls/sendto.S
index b39eaf0..2df5e4f 100644
--- a/libc/arch-x86/syscalls/sendto.S
+++ b/libc/arch-x86/syscalls/sendto.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $11, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setdomainname.S b/libc/arch-x86/syscalls/setdomainname.S
new file mode 100644
index 0000000..8b6afe2
--- /dev/null
+++ b/libc/arch-x86/syscalls/setdomainname.S
@@ -0,0 +1,34 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    pushl   %ebx
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset ebx, 0
+    pushl   %ecx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
+    movl    $__NR_setdomainname, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno_internal
+    addl    $4, %esp
+1:
+    popl    %ecx
+    popl    %ebx
+    ret
+END(setdomainname)
diff --git a/libc/arch-x86/syscalls/setfsgid.S b/libc/arch-x86/syscalls/setfsgid.S
index dc81f72..af4ef89 100644
--- a/libc/arch-x86/syscalls/setfsgid.S
+++ b/libc/arch-x86/syscalls/setfsgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setfsgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setfsuid.S b/libc/arch-x86/syscalls/setfsuid.S
index fdf7850..8001e42 100644
--- a/libc/arch-x86/syscalls/setfsuid.S
+++ b/libc/arch-x86/syscalls/setfsuid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setfsuid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setgid.S b/libc/arch-x86/syscalls/setgid.S
index ce6ee26..c0ddec4 100644
--- a/libc/arch-x86/syscalls/setgid.S
+++ b/libc/arch-x86/syscalls/setgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setgroups.S b/libc/arch-x86/syscalls/setgroups.S
index 7e46ad0..7bd3bfc 100644
--- a/libc/arch-x86/syscalls/setgroups.S
+++ b/libc/arch-x86/syscalls/setgroups.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setgroups32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sethostname.S b/libc/arch-x86/syscalls/sethostname.S
index bfcfd73..26ff1e7 100644
--- a/libc/arch-x86/syscalls/sethostname.S
+++ b/libc/arch-x86/syscalls/sethostname.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sethostname, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setitimer.S b/libc/arch-x86/syscalls/setitimer.S
index 370ab5e..063847b 100644
--- a/libc/arch-x86/syscalls/setitimer.S
+++ b/libc/arch-x86/syscalls/setitimer.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_setitimer, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setns.S b/libc/arch-x86/syscalls/setns.S
index 736df59..28d838e 100644
--- a/libc/arch-x86/syscalls/setns.S
+++ b/libc/arch-x86/syscalls/setns.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setns, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setpgid.S b/libc/arch-x86/syscalls/setpgid.S
index 0bff10a..c5d0d27 100644
--- a/libc/arch-x86/syscalls/setpgid.S
+++ b/libc/arch-x86/syscalls/setpgid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setpgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setpriority.S b/libc/arch-x86/syscalls/setpriority.S
index 4233871..17c81c6 100644
--- a/libc/arch-x86/syscalls/setpriority.S
+++ b/libc/arch-x86/syscalls/setpriority.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_setpriority, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setregid.S b/libc/arch-x86/syscalls/setregid.S
index a56ccfd..dd8101a 100644
--- a/libc/arch-x86/syscalls/setregid.S
+++ b/libc/arch-x86/syscalls/setregid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setregid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setresgid.S b/libc/arch-x86/syscalls/setresgid.S
index 2299831..6f6de5a 100644
--- a/libc/arch-x86/syscalls/setresgid.S
+++ b/libc/arch-x86/syscalls/setresgid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_setresgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setresuid.S b/libc/arch-x86/syscalls/setresuid.S
index 8624e15..ab0059c 100644
--- a/libc/arch-x86/syscalls/setresuid.S
+++ b/libc/arch-x86/syscalls/setresuid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_setresuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setreuid.S b/libc/arch-x86/syscalls/setreuid.S
index 9f6e117..7fda62e 100644
--- a/libc/arch-x86/syscalls/setreuid.S
+++ b/libc/arch-x86/syscalls/setreuid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setreuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setrlimit.S b/libc/arch-x86/syscalls/setrlimit.S
index 2024688..595633e 100644
--- a/libc/arch-x86/syscalls/setrlimit.S
+++ b/libc/arch-x86/syscalls/setrlimit.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setrlimit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setsid.S b/libc/arch-x86/syscalls/setsid.S
index dda6ad8..80ad8a9 100644
--- a/libc/arch-x86/syscalls/setsid.S
+++ b/libc/arch-x86/syscalls/setsid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(setsid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_setsid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setsockopt.S b/libc/arch-x86/syscalls/setsockopt.S
index 29e73bb..bca34e1 100644
--- a/libc/arch-x86/syscalls/setsockopt.S
+++ b/libc/arch-x86/syscalls/setsockopt.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $14, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/settimeofday.S b/libc/arch-x86/syscalls/settimeofday.S
index 4a861ab..31437d0 100644
--- a/libc/arch-x86/syscalls/settimeofday.S
+++ b/libc/arch-x86/syscalls/settimeofday.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_settimeofday, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setuid.S b/libc/arch-x86/syscalls/setuid.S
index 048e0c1..2461182 100644
--- a/libc/arch-x86/syscalls/setuid.S
+++ b/libc/arch-x86/syscalls/setuid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setxattr.S b/libc/arch-x86/syscalls/setxattr.S
index 1e87bf0..787891e 100644
--- a/libc/arch-x86/syscalls/setxattr.S
+++ b/libc/arch-x86/syscalls/setxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_setxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/shutdown.S b/libc/arch-x86/syscalls/shutdown.S
index f224fc6..46e5c18 100644
--- a/libc/arch-x86/syscalls/shutdown.S
+++ b/libc/arch-x86/syscalls/shutdown.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $13, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sigaltstack.S b/libc/arch-x86/syscalls/sigaltstack.S
index 875ef8c..90eae16 100644
--- a/libc/arch-x86/syscalls/sigaltstack.S
+++ b/libc/arch-x86/syscalls/sigaltstack.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sigaltstack, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/socketpair.S b/libc/arch-x86/syscalls/socketpair.S
index 4c5154e..c9c7595 100644
--- a/libc/arch-x86/syscalls/socketpair.S
+++ b/libc/arch-x86/syscalls/socketpair.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $8, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/splice.S b/libc/arch-x86/syscalls/splice.S
index 1dc9037..2d82a3d 100644
--- a/libc/arch-x86/syscalls/splice.S
+++ b/libc/arch-x86/syscalls/splice.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_splice, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/swapoff.S b/libc/arch-x86/syscalls/swapoff.S
index 0788529..d10a748 100644
--- a/libc/arch-x86/syscalls/swapoff.S
+++ b/libc/arch-x86/syscalls/swapoff.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_swapoff, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/swapon.S b/libc/arch-x86/syscalls/swapon.S
index 1070d8e..dc7db64 100644
--- a/libc/arch-x86/syscalls/swapon.S
+++ b/libc/arch-x86/syscalls/swapon.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_swapon, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/symlinkat.S b/libc/arch-x86/syscalls/symlinkat.S
index e7fe69e..51b1330 100644
--- a/libc/arch-x86/syscalls/symlinkat.S
+++ b/libc/arch-x86/syscalls/symlinkat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_symlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sync.S b/libc/arch-x86/syscalls/sync.S
index 252c666..c75e9f9 100644
--- a/libc/arch-x86/syscalls/sync.S
+++ b/libc/arch-x86/syscalls/sync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sysinfo.S b/libc/arch-x86/syscalls/sysinfo.S
index f59a0c3..a40d664 100644
--- a/libc/arch-x86/syscalls/sysinfo.S
+++ b/libc/arch-x86/syscalls/sysinfo.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sysinfo, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/tee.S b/libc/arch-x86/syscalls/tee.S
index b47c460..693ad1e 100644
--- a/libc/arch-x86/syscalls/tee.S
+++ b/libc/arch-x86/syscalls/tee.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_tee, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/tgkill.S b/libc/arch-x86/syscalls/tgkill.S
index 7a43a01..5cce4d8 100644
--- a/libc/arch-x86/syscalls/tgkill.S
+++ b/libc/arch-x86/syscalls/tgkill.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_tgkill, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_create.S b/libc/arch-x86/syscalls/timerfd_create.S
index ad099a5..335b7a6 100644
--- a/libc/arch-x86/syscalls/timerfd_create.S
+++ b/libc/arch-x86/syscalls/timerfd_create.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timerfd_create, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_gettime.S b/libc/arch-x86/syscalls/timerfd_gettime.S
index c679b7c..9dc1a2f 100644
--- a/libc/arch-x86/syscalls/timerfd_gettime.S
+++ b/libc/arch-x86/syscalls/timerfd_gettime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timerfd_gettime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_settime.S b/libc/arch-x86/syscalls/timerfd_settime.S
index 4e889ea..477b5bb 100644
--- a/libc/arch-x86/syscalls/timerfd_settime.S
+++ b/libc/arch-x86/syscalls/timerfd_settime.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_timerfd_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/times.S b/libc/arch-x86/syscalls/times.S
index 0ba0b6f..14fe221 100644
--- a/libc/arch-x86/syscalls/times.S
+++ b/libc/arch-x86/syscalls/times.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_times, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/truncate.S b/libc/arch-x86/syscalls/truncate.S
index 31fec17..dd99942 100644
--- a/libc/arch-x86/syscalls/truncate.S
+++ b/libc/arch-x86/syscalls/truncate.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_truncate, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/truncate64.S b/libc/arch-x86/syscalls/truncate64.S
index 45e24d0..35e4037 100644
--- a/libc/arch-x86/syscalls/truncate64.S
+++ b/libc/arch-x86/syscalls/truncate64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_truncate64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/umask.S b/libc/arch-x86/syscalls/umask.S
index 9b4d3c7..3333fac 100644
--- a/libc/arch-x86/syscalls/umask.S
+++ b/libc/arch-x86/syscalls/umask.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_umask, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/umount2.S b/libc/arch-x86/syscalls/umount2.S
index 13757ab..48e1eb5 100644
--- a/libc/arch-x86/syscalls/umount2.S
+++ b/libc/arch-x86/syscalls/umount2.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_umount2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/uname.S b/libc/arch-x86/syscalls/uname.S
index dab7e0d..9eea2c1 100644
--- a/libc/arch-x86/syscalls/uname.S
+++ b/libc/arch-x86/syscalls/uname.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_uname, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/unlinkat.S b/libc/arch-x86/syscalls/unlinkat.S
index 6faf71e..e039a34 100644
--- a/libc/arch-x86/syscalls/unlinkat.S
+++ b/libc/arch-x86/syscalls/unlinkat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_unlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/unshare.S b/libc/arch-x86/syscalls/unshare.S
index b724798..ae68d7e 100644
--- a/libc/arch-x86/syscalls/unshare.S
+++ b/libc/arch-x86/syscalls/unshare.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_unshare, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/utimensat.S b/libc/arch-x86/syscalls/utimensat.S
index 07eca45..43eebc7 100644
--- a/libc/arch-x86/syscalls/utimensat.S
+++ b/libc/arch-x86/syscalls/utimensat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_utimensat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/vmsplice.S b/libc/arch-x86/syscalls/vmsplice.S
index f12cc65..195b0bf 100644
--- a/libc/arch-x86/syscalls/vmsplice.S
+++ b/libc/arch-x86/syscalls/vmsplice.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_vmsplice, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/wait4.S b/libc/arch-x86/syscalls/wait4.S
index bed7c40..281d5f2 100644
--- a/libc/arch-x86/syscalls/wait4.S
+++ b/libc/arch-x86/syscalls/wait4.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_wait4, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/write.S b/libc/arch-x86/syscalls/write.S
index e147208..e9e5f4e 100644
--- a/libc/arch-x86/syscalls/write.S
+++ b/libc/arch-x86/syscalls/write.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_write, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/writev.S b/libc/arch-x86/syscalls/writev.S
index 07ba7b5..6649905 100644
--- a/libc/arch-x86/syscalls/writev.S
+++ b/libc/arch-x86/syscalls/writev.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
     movl    $__NR_writev, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S
index 56ebb07..34b4365 100644
--- a/libc/arch-x86_64/bionic/setjmp.S
+++ b/libc/arch-x86_64/bionic/setjmp.S
@@ -35,8 +35,22 @@
 
 #include <private/bionic_asm.h>
 
-// These are only the callee-saved registers. Code calling setjmp
-// will expect the rest to be clobbered anyway.
+
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      rbx             registers
+// 1      rbp
+// 2      r12
+// 3      r13
+// 4      r14
+// 5      r15
+// 6      rsp
+// 7      pc
+// 8      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 9      sigmask         signal mask (includes rt signals as well)
+// 10     checksum        checksum of the core registers, to give better error messages.
 
 #define _JB_RBX 0
 #define _JB_RBP 1
@@ -48,9 +62,10 @@
 #define _JB_PC 7
 #define _JB_SIGFLAG 8
 #define _JB_SIGMASK 9
-#define _JB_SIGMASK_RT 10 // sigprocmask will write here too.
+#define _JB_CHECKSUM 10
 
 #define MANGLE_REGISTERS 1
+
 .macro m_mangle_registers reg
 #if MANGLE_REGISTERS
   xorq \reg,%rbx
@@ -68,6 +83,12 @@
   m_mangle_registers \reg
 .endm
 
+.macro m_calculate_checksum dst, src
+  movq $0, \dst
+  .irp i,0,1,2,3,4,5,6,7
+    xorq (\i*8)(\src), \dst
+  .endr
+.endm
 
 ENTRY(setjmp)
   movl $1,%esi
@@ -118,6 +139,9 @@
   movq %r11,(_JB_PC  * 8)(%rdi)
   m_unmangle_registers %rax
 
+  m_calculate_checksum %rax, %rdi
+  movq %rax, (_JB_CHECKSUM * 8)(%rdi)
+
   xorl %eax,%eax
   ret
 END(sigsetjmp)
@@ -127,6 +151,10 @@
   movq %rdi,%r12
   pushq %rsi // Push 'value'.
 
+  m_calculate_checksum %rax, %rdi
+  xorq (_JB_CHECKSUM * 8)(%rdi), %rax
+  jnz 3f
+
   // Do we need to restore the signal mask?
   movq (_JB_SIGFLAG * 8)(%rdi), %rdi
   pushq %rdi // Push cookie
@@ -172,6 +200,9 @@
 1:
   movq %r11,0(%rsp)
   ret
+
+3:
+  call PIC_PLT(__bionic_setjmp_checksum_mismatch)
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
diff --git a/libc/arch-x86_64/syscalls/setdomainname.S b/libc/arch-x86_64/syscalls/setdomainname.S
new file mode 100644
index 0000000..40d1a33
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/setdomainname.S
@@ -0,0 +1,15 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(setdomainname)
+    movl    $__NR_setdomainname, %eax
+    syscall
+    cmpq    $-MAX_ERRNO, %rax
+    jb      1f
+    negl    %eax
+    movl    %eax, %edi
+    call    __set_errno_internal
+1:
+    ret
+END(setdomainname)
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index a29d8a7..01bb9bb 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -51,6 +51,9 @@
 
 void __libc_init_main_thread(KernelArgumentBlock& args) {
   __libc_auxv = args.auxv;
+#if defined(__i386__)
+  __libc_init_sysinfo(args);
+#endif
 
   static pthread_internal_t main_thread;
 
diff --git a/libc/bionic/clock_nanosleep.cpp b/libc/bionic/clock_nanosleep.cpp
index 8e2146f..eade850 100644
--- a/libc/bionic/clock_nanosleep.cpp
+++ b/libc/bionic/clock_nanosleep.cpp
@@ -33,6 +33,8 @@
 extern "C" int ___clock_nanosleep(clockid_t, int, const timespec*, timespec*);
 
 int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
+  if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL;
+
   ErrnoRestorer errno_restorer;
   return (___clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
 }
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index 9b5c9e7..af63977 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -47,6 +47,11 @@
   void* new_tls = NULL;
   int* child_tid = NULL;
 
+  if (!child_stack) {
+    errno = EINVAL;
+    return -1;
+  }
+
   // Extract any optional parameters required by the flags.
   va_list args;
   va_start(args, arg);
diff --git a/libc/bionic/epoll_create.cpp b/libc/bionic/epoll_create.cpp
index 1dfafa8..74f664f 100644
--- a/libc/bionic/epoll_create.cpp
+++ b/libc/bionic/epoll_create.cpp
@@ -26,8 +26,13 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
 #include <sys/epoll.h>
 
-int epoll_create(int /*obsolete_size*/) {
+int epoll_create(int size) {
+  if (size <= 0) {
+    errno = EINVAL;
+    return -1;
+  }
   return epoll_create1(0);
 }
diff --git a/libc/bionic/getdomainname.cpp b/libc/bionic/getdomainname.cpp
new file mode 100644
index 0000000..761a999
--- /dev/null
+++ b/libc/bionic/getdomainname.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+int getdomainname(char* name, size_t len) {
+  utsname uts;
+  if (uname(&uts) == -1) return -1;
+
+  // Note: getdomainname()'s behavior varies across implementations when len is
+  // too small.  bionic follows the historical libc policy of returning EINVAL,
+  // instead of glibc's policy of copying the first len bytes without a NULL
+  // terminator.
+  if (strlen(uts.domainname) >= len) {
+      errno = EINVAL;
+      return -1;
+  }
+
+  strncpy(name, uts.domainname, len);
+  return 0;
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index c2a5fed..0c9e87b 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -70,7 +70,23 @@
   __stack_chk_guard = *reinterpret_cast<uintptr_t*>(args.getauxval(AT_RANDOM));
 }
 
+#if defined(__i386__)
+__LIBC_HIDDEN__ void* __libc_sysinfo = nullptr;
+
+__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args) {
+  __libc_sysinfo = reinterpret_cast<void*>(args.getauxval(AT_SYSINFO));
+}
+
+// TODO: lose this function and just access __libc_sysinfo directly.
+__LIBC_HIDDEN__ extern "C" void* __kernel_syscall() {
+  return __libc_sysinfo;
+}
+#endif
+
 void __libc_init_globals(KernelArgumentBlock& args) {
+#if defined(__i386__)
+  __libc_init_sysinfo(args);
+#endif
   // Initialize libc globals that are needed in both the linker and in libc.
   // In dynamic binaries, this is run at least twice for different copies of the
   // globals, once for the linker's copy and once for the one in libc.so.
@@ -83,6 +99,15 @@
   });
 }
 
+#if !defined(__LP64__)
+static void __check_max_thread_id() {
+  if (gettid() > 65535) {
+    __libc_fatal("Limited by the size of pthread_mutex_t, 32 bit bionic libc only accepts "
+                 "pid <= 65535, but current pid is %d", gettid());
+  }
+}
+#endif
+
 void __libc_init_common(KernelArgumentBlock& args) {
   // Initialize various globals.
   environ = args.envp;
@@ -90,6 +115,10 @@
   __progname = args.argv[0] ? args.argv[0] : "<unknown>";
   __abort_message_ptr = args.abort_message_ptr;
 
+#if !defined(__LP64__)
+  __check_max_thread_id();
+#endif
+
   // Get the main thread from TLS and add it to the thread list.
   pthread_internal_t* main_thread = __get_thread();
   __pthread_internal_add(main_thread);
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 863b07c..e050619 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -334,8 +334,8 @@
   }
 
   // Initialize malloc debugging in the loaded module.
-  void* sym = dlsym(malloc_impl_handle, "debug_initialize");
-  auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*)>(sym);
+  auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*)>(
+      dlsym(malloc_impl_handle, "debug_initialize"));
   if (init_func == nullptr) {
     error_log("%s: debug_initialize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
@@ -343,41 +343,36 @@
   }
 
   // Get the syms for the external functions.
-  sym = dlsym(malloc_impl_handle, "debug_finalize");
-  if (sym == nullptr) {
+  void* finalize_sym = dlsym(malloc_impl_handle, "debug_finalize");
+  if (finalize_sym == nullptr) {
     error_log("%s: debug_finalize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_finalize_func = reinterpret_cast<void (*)()>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
-  if (sym == nullptr) {
+  void* get_leak_info_sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
+  if (get_leak_info_sym == nullptr) {
     error_log("%s: debug_get_malloc_leak_info routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t**, size_t*, size_t*,
-                                                                size_t*, size_t*)>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
-  if (sym == nullptr) {
+  void* free_leak_info_sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
+  if (free_leak_info_sym == nullptr) {
     error_log("%s: debug_free_malloc_leak_info routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
-  if (sym == nullptr) {
+  void* malloc_backtrace_sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
+  if (malloc_backtrace_sym == nullptr) {
     error_log("%s: debug_malloc_backtrace routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(void*, uintptr_t*, size_t)>(sym);
 
   if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild)) {
     dlclose(malloc_impl_handle);
@@ -386,11 +381,19 @@
 
   MallocDispatch malloc_dispatch_table;
   if (!InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "debug")) {
-    g_debug_finalize_func();
+    auto finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+    finalize_func();
     dlclose(malloc_impl_handle);
     return;
   }
 
+  g_debug_finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+  g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(
+      uint8_t**, size_t*, size_t*, size_t*, size_t*)>(get_leak_info_sym);
+  g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(free_leak_info_sym);
+  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(
+      void*, uintptr_t*, size_t)>(malloc_backtrace_sym);
+
   globals->malloc_dispatch = malloc_dispatch_table;
   libc_malloc_impl_handle = malloc_impl_handle;
 
diff --git a/libc/bionic/mntent.cpp b/libc/bionic/mntent.cpp
index d169e29..994b84d 100644
--- a/libc/bionic/mntent.cpp
+++ b/libc/bionic/mntent.cpp
@@ -77,3 +77,24 @@
   }
   return 1;
 }
+
+char* hasmntopt(const struct mntent* mnt, const char* opt) {
+  char* token = mnt->mnt_opts;
+  char* const end = mnt->mnt_opts + strlen(mnt->mnt_opts);
+  const size_t optLen = strlen(opt);
+
+  while (token) {
+    char* const tokenEnd = token + optLen;
+    if (tokenEnd > end) break;
+
+    if (memcmp(token, opt, optLen) == 0 &&
+        (*tokenEnd == '\0' || *tokenEnd == ',' || *tokenEnd == '=')) {
+      return token;
+    }
+
+    token = strchr(token, ',');
+    if (token) token++;
+  }
+
+  return nullptr;
+}
diff --git a/libc/bionic/pthread_setname_np.cpp b/libc/bionic/pthread_setname_np.cpp
index bb1114e..6d2880e 100644
--- a/libc/bionic/pthread_setname_np.cpp
+++ b/libc/bionic/pthread_setname_np.cpp
@@ -41,41 +41,69 @@
 
 // This value is not exported by kernel headers.
 #define MAX_TASK_COMM_LEN 16
-#define TASK_COMM_FMT "/proc/self/task/%d/comm"
+
+static int __open_task_comm_fd(pthread_t t, int flags) {
+  pthread_internal_t* thread = __pthread_internal_find(t);
+  if (thread == nullptr) {
+    errno = ENOENT;
+    return -1;
+  }
+
+  char comm_name[64];
+  snprintf(comm_name, sizeof(comm_name), "/proc/self/task/%d/comm", thread->tid);
+  return open(comm_name, O_CLOEXEC | flags);
+}
+
+int pthread_getname_np(pthread_t t, char* buf, size_t buf_size) {
+  ErrnoRestorer errno_restorer;
+
+  if (buf_size < MAX_TASK_COMM_LEN) return ERANGE;
+
+  // Getting our own name is an easy special case.
+  if (t == pthread_self()) {
+    return prctl(PR_GET_NAME, buf) ? errno : 0;
+  }
+
+  // We have to get another thread's name.
+  int fd = __open_task_comm_fd(t, O_RDONLY);
+  if (fd == -1) return errno;
+
+  ssize_t n = TEMP_FAILURE_RETRY(read(fd, buf, buf_size));
+  close(fd);
+
+  if (n == -1) return errno;
+
+  // The kernel adds a trailing '\n' to the /proc file,
+  // so this is actually the normal case for short names.
+  if (n > 0 && buf[n - 1] == '\n') {
+    buf[n - 1] = '\0';
+    return 0;
+  }
+
+  if (n == static_cast<ssize_t>(buf_size)) return ERANGE;
+  buf[n] = '\0';
+  return 0;
+}
 
 int pthread_setname_np(pthread_t t, const char* thread_name) {
   ErrnoRestorer errno_restorer;
 
   size_t thread_name_len = strlen(thread_name);
-  if (thread_name_len >= MAX_TASK_COMM_LEN) {
-    return ERANGE;
-  }
+  if (thread_name_len >= MAX_TASK_COMM_LEN) return ERANGE;
 
-  // Changing our own name is an easy special case.
+  // Setting our own name is an easy special case.
   if (t == pthread_self()) {
     return prctl(PR_SET_NAME, thread_name) ? errno : 0;
   }
 
-  // We have to change another thread's name.
-  pthread_internal_t* thread = __pthread_internal_find(t);
-  if (thread == NULL) {
-    return ENOENT;
-  }
-  pid_t tid = thread->tid;
+  // We have to set another thread's name.
+  int fd = __open_task_comm_fd(t, O_WRONLY);
+  if (fd == -1) return errno;
 
-  char comm_name[sizeof(TASK_COMM_FMT) + 8];
-  snprintf(comm_name, sizeof(comm_name), TASK_COMM_FMT, tid);
-  int fd = open(comm_name, O_CLOEXEC | O_WRONLY);
-  if (fd == -1) {
-    return errno;
-  }
   ssize_t n = TEMP_FAILURE_RETRY(write(fd, thread_name, thread_name_len));
   close(fd);
 
-  if (n < 0) {
-    return errno;
-  } else if (n != static_cast<ssize_t>(thread_name_len)) {
-    return EIO;
-  }
+  if (n == -1) return errno;
+  if (n != static_cast<ssize_t>(thread_name_len)) return EIO;
   return 0;
 }
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 125b3c9..cff6288 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -124,8 +124,8 @@
     case _SC_THREAD_DESTRUCTOR_ITERATIONS: return PTHREAD_DESTRUCTOR_ITERATIONS;
     case _SC_THREAD_KEYS_MAX:   return PTHREAD_KEYS_MAX;
     case _SC_THREAD_STACK_MIN:    return PTHREAD_STACK_MIN;
-    case _SC_THREAD_THREADS_MAX:  return PTHREAD_THREADS_MAX;
-    case _SC_TTY_NAME_MAX:        return 32;  // Seems default on linux.
+    case _SC_THREAD_THREADS_MAX:  return -1; // No specific limit.
+    case _SC_TTY_NAME_MAX:        return 32; // Seems default on linux.
     case _SC_THREADS:             return _POSIX_THREADS;
     case _SC_THREAD_ATTR_STACKADDR:   return _POSIX_THREAD_ATTR_STACKADDR;
     case _SC_THREAD_ATTR_STACKSIZE:   return _POSIX_THREAD_ATTR_STACKSIZE;
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index de285d0..ab40079 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _MNTENT_H_
 #define _MNTENT_H_
 
@@ -33,7 +34,17 @@
 #include <paths.h>  /* for _PATH_MOUNTED */
 
 #define MOUNTED _PATH_MOUNTED
+
 #define MNTTYPE_IGNORE "ignore"
+#define MNTTYPE_NFS "nfs"
+#define MNTTYPE_SWAP "swap"
+
+#define MNTOPT_DEFAULTS "defaults"
+#define MNTOPT_NOAUTO "noauto"
+#define MNTOPT_NOSUID "nosuid"
+#define MNTOPT_RO "ro"
+#define MNTOPT_RW "rw"
+#define MNTOPT_SUID "suid"
 
 struct mntent {
   char* mnt_fsname;
@@ -50,6 +61,7 @@
 struct mntent* getmntent(FILE*);
 struct mntent* getmntent_r(FILE*, struct mntent*, char*, int);
 FILE* setmntent(const char*, const char*);
+char* hasmntopt(const struct mntent*, const char*);
 
 __END_DECLS
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 50f2024..b409ff2 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -245,6 +245,10 @@
 
 pthread_t pthread_self(void) __pure2;
 
+#if defined(__USE_GNU)
+int pthread_getname_np(pthread_t, char*, size_t) __nonnull((2));
+#endif
+/* TODO: this should be __USE_GNU too. */
 int pthread_setname_np(pthread_t, const char*) __nonnull((2));
 
 int pthread_setschedparam(pthread_t, int, const struct sched_param*) __nonnull((3));
@@ -281,14 +285,8 @@
 #if !defined(__LP64__)
 
 // Bionic additions that are deprecated even in the 32-bit ABI.
-//
-// TODO: Remove them once chromium_org / NFC have switched over.
-int pthread_cond_timedwait_monotonic_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
-int pthread_cond_timedwait_monotonic(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
-
-int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*) /* TODO: __attribute__((deprecated("use pthread_cond_timedwait instead")))*/;
-#define HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1 /* TODO: stop defining this to push LP32 off this API sooner. */
-int pthread_cond_timeout_np(pthread_cond_t*, pthread_mutex_t*, unsigned) /* TODO: __attribute__((deprecated("use pthread_cond_timedwait instead")))*/;
+int pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*) __attribute__((deprecated("use pthread_cond_timedwait instead")));
+int pthread_cond_timeout_np(pthread_cond_t*, pthread_mutex_t*, unsigned) __attribute__((deprecated("use pthread_cond_timedwait instead")));
 
 int pthread_mutex_lock_timeout_np(pthread_mutex_t*, unsigned) __attribute__((deprecated("use pthread_mutex_timedlock instead")));
 
diff --git a/libc/include/sys/limits.h b/libc/include/sys/limits.h
index be79cf3..f84253e 100644
--- a/libc/include/sys/limits.h
+++ b/libc/include/sys/limits.h
@@ -120,8 +120,11 @@
 #define  _XOPEN_VERSION             700       /* by Posix definition */
 
 
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4     // >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_KEYS_MAX              128   // >= _POSIX_THREAD_KEYS_MAX
-#define PTHREAD_THREADS_MAX           2048  // bionic has no specific limit
+/* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+/* >= _POSIX_THREAD_KEYS_MAX */
+#define PTHREAD_KEYS_MAX 128
+/* bionic has no specific limit */
+#undef PTHREAD_THREADS_MAX
 
 #endif
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index e64d6ce..5d2248f 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -31,6 +31,8 @@
 #include <limits.h>
 #include <linux/param.h>
 
+#define DEV_BSIZE 512
+
 #define MAXPATHLEN  PATH_MAX
 #define MAXSYMLINKS 8
 
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 257ded0..86668f6 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -135,6 +135,12 @@
 #define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) /* 0666 */
 #endif
 
+#if defined(__USE_BSD) || defined(__USE_GNU)
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
 extern int chmod(const char*, mode_t);
 extern int fchmod(int, mode_t);
 extern int mkdir(const char*, mode_t);
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index 217fd60..a422261 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -66,6 +66,8 @@
 typedef __kernel_ino_t __ino_t;
 typedef __ino_t ino_t;
 
+typedef uint64_t ino64_t;
+
 typedef uint32_t __nlink_t;
 typedef __nlink_t nlink_t;
 
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 5045267..2d62c1f 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -292,6 +292,9 @@
 __errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
 extern ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
 
+extern int getdomainname(char*, size_t);
+extern int setdomainname(const char*, size_t);
+
 #if defined(__BIONIC_FORTIFY)
 
 __BIONIC_FORTIFY_INLINE
diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map
index 2c0ab15..b8cdd3c 100644
--- a/libc/libc.arm.brillo.map
+++ b/libc/libc.arm.brillo.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1271,6 +1271,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1448,4 +1456,4 @@
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index c22535d..57060ae 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1271,6 +1271,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1487,4 +1495,4 @@
     vfdprintf; # arm x86 mips nobrillo
     wait3; # arm x86 mips nobrillo
     wcswcs; # arm x86 mips nobrillo
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 63c82e5..ac9d009 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1193,6 +1193,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     android_getaddrinfofornet;
@@ -1202,4 +1210,4 @@
     free_malloc_leak_info;
     get_malloc_leak_info;
     gMallocLeakZygoteChild;
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c000fb1..9d51b8d 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1297,6 +1297,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1514,4 +1522,4 @@
     vfdprintf; # arm x86 mips nobrillo
     wait3; # arm x86 mips nobrillo
     wcswcs; # arm x86 mips nobrillo
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map
index 8e5fdf4..7133f4b 100644
--- a/libc/libc.mips.brillo.map
+++ b/libc/libc.mips.brillo.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1255,6 +1255,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86 mips
@@ -1289,4 +1297,4 @@
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index d30ead8..e9b15c3 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1255,6 +1255,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86 mips
@@ -1328,4 +1336,4 @@
     vfdprintf; # arm x86 mips nobrillo
     wait3; # arm x86 mips nobrillo
     wcswcs; # arm x86 mips nobrillo
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 63c82e5..ac9d009 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1193,6 +1193,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     android_getaddrinfofornet;
@@ -1202,4 +1210,4 @@
     free_malloc_leak_info;
     get_malloc_leak_info;
     gMallocLeakZygoteChild;
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map
index 7ac0976..c67f533 100644
--- a/libc/libc.x86.brillo.map
+++ b/libc/libc.x86.brillo.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1254,6 +1254,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86 mips
@@ -1288,4 +1296,4 @@
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 11fb710..6838184 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1254,6 +1254,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86 mips
@@ -1327,4 +1335,4 @@
     vfdprintf; # arm x86 mips nobrillo
     wait3; # arm x86 mips nobrillo
     wcswcs; # arm x86 mips nobrillo
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 63c82e5..ac9d009 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -1193,6 +1193,14 @@
     tmpfile64;
 } LIBC;
 
+LIBC_O {
+  global:
+    getdomainname;
+    hasmntopt;
+    pthread_getname_np;
+    setdomainname;
+} LIBC_N;
+
 LIBC_PRIVATE {
   global:
     android_getaddrinfofornet;
@@ -1202,4 +1210,4 @@
     free_malloc_leak_info;
     get_malloc_leak_info;
     gMallocLeakZygoteChild;
-} LIBC_N;
+} LIBC_O;
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 4586fda3..ded618c 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -333,9 +333,9 @@
   size_t value;
   bool value_set;
   PropertyParser parser(property_str);
-  bool found = false;
   bool valid = true;
   while (valid && parser.Get(&property, &value, &value_set)) {
+    bool found = false;
     for (size_t i = 0; i < sizeof(features)/sizeof(Feature); i++) {
       if (property == features[i].name) {
         if (features[i].option == 0 && features[i].combo_option) {
diff --git a/libc/malloc_debug/FreeTrackData.cpp b/libc/malloc_debug/FreeTrackData.cpp
index 3ac54bf..ed41981 100644
--- a/libc/malloc_debug/FreeTrackData.cpp
+++ b/libc/malloc_debug/FreeTrackData.cpp
@@ -67,18 +67,25 @@
                                   const void* pointer) {
   ScopedDisableDebugCalls disable;
 
-  const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
-  size_t bytes = header->usable_size;
-  bytes = (bytes < debug.config().fill_on_free_bytes) ? bytes : debug.config().fill_on_free_bytes;
-  while (bytes > 0) {
-    size_t bytes_to_cmp = (bytes < cmp_mem_.size()) ? bytes : cmp_mem_.size();
-    if (memcmp(memory, cmp_mem_.data(), bytes_to_cmp) != 0) {
-      LogFreeError(debug, header, reinterpret_cast<const uint8_t*>(pointer));
-      break;
+  if (header->tag != DEBUG_FREE_TAG) {
+    error_log(LOG_DIVIDER);
+    error_log("+++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer, header->tag);
+    error_log(LOG_DIVIDER);
+  } else {
+    const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
+    size_t bytes = header->usable_size;
+    bytes = (bytes < debug.config().fill_on_free_bytes) ? bytes : debug.config().fill_on_free_bytes;
+    while (bytes > 0) {
+      size_t bytes_to_cmp = (bytes < cmp_mem_.size()) ? bytes : cmp_mem_.size();
+      if (memcmp(memory, cmp_mem_.data(), bytes_to_cmp) != 0) {
+        LogFreeError(debug, header, reinterpret_cast<const uint8_t*>(pointer));
+        break;
+      }
+      bytes -= bytes_to_cmp;
+      memory = &memory[bytes_to_cmp];
     }
-    bytes -= bytes_to_cmp;
-    memory = &memory[bytes_to_cmp];
   }
+
   auto back_iter = backtraces_.find(header);
   if (back_iter != backtraces_.end()) {
     g_dispatch->free(reinterpret_cast<void*>(back_iter->second));
@@ -98,7 +105,6 @@
     list_.pop_back();
   }
 
-  // Only log the free backtrace if we are using the free track feature.
   if (backtrace_num_frames_ > 0) {
     BacktraceHeader* back_header = reinterpret_cast<BacktraceHeader*>(
       g_dispatch->malloc(sizeof(BacktraceHeader) + backtrace_num_frames_ * sizeof(uintptr_t)));
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 568192d..1ee7689 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -112,6 +112,7 @@
     );
   });
 }
+
 static void LogTagError(const Header* header, const void* pointer, const char* name) {
   ScopedDisableDebugCalls disable;
 
@@ -145,7 +146,7 @@
     return nullptr;
   }
   header->usable_size -= g_debug->pointer_offset() +
-      reinterpret_cast<uintptr_t>(orig_pointer) - reinterpret_cast<uintptr_t>(header);
+      reinterpret_cast<uintptr_t>(header) - reinterpret_cast<uintptr_t>(orig_pointer);
 
   if (g_debug->config().options & FRONT_GUARD) {
     uint8_t* guard = g_debug->GetFrontGuard(header);
@@ -326,8 +327,9 @@
 
   void* free_pointer = pointer;
   size_t bytes;
+  Header* header;
   if (g_debug->need_header()) {
-    Header* header = g_debug->GetHeader(pointer);
+    header = g_debug->GetHeader(pointer);
     if (header->tag != DEBUG_TAG) {
       LogTagError(header, pointer, "free");
       return;
@@ -353,13 +355,6 @@
       }
       g_debug->track->Remove(header, backtrace_found);
     }
-
-    if (g_debug->config().options & FREE_TRACK) {
-      g_debug->free_track->Add(*g_debug, header);
-
-      // Do not free this pointer just yet.
-      free_pointer = nullptr;
-    }
     header->tag = DEBUG_FREE_TAG;
 
     bytes = header->usable_size;
@@ -373,7 +368,16 @@
     memset(pointer, g_debug->config().fill_free_value, bytes);
   }
 
-  g_dispatch->free(free_pointer);
+  if (g_debug->config().options & FREE_TRACK) {
+    // Do not add the allocation until we are done modifying the pointer
+    // itself. This avoids a race if a lot of threads are all doing
+    // frees at the same time and we wind up trying to really free this
+    // pointer from another thread, while still trying to free it in
+    // this function.
+    g_debug->free_track->Add(*g_debug, header);
+  } else {
+    g_dispatch->free(free_pointer);
+  }
 }
 
 void* debug_memalign(size_t alignment, size_t bytes) {
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index a6cea98..85d5cb5 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -124,6 +124,14 @@
   ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
 }
 
+TEST_F(MallocDebugConfigTest, good_option_and_bad_option) {
+  ASSERT_FALSE(InitConfig("backtrace unknown_option"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg("6 malloc_debug malloc_testing: unknown option unknown_option\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
 TEST_F(MallocDebugConfigTest, unparseable_number) {
   ASSERT_FALSE(InitConfig("backtrace=XXX"));
 
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 2503981..b6bf7bc 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -24,6 +24,7 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <thread>
 #include <vector>
 #include <utility>
 
@@ -898,6 +899,53 @@
   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
 }
 
+TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
+  Init("free_track=100 free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 100);
+  debug_free(pointer);
+
+  pointer[-get_tag_offset()] = 0x00;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
+      pointer);
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_multiple_thread) {
+  Init("free_track=10 free_track_backtrace_num_frames=0");
+
+  std::vector<std::thread*> threads(1000);
+  for (size_t i = 0; i < threads.size(); i++) {
+    threads[i] = new std::thread([](){
+      for (size_t j = 0; j < 100; j++) {
+        void* mem = debug_malloc(100);
+        write(0, mem, 0);
+        debug_free(mem);
+      }
+    });
+  }
+  for (size_t i = 0; i < threads.size(); i++) {
+    threads[i]->join();
+    delete threads[i];
+  }
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
 TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
   Init("fill");
 
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index bcb05a0..b45c0c3 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -49,4 +49,9 @@
 __LIBC_HIDDEN__ void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args);
 __LIBC_HIDDEN__ void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args);
 
+#if defined(__i386__)
+__LIBC_HIDDEN__ extern void* __libc_sysinfo;
+__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args);
+#endif
+
 #endif
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 4d0afe2..f7785d6 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -166,9 +166,20 @@
 
 x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
 
+x86_call_prepare = """\
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+"""
+
 x86_call = """\
     movl    $%(__NR_name)s, %%eax
-    int     $0x80
+    call    *(%%esp)
+    addl    $4, %%esp
+
     cmpl    $-MAX_ERRNO, %%eax
     jb      1f
     negl    %%eax
@@ -311,7 +322,7 @@
     result     = syscall_stub_header % syscall
 
     numparams = count_generic_param_registers(syscall["params"])
-    stack_bias = numparams*4 + 4
+    stack_bias = numparams*4 + 8
     offset = 0
     mov_result = ""
     first_push = True
@@ -327,6 +338,7 @@
         mov_result += "    mov     %d(%%esp), %%%s\n" % (stack_bias+offset, register)
         offset += 4
 
+    result += x86_call_prepare
     result += mov_result
     result += x86_call % syscall
 
@@ -352,7 +364,9 @@
     result += "    pushl   %ecx\n"
     result += "    .cfi_adjust_cfa_offset 4\n"
     result += "    .cfi_rel_offset ecx, 0\n"
-    stack_bias = 12
+    stack_bias = 16
+
+    result += x86_call_prepare
 
     # set the call id (%ebx)
     result += "    mov     $%d, %%ebx\n" % syscall["socketcall_id"]
diff --git a/libc/tools/genversion-scripts.py b/libc/tools/genversion-scripts.py
index e15c04e..4f117f6 100755
--- a/libc/tools/genversion-scripts.py
+++ b/libc/tools/genversion-scripts.py
@@ -7,6 +7,7 @@
 import os.path
 import shutil
 import tempfile
+import sys
 
 
 all_arches = ["arm", "arm64", "mips", "mips64", "x86", "x86_64"]
@@ -17,6 +18,8 @@
 libm_script = os.path.join(bionic_libm_root, "libm.map.txt")
 libdl_script = os.path.join(bionic_libdl_root, "libdl.map.txt")
 
+script_name = os.path.basename(sys.argv[0])
+
 # TODO (dimity): generate architecture-specific version scripts as part of build
 
 # temp directory where we store all intermediate files
@@ -26,7 +29,7 @@
 
 bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
 
-warning = "Generated by genversionscripts.py. Do not edit."
+warning = "Generated by %s. Do not edit." % script_name
 
 
 class VersionScriptGenerator(object):
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index aa6907a..67c8d08 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index c767fb1..4d035f5 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index c767fb1..4d035f5 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index c767fb1..4d035f5 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index c767fb1..4d035f5 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index c767fb1..4d035f5 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 
 LIBC {
   global:
diff --git a/libm/Android.bp b/libm/Android.bp
index a4f6135..52249c9 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -172,6 +172,30 @@
     "upstream-freebsd/lib/msun/src/w_cabsl.c",
     "upstream-freebsd/lib/msun/src/w_drem.c",
     "upstream-freebsd/lib/msun/src/w_dremf.c",
+
+    // The FreeBSD complex functions appear to be better, but they're incomplete.
+    // We take the FreeBSD implementations when they exist, but fill out the rest
+    // of <complex.h> from NetBSD...
+    "upstream-netbsd/lib/libm/complex/cacoshl.c",
+    "upstream-netbsd/lib/libm/complex/cacosl.c",
+    "upstream-netbsd/lib/libm/complex/casinhl.c",
+    "upstream-netbsd/lib/libm/complex/casinl.c",
+    "upstream-netbsd/lib/libm/complex/catanhl.c",
+    "upstream-netbsd/lib/libm/complex/catanl.c",
+    "upstream-netbsd/lib/libm/complex/ccoshl.c",
+    "upstream-netbsd/lib/libm/complex/ccosl.c",
+    "upstream-netbsd/lib/libm/complex/cephes_subrl.c",
+    "upstream-netbsd/lib/libm/complex/cexpl.c",
+    "upstream-netbsd/lib/libm/complex/clog.c",
+    "upstream-netbsd/lib/libm/complex/clogf.c",
+    "upstream-netbsd/lib/libm/complex/clogl.c",
+    "upstream-netbsd/lib/libm/complex/cpow.c",
+    "upstream-netbsd/lib/libm/complex/cpowf.c",
+    "upstream-netbsd/lib/libm/complex/cpowl.c",
+    "upstream-netbsd/lib/libm/complex/csinhl.c",
+    "upstream-netbsd/lib/libm/complex/csinl.c",
+    "upstream-netbsd/lib/libm/complex/ctanhl.c",
+    "upstream-netbsd/lib/libm/complex/ctanl.c",
 ]
 
 libm_common_src_files += [
@@ -283,6 +307,7 @@
     name: "libm",
 
     cflags: libm_common_cflags,
+    conlyflags: ["-std=gnu11"],
     include_dirs: ["bionic/libc"],
     local_include_dirs: libm_common_local_includes,
     srcs: libm_common_src_files,
@@ -387,6 +412,8 @@
                 "x86/libm_reduce_pi04l.S",
                 "x86/libm_sincos_huge.S",
                 "x86/libm_tancot_huge.S",
+                "x86/lrint.S",
+                "x86/lrintf.S",
                 "x86/s_atan.S",
                 "x86/s_cbrt.S",
                 "x86/s_cos.S",
@@ -414,6 +441,8 @@
                 "upstream-freebsd/lib/msun/src/s_cos.c",
                 "upstream-freebsd/lib/msun/src/s_expm1.c",
                 "upstream-freebsd/lib/msun/src/s_log1p.c",
+                "upstream-freebsd/lib/msun/src/s_lrint.c",
+                "upstream-freebsd/lib/msun/src/s_lrintf.c",
                 "upstream-freebsd/lib/msun/src/s_sin.c",
                 "upstream-freebsd/lib/msun/src/s_tan.c",
                 "upstream-freebsd/lib/msun/src/s_tanh.c",
@@ -424,6 +453,8 @@
                     "x86/ceilf.S",
                     "x86/floor.S",
                     "x86/floorf.S",
+                    "x86/rint.S",
+                    "x86/rintf.S",
                     "x86/trunc.S",
                     "x86/truncf.S",
                 ],
@@ -432,6 +463,8 @@
                     "upstream-freebsd/lib/msun/src/s_ceilf.c",
                     "upstream-freebsd/lib/msun/src/s_floor.c",
                     "upstream-freebsd/lib/msun/src/s_floorf.c",
+                    "upstream-freebsd/lib/msun/src/s_rint.c",
+                    "upstream-freebsd/lib/msun/src/s_rintf.c",
                     "upstream-freebsd/lib/msun/src/s_trunc.c",
                     "upstream-freebsd/lib/msun/src/s_truncf.c",
                 ],
@@ -456,6 +489,8 @@
                 "x86_64/e_log.S",
                 "x86_64/e_pow.S",
                 "x86_64/e_sinh.S",
+                "x86_64/lrint.S",
+                "x86_64/lrintf.S",
                 "x86_64/s_atan.S",
                 "x86_64/s_cbrt.S",
                 "x86_64/s_cos.S",
@@ -483,6 +518,10 @@
                 "upstream-freebsd/lib/msun/src/s_cos.c",
                 "upstream-freebsd/lib/msun/src/s_expm1.c",
                 "upstream-freebsd/lib/msun/src/s_log1p.c",
+                "upstream-freebsd/lib/msun/src/s_llrint.c",
+                "upstream-freebsd/lib/msun/src/s_llrintf.c",
+                "upstream-freebsd/lib/msun/src/s_lrint.c",
+                "upstream-freebsd/lib/msun/src/s_lrintf.c",
                 "upstream-freebsd/lib/msun/src/s_sin.c",
                 "upstream-freebsd/lib/msun/src/s_tan.c",
                 "upstream-freebsd/lib/msun/src/s_tanh.c",
@@ -493,6 +532,8 @@
                     "x86_64/ceilf.S",
                     "x86_64/floor.S",
                     "x86_64/floorf.S",
+                    "x86_64/rint.S",
+                    "x86_64/rintf.S",
                     "x86_64/trunc.S",
                     "x86_64/truncf.S",
                 ],
@@ -501,6 +542,8 @@
                     "upstream-freebsd/lib/msun/src/s_ceilf.c",
                     "upstream-freebsd/lib/msun/src/s_floor.c",
                     "upstream-freebsd/lib/msun/src/s_floorf.c",
+                    "upstream-freebsd/lib/msun/src/s_rint.c",
+                    "upstream-freebsd/lib/msun/src/s_rintf.c",
                     "upstream-freebsd/lib/msun/src/s_trunc.c",
                     "upstream-freebsd/lib/msun/src/s_truncf.c",
                 ],
diff --git a/libm/Android.mk b/libm/Android.mk
index 5dd140b..7200e5f 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -180,6 +180,31 @@
     upstream-freebsd/lib/msun/src/w_drem.c \
     upstream-freebsd/lib/msun/src/w_dremf.c \
 
+# The FreeBSD complex functions appear to be better, but they're incomplete.
+# We take the FreeBSD implementations when they exist, but fill out the rest
+# of <complex.h> from NetBSD...
+LOCAL_SRC_FILES += \
+    upstream-netbsd/lib/libm/complex/cacoshl.c \
+    upstream-netbsd/lib/libm/complex/cacosl.c \
+    upstream-netbsd/lib/libm/complex/casinhl.c \
+    upstream-netbsd/lib/libm/complex/casinl.c \
+    upstream-netbsd/lib/libm/complex/catanhl.c \
+    upstream-netbsd/lib/libm/complex/catanl.c \
+    upstream-netbsd/lib/libm/complex/ccoshl.c \
+    upstream-netbsd/lib/libm/complex/ccosl.c \
+    upstream-netbsd/lib/libm/complex/cephes_subrl.c \
+    upstream-netbsd/lib/libm/complex/cexpl.c \
+    upstream-netbsd/lib/libm/complex/clog.c \
+    upstream-netbsd/lib/libm/complex/clogf.c \
+    upstream-netbsd/lib/libm/complex/clogl.c \
+    upstream-netbsd/lib/libm/complex/cpow.c \
+    upstream-netbsd/lib/libm/complex/cpowf.c \
+    upstream-netbsd/lib/libm/complex/cpowl.c \
+    upstream-netbsd/lib/libm/complex/csinhl.c \
+    upstream-netbsd/lib/libm/complex/csinl.c \
+    upstream-netbsd/lib/libm/complex/ctanhl.c \
+    upstream-netbsd/lib/libm/complex/ctanl.c \
+
 LOCAL_SRC_FILES_32 += \
     fake_long_double.c \
 
@@ -498,6 +523,9 @@
     -Wno-unknown-pragmas \
     -fvisibility=hidden \
 
+LOCAL_CONLYFLAGS := \
+    -std=gnu11 \
+
 LOCAL_ASFLAGS := \
     -Ibionic/libc \
 
diff --git a/libm/include/complex.h b/libm/include/complex.h
index ff6b166..b54d2fc 100644
--- a/libm/include/complex.h
+++ b/libm/include/complex.h
@@ -32,9 +32,6 @@
 #include <sys/cdefs.h>
 
 #ifdef __GNUC__
-#if __STDC_VERSION__ < 199901
-#define	_Complex	__complex__
-#endif
 #define	_Complex_I	((float _Complex)1.0i)
 #endif
 
@@ -51,7 +48,7 @@
 #define	CMPLX(x, y)	((double complex){ x, y })
 #define	CMPLXF(x, y)	((float complex){ x, y })
 #define	CMPLXL(x, y)	((long double complex){ x, y })
-#elif __GNUC_PREREQ__(4, 7)
+#else
 #define	CMPLX(x, y)	__builtin_complex((double)(x), (double)(y))
 #define	CMPLXF(x, y)	__builtin_complex((float)(x), (float)(y))
 #define	CMPLXL(x, y)	__builtin_complex((long double)(x), (long double)(y))
@@ -61,56 +58,103 @@
 __BEGIN_DECLS
 #pragma GCC visibility push(default)
 
-double		cabs(double complex);
-float		cabsf(float complex);
-long double	cabsl(long double complex);
-double complex	cacos(double complex);
-float complex	cacosf(float complex);
-double complex	cacosh(double complex);
-float complex	cacoshf(float complex);
-double		carg(double complex);
-float		cargf(float complex);
-long double	cargl(long double complex);
-double complex	casin(double complex);
-float complex	casinf(float complex);
-double complex	casinh(double complex);
-float complex	casinhf(float complex);
-double complex	catan(double complex);
-float complex	catanf(float complex);
-double complex	catanh(double complex);
-float complex	catanhf(float complex);
-double complex	ccos(double complex);
-float complex	ccosf(float complex);
-double complex	ccosh(double complex);
-float complex	ccoshf(float complex);
-double complex	cexp(double complex);
-float complex	cexpf(float complex);
-double		cimag(double complex) __pure2;
-float		cimagf(float complex) __pure2;
-long double	cimagl(long double complex) __pure2;
-double complex	conj(double complex) __pure2;
-float complex	conjf(float complex) __pure2;
-long double complex
-		conjl(long double complex) __pure2;
-float complex	cprojf(float complex) __pure2;
-double complex	cproj(double complex) __pure2;
-long double complex
-		cprojl(long double complex) __pure2;
-double		creal(double complex) __pure2;
-float		crealf(float complex) __pure2;
-long double	creall(long double complex) __pure2;
-double complex	csin(double complex);
-float complex	csinf(float complex);
-double complex	csinh(double complex);
-float complex	csinhf(float complex);
-double complex	csqrt(double complex);
-float complex	csqrtf(float complex);
-long double complex
-		csqrtl(long double complex);
-double complex	ctan(double complex);
-float complex	ctanf(float complex);
-double complex	ctanh(double complex);
-float complex	ctanhf(float complex);
+/* 7.3.5 Trigonometric functions */
+/* 7.3.5.1 The cacos functions */
+double complex cacos(double complex);
+float complex cacosf(float complex);
+long double complex cacosl(long double complex);
+/* 7.3.5.2 The casin functions */
+double complex casin(double complex);
+float complex casinf(float complex);
+long double complex casinl(long double complex);
+/* 7.3.5.1 The catan functions */
+double complex catan(double complex);
+float complex catanf(float complex);
+long double complex catanl(long double complex);
+/* 7.3.5.1 The ccos functions */
+double complex ccos(double complex);
+float complex ccosf(float complex);
+long double complex ccosl(long double complex);
+/* 7.3.5.1 The csin functions */
+double complex csin(double complex);
+float complex csinf(float complex);
+long double complex csinl(long double complex);
+/* 7.3.5.1 The ctan functions */
+double complex ctan(double complex);
+float complex ctanf(float complex);
+long double complex ctanl(long double complex);
+
+/* 7.3.6 Hyperbolic functions */
+/* 7.3.6.1 The cacosh functions */
+double complex cacosh(double complex);
+float complex cacoshf(float complex);
+long double complex cacoshl(long double complex);
+/* 7.3.6.2 The casinh functions */
+double complex casinh(double complex);
+float complex casinhf(float complex);
+long double complex casinhl(long double complex);
+/* 7.3.6.3 The catanh functions */
+double complex catanh(double complex);
+float complex catanhf(float complex);
+long double complex catanhl(long double complex);
+/* 7.3.6.4 The ccosh functions */
+double complex ccosh(double complex);
+float complex ccoshf(float complex);
+long double complex ccoshl(long double complex);
+/* 7.3.6.5 The csinh functions */
+double complex csinh(double complex);
+float complex csinhf(float complex);
+long double complex csinhl(long double complex);
+/* 7.3.6.6 The ctanh functions */
+double complex ctanh(double complex);
+float complex ctanhf(float complex);
+long double complex ctanhl(long double complex);
+
+/* 7.3.7 Exponential and logarithmic functions */
+/* 7.3.7.1 The cexp functions */
+double complex cexp(double complex);
+float complex cexpf(float complex);
+long double complex cexpl(long double complex);
+/* 7.3.7.2 The clog functions */
+double complex clog(double complex);
+float complex clogf(float complex);
+long double complex clogl(long double complex);
+
+/* 7.3.8 Power and absolute-value functions */
+/* 7.3.8.1 The cabs functions */
+double cabs(double complex);
+float cabsf(float complex);
+long double cabsl(long double complex);
+/* 7.3.8.2 The cpow functions */
+double complex cpow(double complex, double complex);
+float complex cpowf(float complex, float complex);
+long double complex cpowl(long double complex, long double complex);
+/* 7.3.8.3 The csqrt functions */
+double complex csqrt(double complex);
+float complex csqrtf(float complex);
+long double complex csqrtl(long double complex);
+
+/* 7.3.9 Manipulation functions */
+/* 7.3.9.1 The carg functions */
+double carg(double complex);
+float cargf(float complex);
+long double cargl(long double complex);
+/* 7.3.9.2 The cimag functions */
+double cimag(double complex);
+float cimagf(float complex);
+long double cimagl(long double complex);
+/* 7.3.9.3 The conj functions */
+double complex conj(double complex);
+float complex conjf(float complex);
+long double complex conjl(long double complex);
+/* 7.3.9.4 The cproj functions */
+double complex cproj(double complex);
+float complex cprojf(float complex);
+long double complex cprojl(long double complex);
+/* 7.3.9.5 The creal functions */
+double creal(double complex);
+float crealf(float complex);
+long double creall(long double complex);
 
 #pragma GCC visibility pop
 __END_DECLS
diff --git a/libm/include/math.h b/libm/include/math.h
index ce8e3b2..8e193cb 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -108,6 +108,22 @@
 extern int signgam;
 #endif /* __BSD_VISIBLE || __XSI_VISIBLE */
 
+#if __USE_GNU
+#define M_El            2.718281828459045235360287471352662498L /* e */
+#define M_LOG2El        1.442695040888963407359924681001892137L /* log 2e */
+#define M_LOG10El       0.434294481903251827651128918916605082L /* log 10e */
+#define M_LN2l          0.693147180559945309417232121458176568L /* log e2 */
+#define M_LN10l         2.302585092994045684017991454684364208L /* log e10 */
+#define M_PIl           3.141592653589793238462643383279502884L /* pi */
+#define M_PI_2l         1.570796326794896619231321691639751442L /* pi/2 */
+#define M_PI_4l         0.785398163397448309615660845819875721L /* pi/4 */
+#define M_1_PIl         0.318309886183790671537767526745028724L /* 1/pi */
+#define M_2_PIl         0.636619772367581343075535053490057448L /* 2/pi */
+#define M_2_SQRTPIl     1.128379167095512573896158903121545172L /* 2/sqrt(pi) */
+#define M_SQRT2l        1.414213562373095048801688724209698079L /* sqrt(2) */
+#define M_SQRT1_2l      0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+#endif
+
 #if __BSD_VISIBLE
 #if 0
 /* Old value from 4.4BSD-Lite math.h; this is probably better. */
diff --git a/libm/libm.arm.map b/libm/libm.arm.map
index 842f46c..a61dc2e 100644
--- a/libm/libm.arm.map
+++ b/libm/libm.arm.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,6 +272,29 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
 LIBC_DEPRECATED { # arm mips
   global: # arm mips
     ___Unwind_Backtrace; # arm
@@ -375,4 +398,4 @@
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
     restore_core_regs; # arm
-} LIBC; # arm mips
+} LIBC_O; # arm mips
diff --git a/libm/libm.arm64.map b/libm/libm.arm64.map
index 1623ea0..11032ca 100644
--- a/libm/libm.arm64.map
+++ b/libm/libm.arm64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,3 +272,26 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
diff --git a/libm/libm.map.txt b/libm/libm.map.txt
index d273603..66dfd19 100644
--- a/libm/libm.map.txt
+++ b/libm/libm.map.txt
@@ -271,6 +271,29 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
 LIBC_DEPRECATED { # arm mips
   global: # arm mips
     ___Unwind_Backtrace; # arm
@@ -374,4 +397,4 @@
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
     restore_core_regs; # arm
-} LIBC; # arm mips
+} LIBC_O; # arm mips
diff --git a/libm/libm.mips.map b/libm/libm.mips.map
index 2429dba..8353627 100644
--- a/libm/libm.mips.map
+++ b/libm/libm.mips.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,10 +272,33 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
 LIBC_DEPRECATED { # arm mips
   global: # arm mips
     __fixdfdi; # arm mips
     __fixsfdi; # arm mips
     __fixunsdfdi; # arm mips
     __fixunssfdi; # arm mips
-} LIBC; # arm mips
+} LIBC_O; # arm mips
diff --git a/libm/libm.mips64.map b/libm/libm.mips64.map
index 1623ea0..11032ca 100644
--- a/libm/libm.mips64.map
+++ b/libm/libm.mips64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,3 +272,26 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
diff --git a/libm/libm.x86.map b/libm/libm.x86.map
index 1623ea0..11032ca 100644
--- a/libm/libm.x86.map
+++ b/libm/libm.x86.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,3 +272,26 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
diff --git a/libm/libm.x86_64.map b/libm/libm.x86_64.map
index 1623ea0..11032ca 100644
--- a/libm/libm.x86_64.map
+++ b/libm/libm.x86_64.map
@@ -1,4 +1,4 @@
-# Generated by genversionscripts.py. Do not edit.
+# Generated by genversion-scripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -272,3 +272,26 @@
     *;
 };
 
+LIBC_O {
+  global:
+    cacoshl;
+    cacosl;
+    casinhl;
+    casinl;
+    catanhl;
+    catanl;
+    ccoshl;
+    ccosl;
+    cexpl;
+    clog;
+    clogf;
+    clogl;
+    cpow;
+    cpowf;
+    cpowl;
+    csinhl;
+    csinl;
+    ctanhl;
+    ctanl;
+} LIBC;
+
diff --git a/libm/upstream-netbsd/lib/libm/complex/cacoshl.c b/libm/upstream-netbsd/lib/libm/complex/cacoshl.c
new file mode 100644
index 0000000..4e4e006
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cacoshl.c
@@ -0,0 +1,45 @@
+/* $NetBSD: cacoshl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <complex.h>
+
+long double complex
+cacoshl(long double complex z)
+{
+	long double complex w;
+
+#if 0 /* does not give the principal value */
+	w = I * cacosl(z);
+#else
+	w = clogl(z + csqrtl(z + 1) * csqrtl(z - 1));
+#endif
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cacosl.c b/libm/upstream-netbsd/lib/libm/complex/cacosl.c
new file mode 100644
index 0000000..e481158
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cacosl.c
@@ -0,0 +1,45 @@
+/* $NetBSD: cacosl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include "cephes_subrl.h"
+
+long double complex
+cacosl(long double complex z)
+{
+	long double complex w;
+
+	w = casinl(z);
+	w = (M_PI_2L - creall(w)) - cimagl(w) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/casinhl.c b/libm/upstream-netbsd/lib/libm/complex/casinhl.c
new file mode 100644
index 0000000..9f74ee9
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/casinhl.c
@@ -0,0 +1,42 @@
+/* $NetBSD: casinhl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+
+long double complex
+casinhl(long double complex z)
+{
+	long double complex w;
+
+	w = -1.0L * I * casinl(z * I);
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/casinl.c b/libm/upstream-netbsd/lib/libm/complex/casinl.c
new file mode 100644
index 0000000..986a8c0
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/casinl.c
@@ -0,0 +1,120 @@
+/* $NetBSD: casinl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+#ifdef __weak_alias
+__weak_alias(casinl, _casinl)
+#endif
+
+long double complex
+casinl(long double complex z)
+{
+	long double complex w;
+	long double complex ca, ct, zz, z2;
+	long double x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+
+#if 0 /* MD: test is incorrect, casin(>1) is defined */
+	if (y == 0.0L) {
+		if (fabsl(x) > 1.0L) {
+			w = M_PI_2L + 0.0L * I;
+#if 0
+			mtherr ("casinl", DOMAIN);
+#endif
+		} else {
+			w = asinl(x) + 0.0L * I;
+		}
+		return w;
+	}
+#endif
+
+/* Power series expansion */
+/*
+b = cabsl(z);
+if( b < 0.125L )
+{
+z2.r = (x - y) * (x + y);
+z2.i = 2.0L * x * y;
+
+cn = 1.0L;
+n = 1.0L;
+ca.r = x;
+ca.i = y;
+sum.r = x;
+sum.i = y;
+do
+	{
+	ct.r = z2.r * ca.r  -  z2.i * ca.i;
+	ct.i = z2.r * ca.i  +  z2.i * ca.r;
+	ca.r = ct.r;
+	ca.i = ct.i;
+
+	cn *= n;
+	n += 1.0;
+	cn /= n;
+	n += 1.0;
+	b = cn/n;
+
+	ct.r *= b;
+	ct.i *= b;
+	sum.r += ct.r;
+	sum.i += ct.i;
+	b = fabsl(ct.r) + fabsl(ct.i);
+	}
+while( b > MACHEPL );
+w->r = sum.r;
+w->i = sum.i;
+return;
+}
+*/
+
+
+	ca = x + y * I;
+	ct = ca * I;
+	/* sqrtl( 1 - z*z) */
+	/* cmull( &ca, &ca, &zz ) */
+	/*x * x  -  y * y */
+	zz = (x - y) * (x + y) + (2.0L * x * y) * I;
+
+	zz = 1.0L - creall(zz) - cimagl(zz) * I;
+	z2 = csqrtl(zz);
+
+	zz = ct + z2;
+	zz = clogl(zz);
+	/* multiply by 1/i = -i */
+	w = zz * (-1.0L * I);
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/catanhl.c b/libm/upstream-netbsd/lib/libm/complex/catanhl.c
new file mode 100644
index 0000000..4969b70
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/catanhl.c
@@ -0,0 +1,42 @@
+/* $NetBSD: catanhl.c,v 1.3 2014/10/10 12:43:15 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+
+long double complex
+catanhl(long double complex z)
+{
+	long double complex w;
+
+	w = -1.0L * I * catanl(z * I);
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/catanl.c b/libm/upstream-netbsd/lib/libm/complex/catanl.c
new file mode 100644
index 0000000..bdff23f
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/catanl.c
@@ -0,0 +1,80 @@
+/* $NetBSD: catanl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include <float.h>
+#include "cephes_subrl.h"
+
+#ifdef __weak_alias
+__weak_alias(catanl, _catanl)
+#endif
+
+#define MAXNUM LDBL_MAX
+
+long double complex
+catanl(long double complex z)
+{
+	long double complex w;
+	long double a, t, x, x2, y;
+
+	x = creall(z);
+	y = cimagl(z);
+
+	if ((x == 0.0L) && (y > 1.0L))
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0L - x2 - (y * y);
+	if (a == 0.0)
+		goto ovrf;
+
+	t = 0.5L * atan2l(2.0L * x, a);
+	w = _redupil(t);
+
+	t = y - 1.0L;
+	a = x2 + (t * t);
+	if (a == 0.0L)
+		goto ovrf;
+
+	t = y + 1.0L;
+	a = (x2 + (t * t))/a;
+	w = w + (0.25L * logl(a)) * I;
+	return w;
+
+ovrf:
+#if 0
+	mtherr ("catanl", OVERFLOW);
+#endif
+	w = MAXNUM + MAXNUM * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/ccoshl.c b/libm/upstream-netbsd/lib/libm/complex/ccoshl.c
new file mode 100644
index 0000000..4c33f9d
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/ccoshl.c
@@ -0,0 +1,46 @@
+/* $NetBSD: ccoshl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+ccoshl(long double complex z)
+{
+	long double complex w;
+	long double x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+	w = coshl(x) * cosl(y) + (sinhl(x) * sinl(y)) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/ccosl.c b/libm/upstream-netbsd/lib/libm/complex/ccosl.c
new file mode 100644
index 0000000..6ce5661
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/ccosl.c
@@ -0,0 +1,46 @@
+/* $NetBSD: ccosl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include "cephes_subrl.h"
+
+long double complex
+ccosl(long double complex z)
+{
+	long double complex w;
+	long double ch, sh;
+
+	_cchshl(cimagl(z), &ch, &sh);
+	w = cosl(creall(z)) * ch - (sinl(creall(z)) * sh) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.c b/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.c
new file mode 100644
index 0000000..90dbd86
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.c
@@ -0,0 +1,129 @@
+/* $NetBSD: cephes_subrl.c,v 1.2 2014/10/10 14:06:40 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include "cephes_subrl.h"
+
+/* calculate cosh and sinh */
+
+void
+_cchshl(long double x, long double *c, long double *s)
+{
+	long double e, ei;
+
+	if (fabsl(x) <= 0.5L) {
+		*c = coshl(x);
+		*s = sinhl(x);
+	} else {
+		e = expl(x);
+		ei = 0.5L / e;
+		e = 0.5L * e;
+		*s = e - ei;
+		*c = e + ei;
+	}
+}
+
+/* Program to subtract nearest integer multiple of PI */
+
+/* extended precision value of PI: */
+static const long double DP1 = 3.14159265358979323829596852490908531763125L;
+static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;
+#ifndef __vax__
+static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;
+#define MACHEPL 1.1e-38L
+#else
+static const long double DP3 = 0L;
+#define MACHEPL 1.1e-19L
+#endif
+
+long double
+_redupil(long double x)
+{
+	long double t;
+	long long i;
+
+	t = x / M_PIL;
+	if (t >= 0.0L)
+		t += 0.5L;
+	else
+		t -= 0.5L;
+
+	i = t;	/* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+/* Taylor series expansion for cosh(2y) - cos(2x) */
+
+long double
+_ctansl(long double complex z)
+{
+	long double f, x, x2, y, y2, rn, t;
+	long double d;
+
+	x = fabsl(2.0L * creall(z));
+	y = fabsl(2.0L * cimagl(z));
+
+	x = _redupil(x);
+
+	x = x * x;
+	y = y * y;
+	x2 = 1.0;
+	y2 = 1.0;
+	f = 1.0;
+	rn = 0.0;
+	d = 0.0;
+	do {
+		rn += 1.0L;
+		f *= rn;
+		rn += 1.0L;
+		f *= rn;
+		x2 *= x;
+		y2 *= y;
+		t = y2 + x2;
+		t /= f;
+		d += t;
+
+		rn += 1.0L;
+		f *= rn;
+		rn += 1.0L;
+		f *= rn;
+		x2 *= x;
+		y2 *= y;
+		t = y2 - x2;
+		t /= f;
+		d += t;
+	} while (fabsl(t/d) > MACHEPL);
+	return d;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.h b/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.h
new file mode 100644
index 0000000..6354b23
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cephes_subrl.h
@@ -0,0 +1,9 @@
+/* $NetBSD: cephes_subrl.h,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+void _cchshl(long double, long double *, long double *);
+long double _redupil(long double);
+long double _ctansl(long double complex);
+
+#define	M_PIL	3.14159265358979323846264338327950280e+00L
+#define	M_PI_2L	1.57079632679489661923132169163975140e+00L
+
diff --git a/libm/upstream-netbsd/lib/libm/complex/cexpl.c b/libm/upstream-netbsd/lib/libm/complex/cexpl.c
new file mode 100644
index 0000000..a1e2235
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cexpl.c
@@ -0,0 +1,47 @@
+/* $NetBSD: cexpl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+cexpl(long double complex z)
+{
+	long double complex w;
+	long double r, x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+	r = expl(x);
+	w = r * cosl(y) + r * sinl(y) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/clog.c b/libm/upstream-netbsd/lib/libm/complex/clog.c
new file mode 100644
index 0000000..6362c44
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/clog.c
@@ -0,0 +1,47 @@
+/* $NetBSD: clog.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+double complex
+clog(double complex z)
+{
+	double complex w;
+	double p, rr;
+
+	rr = cabs(z);
+	p = log(rr);
+	rr = atan2(cimag(z), creal(z));
+	w = p + rr * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/clogf.c b/libm/upstream-netbsd/lib/libm/complex/clogf.c
new file mode 100644
index 0000000..c3cdad0
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/clogf.c
@@ -0,0 +1,47 @@
+/* $NetBSD: clogf.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+float complex
+clogf(float complex z)
+{
+	float complex w;
+	float p, rr;
+
+	rr = cabsf(z);
+	p = logf(rr);
+	rr = atan2f(cimagf(z), crealf(z));
+	w = p + rr * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/clogl.c b/libm/upstream-netbsd/lib/libm/complex/clogl.c
new file mode 100644
index 0000000..11e7a15
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/clogl.c
@@ -0,0 +1,47 @@
+/* $NetBSD: clogl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+clogl(long double complex z)
+{
+	long double complex w;
+	long double p, rr;
+
+	rr = cabsl(z);
+	p = logl(rr);
+	rr = atan2l(cimagl(z), creall(z));
+	w = p + rr * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cpow.c b/libm/upstream-netbsd/lib/libm/complex/cpow.c
new file mode 100644
index 0000000..5bc8d3f
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cpow.c
@@ -0,0 +1,57 @@
+/* $NetBSD: cpow.c,v 1.1 2007/08/20 16:01:35 drochner Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+double complex
+cpow(double complex a, double complex z)
+{
+	double complex w;
+	double x, y, r, theta, absa, arga;
+
+	x = creal(z);
+	y = cimag(z);
+	absa = cabs(a);
+	if (absa == 0.0) {
+		return (0.0 + 0.0 * I);
+	}
+	arga = carg(a);
+	r = pow(absa, x);
+	theta = x * arga;
+	if (y != 0.0) {
+		r = r * exp(-y * arga);
+		theta = theta + y * log(absa);
+	}
+	w = r * cos(theta) + (r * sin(theta)) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cpowf.c b/libm/upstream-netbsd/lib/libm/complex/cpowf.c
new file mode 100644
index 0000000..f7af10a
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cpowf.c
@@ -0,0 +1,57 @@
+/* $NetBSD: cpowf.c,v 1.1 2007/08/20 16:01:36 drochner Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+float complex
+cpowf(float complex a, float complex z)
+{
+	float complex w;
+	float x, y, r, theta, absa, arga;
+
+	x = crealf(z);
+	y = cimagf(z);
+	absa = cabsf(a);
+	if (absa == 0.0f) {
+		return (0.0f + 0.0f * I);
+	}
+	arga = cargf(a);
+	r = powf(absa, x);
+	theta = x * arga;
+	if (y != 0.0f) {
+		r = r * expf(-y * arga);
+		theta = theta + y * logf(absa);
+	}
+	w = r * cosf(theta) + (r * sinf(theta)) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/cpowl.c b/libm/upstream-netbsd/lib/libm/complex/cpowl.c
new file mode 100644
index 0000000..39336ea
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/cpowl.c
@@ -0,0 +1,57 @@
+/* $NetBSD: cpowl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+cpowl(long double complex a, long double complex z)
+{
+	long double complex w;
+	long double x, y, r, theta, absa, arga;
+
+	x = creall(z);
+	y = cimagl(z);
+	absa = cabsl(a);
+	if (absa == 0.0L) {
+		return (0.0L + 0.0L * I);
+	}
+	arga = cargl(a);
+	r = powl(absa, x);
+	theta = x * arga;
+	if (y != 0.0L) {
+		r = r * expl(-y * arga);
+		theta = theta + y * logl(absa);
+	}
+	w = r * cosl(theta) + (r * sinl(theta)) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/csinhl.c b/libm/upstream-netbsd/lib/libm/complex/csinhl.c
new file mode 100644
index 0000000..b78f7f1
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/csinhl.c
@@ -0,0 +1,46 @@
+/* $NetBSD: csinhl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+csinhl(long double complex z)
+{
+	long double complex w;
+	long double x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+	w = sinhl(x) * cosl(y) + (coshl(x) * sinl(y)) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/csinl.c b/libm/upstream-netbsd/lib/libm/complex/csinl.c
new file mode 100644
index 0000000..c86847b
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/csinl.c
@@ -0,0 +1,46 @@
+/* $NetBSD: csinl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include "cephes_subrl.h"
+
+long double complex
+csinl(long double complex z)
+{
+	long double complex w;
+	long double ch, sh;
+
+	_cchshl(cimagl(z), &ch, &sh);
+	w = sinl(creall(z)) * ch + (cosl(creall(z)) * sh) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/ctanhl.c b/libm/upstream-netbsd/lib/libm/complex/ctanhl.c
new file mode 100644
index 0000000..0894dd0
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/ctanhl.c
@@ -0,0 +1,48 @@
+/* $NetBSD: ctanhl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+
+long double complex
+ctanhl(long double complex z)
+{
+	long double complex w;
+	long double x, y, d;
+
+	x = creall(z);
+	y = cimagl(z);
+	d = coshl(2.0L * x) + cosl(2.0L * y);
+	w = sinhl(2.0L * x) / d  +  (sinl(2.0L * y) / d) * I;
+
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/complex/ctanl.c b/libm/upstream-netbsd/lib/libm/complex/ctanl.c
new file mode 100644
index 0000000..7932aef
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/complex/ctanl.c
@@ -0,0 +1,59 @@
+/* $NetBSD: ctanl.c,v 1.1 2014/10/10 00:48:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software written by Stephen L. Moshier.
+ * It is redistributed by the NetBSD Foundation by permission of the author.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/namespace.h"
+#include <complex.h>
+#include <math.h>
+#include <float.h>
+#include "cephes_subrl.h"
+
+#define MAXNUM LDBL_MAX
+
+long double complex
+ctanl(long double complex z)
+{
+	long double complex w;
+	long double d;
+
+	d = cosl(2.0L * creall(z)) + coshl(2.0L * cimagl(z));
+
+	if (fabsl(d) < 0.25L)
+		d = _ctansl(z);
+
+	if (d == 0.0L) {
+		/* mtherr ("ctan", OVERFLOW); */
+		w = MAXNUM + MAXNUM * I;
+		return w;
+	}
+
+	w = sinl(2.0L * creall(z)) / d + (sinhl(2.0L * cimagl(z)) / d) * I;
+	return w;
+}
diff --git a/libm/upstream-netbsd/lib/libm/src/namespace.h b/libm/upstream-netbsd/lib/libm/src/namespace.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libm/upstream-netbsd/lib/libm/src/namespace.h
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a7c3fb0..2fc8af0 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -68,7 +68,7 @@
 static void* dlopen_ext(const char* filename, int flags,
                         const android_dlextinfo* extinfo, void* caller_addr) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  soinfo* result = do_dlopen(filename, flags, extinfo, caller_addr);
+  void* result = do_dlopen(filename, flags, extinfo, caller_addr);
   if (result == nullptr) {
     __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
     return nullptr;
@@ -86,8 +86,6 @@
   return dlopen_ext(filename, flags, nullptr, caller_addr);
 }
 
-extern android_namespace_t* g_anonymous_namespace;
-
 void* dlsym_impl(void* handle, const char* symbol, const char* version, void* caller_addr) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
   void* result;
@@ -116,9 +114,11 @@
 
 int dlclose(void* handle) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  do_dlclose(reinterpret_cast<soinfo*>(handle));
-  // dlclose has no defined errors.
-  return 0;
+  int result = do_dlclose(handle);
+  if (result != 0) {
+    __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
+  }
+  return result;
 }
 
 int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
@@ -263,6 +263,7 @@
     __libdl_info->local_group_root_ = __libdl_info;
     __libdl_info->soname_ = "libdl.so";
     __libdl_info->target_sdk_version_ = __ANDROID_API__;
+    __libdl_info->generate_handle();
 #if defined(__work_around_b_24465209__)
     strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
 #endif
diff --git a/linker/linked_list.h b/linker/linked_list.h
index 88386b0..092e831 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -43,7 +43,7 @@
     return *this;
   }
 
-  T* operator*() {
+  T* const operator*() {
     return entry_->element;
   }
 
@@ -190,15 +190,15 @@
     return nullptr;
   }
 
-  iterator begin() {
+  iterator begin() const {
     return iterator(head_);
   }
 
-  iterator end() {
+  iterator end() const {
     return iterator(nullptr);
   }
 
-  iterator find(T* value) {
+  iterator find(T* value) const {
     for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
       if (e->element == value) {
         return iterator(e);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c07b21d..855b32b 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -44,6 +44,7 @@
 #include <vector>
 
 // Private C library headers.
+#include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 #include "private/ScopedPthreadMutexLocker.h"
@@ -65,6 +66,8 @@
 extern void __libc_init_globals(KernelArgumentBlock&);
 extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
 
+extern "C" void _start();
+
 // Override macros to use C++ style casts.
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
@@ -100,7 +103,23 @@
     permitted_paths_ = permitted_paths;
   }
 
-  soinfo::soinfo_list_t& soinfo_list() { return soinfo_list_; }
+  void add_soinfo(soinfo* si) {
+    soinfo_list_.push_back(si);
+  }
+
+  void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
+    for (auto si : soinfos) {
+      add_soinfo(si);
+    }
+  }
+
+  void remove_soinfo(soinfo* si) {
+    soinfo_list_.remove_if([&](soinfo* candidate) {
+      return si == candidate;
+    });
+  }
+
+  const soinfo::soinfo_list_t& soinfo_list() const { return soinfo_list_; }
 
   // For isolated namespaces - checks if the file is on the search path;
   // always returns true for not isolated namespace.
@@ -118,7 +137,8 @@
 };
 
 android_namespace_t g_default_namespace;
-android_namespace_t* g_anonymous_namespace = &g_default_namespace;
+static std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
+static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
 
 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
 
@@ -280,7 +300,8 @@
   sonext->next = si;
   sonext = si;
 
-  ns->soinfo_list().push_back(si);
+  si->generate_handle();
+  ns->add_soinfo(si);
 
   TRACE("name %s: allocated soinfo @ %p", name, si);
   return si;
@@ -329,9 +350,7 @@
   }
 
   // remove from the namespace
-  si->get_namespace()->soinfo_list().remove_if([&](soinfo* candidate) {
-    return si == candidate;
-  });
+  si->get_namespace()->remove_soinfo(si);
 
   si->~soinfo();
   g_soinfo_allocator.free(si);
@@ -379,13 +398,21 @@
         }
 
         ZipArchiveHandle handle = nullptr;
+        void* cookie = nullptr;
+        auto zip_guard = make_scope_guard([&]() {
+          if (cookie != nullptr) {
+            EndIteration(cookie);
+          }
+          if (handle != nullptr) {
+            CloseArchive(handle);
+          }
+        });
         if (OpenArchive(resolved_path, &handle) != 0) {
           DL_WARN("Warning: unable to open zip archive: %s", resolved_path);
           continue;
         }
 
         // Check if zip-file has a dir with entry_path name
-        void* cookie = nullptr;
         std::string prefix_str = entry_path + "/";
         ZipString prefix(prefix_str.c_str());
 
@@ -406,13 +433,6 @@
           continue;
         }
 
-        auto zip_guard = make_scope_guard([&]() {
-          if (cookie != nullptr) {
-            EndIteration(cookie);
-          }
-          CloseArchive(handle);
-        });
-
         resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
       }
     }
@@ -826,6 +846,10 @@
   this->namespace_ = ns;
 }
 
+soinfo::~soinfo() {
+  g_soinfo_handles_map.erase(handle_);
+}
+
 static uint32_t calculate_elf_hash(const char* name) {
   const uint8_t* name_bytes = reinterpret_cast<const uint8_t*>(name);
   uint32_t h = 0, g;
@@ -1248,21 +1272,21 @@
                                             void* handle) {
   SymbolName symbol_name(name);
 
-  soinfo::soinfo_list_t& soinfo_list = ns->soinfo_list();
-  soinfo::soinfo_list_t::iterator start = soinfo_list.begin();
+  auto& soinfo_list = ns->soinfo_list();
+  auto start = soinfo_list.begin();
 
   if (handle == RTLD_NEXT) {
     if (caller == nullptr) {
       return nullptr;
     } else {
-      soinfo::soinfo_list_t::iterator it = soinfo_list.find(caller);
+      auto it = soinfo_list.find(caller);
       CHECK (it != soinfo_list.end());
       start = ++it;
     }
   }
 
   const ElfW(Sym)* s = nullptr;
-  for (soinfo::soinfo_list_t::iterator it = start, end = soinfo_list.end(); it != end; ++it) {
+  for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
     soinfo* si = *it;
     // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
     // if the library is opened by application with target api level <= 22
@@ -1382,6 +1406,7 @@
 
   if (OpenArchiveFd(fd, "", handle) != 0) {
     // invalid zip-file (?)
+    CloseArchive(handle);
     close(fd);
     return false;
   }
@@ -1633,7 +1658,7 @@
     if (si == nullptr) {
       si = g_public_namespace.find_if(predicate);
       if (si != nullptr) {
-        ns->soinfo_list().push_back(si);
+        ns->add_soinfo(si);
       }
     }
 
@@ -1807,7 +1832,7 @@
     });
 
     if (candidate != nullptr) {
-      ns->soinfo_list().push_back(candidate);
+      ns->add_soinfo(candidate);
       task->set_soinfo(candidate);
       return true;
     }
@@ -2174,7 +2199,7 @@
   parse_LD_LIBRARY_PATH(ld_library_path);
 }
 
-soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo,
+void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo,
                   void* caller_addr) {
   soinfo* const caller = find_containing_library(caller_addr);
 
@@ -2218,9 +2243,10 @@
   soinfo* si = find_library(ns, name, flags, extinfo, caller);
   if (si != nullptr) {
     si->call_constructors();
+    return si->to_handle();
   }
 
-  return si;
+  return nullptr;
 }
 
 int do_dladdr(const void* addr, Dl_info* info) {
@@ -2246,6 +2272,19 @@
   return 1;
 }
 
+static soinfo* soinfo_from_handle(void* handle) {
+  if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
+    auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
+    if (it == g_soinfo_handles_map.end()) {
+      return nullptr;
+    } else {
+      return it->second;
+    }
+  }
+
+  return static_cast<soinfo*>(handle);
+}
+
 bool do_dlsym(void* handle, const char* sym_name, const char* sym_ver,
               void* caller_addr, void** symbol) {
 #if !defined(__LP64__)
@@ -2277,7 +2316,12 @@
   if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
     sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
   } else {
-    sym = dlsym_handle_lookup(reinterpret_cast<soinfo*>(handle), &found, sym_name, vi);
+    soinfo* si = soinfo_from_handle(handle);
+    if (si == nullptr) {
+      DL_ERR("dlsym failed: invalid handle: %p", handle);
+      return false;
+    }
+    sym = dlsym_handle_lookup(si, &found, sym_name, vi);
   }
 
   if (sym != nullptr) {
@@ -2296,9 +2340,16 @@
   return false;
 }
 
-void do_dlclose(soinfo* si) {
+int do_dlclose(void* handle) {
   ProtectedDataGuard guard;
+  soinfo* si = soinfo_from_handle(handle);
+  if (si == nullptr) {
+    DL_ERR("invalid handle: %p", handle);
+    return -1;
+  }
+
   soinfo_unload(si);
+  return 0;
 }
 
 bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path) {
@@ -2385,12 +2436,10 @@
 
   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
     // If shared - clone the caller namespace
-    auto& soinfo_list = caller_ns->soinfo_list();
-    std::copy(soinfo_list.begin(), soinfo_list.end(), std::back_inserter(ns->soinfo_list()));
+    ns->add_soinfos(caller_ns->soinfo_list());
   } else {
     // If not shared - copy only the global group
-    auto global_group = make_global_group(caller_ns);
-    std::copy(global_group.begin(), global_group.end(), std::back_inserter(ns->soinfo_list()));
+    ns->add_soinfos(make_global_group(caller_ns));
   }
 
   return ns;
@@ -3234,6 +3283,39 @@
   return local_group_root_->target_sdk_version_;
 }
 
+uintptr_t soinfo::get_handle() const {
+  CHECK(has_min_version(3));
+  CHECK(handle_ != 0);
+  return handle_;
+}
+
+void* soinfo::to_handle() {
+  if (get_application_target_sdk_version() <= 23 || !has_min_version(3)) {
+    return this;
+  }
+
+  return reinterpret_cast<void*>(get_handle());
+}
+
+void soinfo::generate_handle() {
+  CHECK(has_min_version(3));
+  CHECK(handle_ == 0); // Make sure this is the first call
+
+  // Make sure the handle is unique and does not collide
+  // with special values which are RTLD_DEFAULT and RTLD_NEXT.
+  do {
+    arc4random_buf(&handle_, sizeof(handle_));
+    // the least significant bit for the handle is always 1
+    // making it easy to test the type of handle passed to
+    // dl* functions.
+    handle_ = handle_ | 1;
+  } while (handle_ == reinterpret_cast<uintptr_t>(RTLD_DEFAULT) ||
+           handle_ == reinterpret_cast<uintptr_t>(RTLD_NEXT) ||
+           g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());
+
+  g_soinfo_handles_map[handle_] = this;
+}
+
 bool soinfo::prelink_image() {
   /* Extract dynamic section */
   ElfW(Word) dynamic_flags = 0;
@@ -3787,10 +3869,9 @@
   }
 #endif
 
-  /* We can also turn on GNU RELRO protection */
-  if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
-    DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
-           get_realpath(), strerror(errno));
+  // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
+  // itself --- it can't make system calls yet, and will have to call protect_relro later.
+  if (!is_linker() && !protect_relro()) {
     return false;
   }
 
@@ -3815,6 +3896,15 @@
   return true;
 }
 
+bool soinfo::protect_relro() {
+  if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
+    DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
+           get_realpath(), strerror(errno));
+    return false;
+  }
+  return true;
+}
+
 /*
  * This function add vdso to internal dso list.
  * It helps to stack unwinding through signal handlers.
@@ -4117,8 +4207,9 @@
   return 0;
 }
 
-extern "C" int __set_tls(void*);
-extern "C" void _start();
+static void __linker_cannot_link(KernelArgumentBlock& args) {
+  __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
+}
 
 /*
  * This is the entry point for the linker, called from begin.S. This
@@ -4132,9 +4223,6 @@
 extern "C" ElfW(Addr) __linker_init(void* raw_args) {
   KernelArgumentBlock args(raw_args);
 
-  void* tls[BIONIC_TLS_SLOTS];
-  __set_tls(tls);
-
   ElfW(Addr) linker_addr = args.getauxval(AT_BASE);
   ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
@@ -4163,18 +4251,33 @@
   linker_so.phnum = elf_hdr->e_phnum;
   linker_so.set_linker_flag();
 
+  // Prelink the linker so we can access linker globals.
+  if (!linker_so.prelink_image()) __linker_cannot_link(args);
+
   // This might not be obvious... The reasons why we pass g_empty_list
   // in place of local_group here are (1) we do not really need it, because
   // linker is built with DT_SYMBOLIC and therefore relocates its symbols against
   // itself without having to look into local_group and (2) allocators
   // are not yet initialized, and therefore we cannot use linked_list.push_*
   // functions at this point.
-  if (!(linker_so.prelink_image() && linker_so.link_image(g_empty_list, g_empty_list, nullptr))) {
-    __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
-  }
+  if (!linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args);
 
+#if defined(__i386__)
+  // On x86, we can't make system calls before this point.
+  // We can't move this up because this needs to assign to a global.
+  // Note that until we call __libc_init_main_thread below we have
+  // no TLS, so you shouldn't make a system call that can fail, because
+  // it will SEGV when it tries to set errno.
+  __libc_init_sysinfo(args);
+#endif
+
+  // Initialize the main thread (including TLS, so system calls really work).
   __libc_init_main_thread(args);
 
+  // We didn't protect the linker's RELRO pages in link_image because we
+  // couldn't make system calls on x86 at that point, but we can now...
+  if (!linker_so.protect_relro()) __linker_cannot_link(args);
+
   // Initialize the linker's static libc's globals
   __libc_init_globals(args);
 
@@ -4186,7 +4289,7 @@
   // before get_libdl_info().
   solist = get_libdl_info();
   sonext = get_libdl_info();
-  g_default_namespace.soinfo_list().push_back(get_libdl_info());
+  g_default_namespace.add_soinfo(get_libdl_info());
 
   // We have successfully fixed our own relocations. It's safe to run
   // the main part of the linker now.
diff --git a/linker/linker.h b/linker/linker.h
index d364021..81f93ac 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -268,6 +268,7 @@
  public:
   soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
          off64_t file_offset, int rtld_flags);
+  ~soinfo();
 
   void call_constructors();
   void call_destructors();
@@ -275,6 +276,7 @@
   bool prelink_image();
   bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
                   const android_dlextinfo* extinfo);
+  bool protect_relro();
 
   void add_child(soinfo* child);
   void remove_all_links();
@@ -345,6 +347,10 @@
   void set_mapped_by_caller(bool reserved_map);
   bool is_mapped_by_caller() const;
 
+  uintptr_t get_handle() const;
+  void generate_handle();
+  void* to_handle();
+
  private:
   bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
   ElfW(Sym)* elf_addr_lookup(const void* addr);
@@ -409,6 +415,7 @@
   // version >= 3
   std::vector<std::string> dt_runpath_;
   android_namespace_t* namespace_;
+  uintptr_t handle_;
 
   friend soinfo* get_libdl_info();
 };
@@ -431,8 +438,8 @@
 
 void do_android_get_LD_LIBRARY_PATH(char*, size_t);
 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
-soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, void* caller_addr);
-void do_dlclose(soinfo* si);
+void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, void* caller_addr);
+int do_dlclose(void* handle);
 
 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
 
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 47964f6..710912a 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -17,244 +17,294 @@
 #include <gtest/gtest.h>
 
 // libc++ actively gets in the way of including <complex.h> from C++, so we
-// have to declare the complex math functions ourselves.
+// have to be naughty.
+#include <../libm/include/complex.h>
+
 // (libc++ also seems to have really bad implementations of its own that ignore
 // the intricacies of floating point math.)
 // http://llvm.org/bugs/show_bug.cgi?id=21504
 
-#include <math.h> // For M_PI.
+#include <math.h> // For M_PI_2/M_PI_2l.
 
-extern "C" double cabs(double _Complex);
+// Note that gtest doesn't support complex numbers, so the output from
+// assertion failures is misleading/useless (at best you'll only see the real
+// part).
+// TODO: find out why gtest doesn't use these; until then they're only useful
+// for manual printf^Woperator<< debugging.
+#include <iostream>
+std::ostream& operator<<(std::ostream& os, const double _Complex c) {
+  os << "(" << creal(c) << "," << cimag(c) << "i)";
+ return os;
+}
+std::ostream& operator<<(std::ostream& os, const float _Complex c) {
+  os << "(" << crealf(c) << "," << cimagf(c) << "i)";
+  return os;
+}
+std::ostream& operator<<(std::ostream& os, const long double _Complex c) {
+  os << "(" << creall(c) << "," << cimagl(c) << "i)";
+  return os;
+}
+
 TEST(complex, cabs) {
   ASSERT_EQ(0.0, cabs(0));
 }
 
-extern "C" float cabsf(float _Complex);
 TEST(complex, cabsf) {
   ASSERT_EQ(0.0, cabsf(0));
 }
 
-extern "C" long double cabsl(long double _Complex);
 TEST(complex, cabsl) {
   ASSERT_EQ(0.0, cabsl(0));
 }
 
-extern "C" double _Complex cacos(double _Complex);
 TEST(complex, cacos) {
-  ASSERT_EQ(M_PI/2.0, cacos(0.0));
+  ASSERT_EQ(M_PI_2, cacos(0.0));
 }
 
-extern "C" float _Complex cacosf(float _Complex);
 TEST(complex, cacosf) {
-  ASSERT_EQ(static_cast<float>(M_PI)/2.0f, cacosf(0.0));
+  ASSERT_EQ(static_cast<float>(M_PI_2), cacosf(0.0));
 }
 
-extern "C" double _Complex cacosh(double _Complex);
+TEST(complex, cacosl) {
+  ASSERT_EQ(M_PI_2l, cacosl(0.0));
+}
+
 TEST(complex, cacosh) {
   ASSERT_EQ(0.0, cacosh(1.0));
 }
 
-extern "C" float _Complex cacoshf(float _Complex);
+TEST(complex, cacoshl) {
+  ASSERT_EQ(0.0, cacoshl(1.0));
+}
+
 TEST(complex, cacoshf) {
   ASSERT_EQ(0.0, cacoshf(1.0));
 }
 
-extern "C" double carg(double _Complex);
 TEST(complex, carg) {
   ASSERT_EQ(0.0, carg(0));
 }
 
-extern "C" float cargf(float _Complex);
 TEST(complex, cargf) {
   ASSERT_EQ(0.0, cargf(0));
 }
 
-extern "C" long double cargl(long double _Complex);
 TEST(complex, cargl) {
   ASSERT_EQ(0.0, cargl(0));
 }
 
-extern "C" double _Complex casin(double _Complex);
 TEST(complex, casin) {
   ASSERT_EQ(0.0, casin(0));
 }
 
-extern "C" float _Complex casinf(float _Complex);
 TEST(complex, casinf) {
   ASSERT_EQ(0.0, casinf(0));
 }
 
-extern "C" double _Complex casinh(double _Complex);
+TEST(complex, casinl) {
+  ASSERT_EQ(0.0, casinl(0));
+}
+
 TEST(complex, casinh) {
   ASSERT_EQ(0.0, casinh(0));
 }
 
-extern "C" float _Complex casinhf(float _Complex);
 TEST(complex, casinhf) {
   ASSERT_EQ(0.0, casinhf(0));
 }
 
-extern "C" double _Complex catan(double _Complex);
+TEST(complex, casinhl) {
+  ASSERT_EQ(0.0, casinhl(0));
+}
+
 TEST(complex, catan) {
   ASSERT_EQ(0.0, catan(0));
 }
 
-extern "C" float _Complex catanf(float _Complex);
 TEST(complex, catanf) {
   ASSERT_EQ(0.0, catanf(0));
 }
 
-extern "C" double _Complex catanh(double _Complex);
+TEST(complex, catanl) {
+  ASSERT_EQ(0.0, catanl(0));
+}
+
 TEST(complex, catanh) {
   ASSERT_EQ(0.0, catanh(0));
 }
 
-extern "C" float _Complex catanhf(float _Complex);
 TEST(complex, catanhf) {
   ASSERT_EQ(0.0, catanhf(0));
 }
 
-extern "C" double _Complex ccos(double _Complex);
+TEST(complex, catanhl) {
+  ASSERT_EQ(0.0, catanhl(0));
+}
+
 TEST(complex, ccos) {
   ASSERT_EQ(1.0, ccos(0));
 }
 
-extern "C" float _Complex ccosf(float _Complex);
 TEST(complex, ccosf) {
   ASSERT_EQ(1.0, ccosf(0));
 }
 
-extern "C" double _Complex ccosh(double _Complex);
+TEST(complex, ccosl) {
+  ASSERT_EQ(1.0, ccosl(0));
+}
+
 TEST(complex, ccosh) {
   ASSERT_EQ(1.0, ccosh(0));
 }
 
-extern "C" float _Complex ccoshf(float _Complex);
 TEST(complex, ccoshf) {
   ASSERT_EQ(1.0, ccoshf(0));
 }
 
-extern "C" double _Complex cexp(double _Complex);
+TEST(complex, ccoshl) {
+  ASSERT_EQ(1.0, ccoshl(0));
+}
+
 TEST(complex, cexp) {
   ASSERT_EQ(1.0, cexp(0));
 }
 
-extern "C" float _Complex cexpf(float _Complex);
 TEST(complex, cexpf) {
   ASSERT_EQ(1.0, cexpf(0));
 }
 
-extern "C" double cimag(double _Complex);
+TEST(complex, cexpl) {
+  ASSERT_EQ(1.0, cexpl(0));
+}
+
 TEST(complex, cimag) {
   ASSERT_EQ(0.0, cimag(0));
 }
 
-extern "C" float cimagf(float _Complex);
 TEST(complex, cimagf) {
   ASSERT_EQ(0.0f, cimagf(0));
 }
 
-extern "C" long double cimagl(long double _Complex);
 TEST(complex, cimagl) {
   ASSERT_EQ(0.0, cimagl(0));
 }
 
-extern "C" double _Complex conj(double _Complex);
+TEST(complex, clog) {
+  ASSERT_EQ(0.0, clog(1.0));
+}
+
+TEST(complex, clogf) {
+  ASSERT_EQ(0.0f, clogf(1.0f));
+}
+
+TEST(complex, clogl) {
+  ASSERT_EQ(0.0L, clogl(1.0L));
+}
+
 TEST(complex, conj) {
   ASSERT_EQ(0.0, conj(0));
 }
 
-extern "C" float _Complex conjf(float _Complex);
 TEST(complex, conjf) {
   ASSERT_EQ(0.0f, conjf(0));
 }
 
-extern "C" long double _Complex conjl(long double _Complex);
 TEST(complex, conjl) {
   ASSERT_EQ(0.0, conjl(0));
 }
 
-extern "C" double _Complex cproj(double _Complex);
+TEST(complex, cpow) {
+  ASSERT_EQ(8.0, cpow(2.0, 3.0));
+}
+
+TEST(complex, cpowf) {
+  ASSERT_EQ(8.0f, cpowf(2.0f, 3.0f));
+}
+
+TEST(complex, cpowl) {
+  ASSERT_EQ(8.0L, cpowl(2.0L, 3.0L));
+}
+
 TEST(complex, cproj) {
   ASSERT_EQ(0.0, cproj(0));
 }
 
-extern "C" float _Complex cprojf(float _Complex);
 TEST(complex, cprojf) {
   ASSERT_EQ(0.0f, cprojf(0));
 }
 
-extern "C" long double _Complex cprojl(long double _Complex);
 TEST(complex, cprojl) {
   ASSERT_EQ(0.0, cprojl(0));
 }
 
-extern "C" double creal(double _Complex);
 TEST(complex, creal) {
-  ASSERT_EQ(0.0, creal(0));
+  ASSERT_EQ(2.0, creal(2.0 + 3.0I));
 }
 
-extern "C" float crealf(float _Complex);
 TEST(complex, crealf) {
-  ASSERT_EQ(0.0f, crealf(0));
+  ASSERT_EQ(2.0f, crealf(2.0f + 3.0fI));
 }
 
-extern "C" long double creall(long double _Complex);
 TEST(complex, creall) {
-  ASSERT_EQ(0.0, creall(0));
+  ASSERT_EQ(2.0, creall(2.0L + 3.0LI));
 }
 
-extern "C" double _Complex csin(double _Complex);
 TEST(complex, csin) {
   ASSERT_EQ(0.0, csin(0));
 }
 
-extern "C" float _Complex csinf(float _Complex);
 TEST(complex, csinf) {
   ASSERT_EQ(0.0, csinf(0));
 }
 
-extern "C" double _Complex csinh(double _Complex);
+TEST(complex, csinl) {
+  ASSERT_EQ(0.0, csinl(0));
+}
+
 TEST(complex, csinh) {
   ASSERT_EQ(0.0, csinh(0));
 }
 
-extern "C" float _Complex csinhf(float _Complex);
 TEST(complex, csinhf) {
   ASSERT_EQ(0.0, csinhf(0));
 }
 
-extern "C" double _Complex csqrt(double _Complex);
+TEST(complex, csinhl) {
+  ASSERT_EQ(0.0, csinhl(0));
+}
+
 TEST(complex, csqrt) {
   ASSERT_EQ(0.0, csqrt(0));
 }
 
-extern "C" float _Complex csqrtf(float _Complex);
 TEST(complex, csqrtf) {
   ASSERT_EQ(0.0f, csqrt(0));
 }
 
-extern "C" long double _Complex csqrtl(long double _Complex);
 TEST(complex, csqrtl) {
   ASSERT_EQ(0.0, csqrtl(0));
 }
 
-extern "C" double _Complex ctan(double _Complex);
 TEST(complex, ctan) {
   ASSERT_EQ(0.0, ctan(0));
 }
 
-extern "C" float _Complex ctanf(float _Complex);
 TEST(complex, ctanf) {
   ASSERT_EQ(0.0, ctanf(0));
 }
 
-extern "C" double _Complex ctanh(double _Complex);
+TEST(complex, ctanl) {
+  ASSERT_EQ(0.0, ctanl(0));
+}
+
 TEST(complex, ctanh) {
   ASSERT_EQ(0.0, ctanh(0));
 }
 
-extern "C" float _Complex ctanhf(float _Complex);
 TEST(complex, ctanhf) {
   ASSERT_EQ(0.0, ctanhf(0));
 }
+
+TEST(complex, ctanhl) {
+  ASSERT_EQ(0.0, ctanhl(0));
+}
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 66d8859..bbdc024 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1050,3 +1050,19 @@
 
   ASSERT_TRUE(ns_get_dlopened_string_anon() != ns_get_dlopened_string_private());
 }
+
+TEST(dlext, dlopen_handle_value_platform) {
+  void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
+  ASSERT_TRUE((reinterpret_cast<uintptr_t>(handle) & 1) != 0)
+          << "dlopen should return odd value for the handle";
+  dlclose(handle);
+}
+
+TEST(dlext, dlopen_handle_value_app_compat) {
+  android_set_application_target_sdk_version(23);
+  void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
+  ASSERT_TRUE(reinterpret_cast<uintptr_t>(handle) % sizeof(uintptr_t) == 0)
+          << "dlopen should return valid pointer";
+  dlclose(handle);
+}
+
diff --git a/tests/getauxval_test.cpp b/tests/getauxval_test.cpp
index 6ce00f1..63bc963 100644
--- a/tests/getauxval_test.cpp
+++ b/tests/getauxval_test.cpp
@@ -16,6 +16,7 @@
 
 #include <errno.h>
 #include <sys/cdefs.h>
+#include <sys/utsname.h>
 #include <gtest/gtest.h>
 
 // getauxval() was only added as of glibc version 2.16.
@@ -36,28 +37,51 @@
 
 TEST(getauxval, expected_values) {
 #if defined(GETAUXVAL_CAN_COMPILE)
-  ASSERT_EQ((unsigned long int) 0, getauxval(AT_SECURE));
+  ASSERT_EQ(0UL, getauxval(AT_SECURE));
   ASSERT_EQ(getuid(), getauxval(AT_UID));
   ASSERT_EQ(geteuid(), getauxval(AT_EUID));
   ASSERT_EQ(getgid(), getauxval(AT_GID));
   ASSERT_EQ(getegid(), getauxval(AT_EGID));
-  ASSERT_EQ((unsigned long int) getpagesize(), getauxval(AT_PAGESZ));
+  ASSERT_EQ(static_cast<unsigned long>(getpagesize()), getauxval(AT_PAGESZ));
 
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PHDR));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PHNUM));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_ENTRY));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PAGESZ));
+  ASSERT_NE(0UL, getauxval(AT_PHDR));
+  ASSERT_NE(0UL, getauxval(AT_PHNUM));
+  ASSERT_NE(0UL, getauxval(AT_ENTRY));
+  ASSERT_NE(0UL, getauxval(AT_PAGESZ));
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
 #endif
 }
 
 TEST(getauxval, unexpected_values) {
 #if defined(GETAUXVAL_CAN_COMPILE)
   errno = 0;
-  ASSERT_EQ((unsigned long int) 0, getauxval(0xdeadbeef));
+  ASSERT_EQ(0UL, getauxval(0xdeadbeef));
   ASSERT_EQ(ENOENT, errno);
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
 #endif
 }
+
+TEST(getauxval, arm_has_AT_HWCAP2) {
+#if defined(__arm__)
+  // There are no known 32-bit processors that implement any of these instructions, so rather
+  // than require that OEMs backport kernel patches, let's just ignore old hardware. Strictly
+  // speaking this would be fooled by someone choosing to ship a 32-bit kernel on 64-bit hardware,
+  // but that doesn't seem very likely in 2016.
+  utsname u;
+  ASSERT_EQ(0, uname(&u));
+  if (strcmp(u.machine, "aarch64") == 0) {
+    // If this test fails, apps that use getauxval to decide at runtime whether crypto hardware is
+    // available will incorrectly assume that it isn't, and will have really bad performance.
+    // If this test fails, ensure that you've enabled COMPAT_BINFMT_ELF in your kernel configuration.
+    // Note that 0 ("I don't support any of these things") is a legitimate response --- we need
+    // to check errno to see whether we got a "true" 0 or a "not found" 0.
+    errno = 0;
+    getauxval(AT_HWCAP2);
+    ASSERT_EQ(0, errno) << "64-bit kernel not reporting AT_HWCAP2 to 32-bit ARM process";
+    return;
+  }
+#endif
+  GTEST_LOG_(INFO) << "This test is only meaningful for 32-bit ARM code on 64-bit devices.\n";
+}
diff --git a/tests/libs/bionic_tests_zipalign.cpp b/tests/libs/bionic_tests_zipalign.cpp
index dbbfd7c..a72820f 100644
--- a/tests/libs/bionic_tests_zipalign.cpp
+++ b/tests/libs/bionic_tests_zipalign.cpp
@@ -138,6 +138,7 @@
 
   int32_t return_value = OpenArchive(argv[2], &handle);
   if (return_value != 0) {
+    CloseArchive(handle);
     fprintf(stderr, "Unable to open '%s': %s\n", argv[2], ErrorCodeString(return_value));
     return false;
   }
diff --git a/tests/mntent_test.cpp b/tests/mntent_test.cpp
index a102849..3fb2f86 100644
--- a/tests/mntent_test.cpp
+++ b/tests/mntent_test.cpp
@@ -38,3 +38,20 @@
 
   ASSERT_EQ(1, endmntent(fp));
 }
+
+TEST(mntent, hasmntopt) {
+  // indices                  1  1
+  // of keys:      0    5   9 1  4
+  char mnt_opts[]{"aa=b,a=b,b,bb,c=d"};
+  struct mntent ent;
+  memset(&ent, 0, sizeof(ent));
+  ent.mnt_opts = mnt_opts;
+
+  EXPECT_EQ(mnt_opts, hasmntopt(&ent, "aa"));
+  EXPECT_EQ(mnt_opts + 5, hasmntopt(&ent, "a"));
+  EXPECT_EQ(mnt_opts + 9, hasmntopt(&ent, "b"));
+  EXPECT_EQ(mnt_opts + 11, hasmntopt(&ent, "bb"));
+  EXPECT_EQ(mnt_opts + 14, hasmntopt(&ent, "c"));
+  EXPECT_EQ(nullptr, hasmntopt(&ent, "d"));
+  EXPECT_EQ(nullptr, hasmntopt(&ent, "e"));
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index aab78ad..019016d 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -260,10 +260,10 @@
 }
 
 TEST(pthread, pthread_no_join_after_detach) {
-  SpinFunctionHelper spinhelper;
+  SpinFunctionHelper spin_helper;
 
   pthread_t t1;
-  ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
+  ASSERT_EQ(0, pthread_create(&t1, NULL, spin_helper.GetFunction(), NULL));
 
   // After a pthread_detach...
   ASSERT_EQ(0, pthread_detach(t1));
@@ -274,10 +274,10 @@
 }
 
 TEST(pthread, pthread_no_op_detach_after_join) {
-  SpinFunctionHelper spinhelper;
+  SpinFunctionHelper spin_helper;
 
   pthread_t t1;
-  ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
+  ASSERT_EQ(0, pthread_create(&t1, NULL, spin_helper.GetFunction(), NULL));
 
   // If thread 2 is already waiting to join thread 1...
   pthread_t t2;
@@ -292,7 +292,7 @@
 #endif
   AssertDetached(t1, false);
 
-  spinhelper.UnSpin();
+  spin_helper.UnSpin();
 
   // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
   void* join_result;
@@ -396,32 +396,46 @@
   ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL));
 }
 
-TEST(pthread, pthread_setname_np__too_long) {
+static void test_pthread_setname_np__pthread_getname_np(pthread_t t) {
+  ASSERT_EQ(0, pthread_setname_np(t, "short"));
+  char name[32];
+  ASSERT_EQ(0, pthread_getname_np(t, name, sizeof(name)));
+  ASSERT_STREQ("short", name);
+
   // The limit is 15 characters --- the kernel's buffer is 16, but includes a NUL.
-  ASSERT_EQ(0, pthread_setname_np(pthread_self(), "123456789012345"));
-  ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "1234567890123456"));
+  ASSERT_EQ(0, pthread_setname_np(t, "123456789012345"));
+  ASSERT_EQ(0, pthread_getname_np(t, name, sizeof(name)));
+  ASSERT_STREQ("123456789012345", name);
+
+  ASSERT_EQ(ERANGE, pthread_setname_np(t, "1234567890123456"));
+
+  // The passed-in buffer should be at least 16 bytes.
+  ASSERT_EQ(0, pthread_getname_np(t, name, 16));
+  ASSERT_EQ(ERANGE, pthread_getname_np(t, name, 15));
 }
 
-TEST(pthread, pthread_setname_np__self) {
-  ASSERT_EQ(0, pthread_setname_np(pthread_self(), "short 1"));
+TEST(pthread, pthread_setname_np__pthread_getname_np__self) {
+  test_pthread_setname_np__pthread_getname_np(pthread_self());
 }
 
-TEST(pthread, pthread_setname_np__other) {
-  SpinFunctionHelper spinhelper;
+TEST(pthread, pthread_setname_np__pthread_getname_np__other) {
+  SpinFunctionHelper spin_helper;
 
-  pthread_t t1;
-  ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
-  ASSERT_EQ(0, pthread_setname_np(t1, "short 2"));
-  spinhelper.UnSpin();
-  ASSERT_EQ(0, pthread_join(t1, nullptr));
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, NULL, spin_helper.GetFunction(), NULL));
+  test_pthread_setname_np__pthread_getname_np(t);
+  spin_helper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
 }
 
-TEST(pthread, pthread_setname_np__no_such_thread) {
+TEST(pthread, pthread_setname_np__pthread_getname_np__no_such_thread) {
   pthread_t dead_thread;
   MakeDeadThread(dead_thread);
 
-  // Call pthread_setname_np after thread has already exited.
+  // Call pthread_getname_np and pthread_setname_np after the thread has already exited.
   ASSERT_EQ(ENOENT, pthread_setname_np(dead_thread, "short 3"));
+  char name[64];
+  ASSERT_EQ(ENOENT, pthread_getname_np(dead_thread, name, sizeof(name)));
 }
 
 TEST(pthread, pthread_kill__0) {
@@ -455,16 +469,16 @@
 }
 
 TEST(pthread, pthread_getcpuclockid__clock_gettime) {
-  SpinFunctionHelper spinhelper;
+  SpinFunctionHelper spin_helper;
 
   pthread_t t;
-  ASSERT_EQ(0, pthread_create(&t, NULL, spinhelper.GetFunction(), NULL));
+  ASSERT_EQ(0, pthread_create(&t, NULL, spin_helper.GetFunction(), NULL));
 
   clockid_t c;
   ASSERT_EQ(0, pthread_getcpuclockid(t, &c));
   timespec ts;
   ASSERT_EQ(0, clock_gettime(c, &ts));
-  spinhelper.UnSpin();
+  spin_helper.UnSpin();
   ASSERT_EQ(0, pthread_join(t, nullptr));
 }
 
@@ -509,10 +523,10 @@
 }
 
 TEST(pthread, pthread_join__multijoin) {
-  SpinFunctionHelper spinhelper;
+  SpinFunctionHelper spin_helper;
 
   pthread_t t1;
-  ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
+  ASSERT_EQ(0, pthread_create(&t1, NULL, spin_helper.GetFunction(), NULL));
 
   pthread_t t2;
   ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1)));
@@ -522,7 +536,7 @@
   // Multiple joins to the same thread should fail.
   ASSERT_EQ(EINVAL, pthread_join(t1, NULL));
 
-  spinhelper.UnSpin();
+  spin_helper.UnSpin();
 
   // ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
   void* join_result;
@@ -1818,55 +1832,82 @@
   ASSERT_EQ(0, pthread_barrierattr_destroy(&attr));
 }
 
-struct BarrierTestHelperArg {
-  std::atomic<pid_t> tid;
-  pthread_barrier_t* barrier;
+struct BarrierTestHelperData {
+  size_t thread_count;
+  pthread_barrier_t barrier;
+  std::atomic<int> finished_mask;
+  std::atomic<int> serial_thread_count;
   size_t iteration_count;
+  std::atomic<size_t> finished_iteration_count;
+
+  BarrierTestHelperData(size_t thread_count, size_t iteration_count)
+      : thread_count(thread_count), finished_mask(0), serial_thread_count(0),
+        iteration_count(iteration_count), finished_iteration_count(0) {
+  }
+};
+
+struct BarrierTestHelperArg {
+  int id;
+  BarrierTestHelperData* data;
 };
 
 static void BarrierTestHelper(BarrierTestHelperArg* arg) {
-  arg->tid = gettid();
-  for (size_t i = 0; i < arg->iteration_count; ++i) {
-    ASSERT_EQ(0, pthread_barrier_wait(arg->barrier));
+  for (size_t i = 0; i < arg->data->iteration_count; ++i) {
+    int result = pthread_barrier_wait(&arg->data->barrier);
+    if (result == PTHREAD_BARRIER_SERIAL_THREAD) {
+      arg->data->serial_thread_count++;
+    } else {
+      ASSERT_EQ(0, result);
+    }
+    arg->data->finished_mask |= (1 << arg->id);
+    if (arg->data->finished_mask == ((1 << arg->data->thread_count) - 1)) {
+      ASSERT_EQ(1, arg->data->serial_thread_count);
+      arg->data->finished_iteration_count++;
+      arg->data->finished_mask = 0;
+      arg->data->serial_thread_count = 0;
+    }
   }
 }
 
 TEST(pthread, pthread_barrier_smoke) {
   const size_t BARRIER_ITERATION_COUNT = 10;
   const size_t BARRIER_THREAD_COUNT = 10;
-  pthread_barrier_t barrier;
-  ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, BARRIER_THREAD_COUNT + 1));
-  std::vector<pthread_t> threads(BARRIER_THREAD_COUNT);
+  BarrierTestHelperData data(BARRIER_THREAD_COUNT, BARRIER_ITERATION_COUNT);
+  ASSERT_EQ(0, pthread_barrier_init(&data.barrier, nullptr, data.thread_count));
+  std::vector<pthread_t> threads(data.thread_count);
   std::vector<BarrierTestHelperArg> args(threads.size());
   for (size_t i = 0; i < threads.size(); ++i) {
-    args[i].tid = 0;
-    args[i].barrier = &barrier;
-    args[i].iteration_count = BARRIER_ITERATION_COUNT;
+    args[i].id = i;
+    args[i].data = &data;
     ASSERT_EQ(0, pthread_create(&threads[i], nullptr,
                                 reinterpret_cast<void* (*)(void*)>(BarrierTestHelper), &args[i]));
   }
-  for (size_t iteration = 0; iteration < BARRIER_ITERATION_COUNT; ++iteration) {
-    for (size_t i = 0; i < threads.size(); ++i) {
-      WaitUntilThreadSleep(args[i].tid);
-    }
-    ASSERT_EQ(PTHREAD_BARRIER_SERIAL_THREAD, pthread_barrier_wait(&barrier));
-  }
   for (size_t i = 0; i < threads.size(); ++i) {
     ASSERT_EQ(0, pthread_join(threads[i], nullptr));
   }
-  ASSERT_EQ(0, pthread_barrier_destroy(&barrier));
+  ASSERT_EQ(data.iteration_count, data.finished_iteration_count);
+  ASSERT_EQ(0, pthread_barrier_destroy(&data.barrier));
+}
+
+struct BarrierDestroyTestArg {
+  std::atomic<int> tid;
+  pthread_barrier_t* barrier;
+};
+
+static void BarrierDestroyTestHelper(BarrierDestroyTestArg* arg) {
+  arg->tid = gettid();
+  ASSERT_EQ(0, pthread_barrier_wait(arg->barrier));
 }
 
 TEST(pthread, pthread_barrier_destroy) {
   pthread_barrier_t barrier;
   ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, 2));
   pthread_t thread;
-  BarrierTestHelperArg arg;
+  BarrierDestroyTestArg arg;
   arg.tid = 0;
   arg.barrier = &barrier;
-  arg.iteration_count = 1;
   ASSERT_EQ(0, pthread_create(&thread, nullptr,
-                              reinterpret_cast<void* (*)(void*)>(BarrierTestHelper), &arg));
+                              reinterpret_cast<void* (*)(void*)>(BarrierDestroyTestHelper), &arg));
   WaitUntilThreadSleep(arg.tid);
   ASSERT_EQ(EBUSY, pthread_barrier_destroy(&barrier));
   ASSERT_EQ(PTHREAD_BARRIER_SERIAL_THREAD, pthread_barrier_wait(&barrier));
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index caf4c65..92d6c26 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -21,12 +21,12 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#if defined(__BIONIC__)
 static int child_fn(void* i_ptr) {
   *reinterpret_cast<int*>(i_ptr) = 42;
   return 123;
 }
 
+#if defined(__BIONIC__)
 TEST(sched, clone) {
   void* child_stack[1024];
 
@@ -59,6 +59,13 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
+TEST(sched, clone_null_child_stack) {
+  int i = 0;
+  errno = 0;
+  ASSERT_EQ(-1, clone(child_fn, nullptr, CLONE_VM, &i));
+  ASSERT_EQ(EINVAL, errno);
+}
+
 TEST(sched, cpu_set) {
   cpu_set_t set;
 
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index b7e856f..bb01601 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -254,7 +254,7 @@
 
   if (value == 0) {
     // Flip a bit.
-    reinterpret_cast<long*>(jb)[0] ^= 1;
+    reinterpret_cast<long*>(jb)[1] ^= 1;
 
     EXPECT_DEATH(longjmp(jb, 1), "checksum mismatch");
   } else {
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 8c1e834..c5128ea 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -387,13 +387,15 @@
     "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
   static siginfo received;
 
-  struct sigaction handler = {};
+  struct sigaction handler;
+  memset(&handler, 0, sizeof(handler));
   handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
   handler.sa_flags = SA_SIGINFO;
 
   ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
 
-  siginfo sent = {};
+  siginfo sent;
+  memset(&sent, 0, sizeof(sent));
 
   sent.si_code = SI_TKILL;
   ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
@@ -409,4 +411,14 @@
                                             << sent.si_code << ", received " << received.si_code
                                             << error_msg;
 }
+
+#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+TEST(signal, sigset_size) {
+  // The setjmp implementations for ARM, AArch64, x86, and x86_64 assume that sigset_t can fit in a
+  // long. This is true because ARM and x86 have broken rt signal support, and AArch64 and x86_64
+  // both have a SIGRTMAX defined as 64.
+  static_assert(sizeof(sigset_t) <= sizeof(long), "sigset_t doesn't fit in a long");
+}
+
+#endif
 #endif
diff --git a/tests/stack_protector_test_helper.cpp b/tests/stack_protector_test_helper.cpp
index 34f3c77..53a5e05 100644
--- a/tests/stack_protector_test_helper.cpp
+++ b/tests/stack_protector_test_helper.cpp
@@ -19,6 +19,13 @@
   char buf[128];
   // We can't use memset here because it's fortified, and we want to test
   // the line of defense *after* that.
-  char* p = buf;
-  while ((p - buf) < static_cast<int>(sizeof(buf) + sizeof(void*))) *p++ = '\0';
+  // Without volatile, the generic x86/x86-64 targets don't write to the stack.
+  volatile char* p = buf;
+  int size = static_cast<int>(sizeof(buf) + 1);
+#if __x86_64__
+  // The generic x86-64 target leaves an 8-byte gap between `buf` and the stack guard.
+  // We only need to corrupt one byte though.
+  size += 8;
+#endif
+  while ((p - buf) < size) *p++ = '\0';
 }
diff --git a/tests/sys_epoll_test.cpp b/tests/sys_epoll_test.cpp
index 6e7a807..f6be4af 100644
--- a/tests/sys_epoll_test.cpp
+++ b/tests/sys_epoll_test.cpp
@@ -40,6 +40,12 @@
   ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, &ss));
 }
 
+TEST(sys_epoll, epoll_create_invalid_size) {
+  errno = 0;
+  ASSERT_EQ(-1, epoll_create(0));
+  ASSERT_EQ(EINVAL, errno);
+}
+
 TEST(sys_epoll, epoll_event_data) {
   int epoll_fd = epoll_create(1);
   ASSERT_NE(-1, epoll_fd) << strerror(errno);
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 6cdabd2..b1f6364 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -573,3 +573,10 @@
   timespec out;
   ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
 }
+
+TEST(time, clock_nanosleep_thread_cputime_id) {
+  timespec in;
+  in.tv_sec = 1;
+  in.tv_nsec = 0;
+  ASSERT_EQ(EINVAL, clock_nanosleep(CLOCK_THREAD_CPUTIME_ID, 0, &in, nullptr));
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 62e39fd..841641f 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <stdint.h>
+#include <sys/capability.h>
 #include <sys/param.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
@@ -57,14 +58,24 @@
 TEST(UNISTD_TEST, brk) {
   void* initial_break = get_brk();
 
-  // The kernel aligns the break to a page.
   void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
-  ASSERT_EQ(0, brk(new_break));
-  ASSERT_GE(get_brk(), new_break);
+  int ret = brk(new_break);
+  if (ret == -1) {
+    ASSERT_EQ(errno, ENOMEM);
+  } else {
+    ASSERT_EQ(0, ret);
+    ASSERT_GE(get_brk(), new_break);
+  }
 
+  // Expand by a full page to force the mapping to expand
   new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
-  ASSERT_EQ(0, brk(new_break));
-  ASSERT_EQ(get_brk(), new_break);
+  ret = brk(new_break);
+  if (ret == -1) {
+    ASSERT_EQ(errno, ENOMEM);
+  } else {
+    ASSERT_EQ(0, ret);
+    ASSERT_EQ(get_brk(), new_break);
+  }
 }
 
 TEST(UNISTD_TEST, brk_ENOMEM) {
@@ -986,3 +997,46 @@
   ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
   ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
 }
+
+TEST(UNISTD_TEST, getdomainname) {
+  struct utsname u;
+  ASSERT_EQ(0, uname(&u));
+
+  char buf[sizeof(u.domainname)];
+  ASSERT_EQ(0, getdomainname(buf, sizeof(buf)));
+  EXPECT_STREQ(u.domainname, buf);
+
+#if defined(__BIONIC__)
+  // bionic and glibc have different behaviors when len is too small
+  ASSERT_EQ(-1, getdomainname(buf, strlen(u.domainname)));
+  EXPECT_EQ(EINVAL, errno);
+#endif
+}
+
+TEST(UNISTD_TEST, setdomainname) {
+  __user_cap_header_struct header;
+  memset(&header, 0, sizeof(header));
+  header.version = _LINUX_CAPABILITY_VERSION_3;
+
+  __user_cap_data_struct old_caps[_LINUX_CAPABILITY_U32S_3];
+  ASSERT_EQ(0, capget(&header, &old_caps[0]));
+
+  auto admin_idx = CAP_TO_INDEX(CAP_SYS_ADMIN);
+  auto admin_mask = CAP_TO_MASK(CAP_SYS_ADMIN);
+  bool has_admin = old_caps[admin_idx].effective & admin_mask;
+  if (has_admin) {
+    __user_cap_data_struct new_caps[_LINUX_CAPABILITY_U32S_3];
+    memcpy(new_caps, old_caps, sizeof(new_caps));
+    new_caps[admin_idx].effective &= ~admin_mask;
+
+    ASSERT_EQ(0, capset(&header, &new_caps[0])) << "failed to drop admin privileges";
+  }
+
+  const char* name = "newdomainname";
+  ASSERT_EQ(-1, setdomainname(name, strlen(name)));
+  ASSERT_EQ(EPERM, errno);
+
+  if (has_admin) {
+    ASSERT_EQ(0, capset(&header, &old_caps[0])) << "failed to restore admin privileges";
+  }
+}
diff --git a/tools/relocation_packer/Android.mk b/tools/relocation_packer/Android.mk
index 2bf77b9..bdb54b7 100644
--- a/tools/relocation_packer/Android.mk
+++ b/tools/relocation_packer/Android.mk
@@ -31,13 +31,10 @@
   src/sleb128.cc \
 
 LOCAL_STATIC_LIBRARIES := libelf libz
-LOCAL_C_INCLUDES := external/elfutils/src/libelf
 LOCAL_MODULE := lib_relocation_packer
 
 LOCAL_CPPFLAGS := $(common_cppflags)
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -45,18 +42,15 @@
 LOCAL_CPP_EXTENSION := .cc
 
 LOCAL_SRC_FILES := src/main.cc
-LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf libz
+LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf libz libbase
 
 # Statically linking libc++ to make it work from prebuilts
 LOCAL_CXX_STL := libc++_static
-LOCAL_C_INCLUDES := external/elfutils/src/libelf libnativehelper/include
 
 LOCAL_MODULE := relocation_packer
 
 LOCAL_CPPFLAGS := $(common_cppflags)
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
 include $(BUILD_HOST_EXECUTABLE)
 
 include $(CLEAR_VARS)
@@ -71,7 +65,6 @@
   src/packer_unittest.cc \
 
 LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf libz
-LOCAL_C_INCLUDES := external/elfutils/src/libelf
 
 LOCAL_CPPFLAGS := $(common_cppflags)
 
diff --git a/tools/relocation_packer/src/main.cc b/tools/relocation_packer/src/main.cc
index 8e9de6d..d0a0dd4 100644
--- a/tools/relocation_packer/src/main.cc
+++ b/tools/relocation_packer/src/main.cc
@@ -25,7 +25,7 @@
 #include "elf_traits.h"
 #include "libelf.h"
 
-#include "nativehelper/ScopedFd.h"
+#include <android-base/unique_fd.h>
 
 static void PrintUsage(const char* argv0) {
   std::string temporary = argv0;
@@ -94,7 +94,7 @@
   }
 
   const char* file = argv[argc - 1];
-  ScopedFd fd(open(file, O_RDWR));
+  android::base::unique_fd fd(open(file, O_RDWR));
   if (fd.get() == -1) {
     LOG(ERROR) << file << ": " << strerror(errno);
     return 1;