Merge "Switch to POSIX dprintf/vdprintf."
diff --git a/libc/Android.mk b/libc/Android.mk
index f19a989..d8c8f63 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -499,6 +499,16 @@
   libc_common_cflags += -DDEBUG
 endif
 
+ifeq ($(MALLOC_IMPL),jemalloc)
+  libc_common_cflags += -DUSE_JEMALLOC
+
+  libc_malloc_src := bionic/jemalloc.cpp
+else
+  libc_common_cflags += -DUSE_DLMALLOC
+
+  libc_malloc_src := bionic/dlmalloc.c
+endif
+
 # To customize dlmalloc's alignment, set BOARD_MALLOC_ALIGNMENT in
 # the appropriate BoardConfig.mk file.
 #
@@ -527,6 +537,10 @@
     $(LOCAL_PATH)/stdlib  \
     $(LOCAL_PATH)/stdio   \
 
+ifeq ($(MALLOC_IMPL),jemalloc)
+  libc_common_c_includes += external/jemalloc/include
+endif
+
 # ========================================================
 # Add in the arch-specific flags.
 # Must be called with $(eval).
@@ -813,6 +827,11 @@
     libc_syscalls \
     libc_tzcode \
 
+ifeq ($(MALLOC_IMPL),jemalloc)
+LOCAL_WHOLE_STATIC_LIBRARIES += \
+    libjemalloc
+endif
+
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
 # TODO: split out the asflags.
@@ -867,7 +886,7 @@
 LOCAL_SRC_FILES := \
     $(libc_arch_static_src_files) \
     $(libc_static_common_src_files) \
-    bionic/dlmalloc.c \
+    $(libc_malloc_src) \
     bionic/malloc_debug_common.cpp \
     bionic/libc_init_static.cpp \
 
@@ -897,11 +916,10 @@
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
-
 LOCAL_SRC_FILES := \
     $(libc_arch_dynamic_src_files) \
     $(libc_static_common_src_files) \
-    bionic/dlmalloc.c \
+    $(libc_malloc_src) \
     bionic/malloc_debug_common.cpp \
     bionic/debug_mapinfo.cpp \
     bionic/debug_stacktrace.cpp \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 2a891b7..71d76e3 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -291,13 +291,11 @@
 int     uname(struct utsname*)  all
 mode_t  umask(mode_t)  all
 int     __reboot:reboot(int, int, int, void*)  all
-int     __syslog:syslog(int, char*, int)  all
 int     init_module(void*, unsigned long, const char*)  all
 int     delete_module(const char*, unsigned int)   all
 int     klogctl:syslog(int, char*, int)   all
 int     sysinfo(struct sysinfo*)  all
 int     personality(unsigned long)  all
-long    perf_event_open(struct perf_event_attr* attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) all
 
 int epoll_create1(int)  all
 int epoll_ctl(int, int op, int, struct epoll_event*)  all
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index 06b1675..3821854 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -13,7 +13,6 @@
 libc_common_src_files_arm += \
     bionic/index.cpp \
     bionic/memchr.c \
-    bionic/memmove.c.arm \
     bionic/memrchr.c \
     bionic/strchr.cpp \
     bionic/strnlen.c \
diff --git a/libc/arch-arm/bionic/__get_sp.S b/libc/arch-arm/bionic/__get_sp.S
index aabec6d..9ae6f24 100644
--- a/libc/arch-arm/bionic/__get_sp.S
+++ b/libc/arch-arm/bionic/__get_sp.S
@@ -28,7 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
   mov r0, sp
   bx lr
 END(__get_sp)
diff --git a/libc/arch-arm/bionic/futex_arm.S b/libc/arch-arm/bionic/futex_arm.S
index 0aba278..89a1e96 100644
--- a/libc/arch-arm/bionic/futex_arm.S
+++ b/libc/arch-arm/bionic/futex_arm.S
@@ -28,42 +28,11 @@
 
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-ENTRY(__futex_syscall3)
-    mov     ip, r7
-    ldr     r7, =__NR_futex
-    swi     #0
-    mov     r7, ip
-    bx      lr
-END(__futex_syscall3)
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
-ENTRY(__futex_syscall4)
-    b __futex_syscall3
+ENTRY_PRIVATE(__futex_syscall4)
+    mov     ip, r7
+    ldr     r7, =__NR_futex
+    swi     #0
+    mov     r7, ip
+    bx      lr
 END(__futex_syscall4)
-
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-ENTRY(__futex_wait)
-    mov     ip, r7
-    mov     r3, r2
-    mov     r2, r1
-    mov     r1, #FUTEX_WAIT
-    ldr     r7, =__NR_futex
-    swi     #0
-    mov     r7, ip
-    bx      lr
-END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-ENTRY(__futex_wake)
-    mov     ip, r7
-    mov     r2, r1
-    mov     r1, #FUTEX_WAKE
-    ldr     r7, =__NR_futex
-    swi     #0
-    mov     r7, ip
-    bx      lr
-END(__futex_wake)
diff --git a/libc/arch-arm/cortex-a15/cortex-a15.mk b/libc/arch-arm/cortex-a15/cortex-a15.mk
index d0896af..552811e 100644
--- a/libc/arch-arm/cortex-a15/cortex-a15.mk
+++ b/libc/arch-arm/cortex-a15/cortex-a15.mk
@@ -7,3 +7,4 @@
     arch-arm/cortex-a15/bionic/strlen.S \
     arch-arm/cortex-a15/bionic/__strcat_chk.S \
     arch-arm/cortex-a15/bionic/__strcpy_chk.S \
+    bionic/memmove.c \
diff --git a/libc/arch-arm/cortex-a9/cortex-a9.mk b/libc/arch-arm/cortex-a9/cortex-a9.mk
index e15602b..9b99387 100644
--- a/libc/arch-arm/cortex-a9/cortex-a9.mk
+++ b/libc/arch-arm/cortex-a9/cortex-a9.mk
@@ -7,3 +7,4 @@
     arch-arm/cortex-a9/bionic/strlen.S \
     arch-arm/cortex-a9/bionic/__strcat_chk.S \
     arch-arm/cortex-a9/bionic/__strcpy_chk.S \
+    bionic/memmove.c \
diff --git a/libc/arch-arm/denver/bionic/memmove.S b/libc/arch-arm/denver/bionic/memmove.S
new file mode 100644
index 0000000..132190b
--- /dev/null
+++ b/libc/arch-arm/denver/bionic/memmove.S
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ * Copyright (c) 2013-2014 NVIDIA Corporation.  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 <private/bionic_asm.h>
+#include <private/libc_events.h>
+
+        .text
+        .syntax unified
+        .fpu    neon
+
+#define CACHE_LINE_SIZE         (64)
+#define MEMCPY_BLOCK_SIZE_SMALL (32768)
+#define MEMCPY_BLOCK_SIZE_MID   (1048576)
+#define PREFETCH_DISTANCE_NEAR  (CACHE_LINE_SIZE*4)
+#define PREFETCH_DISTANCE_MID   (CACHE_LINE_SIZE*4)
+#define PREFETCH_DISTANCE_FAR   (CACHE_LINE_SIZE*16)
+
+ENTRY(memmove)
+        cmp         r2, #0
+        cmpne       r0, r1
+        bxeq        lr
+        subs        r3, r0, r1
+        bls         .L_jump_to_memcpy
+        cmp         r2, r3
+        bhi         .L_reversed_memcpy
+
+.L_jump_to_memcpy:
+        b           memcpy
+
+.L_reversed_memcpy:
+        push        {r0, lr}
+        .cfi_def_cfa_offset 8
+        .cfi_rel_offset r0, 0
+        .cfi_rel_offset lr, 4
+
+        add         r0, r0, r2
+        add         r1, r1, r2
+
+        /* preload next cache line */
+        pld         [r1, #-CACHE_LINE_SIZE]
+        pld         [r1, #-CACHE_LINE_SIZE*2]
+
+.L_reversed_memcpy_align_dest:
+        /* Deal with very small blocks (< 32bytes) asap */
+        cmp         r2, #32
+        blo         .L_reversed_memcpy_lt_32bytes
+        /* no need to align if len < 128 bytes */
+        cmp         r2, #128
+        blo         .L_reversed_memcpy_lt_128bytes
+        /* align destination to 64 bytes (1 cache line) */
+        ands        r3, r0, #0x3f
+        beq         .L_reversed_memcpy_dispatch
+        sub         r2, r2, r3
+0:      /* copy 1 byte */
+        movs        ip, r3, lsl #31
+        ldrbmi      ip, [r1, #-1]!
+        strbmi      ip, [r0, #-1]!
+1:      /* copy 2 bytes */
+        ldrbcs      ip, [r1, #-1]!
+        strbcs      ip, [r0, #-1]!
+        ldrbcs      ip, [r1, #-1]!
+        strbcs      ip, [r0, #-1]!
+2:      /* copy 4 bytes */
+        movs        ip, r3, lsl #29
+        bpl         3f
+        sub         r1, r1, #4
+        sub         r0, r0, #4
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]
+3:      /* copy 8 bytes */
+        bcc         4f
+        sub         r1, r1, #8
+        sub         r0, r0, #8
+        vld1.8      {d0}, [r1]
+        vst1.8      {d0}, [r0, :64]
+4:      /* copy 16 bytes */
+        movs        ip, r3, lsl #27
+        bpl         5f
+        sub         r1, r1, #16
+        sub         r0, r0, #16
+        vld1.8      {q0}, [r1]
+        vst1.8      {q0}, [r0, :128]
+5:      /* copy 32 bytes */
+        bcc         .L_reversed_memcpy_dispatch
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        vld1.8      {q0, q1}, [r1]
+        vst1.8      {q0, q1}, [r0, :256]
+
+.L_reversed_memcpy_dispatch:
+        /* preload more cache lines */
+        pld         [r1, #-CACHE_LINE_SIZE*3]
+        pld         [r1, #-CACHE_LINE_SIZE*4]
+
+        cmp         r2, #MEMCPY_BLOCK_SIZE_SMALL
+        blo         .L_reversed_memcpy_neon_pld_near
+        cmp         r2, #MEMCPY_BLOCK_SIZE_MID
+        blo         .L_reversed_memcpy_neon_pld_mid
+        b           .L_reversed_memcpy_neon_pld_far
+
+.L_reversed_memcpy_neon_pld_near:
+        /* less than 128 bytes? */
+        subs        r2, r2, #128
+        blo         1f
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        mov         r3, #-32
+        .align      4
+0:
+        /* copy 128 bytes in each loop */
+        subs        r2, r2, #128
+
+        /* preload to cache */
+        pld         [r1, #-(PREFETCH_DISTANCE_NEAR+CACHE_LINE_SIZE*2)+32]
+        /* copy a cache line */
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+
+        /* preload to cache */
+        pld         [r1, #-(PREFETCH_DISTANCE_NEAR+CACHE_LINE_SIZE*2)+32]
+        /* copy a cache line */
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+
+        bhs         0b
+        add         r1, r1, #32
+        add         r0, r0, #32
+1:
+        adds        r2, r2, #128
+        bne         .L_reversed_memcpy_lt_128bytes
+        pop         {r0, pc}
+
+.L_reversed_memcpy_neon_pld_mid:
+        subs        r2, r2, #128
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        mov         r3, #-32
+        .align      4
+0:
+        /* copy 128 bytes in each loop */
+        subs        r2, r2, #128
+
+        /* preload to cache */
+        pld         [r1, #-(PREFETCH_DISTANCE_MID+CACHE_LINE_SIZE)+32]
+        /* copy a cache line */
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+
+        /* preload to cache */
+        pld         [r1, #-(PREFETCH_DISTANCE_MID+CACHE_LINE_SIZE)+32]
+        /* copy a cache line */
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+        vld1.8      {q0, q1}, [r1], r3
+        vst1.8      {q0, q1}, [r0, :256], r3
+
+        bhs         0b
+        add         r1, r1, #32
+        add         r0, r0, #32
+1:
+        adds        r2, r2, #128
+        bne         .L_reversed_memcpy_lt_128bytes
+        pop         {r0, pc}
+
+.L_reversed_memcpy_neon_pld_far:
+        sub         r2, r2, #128
+        sub         r0, r0, #128
+        sub         r1, r1, #128
+        .align      4
+0:
+        /* copy 128 bytes in each loop */
+        subs        r2, r2, #128
+
+        /* preload to cache */
+        pld         [r1, #-(PREFETCH_DISTANCE_FAR+CACHE_LINE_SIZE*2)+128]
+        pld         [r1, #-(PREFETCH_DISTANCE_FAR+CACHE_LINE_SIZE)+128]
+        /* read */
+        vld1.8      {q0, q1}, [r1]!
+        vld1.8      {q2, q3}, [r1]!
+        vld1.8      {q8, q9}, [r1]!
+        vld1.8      {q10, q11}, [r1]!
+        /* write */
+        vst1.8      {q0, q1}, [r0, :256]!
+        vst1.8      {q2, q3}, [r0, :256]!
+        vst1.8      {q8, q9}, [r0, :256]!
+        vst1.8      {q10, q11}, [r0, :256]!
+
+        sub         r0, r0, #256
+        sub         r1, r1, #256
+        bhs         0b
+        add         r0, r0, #128
+        add         r1, r1, #128
+1:
+        adds        r2, r2, #128
+        bne         .L_reversed_memcpy_lt_128bytes
+        pop         {r0, pc}
+
+.L_reversed_memcpy_lt_128bytes:
+6:      /* copy 64 bytes */
+        movs        ip, r2, lsl #26
+        bcc         5f
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        vld1.8      {q0, q1}, [r1]
+        vst1.8      {q0, q1}, [r0]
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        vld1.8      {q0, q1}, [r1]
+        vst1.8      {q0, q1}, [r0]
+5:      /* copy 32 bytes */
+        bpl         4f
+        sub         r1, r1, #32
+        sub         r0, r0, #32
+        vld1.8      {q0, q1}, [r1]
+        vst1.8      {q0, q1}, [r0]
+.L_reversed_memcpy_lt_32bytes:
+4:      /* copy 16 bytes */
+        movs        ip, r2, lsl #28
+        bcc         3f
+        sub         r1, r1, #16
+        sub         r0, r0, #16
+        vld1.8      {q0}, [r1]
+        vst1.8      {q0}, [r0]
+3:      /* copy 8 bytes */
+        bpl         2f
+        sub         r1, r1, #8
+        sub         r0, r0, #8
+        vld1.8      {d0}, [r1]
+        vst1.8      {d0}, [r0]
+2:      /* copy 4 bytes */
+        ands        ip, r2, #0x4
+        beq         1f
+        sub         r1, r1, #4
+        sub         r0, r0, #4
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]
+1:      /* copy 2 bytes */
+        movs        ip, r2, lsl #31
+        ldrbcs      ip, [r1, #-1]!
+        strbcs      ip, [r0, #-1]!
+        ldrbcs      ip, [r1, #-1]!
+        strbcs      ip, [r0, #-1]!
+0:      /* copy 1 byte */
+        ldrbmi      ip, [r1, #-1]!
+        strbmi      ip, [r0, #-1]!
+
+        pop         {r0, pc}
+
+END(memmove)
diff --git a/libc/arch-arm/denver/denver.mk b/libc/arch-arm/denver/denver.mk
index 3fcc457..6989187 100644
--- a/libc/arch-arm/denver/denver.mk
+++ b/libc/arch-arm/denver/denver.mk
@@ -1,12 +1,13 @@
 libc_bionic_src_files_arm += \
     arch-arm/denver/bionic/memcpy.S \
+    arch-arm/denver/bionic/memmove.S \
     arch-arm/denver/bionic/memset.S \
     arch-arm/denver/bionic/__strcat_chk.S \
-    arch-arm/denver/bionic/__strcpy_chk.S
+    arch-arm/denver/bionic/__strcpy_chk.S \
 
 # Use cortex-a15 versions of strcat/strcpy/strlen.
 libc_bionic_src_files_arm += \
     arch-arm/cortex-a15/bionic/strcat.S \
     arch-arm/cortex-a15/bionic/strcpy.S \
     arch-arm/cortex-a15/bionic/strlen.S \
-    arch-arm/cortex-a15/bionic/strcmp.S
+    arch-arm/cortex-a15/bionic/strcmp.S \
diff --git a/libc/arch-arm/generic/generic.mk b/libc/arch-arm/generic/generic.mk
index 2bc84e0..2456e6e 100644
--- a/libc/arch-arm/generic/generic.mk
+++ b/libc/arch-arm/generic/generic.mk
@@ -4,6 +4,7 @@
     arch-arm/generic/bionic/strcmp.S \
     arch-arm/generic/bionic/strcpy.S \
     arch-arm/generic/bionic/strlen.c \
+    bionic/memmove.c \
     bionic/__strcat_chk.cpp \
     bionic/__strcpy_chk.cpp \
     upstream-openbsd/lib/libc/string/strcat.c \
diff --git a/libc/arch-arm/krait/krait.mk b/libc/arch-arm/krait/krait.mk
index 08342d6..631ab68 100644
--- a/libc/arch-arm/krait/krait.mk
+++ b/libc/arch-arm/krait/krait.mk
@@ -5,8 +5,9 @@
     arch-arm/krait/bionic/__strcat_chk.S \
     arch-arm/krait/bionic/__strcpy_chk.S \
 
-# Use cortex-a15 versions of strcat/strcpy/strlen.
+# Use cortex-a15 versions of strcat/strcpy/strlen and standard memmove
 libc_bionic_src_files_arm += \
     arch-arm/cortex-a15/bionic/strcat.S \
     arch-arm/cortex-a15/bionic/strcpy.S \
     arch-arm/cortex-a15/bionic/strlen.S \
+    bionic/memmove.c \
diff --git a/libc/arch-arm/syscalls/__syslog.S b/libc/arch-arm/syscalls/__syslog.S
deleted file mode 100644
index 66e761a..0000000
--- a/libc/arch-arm/syscalls/__syslog.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    mov     ip, r7
-    ldr     r7, =__NR_syslog
-    swi     #0
-    mov     r7, ip
-    cmn     r0, #(MAX_ERRNO + 1)
-    bxls    lr
-    neg     r0, r0
-    b       __set_errno
-END(__syslog)
diff --git a/libc/arch-arm/syscalls/perf_event_open.S b/libc/arch-arm/syscalls/perf_event_open.S
deleted file mode 100644
index 2821ac5..0000000
--- a/libc/arch-arm/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    mov     ip, sp
-    stmfd   sp!, {r4, r5, r6, r7}
-    .cfi_def_cfa_offset 16
-    .cfi_rel_offset r4, 0
-    .cfi_rel_offset r5, 4
-    .cfi_rel_offset r6, 8
-    .cfi_rel_offset r7, 12
-    ldmfd   ip, {r4, r5, r6}
-    ldr     r7, =__NR_perf_event_open
-    swi     #0
-    ldmfd   sp!, {r4, r5, r6, r7}
-    .cfi_def_cfa_offset 0
-    cmn     r0, #(MAX_ERRNO + 1)
-    bxls    lr
-    neg     r0, r0
-    b       __set_errno
-END(perf_event_open)
diff --git a/libc/arch-arm64/bionic/__bionic_clone.S b/libc/arch-arm64/bionic/__bionic_clone.S
index ddd8ee0..c49782c 100644
--- a/libc/arch-arm64/bionic/__bionic_clone.S
+++ b/libc/arch-arm64/bionic/__bionic_clone.S
@@ -32,15 +32,14 @@
 
 ENTRY(__bionic_clone)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     # Copy 'fn' and 'arg' onto the child stack.
     stp     x5, x6, [x1, #-16]
 
-    # Zero out the top 32 bits of 'flags'. (Is this necessary?)
-    uxtw    x0, w0
-
     # Make the system call.
     mov     x8, __NR_clone
     svc     #0
@@ -48,8 +47,10 @@
     # Are we the child?
     cbz     x0, .L_bc_child
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     # Set errno if something went wrong.
     cmn     x0, #(MAX_ERRNO + 1)
@@ -60,6 +61,8 @@
 
 .L_bc_child:
     # We're in the child now. Set the end of the frame record chain...
+    .cfi_undefined x29
+    .cfi_undefined x30
     mov     x29, xzr
     # ...and call __bionic_clone_entry with the 'fn' and 'arg' we stored on the child stack.
     ldp     x0, x1, [sp, #-16]
diff --git a/libc/arch-arm64/bionic/__get_sp.S b/libc/arch-arm64/bionic/__get_sp.S
index d495b6a..d5e88e9 100644
--- a/libc/arch-arm64/bionic/__get_sp.S
+++ b/libc/arch-arm64/bionic/__get_sp.S
@@ -28,7 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
     mov x0, sp
     ret
 END(__get_sp)
diff --git a/libc/arch-arm64/bionic/__set_tls.c b/libc/arch-arm64/bionic/__set_tls.c
index 4eb3ade..0d88d11 100644
--- a/libc/arch-arm64/bionic/__set_tls.c
+++ b/libc/arch-arm64/bionic/__set_tls.c
@@ -26,6 +26,8 @@
  * SUCH DAMAGE.
  */
 
-void __set_tls(void* tls) {
+#include <sys/cdefs.h>
+
+__LIBC_HIDDEN__ void __set_tls(void* tls) {
   asm("msr tpidr_el0, %0" : : "r" (tls));
 }
diff --git a/libc/arch-arm64/bionic/futex_arm64.S b/libc/arch-arm64/bionic/futex_arm64.S
index 5a47826..9d7465a 100644
--- a/libc/arch-arm64/bionic/futex_arm64.S
+++ b/libc/arch-arm64/bionic/futex_arm64.S
@@ -28,59 +28,20 @@
 
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
-ENTRY(__futex_syscall4)
+ENTRY_PRIVATE(__futex_syscall4)
   stp x29, x30, [sp, #-16]!
+  .cfi_def_cfa_offset 16
+  .cfi_rel_offset x29, 0
+  .cfi_rel_offset x30, 8
   mov x29, sp
 
-  str x8, [sp, #-16]!
   mov x8, __NR_futex
   svc #0
-  ldr x8, [sp], #16
 
   ldp x29, x30, [sp], #16
+  .cfi_def_cfa_offset 0
+  .cfi_restore x29
+  .cfi_restore x30
   ret
 END(__futex_syscall4)
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-ENTRY(__futex_syscall3)
-  b __futex_syscall4
-END(__futex_syscall3)
-
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-ENTRY_PRIVATE(__futex_wait)
-  stp x29, x30, [sp, #-16]!
-  mov x29, sp
-
-  mov x3, x2
-  mov x2, x1
-  mov x1, #FUTEX_WAIT
-
-  str x8, [sp, #-16]!
-  mov x8, __NR_futex
-  svc #0
-  ldr x8, [sp], #16
-
-  ldp x29, x30, [sp], #16
-  ret
-END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-ENTRY_PRIVATE(__futex_wake)
-  stp x29, x30, [sp, #-16]!
-  mov x29, sp
-
-  mov x2, x1
-  mov x1, #FUTEX_WAKE
-
-  str x8, [sp, #-16]!
-  mov x8, __NR_futex
-  svc #0
-  ldr x8, [sp], #16
-
-  ldp x29, x30, [sp], #16
-  ret
-END(__futex_wake)
diff --git a/libc/arch-arm64/bionic/syscall.S b/libc/arch-arm64/bionic/syscall.S
index e5be1d5..42e8883 100644
--- a/libc/arch-arm64/bionic/syscall.S
+++ b/libc/arch-arm64/bionic/syscall.S
@@ -31,11 +31,11 @@
 ENTRY(syscall)
     /* create AAPCS frame pointer */
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
 
-    /* store x8 */
-    str     x8,       [sp, #-16]!
-
     /* Move syscall No. from x0 to x8 */
     mov     x8, x0
     /* Move syscall parameters from x1 thru x6 to x0 thru x5 */
@@ -47,9 +47,10 @@
     mov     x5, x6
     svc     #0
 
-    /* restore x8 */
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     /* check if syscall returned successfully */
     cmn     x0, #(MAX_ERRNO + 1)
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 52009e2..c700623 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -37,10 +37,8 @@
     mov     x3, xzr
     mov     x4, xzr
 
-    str     x8, [sp, #-16]!
     mov     x8, __NR_clone
     svc     #0
-    ldr     x8, [sp], #16
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__accept4.S b/libc/arch-arm64/syscalls/__accept4.S
index c66cd2e..34f2c52 100644
--- a/libc/arch-arm64/syscalls/__accept4.S
+++ b/libc/arch-arm64/syscalls/__accept4.S
@@ -4,14 +4,18 @@
 
 ENTRY(__accept4)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_accept4
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__brk.S b/libc/arch-arm64/syscalls/__brk.S
index 918edf0..fb63fb9 100644
--- a/libc/arch-arm64/syscalls/__brk.S
+++ b/libc/arch-arm64/syscalls/__brk.S
@@ -4,14 +4,18 @@
 
 ENTRY(__brk)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_brk
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__connect.S b/libc/arch-arm64/syscalls/__connect.S
index c46f418..e578ccc 100644
--- a/libc/arch-arm64/syscalls/__connect.S
+++ b/libc/arch-arm64/syscalls/__connect.S
@@ -4,14 +4,18 @@
 
 ENTRY(__connect)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_connect
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__epoll_pwait.S b/libc/arch-arm64/syscalls/__epoll_pwait.S
index b487360..57b01c2 100644
--- a/libc/arch-arm64/syscalls/__epoll_pwait.S
+++ b/libc/arch-arm64/syscalls/__epoll_pwait.S
@@ -4,14 +4,18 @@
 
 ENTRY(__epoll_pwait)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_epoll_pwait
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__exit.S b/libc/arch-arm64/syscalls/__exit.S
index 5e97928..8600b13 100644
--- a/libc/arch-arm64/syscalls/__exit.S
+++ b/libc/arch-arm64/syscalls/__exit.S
@@ -4,14 +4,18 @@
 
 ENTRY(__exit)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_exit
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__getcpu.S b/libc/arch-arm64/syscalls/__getcpu.S
index a312188..e81ba23 100644
--- a/libc/arch-arm64/syscalls/__getcpu.S
+++ b/libc/arch-arm64/syscalls/__getcpu.S
@@ -4,14 +4,18 @@
 
 ENTRY(__getcpu)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getcpu
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__getcwd.S b/libc/arch-arm64/syscalls/__getcwd.S
index 4b27a9c..fc48f80 100644
--- a/libc/arch-arm64/syscalls/__getcwd.S
+++ b/libc/arch-arm64/syscalls/__getcwd.S
@@ -4,14 +4,18 @@
 
 ENTRY(__getcwd)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getcwd
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__getpriority.S b/libc/arch-arm64/syscalls/__getpriority.S
index 3ccd104..486ea8f 100644
--- a/libc/arch-arm64/syscalls/__getpriority.S
+++ b/libc/arch-arm64/syscalls/__getpriority.S
@@ -4,14 +4,18 @@
 
 ENTRY(__getpriority)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getpriority
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__ioctl.S b/libc/arch-arm64/syscalls/__ioctl.S
index 68d89bc..30ff73c 100644
--- a/libc/arch-arm64/syscalls/__ioctl.S
+++ b/libc/arch-arm64/syscalls/__ioctl.S
@@ -4,14 +4,18 @@
 
 ENTRY(__ioctl)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ioctl
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__openat.S b/libc/arch-arm64/syscalls/__openat.S
index a49eaff..22e2f6a 100644
--- a/libc/arch-arm64/syscalls/__openat.S
+++ b/libc/arch-arm64/syscalls/__openat.S
@@ -4,14 +4,18 @@
 
 ENTRY(__openat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_openat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__ppoll.S b/libc/arch-arm64/syscalls/__ppoll.S
index 370e768..1739dea 100644
--- a/libc/arch-arm64/syscalls/__ppoll.S
+++ b/libc/arch-arm64/syscalls/__ppoll.S
@@ -4,14 +4,18 @@
 
 ENTRY(__ppoll)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ppoll
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__pselect6.S b/libc/arch-arm64/syscalls/__pselect6.S
index 193e19f..2770164 100644
--- a/libc/arch-arm64/syscalls/__pselect6.S
+++ b/libc/arch-arm64/syscalls/__pselect6.S
@@ -4,14 +4,18 @@
 
 ENTRY(__pselect6)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_pselect6
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__ptrace.S b/libc/arch-arm64/syscalls/__ptrace.S
index ee63cb0..3746530 100644
--- a/libc/arch-arm64/syscalls/__ptrace.S
+++ b/libc/arch-arm64/syscalls/__ptrace.S
@@ -4,14 +4,18 @@
 
 ENTRY(__ptrace)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ptrace
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__reboot.S b/libc/arch-arm64/syscalls/__reboot.S
index 10b33ad..b1ea418 100644
--- a/libc/arch-arm64/syscalls/__reboot.S
+++ b/libc/arch-arm64/syscalls/__reboot.S
@@ -4,14 +4,18 @@
 
 ENTRY(__reboot)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_reboot
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__rt_sigaction.S b/libc/arch-arm64/syscalls/__rt_sigaction.S
index cea0941..33e07cb 100644
--- a/libc/arch-arm64/syscalls/__rt_sigaction.S
+++ b/libc/arch-arm64/syscalls/__rt_sigaction.S
@@ -4,14 +4,18 @@
 
 ENTRY(__rt_sigaction)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_rt_sigaction
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__rt_sigpending.S b/libc/arch-arm64/syscalls/__rt_sigpending.S
index 97db3b9..fa6812e 100644
--- a/libc/arch-arm64/syscalls/__rt_sigpending.S
+++ b/libc/arch-arm64/syscalls/__rt_sigpending.S
@@ -4,14 +4,18 @@
 
 ENTRY(__rt_sigpending)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_rt_sigpending
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__rt_sigprocmask.S b/libc/arch-arm64/syscalls/__rt_sigprocmask.S
index 97dabe1..537f8bd 100644
--- a/libc/arch-arm64/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-arm64/syscalls/__rt_sigprocmask.S
@@ -4,14 +4,18 @@
 
 ENTRY(__rt_sigprocmask)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_rt_sigprocmask
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__rt_sigsuspend.S b/libc/arch-arm64/syscalls/__rt_sigsuspend.S
index d8eaa3e..b8a99c6 100644
--- a/libc/arch-arm64/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-arm64/syscalls/__rt_sigsuspend.S
@@ -4,14 +4,18 @@
 
 ENTRY(__rt_sigsuspend)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_rt_sigsuspend
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__rt_sigtimedwait.S b/libc/arch-arm64/syscalls/__rt_sigtimedwait.S
index 95f031a..869442c 100644
--- a/libc/arch-arm64/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-arm64/syscalls/__rt_sigtimedwait.S
@@ -4,14 +4,18 @@
 
 ENTRY(__rt_sigtimedwait)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_rt_sigtimedwait
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__sched_getaffinity.S b/libc/arch-arm64/syscalls/__sched_getaffinity.S
index 58715d0..8ca23d4 100644
--- a/libc/arch-arm64/syscalls/__sched_getaffinity.S
+++ b/libc/arch-arm64/syscalls/__sched_getaffinity.S
@@ -4,14 +4,18 @@
 
 ENTRY(__sched_getaffinity)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_getaffinity
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__set_tid_address.S b/libc/arch-arm64/syscalls/__set_tid_address.S
index 3cc452c..5514aed 100644
--- a/libc/arch-arm64/syscalls/__set_tid_address.S
+++ b/libc/arch-arm64/syscalls/__set_tid_address.S
@@ -4,14 +4,18 @@
 
 ENTRY(__set_tid_address)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_set_tid_address
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__signalfd4.S b/libc/arch-arm64/syscalls/__signalfd4.S
index 91510f6..ea49fc5 100644
--- a/libc/arch-arm64/syscalls/__signalfd4.S
+++ b/libc/arch-arm64/syscalls/__signalfd4.S
@@ -4,14 +4,18 @@
 
 ENTRY(__signalfd4)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_signalfd4
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__socket.S b/libc/arch-arm64/syscalls/__socket.S
index aa9da22..f96a1ab 100644
--- a/libc/arch-arm64/syscalls/__socket.S
+++ b/libc/arch-arm64/syscalls/__socket.S
@@ -4,14 +4,18 @@
 
 ENTRY(__socket)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_socket
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__syslog.S b/libc/arch-arm64/syscalls/__syslog.S
deleted file mode 100644
index 2e1fb1d..0000000
--- a/libc/arch-arm64/syscalls/__syslog.S
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    stp     x29, x30, [sp, #-16]!
-    mov     x29,  sp
-    str     x8,       [sp, #-16]!
-
-    mov     x8, __NR_syslog
-    svc     #0
-
-    ldr     x8,       [sp], #16
-    ldp     x29, x30, [sp], #16
-
-    cmn     x0, #(MAX_ERRNO + 1)
-    cneg    x0, x0, hi
-    b.hi    __set_errno
-
-    ret
-END(__syslog)
-.hidden __syslog
diff --git a/libc/arch-arm64/syscalls/__timer_create.S b/libc/arch-arm64/syscalls/__timer_create.S
index b551048..87183b4 100644
--- a/libc/arch-arm64/syscalls/__timer_create.S
+++ b/libc/arch-arm64/syscalls/__timer_create.S
@@ -4,14 +4,18 @@
 
 ENTRY(__timer_create)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timer_create
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__timer_delete.S b/libc/arch-arm64/syscalls/__timer_delete.S
index 2aff540..c21ec4f 100644
--- a/libc/arch-arm64/syscalls/__timer_delete.S
+++ b/libc/arch-arm64/syscalls/__timer_delete.S
@@ -4,14 +4,18 @@
 
 ENTRY(__timer_delete)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timer_delete
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__timer_getoverrun.S b/libc/arch-arm64/syscalls/__timer_getoverrun.S
index b11e356..47f1ef9 100644
--- a/libc/arch-arm64/syscalls/__timer_getoverrun.S
+++ b/libc/arch-arm64/syscalls/__timer_getoverrun.S
@@ -4,14 +4,18 @@
 
 ENTRY(__timer_getoverrun)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timer_getoverrun
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__timer_gettime.S b/libc/arch-arm64/syscalls/__timer_gettime.S
index c7c4d09..4eaa655 100644
--- a/libc/arch-arm64/syscalls/__timer_gettime.S
+++ b/libc/arch-arm64/syscalls/__timer_gettime.S
@@ -4,14 +4,18 @@
 
 ENTRY(__timer_gettime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timer_gettime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__timer_settime.S b/libc/arch-arm64/syscalls/__timer_settime.S
index 4f5f5fc..aef0cc4 100644
--- a/libc/arch-arm64/syscalls/__timer_settime.S
+++ b/libc/arch-arm64/syscalls/__timer_settime.S
@@ -4,14 +4,18 @@
 
 ENTRY(__timer_settime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timer_settime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/__waitid.S b/libc/arch-arm64/syscalls/__waitid.S
index 66e986a..6d9e940 100644
--- a/libc/arch-arm64/syscalls/__waitid.S
+++ b/libc/arch-arm64/syscalls/__waitid.S
@@ -4,14 +4,18 @@
 
 ENTRY(__waitid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_waitid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/_exit.S b/libc/arch-arm64/syscalls/_exit.S
index 40ada48..37d1499 100644
--- a/libc/arch-arm64/syscalls/_exit.S
+++ b/libc/arch-arm64/syscalls/_exit.S
@@ -4,14 +4,18 @@
 
 ENTRY(_exit)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_exit_group
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/acct.S b/libc/arch-arm64/syscalls/acct.S
index 901e420..f391cd8 100644
--- a/libc/arch-arm64/syscalls/acct.S
+++ b/libc/arch-arm64/syscalls/acct.S
@@ -4,14 +4,18 @@
 
 ENTRY(acct)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_acct
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/bind.S b/libc/arch-arm64/syscalls/bind.S
index 471d783..10dd01f 100644
--- a/libc/arch-arm64/syscalls/bind.S
+++ b/libc/arch-arm64/syscalls/bind.S
@@ -4,14 +4,18 @@
 
 ENTRY(bind)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_bind
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/capget.S b/libc/arch-arm64/syscalls/capget.S
index 33fe11c..d01dc47 100644
--- a/libc/arch-arm64/syscalls/capget.S
+++ b/libc/arch-arm64/syscalls/capget.S
@@ -4,14 +4,18 @@
 
 ENTRY(capget)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_capget
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/capset.S b/libc/arch-arm64/syscalls/capset.S
index 75f03a9..c4ed92e 100644
--- a/libc/arch-arm64/syscalls/capset.S
+++ b/libc/arch-arm64/syscalls/capset.S
@@ -4,14 +4,18 @@
 
 ENTRY(capset)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_capset
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/chdir.S b/libc/arch-arm64/syscalls/chdir.S
index 051f823..6f1baf0 100644
--- a/libc/arch-arm64/syscalls/chdir.S
+++ b/libc/arch-arm64/syscalls/chdir.S
@@ -4,14 +4,18 @@
 
 ENTRY(chdir)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_chdir
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/chroot.S b/libc/arch-arm64/syscalls/chroot.S
index c06399f..b15f04a 100644
--- a/libc/arch-arm64/syscalls/chroot.S
+++ b/libc/arch-arm64/syscalls/chroot.S
@@ -4,14 +4,18 @@
 
 ENTRY(chroot)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_chroot
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/clock_getres.S b/libc/arch-arm64/syscalls/clock_getres.S
index bffc7cb..b18c10b 100644
--- a/libc/arch-arm64/syscalls/clock_getres.S
+++ b/libc/arch-arm64/syscalls/clock_getres.S
@@ -4,14 +4,18 @@
 
 ENTRY(clock_getres)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_clock_getres
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/clock_gettime.S b/libc/arch-arm64/syscalls/clock_gettime.S
index 3c58236..b3518c1 100644
--- a/libc/arch-arm64/syscalls/clock_gettime.S
+++ b/libc/arch-arm64/syscalls/clock_gettime.S
@@ -4,14 +4,18 @@
 
 ENTRY(clock_gettime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_clock_gettime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/clock_nanosleep.S b/libc/arch-arm64/syscalls/clock_nanosleep.S
index 357bda6..eddf6f1 100644
--- a/libc/arch-arm64/syscalls/clock_nanosleep.S
+++ b/libc/arch-arm64/syscalls/clock_nanosleep.S
@@ -4,14 +4,18 @@
 
 ENTRY(clock_nanosleep)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_clock_nanosleep
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/clock_settime.S b/libc/arch-arm64/syscalls/clock_settime.S
index 06e9393..c6ba5c0 100644
--- a/libc/arch-arm64/syscalls/clock_settime.S
+++ b/libc/arch-arm64/syscalls/clock_settime.S
@@ -4,14 +4,18 @@
 
 ENTRY(clock_settime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_clock_settime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/close.S b/libc/arch-arm64/syscalls/close.S
index fefe147..a623895 100644
--- a/libc/arch-arm64/syscalls/close.S
+++ b/libc/arch-arm64/syscalls/close.S
@@ -4,14 +4,18 @@
 
 ENTRY(close)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_close
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/delete_module.S b/libc/arch-arm64/syscalls/delete_module.S
index 4e8b09d..a57517d 100644
--- a/libc/arch-arm64/syscalls/delete_module.S
+++ b/libc/arch-arm64/syscalls/delete_module.S
@@ -4,14 +4,18 @@
 
 ENTRY(delete_module)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_delete_module
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/dup.S b/libc/arch-arm64/syscalls/dup.S
index 9dbe562..b7e04ed 100644
--- a/libc/arch-arm64/syscalls/dup.S
+++ b/libc/arch-arm64/syscalls/dup.S
@@ -4,14 +4,18 @@
 
 ENTRY(dup)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_dup
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/dup3.S b/libc/arch-arm64/syscalls/dup3.S
index ee04440..fada63d 100644
--- a/libc/arch-arm64/syscalls/dup3.S
+++ b/libc/arch-arm64/syscalls/dup3.S
@@ -4,14 +4,18 @@
 
 ENTRY(dup3)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_dup3
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/epoll_create1.S b/libc/arch-arm64/syscalls/epoll_create1.S
index 0ed34b5..94990bf 100644
--- a/libc/arch-arm64/syscalls/epoll_create1.S
+++ b/libc/arch-arm64/syscalls/epoll_create1.S
@@ -4,14 +4,18 @@
 
 ENTRY(epoll_create1)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_epoll_create1
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/epoll_ctl.S b/libc/arch-arm64/syscalls/epoll_ctl.S
index a09ba29..ea6f735 100644
--- a/libc/arch-arm64/syscalls/epoll_ctl.S
+++ b/libc/arch-arm64/syscalls/epoll_ctl.S
@@ -4,14 +4,18 @@
 
 ENTRY(epoll_ctl)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_epoll_ctl
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/eventfd.S b/libc/arch-arm64/syscalls/eventfd.S
index e6b592b..afa88b3 100644
--- a/libc/arch-arm64/syscalls/eventfd.S
+++ b/libc/arch-arm64/syscalls/eventfd.S
@@ -4,14 +4,18 @@
 
 ENTRY(eventfd)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_eventfd2
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/execve.S b/libc/arch-arm64/syscalls/execve.S
index 4f3cdb8..031b6d4 100644
--- a/libc/arch-arm64/syscalls/execve.S
+++ b/libc/arch-arm64/syscalls/execve.S
@@ -4,14 +4,18 @@
 
 ENTRY(execve)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_execve
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/faccessat.S b/libc/arch-arm64/syscalls/faccessat.S
index c6b6557..cebbf18 100644
--- a/libc/arch-arm64/syscalls/faccessat.S
+++ b/libc/arch-arm64/syscalls/faccessat.S
@@ -4,14 +4,18 @@
 
 ENTRY(faccessat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_faccessat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fallocate.S b/libc/arch-arm64/syscalls/fallocate.S
index 15e727d..94832aa 100644
--- a/libc/arch-arm64/syscalls/fallocate.S
+++ b/libc/arch-arm64/syscalls/fallocate.S
@@ -4,14 +4,18 @@
 
 ENTRY(fallocate)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fallocate
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fchdir.S b/libc/arch-arm64/syscalls/fchdir.S
index c608231..afba3c1 100644
--- a/libc/arch-arm64/syscalls/fchdir.S
+++ b/libc/arch-arm64/syscalls/fchdir.S
@@ -4,14 +4,18 @@
 
 ENTRY(fchdir)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fchdir
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fchmod.S b/libc/arch-arm64/syscalls/fchmod.S
index a777cdc..35f9dec 100644
--- a/libc/arch-arm64/syscalls/fchmod.S
+++ b/libc/arch-arm64/syscalls/fchmod.S
@@ -4,14 +4,18 @@
 
 ENTRY(fchmod)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fchmod
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fchmodat.S b/libc/arch-arm64/syscalls/fchmodat.S
index 1a52c9f..59bfb8a 100644
--- a/libc/arch-arm64/syscalls/fchmodat.S
+++ b/libc/arch-arm64/syscalls/fchmodat.S
@@ -4,14 +4,18 @@
 
 ENTRY(fchmodat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fchmodat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fchown.S b/libc/arch-arm64/syscalls/fchown.S
index 073e36f..2294187 100644
--- a/libc/arch-arm64/syscalls/fchown.S
+++ b/libc/arch-arm64/syscalls/fchown.S
@@ -4,14 +4,18 @@
 
 ENTRY(fchown)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fchown
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fchownat.S b/libc/arch-arm64/syscalls/fchownat.S
index db80ab1..ff24187 100644
--- a/libc/arch-arm64/syscalls/fchownat.S
+++ b/libc/arch-arm64/syscalls/fchownat.S
@@ -4,14 +4,18 @@
 
 ENTRY(fchownat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fchownat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fcntl.S b/libc/arch-arm64/syscalls/fcntl.S
index 23ce155..a9d6976 100644
--- a/libc/arch-arm64/syscalls/fcntl.S
+++ b/libc/arch-arm64/syscalls/fcntl.S
@@ -4,14 +4,18 @@
 
 ENTRY(fcntl)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fcntl
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fdatasync.S b/libc/arch-arm64/syscalls/fdatasync.S
index b4e9aa9..4cf4de3 100644
--- a/libc/arch-arm64/syscalls/fdatasync.S
+++ b/libc/arch-arm64/syscalls/fdatasync.S
@@ -4,14 +4,18 @@
 
 ENTRY(fdatasync)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fdatasync
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fgetxattr.S b/libc/arch-arm64/syscalls/fgetxattr.S
index 3278a12..914ea7f 100644
--- a/libc/arch-arm64/syscalls/fgetxattr.S
+++ b/libc/arch-arm64/syscalls/fgetxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(fgetxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fgetxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/flistxattr.S b/libc/arch-arm64/syscalls/flistxattr.S
index 40b2a30..2a64381 100644
--- a/libc/arch-arm64/syscalls/flistxattr.S
+++ b/libc/arch-arm64/syscalls/flistxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(flistxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_flistxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/flock.S b/libc/arch-arm64/syscalls/flock.S
index 7e28789..0d87233 100644
--- a/libc/arch-arm64/syscalls/flock.S
+++ b/libc/arch-arm64/syscalls/flock.S
@@ -4,14 +4,18 @@
 
 ENTRY(flock)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_flock
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fremovexattr.S b/libc/arch-arm64/syscalls/fremovexattr.S
index be86dd0..e2ef649 100644
--- a/libc/arch-arm64/syscalls/fremovexattr.S
+++ b/libc/arch-arm64/syscalls/fremovexattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(fremovexattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fremovexattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fsetxattr.S b/libc/arch-arm64/syscalls/fsetxattr.S
index 2cb72c9..eb41951 100644
--- a/libc/arch-arm64/syscalls/fsetxattr.S
+++ b/libc/arch-arm64/syscalls/fsetxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(fsetxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fsetxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fstat64.S b/libc/arch-arm64/syscalls/fstat64.S
index fdff681..ee0d9e7 100644
--- a/libc/arch-arm64/syscalls/fstat64.S
+++ b/libc/arch-arm64/syscalls/fstat64.S
@@ -4,14 +4,18 @@
 
 ENTRY(fstat64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fstat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fstatat64.S b/libc/arch-arm64/syscalls/fstatat64.S
index 0f3ef4d..4ff3039 100644
--- a/libc/arch-arm64/syscalls/fstatat64.S
+++ b/libc/arch-arm64/syscalls/fstatat64.S
@@ -4,14 +4,18 @@
 
 ENTRY(fstatat64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_newfstatat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fstatfs64.S b/libc/arch-arm64/syscalls/fstatfs64.S
index 6318d56..b908b57 100644
--- a/libc/arch-arm64/syscalls/fstatfs64.S
+++ b/libc/arch-arm64/syscalls/fstatfs64.S
@@ -4,14 +4,18 @@
 
 ENTRY(fstatfs64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fstatfs
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/fsync.S b/libc/arch-arm64/syscalls/fsync.S
index e1076f2..bac2e8b 100644
--- a/libc/arch-arm64/syscalls/fsync.S
+++ b/libc/arch-arm64/syscalls/fsync.S
@@ -4,14 +4,18 @@
 
 ENTRY(fsync)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_fsync
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/ftruncate.S b/libc/arch-arm64/syscalls/ftruncate.S
index c8f5b6b..ca4315a 100644
--- a/libc/arch-arm64/syscalls/ftruncate.S
+++ b/libc/arch-arm64/syscalls/ftruncate.S
@@ -4,14 +4,18 @@
 
 ENTRY(ftruncate)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ftruncate
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/futex.S b/libc/arch-arm64/syscalls/futex.S
index 5149d6b..c14ebbf 100644
--- a/libc/arch-arm64/syscalls/futex.S
+++ b/libc/arch-arm64/syscalls/futex.S
@@ -4,14 +4,18 @@
 
 ENTRY(futex)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_futex
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getdents.S b/libc/arch-arm64/syscalls/getdents.S
index 56496c2..8cd3ca7 100644
--- a/libc/arch-arm64/syscalls/getdents.S
+++ b/libc/arch-arm64/syscalls/getdents.S
@@ -4,14 +4,18 @@
 
 ENTRY(getdents)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getdents64
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getegid.S b/libc/arch-arm64/syscalls/getegid.S
index 144fe88..593f51d 100644
--- a/libc/arch-arm64/syscalls/getegid.S
+++ b/libc/arch-arm64/syscalls/getegid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getegid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getegid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/geteuid.S b/libc/arch-arm64/syscalls/geteuid.S
index fcec977..845acbc 100644
--- a/libc/arch-arm64/syscalls/geteuid.S
+++ b/libc/arch-arm64/syscalls/geteuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(geteuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_geteuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getgid.S b/libc/arch-arm64/syscalls/getgid.S
index 0fd172e..5f34355 100644
--- a/libc/arch-arm64/syscalls/getgid.S
+++ b/libc/arch-arm64/syscalls/getgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getgroups.S b/libc/arch-arm64/syscalls/getgroups.S
index 3c12ef4..d0e2540 100644
--- a/libc/arch-arm64/syscalls/getgroups.S
+++ b/libc/arch-arm64/syscalls/getgroups.S
@@ -4,14 +4,18 @@
 
 ENTRY(getgroups)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getgroups
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getitimer.S b/libc/arch-arm64/syscalls/getitimer.S
index d795cd7..2d4d541 100644
--- a/libc/arch-arm64/syscalls/getitimer.S
+++ b/libc/arch-arm64/syscalls/getitimer.S
@@ -4,14 +4,18 @@
 
 ENTRY(getitimer)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getitimer
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getpeername.S b/libc/arch-arm64/syscalls/getpeername.S
index aea3122..1f64130 100644
--- a/libc/arch-arm64/syscalls/getpeername.S
+++ b/libc/arch-arm64/syscalls/getpeername.S
@@ -4,14 +4,18 @@
 
 ENTRY(getpeername)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getpeername
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getpgid.S b/libc/arch-arm64/syscalls/getpgid.S
index 1bda83f..01d876f 100644
--- a/libc/arch-arm64/syscalls/getpgid.S
+++ b/libc/arch-arm64/syscalls/getpgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getpgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getpgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getpid.S b/libc/arch-arm64/syscalls/getpid.S
index 3a408c8..94b823c 100644
--- a/libc/arch-arm64/syscalls/getpid.S
+++ b/libc/arch-arm64/syscalls/getpid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getpid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getpid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getppid.S b/libc/arch-arm64/syscalls/getppid.S
index 1b85cef..0a46878 100644
--- a/libc/arch-arm64/syscalls/getppid.S
+++ b/libc/arch-arm64/syscalls/getppid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getppid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getppid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getresgid.S b/libc/arch-arm64/syscalls/getresgid.S
index ab00b06..bc121fc 100644
--- a/libc/arch-arm64/syscalls/getresgid.S
+++ b/libc/arch-arm64/syscalls/getresgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getresgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getresgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getresuid.S b/libc/arch-arm64/syscalls/getresuid.S
index 0ff218a..28cd9a4 100644
--- a/libc/arch-arm64/syscalls/getresuid.S
+++ b/libc/arch-arm64/syscalls/getresuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getresuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getresuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getrlimit.S b/libc/arch-arm64/syscalls/getrlimit.S
index 4fb5f7c..aa966ca 100644
--- a/libc/arch-arm64/syscalls/getrlimit.S
+++ b/libc/arch-arm64/syscalls/getrlimit.S
@@ -4,14 +4,18 @@
 
 ENTRY(getrlimit)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getrlimit
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getrusage.S b/libc/arch-arm64/syscalls/getrusage.S
index 5e2bace..aaaf3a2 100644
--- a/libc/arch-arm64/syscalls/getrusage.S
+++ b/libc/arch-arm64/syscalls/getrusage.S
@@ -4,14 +4,18 @@
 
 ENTRY(getrusage)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getrusage
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getsid.S b/libc/arch-arm64/syscalls/getsid.S
index c85ca60..e75b7b4 100644
--- a/libc/arch-arm64/syscalls/getsid.S
+++ b/libc/arch-arm64/syscalls/getsid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getsid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getsid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getsockname.S b/libc/arch-arm64/syscalls/getsockname.S
index 1d0279a..61e4b4b 100644
--- a/libc/arch-arm64/syscalls/getsockname.S
+++ b/libc/arch-arm64/syscalls/getsockname.S
@@ -4,14 +4,18 @@
 
 ENTRY(getsockname)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getsockname
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getsockopt.S b/libc/arch-arm64/syscalls/getsockopt.S
index 3bfd5b8..3740df9 100644
--- a/libc/arch-arm64/syscalls/getsockopt.S
+++ b/libc/arch-arm64/syscalls/getsockopt.S
@@ -4,14 +4,18 @@
 
 ENTRY(getsockopt)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getsockopt
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/gettid.S b/libc/arch-arm64/syscalls/gettid.S
index d8c128e..44ca913 100644
--- a/libc/arch-arm64/syscalls/gettid.S
+++ b/libc/arch-arm64/syscalls/gettid.S
@@ -4,14 +4,18 @@
 
 ENTRY(gettid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_gettid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/gettimeofday.S b/libc/arch-arm64/syscalls/gettimeofday.S
index 4f9ac28..a72ac91 100644
--- a/libc/arch-arm64/syscalls/gettimeofday.S
+++ b/libc/arch-arm64/syscalls/gettimeofday.S
@@ -4,14 +4,18 @@
 
 ENTRY(gettimeofday)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_gettimeofday
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getuid.S b/libc/arch-arm64/syscalls/getuid.S
index 96198b7..d749cc3 100644
--- a/libc/arch-arm64/syscalls/getuid.S
+++ b/libc/arch-arm64/syscalls/getuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(getuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/getxattr.S b/libc/arch-arm64/syscalls/getxattr.S
index 11b90aa..451eef5 100644
--- a/libc/arch-arm64/syscalls/getxattr.S
+++ b/libc/arch-arm64/syscalls/getxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(getxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_getxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/init_module.S b/libc/arch-arm64/syscalls/init_module.S
index 8648b04..42ec765 100644
--- a/libc/arch-arm64/syscalls/init_module.S
+++ b/libc/arch-arm64/syscalls/init_module.S
@@ -4,14 +4,18 @@
 
 ENTRY(init_module)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_init_module
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/inotify_add_watch.S b/libc/arch-arm64/syscalls/inotify_add_watch.S
index 583ab72..066816c 100644
--- a/libc/arch-arm64/syscalls/inotify_add_watch.S
+++ b/libc/arch-arm64/syscalls/inotify_add_watch.S
@@ -4,14 +4,18 @@
 
 ENTRY(inotify_add_watch)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_inotify_add_watch
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/inotify_init1.S b/libc/arch-arm64/syscalls/inotify_init1.S
index 3ee946e..d6bee8c 100644
--- a/libc/arch-arm64/syscalls/inotify_init1.S
+++ b/libc/arch-arm64/syscalls/inotify_init1.S
@@ -4,14 +4,18 @@
 
 ENTRY(inotify_init1)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_inotify_init1
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/inotify_rm_watch.S b/libc/arch-arm64/syscalls/inotify_rm_watch.S
index 3121b51..ee9c70f 100644
--- a/libc/arch-arm64/syscalls/inotify_rm_watch.S
+++ b/libc/arch-arm64/syscalls/inotify_rm_watch.S
@@ -4,14 +4,18 @@
 
 ENTRY(inotify_rm_watch)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_inotify_rm_watch
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/ioprio_get.S b/libc/arch-arm64/syscalls/ioprio_get.S
index 207a4e7..4a4a749 100644
--- a/libc/arch-arm64/syscalls/ioprio_get.S
+++ b/libc/arch-arm64/syscalls/ioprio_get.S
@@ -4,14 +4,18 @@
 
 ENTRY(ioprio_get)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ioprio_get
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/ioprio_set.S b/libc/arch-arm64/syscalls/ioprio_set.S
index eb7b026..8b48f12 100644
--- a/libc/arch-arm64/syscalls/ioprio_set.S
+++ b/libc/arch-arm64/syscalls/ioprio_set.S
@@ -4,14 +4,18 @@
 
 ENTRY(ioprio_set)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_ioprio_set
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/kill.S b/libc/arch-arm64/syscalls/kill.S
index 3788df7..15c399b 100644
--- a/libc/arch-arm64/syscalls/kill.S
+++ b/libc/arch-arm64/syscalls/kill.S
@@ -4,14 +4,18 @@
 
 ENTRY(kill)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_kill
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/klogctl.S b/libc/arch-arm64/syscalls/klogctl.S
index efa8b4a..1d161ec 100644
--- a/libc/arch-arm64/syscalls/klogctl.S
+++ b/libc/arch-arm64/syscalls/klogctl.S
@@ -4,14 +4,18 @@
 
 ENTRY(klogctl)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_syslog
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/lgetxattr.S b/libc/arch-arm64/syscalls/lgetxattr.S
index 1fda092..2799285 100644
--- a/libc/arch-arm64/syscalls/lgetxattr.S
+++ b/libc/arch-arm64/syscalls/lgetxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(lgetxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_lgetxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/linkat.S b/libc/arch-arm64/syscalls/linkat.S
index 999c007..e65aa3f 100644
--- a/libc/arch-arm64/syscalls/linkat.S
+++ b/libc/arch-arm64/syscalls/linkat.S
@@ -4,14 +4,18 @@
 
 ENTRY(linkat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_linkat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/listen.S b/libc/arch-arm64/syscalls/listen.S
index 8b7fa0f..44ae288 100644
--- a/libc/arch-arm64/syscalls/listen.S
+++ b/libc/arch-arm64/syscalls/listen.S
@@ -4,14 +4,18 @@
 
 ENTRY(listen)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_listen
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/listxattr.S b/libc/arch-arm64/syscalls/listxattr.S
index cc399a9..b31d22c 100644
--- a/libc/arch-arm64/syscalls/listxattr.S
+++ b/libc/arch-arm64/syscalls/listxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(listxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_listxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/llistxattr.S b/libc/arch-arm64/syscalls/llistxattr.S
index 87bfe10..fdcafde 100644
--- a/libc/arch-arm64/syscalls/llistxattr.S
+++ b/libc/arch-arm64/syscalls/llistxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(llistxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_llistxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/lremovexattr.S b/libc/arch-arm64/syscalls/lremovexattr.S
index ad823e4..741fa86 100644
--- a/libc/arch-arm64/syscalls/lremovexattr.S
+++ b/libc/arch-arm64/syscalls/lremovexattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(lremovexattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_lremovexattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/lseek.S b/libc/arch-arm64/syscalls/lseek.S
index 0c04203..3d16e75 100644
--- a/libc/arch-arm64/syscalls/lseek.S
+++ b/libc/arch-arm64/syscalls/lseek.S
@@ -4,14 +4,18 @@
 
 ENTRY(lseek)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_lseek
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/lsetxattr.S b/libc/arch-arm64/syscalls/lsetxattr.S
index 683fc2b..a7fe1df 100644
--- a/libc/arch-arm64/syscalls/lsetxattr.S
+++ b/libc/arch-arm64/syscalls/lsetxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(lsetxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_lsetxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/madvise.S b/libc/arch-arm64/syscalls/madvise.S
index 8136ec9..8eed274 100644
--- a/libc/arch-arm64/syscalls/madvise.S
+++ b/libc/arch-arm64/syscalls/madvise.S
@@ -4,14 +4,18 @@
 
 ENTRY(madvise)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_madvise
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mincore.S b/libc/arch-arm64/syscalls/mincore.S
index 8a8e5a5..21dbe14 100644
--- a/libc/arch-arm64/syscalls/mincore.S
+++ b/libc/arch-arm64/syscalls/mincore.S
@@ -4,14 +4,18 @@
 
 ENTRY(mincore)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mincore
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mkdirat.S b/libc/arch-arm64/syscalls/mkdirat.S
index b3dd838..efd9786 100644
--- a/libc/arch-arm64/syscalls/mkdirat.S
+++ b/libc/arch-arm64/syscalls/mkdirat.S
@@ -4,14 +4,18 @@
 
 ENTRY(mkdirat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mkdirat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mknodat.S b/libc/arch-arm64/syscalls/mknodat.S
index aca6786..1bf42d0 100644
--- a/libc/arch-arm64/syscalls/mknodat.S
+++ b/libc/arch-arm64/syscalls/mknodat.S
@@ -4,14 +4,18 @@
 
 ENTRY(mknodat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mknodat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mlock.S b/libc/arch-arm64/syscalls/mlock.S
index bb01435..e09e7fc 100644
--- a/libc/arch-arm64/syscalls/mlock.S
+++ b/libc/arch-arm64/syscalls/mlock.S
@@ -4,14 +4,18 @@
 
 ENTRY(mlock)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mlock
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mlockall.S b/libc/arch-arm64/syscalls/mlockall.S
index 278e6d3..bfb2b60 100644
--- a/libc/arch-arm64/syscalls/mlockall.S
+++ b/libc/arch-arm64/syscalls/mlockall.S
@@ -4,14 +4,18 @@
 
 ENTRY(mlockall)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mlockall
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mmap.S b/libc/arch-arm64/syscalls/mmap.S
index 4d49185..437698a 100644
--- a/libc/arch-arm64/syscalls/mmap.S
+++ b/libc/arch-arm64/syscalls/mmap.S
@@ -4,14 +4,18 @@
 
 ENTRY(mmap)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mmap
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mount.S b/libc/arch-arm64/syscalls/mount.S
index d88a54b..34170d8 100644
--- a/libc/arch-arm64/syscalls/mount.S
+++ b/libc/arch-arm64/syscalls/mount.S
@@ -4,14 +4,18 @@
 
 ENTRY(mount)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mount
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mprotect.S b/libc/arch-arm64/syscalls/mprotect.S
index c8a2efe..cdb4bc8 100644
--- a/libc/arch-arm64/syscalls/mprotect.S
+++ b/libc/arch-arm64/syscalls/mprotect.S
@@ -4,14 +4,18 @@
 
 ENTRY(mprotect)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mprotect
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/mremap.S
index 7c7fe5b..605b39d 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/mremap.S
@@ -4,14 +4,18 @@
 
 ENTRY(mremap)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_mremap
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/msync.S b/libc/arch-arm64/syscalls/msync.S
index b45c99d..e511e86 100644
--- a/libc/arch-arm64/syscalls/msync.S
+++ b/libc/arch-arm64/syscalls/msync.S
@@ -4,14 +4,18 @@
 
 ENTRY(msync)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_msync
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/munlock.S b/libc/arch-arm64/syscalls/munlock.S
index d84b850..f837c9c 100644
--- a/libc/arch-arm64/syscalls/munlock.S
+++ b/libc/arch-arm64/syscalls/munlock.S
@@ -4,14 +4,18 @@
 
 ENTRY(munlock)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_munlock
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/munlockall.S b/libc/arch-arm64/syscalls/munlockall.S
index e043f71..93e9121 100644
--- a/libc/arch-arm64/syscalls/munlockall.S
+++ b/libc/arch-arm64/syscalls/munlockall.S
@@ -4,14 +4,18 @@
 
 ENTRY(munlockall)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_munlockall
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/munmap.S b/libc/arch-arm64/syscalls/munmap.S
index 02afbe8..f2b22bd 100644
--- a/libc/arch-arm64/syscalls/munmap.S
+++ b/libc/arch-arm64/syscalls/munmap.S
@@ -4,14 +4,18 @@
 
 ENTRY(munmap)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_munmap
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/nanosleep.S b/libc/arch-arm64/syscalls/nanosleep.S
index 8cd9a95..e33311a 100644
--- a/libc/arch-arm64/syscalls/nanosleep.S
+++ b/libc/arch-arm64/syscalls/nanosleep.S
@@ -4,14 +4,18 @@
 
 ENTRY(nanosleep)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_nanosleep
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/perf_event_open.S b/libc/arch-arm64/syscalls/perf_event_open.S
deleted file mode 100644
index 3960264..0000000
--- a/libc/arch-arm64/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    stp     x29, x30, [sp, #-16]!
-    mov     x29,  sp
-    str     x8,       [sp, #-16]!
-
-    mov     x8, __NR_perf_event_open
-    svc     #0
-
-    ldr     x8,       [sp], #16
-    ldp     x29, x30, [sp], #16
-
-    cmn     x0, #(MAX_ERRNO + 1)
-    cneg    x0, x0, hi
-    b.hi    __set_errno
-
-    ret
-END(perf_event_open)
diff --git a/libc/arch-arm64/syscalls/personality.S b/libc/arch-arm64/syscalls/personality.S
index 2535467..c37cae2 100644
--- a/libc/arch-arm64/syscalls/personality.S
+++ b/libc/arch-arm64/syscalls/personality.S
@@ -4,14 +4,18 @@
 
 ENTRY(personality)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_personality
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/pipe2.S b/libc/arch-arm64/syscalls/pipe2.S
index f72e707..ab2e259 100644
--- a/libc/arch-arm64/syscalls/pipe2.S
+++ b/libc/arch-arm64/syscalls/pipe2.S
@@ -4,14 +4,18 @@
 
 ENTRY(pipe2)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_pipe2
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/prctl.S b/libc/arch-arm64/syscalls/prctl.S
index 79b3e92..dd46fd4 100644
--- a/libc/arch-arm64/syscalls/prctl.S
+++ b/libc/arch-arm64/syscalls/prctl.S
@@ -4,14 +4,18 @@
 
 ENTRY(prctl)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_prctl
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/pread64.S b/libc/arch-arm64/syscalls/pread64.S
index b333946..ddc6c12 100644
--- a/libc/arch-arm64/syscalls/pread64.S
+++ b/libc/arch-arm64/syscalls/pread64.S
@@ -4,14 +4,18 @@
 
 ENTRY(pread64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_pread64
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/prlimit64.S b/libc/arch-arm64/syscalls/prlimit64.S
index c8820ef..39d31b0 100644
--- a/libc/arch-arm64/syscalls/prlimit64.S
+++ b/libc/arch-arm64/syscalls/prlimit64.S
@@ -4,14 +4,18 @@
 
 ENTRY(prlimit64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_prlimit64
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/pwrite64.S b/libc/arch-arm64/syscalls/pwrite64.S
index 1ae312c..81e2cf7 100644
--- a/libc/arch-arm64/syscalls/pwrite64.S
+++ b/libc/arch-arm64/syscalls/pwrite64.S
@@ -4,14 +4,18 @@
 
 ENTRY(pwrite64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_pwrite64
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/read.S b/libc/arch-arm64/syscalls/read.S
index cf7ca04..c529576 100644
--- a/libc/arch-arm64/syscalls/read.S
+++ b/libc/arch-arm64/syscalls/read.S
@@ -4,14 +4,18 @@
 
 ENTRY(read)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_read
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/readahead.S b/libc/arch-arm64/syscalls/readahead.S
index fe45cf9..e8394cc 100644
--- a/libc/arch-arm64/syscalls/readahead.S
+++ b/libc/arch-arm64/syscalls/readahead.S
@@ -4,14 +4,18 @@
 
 ENTRY(readahead)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_readahead
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/readlinkat.S b/libc/arch-arm64/syscalls/readlinkat.S
index eb8221c..d7cadcc 100644
--- a/libc/arch-arm64/syscalls/readlinkat.S
+++ b/libc/arch-arm64/syscalls/readlinkat.S
@@ -4,14 +4,18 @@
 
 ENTRY(readlinkat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_readlinkat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/readv.S b/libc/arch-arm64/syscalls/readv.S
index f4fa612..98d0742 100644
--- a/libc/arch-arm64/syscalls/readv.S
+++ b/libc/arch-arm64/syscalls/readv.S
@@ -4,14 +4,18 @@
 
 ENTRY(readv)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_readv
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/recvfrom.S b/libc/arch-arm64/syscalls/recvfrom.S
index 51ac25f..63181f1 100644
--- a/libc/arch-arm64/syscalls/recvfrom.S
+++ b/libc/arch-arm64/syscalls/recvfrom.S
@@ -4,14 +4,18 @@
 
 ENTRY(recvfrom)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_recvfrom
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/recvmmsg.S b/libc/arch-arm64/syscalls/recvmmsg.S
index 44875cc..cb1fbfc 100644
--- a/libc/arch-arm64/syscalls/recvmmsg.S
+++ b/libc/arch-arm64/syscalls/recvmmsg.S
@@ -4,14 +4,18 @@
 
 ENTRY(recvmmsg)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_recvmmsg
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/recvmsg.S b/libc/arch-arm64/syscalls/recvmsg.S
index 4ca40ea..8a91a5f 100644
--- a/libc/arch-arm64/syscalls/recvmsg.S
+++ b/libc/arch-arm64/syscalls/recvmsg.S
@@ -4,14 +4,18 @@
 
 ENTRY(recvmsg)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_recvmsg
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/removexattr.S b/libc/arch-arm64/syscalls/removexattr.S
index ae53307..6fb557a 100644
--- a/libc/arch-arm64/syscalls/removexattr.S
+++ b/libc/arch-arm64/syscalls/removexattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(removexattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_removexattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/renameat.S b/libc/arch-arm64/syscalls/renameat.S
index 3f6e4d4..e4efeb8 100644
--- a/libc/arch-arm64/syscalls/renameat.S
+++ b/libc/arch-arm64/syscalls/renameat.S
@@ -4,14 +4,18 @@
 
 ENTRY(renameat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_renameat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_get_priority_max.S b/libc/arch-arm64/syscalls/sched_get_priority_max.S
index 735ca93..74f919b 100644
--- a/libc/arch-arm64/syscalls/sched_get_priority_max.S
+++ b/libc/arch-arm64/syscalls/sched_get_priority_max.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_get_priority_max)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_get_priority_max
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_get_priority_min.S b/libc/arch-arm64/syscalls/sched_get_priority_min.S
index a453b0b..d043b3b 100644
--- a/libc/arch-arm64/syscalls/sched_get_priority_min.S
+++ b/libc/arch-arm64/syscalls/sched_get_priority_min.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_get_priority_min)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_get_priority_min
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_getparam.S b/libc/arch-arm64/syscalls/sched_getparam.S
index f3492b9..fedcec8 100644
--- a/libc/arch-arm64/syscalls/sched_getparam.S
+++ b/libc/arch-arm64/syscalls/sched_getparam.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_getparam)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_getparam
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_getscheduler.S b/libc/arch-arm64/syscalls/sched_getscheduler.S
index db944f1..1225601 100644
--- a/libc/arch-arm64/syscalls/sched_getscheduler.S
+++ b/libc/arch-arm64/syscalls/sched_getscheduler.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_getscheduler)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_getscheduler
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_rr_get_interval.S b/libc/arch-arm64/syscalls/sched_rr_get_interval.S
index b91f646..796edda 100644
--- a/libc/arch-arm64/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-arm64/syscalls/sched_rr_get_interval.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_rr_get_interval)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_rr_get_interval
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_setaffinity.S b/libc/arch-arm64/syscalls/sched_setaffinity.S
index e8e1aec..2a7022d 100644
--- a/libc/arch-arm64/syscalls/sched_setaffinity.S
+++ b/libc/arch-arm64/syscalls/sched_setaffinity.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_setaffinity)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_setaffinity
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_setparam.S b/libc/arch-arm64/syscalls/sched_setparam.S
index 5df84f0..dd82a10 100644
--- a/libc/arch-arm64/syscalls/sched_setparam.S
+++ b/libc/arch-arm64/syscalls/sched_setparam.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_setparam)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_setparam
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_setscheduler.S b/libc/arch-arm64/syscalls/sched_setscheduler.S
index 83c31e4..25e1e36 100644
--- a/libc/arch-arm64/syscalls/sched_setscheduler.S
+++ b/libc/arch-arm64/syscalls/sched_setscheduler.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_setscheduler)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_setscheduler
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sched_yield.S b/libc/arch-arm64/syscalls/sched_yield.S
index 7d5f88b..cbee020 100644
--- a/libc/arch-arm64/syscalls/sched_yield.S
+++ b/libc/arch-arm64/syscalls/sched_yield.S
@@ -4,14 +4,18 @@
 
 ENTRY(sched_yield)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sched_yield
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sendfile.S b/libc/arch-arm64/syscalls/sendfile.S
index 7bf415d..1705d3c 100644
--- a/libc/arch-arm64/syscalls/sendfile.S
+++ b/libc/arch-arm64/syscalls/sendfile.S
@@ -4,14 +4,18 @@
 
 ENTRY(sendfile)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sendfile
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sendmmsg.S b/libc/arch-arm64/syscalls/sendmmsg.S
index 43b2fbf..2277110 100644
--- a/libc/arch-arm64/syscalls/sendmmsg.S
+++ b/libc/arch-arm64/syscalls/sendmmsg.S
@@ -4,14 +4,18 @@
 
 ENTRY(sendmmsg)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sendmmsg
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sendmsg.S b/libc/arch-arm64/syscalls/sendmsg.S
index 2f0cdc8..96fcb9a 100644
--- a/libc/arch-arm64/syscalls/sendmsg.S
+++ b/libc/arch-arm64/syscalls/sendmsg.S
@@ -4,14 +4,18 @@
 
 ENTRY(sendmsg)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sendmsg
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sendto.S b/libc/arch-arm64/syscalls/sendto.S
index 3fd54d1..67589ba 100644
--- a/libc/arch-arm64/syscalls/sendto.S
+++ b/libc/arch-arm64/syscalls/sendto.S
@@ -4,14 +4,18 @@
 
 ENTRY(sendto)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sendto
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setgid.S b/libc/arch-arm64/syscalls/setgid.S
index 0a811b0..fbaa785 100644
--- a/libc/arch-arm64/syscalls/setgid.S
+++ b/libc/arch-arm64/syscalls/setgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setgroups.S b/libc/arch-arm64/syscalls/setgroups.S
index d316e5e..48035b6 100644
--- a/libc/arch-arm64/syscalls/setgroups.S
+++ b/libc/arch-arm64/syscalls/setgroups.S
@@ -4,14 +4,18 @@
 
 ENTRY(setgroups)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setgroups
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setitimer.S b/libc/arch-arm64/syscalls/setitimer.S
index 7c2b718..42af94b 100644
--- a/libc/arch-arm64/syscalls/setitimer.S
+++ b/libc/arch-arm64/syscalls/setitimer.S
@@ -4,14 +4,18 @@
 
 ENTRY(setitimer)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setitimer
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setns.S b/libc/arch-arm64/syscalls/setns.S
index 2ce2a75..f695597 100644
--- a/libc/arch-arm64/syscalls/setns.S
+++ b/libc/arch-arm64/syscalls/setns.S
@@ -4,14 +4,18 @@
 
 ENTRY(setns)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setns
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setpgid.S b/libc/arch-arm64/syscalls/setpgid.S
index bd12e70..5653256 100644
--- a/libc/arch-arm64/syscalls/setpgid.S
+++ b/libc/arch-arm64/syscalls/setpgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setpgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setpgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setpriority.S b/libc/arch-arm64/syscalls/setpriority.S
index d9a4857..121bcaa 100644
--- a/libc/arch-arm64/syscalls/setpriority.S
+++ b/libc/arch-arm64/syscalls/setpriority.S
@@ -4,14 +4,18 @@
 
 ENTRY(setpriority)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setpriority
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setregid.S b/libc/arch-arm64/syscalls/setregid.S
index 702ae8b..6389551 100644
--- a/libc/arch-arm64/syscalls/setregid.S
+++ b/libc/arch-arm64/syscalls/setregid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setregid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setregid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setresgid.S b/libc/arch-arm64/syscalls/setresgid.S
index c9501ac..bf78249 100644
--- a/libc/arch-arm64/syscalls/setresgid.S
+++ b/libc/arch-arm64/syscalls/setresgid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setresgid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setresgid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setresuid.S b/libc/arch-arm64/syscalls/setresuid.S
index 6f680c3..83200da 100644
--- a/libc/arch-arm64/syscalls/setresuid.S
+++ b/libc/arch-arm64/syscalls/setresuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setresuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setresuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setreuid.S b/libc/arch-arm64/syscalls/setreuid.S
index ef870fa..2253eec 100644
--- a/libc/arch-arm64/syscalls/setreuid.S
+++ b/libc/arch-arm64/syscalls/setreuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setreuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setreuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setrlimit.S b/libc/arch-arm64/syscalls/setrlimit.S
index 4bc412a..034ae36 100644
--- a/libc/arch-arm64/syscalls/setrlimit.S
+++ b/libc/arch-arm64/syscalls/setrlimit.S
@@ -4,14 +4,18 @@
 
 ENTRY(setrlimit)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setrlimit
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setsid.S b/libc/arch-arm64/syscalls/setsid.S
index c9ba594..64123df 100644
--- a/libc/arch-arm64/syscalls/setsid.S
+++ b/libc/arch-arm64/syscalls/setsid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setsid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setsid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setsockopt.S b/libc/arch-arm64/syscalls/setsockopt.S
index 7c9d584..fe8da22 100644
--- a/libc/arch-arm64/syscalls/setsockopt.S
+++ b/libc/arch-arm64/syscalls/setsockopt.S
@@ -4,14 +4,18 @@
 
 ENTRY(setsockopt)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setsockopt
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/settimeofday.S b/libc/arch-arm64/syscalls/settimeofday.S
index 4cf6ff2..50debf9 100644
--- a/libc/arch-arm64/syscalls/settimeofday.S
+++ b/libc/arch-arm64/syscalls/settimeofday.S
@@ -4,14 +4,18 @@
 
 ENTRY(settimeofday)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_settimeofday
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setuid.S b/libc/arch-arm64/syscalls/setuid.S
index a886c15..0a9adbe 100644
--- a/libc/arch-arm64/syscalls/setuid.S
+++ b/libc/arch-arm64/syscalls/setuid.S
@@ -4,14 +4,18 @@
 
 ENTRY(setuid)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setuid
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/setxattr.S b/libc/arch-arm64/syscalls/setxattr.S
index 1d25f3a..ebfd607 100644
--- a/libc/arch-arm64/syscalls/setxattr.S
+++ b/libc/arch-arm64/syscalls/setxattr.S
@@ -4,14 +4,18 @@
 
 ENTRY(setxattr)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_setxattr
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/shutdown.S b/libc/arch-arm64/syscalls/shutdown.S
index b9fc3c3..6e878d6 100644
--- a/libc/arch-arm64/syscalls/shutdown.S
+++ b/libc/arch-arm64/syscalls/shutdown.S
@@ -4,14 +4,18 @@
 
 ENTRY(shutdown)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_shutdown
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sigaltstack.S b/libc/arch-arm64/syscalls/sigaltstack.S
index 6052caa..46794d4 100644
--- a/libc/arch-arm64/syscalls/sigaltstack.S
+++ b/libc/arch-arm64/syscalls/sigaltstack.S
@@ -4,14 +4,18 @@
 
 ENTRY(sigaltstack)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sigaltstack
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/socketpair.S b/libc/arch-arm64/syscalls/socketpair.S
index 05e617b..c42ff24 100644
--- a/libc/arch-arm64/syscalls/socketpair.S
+++ b/libc/arch-arm64/syscalls/socketpair.S
@@ -4,14 +4,18 @@
 
 ENTRY(socketpair)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_socketpair
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/statfs64.S b/libc/arch-arm64/syscalls/statfs64.S
index c037980..66662ee 100644
--- a/libc/arch-arm64/syscalls/statfs64.S
+++ b/libc/arch-arm64/syscalls/statfs64.S
@@ -4,14 +4,18 @@
 
 ENTRY(statfs64)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_statfs
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/swapoff.S b/libc/arch-arm64/syscalls/swapoff.S
index 742b460..1d465b0 100644
--- a/libc/arch-arm64/syscalls/swapoff.S
+++ b/libc/arch-arm64/syscalls/swapoff.S
@@ -4,14 +4,18 @@
 
 ENTRY(swapoff)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_swapoff
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/swapon.S b/libc/arch-arm64/syscalls/swapon.S
index b82d7de..7e5f850 100644
--- a/libc/arch-arm64/syscalls/swapon.S
+++ b/libc/arch-arm64/syscalls/swapon.S
@@ -4,14 +4,18 @@
 
 ENTRY(swapon)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_swapon
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/symlinkat.S b/libc/arch-arm64/syscalls/symlinkat.S
index c6a8313..0081cf2 100644
--- a/libc/arch-arm64/syscalls/symlinkat.S
+++ b/libc/arch-arm64/syscalls/symlinkat.S
@@ -4,14 +4,18 @@
 
 ENTRY(symlinkat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_symlinkat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sync.S b/libc/arch-arm64/syscalls/sync.S
index 1954fe8..67bc554 100644
--- a/libc/arch-arm64/syscalls/sync.S
+++ b/libc/arch-arm64/syscalls/sync.S
@@ -4,14 +4,18 @@
 
 ENTRY(sync)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sync
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/sysinfo.S b/libc/arch-arm64/syscalls/sysinfo.S
index cb91550..0797a39 100644
--- a/libc/arch-arm64/syscalls/sysinfo.S
+++ b/libc/arch-arm64/syscalls/sysinfo.S
@@ -4,14 +4,18 @@
 
 ENTRY(sysinfo)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_sysinfo
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/tgkill.S b/libc/arch-arm64/syscalls/tgkill.S
index a401819..9366c70 100644
--- a/libc/arch-arm64/syscalls/tgkill.S
+++ b/libc/arch-arm64/syscalls/tgkill.S
@@ -4,14 +4,18 @@
 
 ENTRY(tgkill)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_tgkill
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/timerfd_create.S b/libc/arch-arm64/syscalls/timerfd_create.S
index e0558be..1e9d2e3 100644
--- a/libc/arch-arm64/syscalls/timerfd_create.S
+++ b/libc/arch-arm64/syscalls/timerfd_create.S
@@ -4,14 +4,18 @@
 
 ENTRY(timerfd_create)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timerfd_create
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/timerfd_gettime.S b/libc/arch-arm64/syscalls/timerfd_gettime.S
index 09234cd..56d7f96 100644
--- a/libc/arch-arm64/syscalls/timerfd_gettime.S
+++ b/libc/arch-arm64/syscalls/timerfd_gettime.S
@@ -4,14 +4,18 @@
 
 ENTRY(timerfd_gettime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timerfd_gettime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/timerfd_settime.S b/libc/arch-arm64/syscalls/timerfd_settime.S
index cc205ad..29af0f1 100644
--- a/libc/arch-arm64/syscalls/timerfd_settime.S
+++ b/libc/arch-arm64/syscalls/timerfd_settime.S
@@ -4,14 +4,18 @@
 
 ENTRY(timerfd_settime)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_timerfd_settime
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/times.S b/libc/arch-arm64/syscalls/times.S
index c5fe38b..9487186 100644
--- a/libc/arch-arm64/syscalls/times.S
+++ b/libc/arch-arm64/syscalls/times.S
@@ -4,14 +4,18 @@
 
 ENTRY(times)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_times
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/tkill.S b/libc/arch-arm64/syscalls/tkill.S
index 0b910fc..307bd14 100644
--- a/libc/arch-arm64/syscalls/tkill.S
+++ b/libc/arch-arm64/syscalls/tkill.S
@@ -4,14 +4,18 @@
 
 ENTRY(tkill)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_tkill
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/truncate.S b/libc/arch-arm64/syscalls/truncate.S
index 7e3385b..3bbe356 100644
--- a/libc/arch-arm64/syscalls/truncate.S
+++ b/libc/arch-arm64/syscalls/truncate.S
@@ -4,14 +4,18 @@
 
 ENTRY(truncate)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_truncate
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/umask.S b/libc/arch-arm64/syscalls/umask.S
index 70a3e01..ca72092 100644
--- a/libc/arch-arm64/syscalls/umask.S
+++ b/libc/arch-arm64/syscalls/umask.S
@@ -4,14 +4,18 @@
 
 ENTRY(umask)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_umask
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/umount2.S b/libc/arch-arm64/syscalls/umount2.S
index cdd0362..a959625 100644
--- a/libc/arch-arm64/syscalls/umount2.S
+++ b/libc/arch-arm64/syscalls/umount2.S
@@ -4,14 +4,18 @@
 
 ENTRY(umount2)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_umount2
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/uname.S b/libc/arch-arm64/syscalls/uname.S
index c242786..2f87563 100644
--- a/libc/arch-arm64/syscalls/uname.S
+++ b/libc/arch-arm64/syscalls/uname.S
@@ -4,14 +4,18 @@
 
 ENTRY(uname)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_uname
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/unlinkat.S b/libc/arch-arm64/syscalls/unlinkat.S
index f7bb2c5..0025726 100644
--- a/libc/arch-arm64/syscalls/unlinkat.S
+++ b/libc/arch-arm64/syscalls/unlinkat.S
@@ -4,14 +4,18 @@
 
 ENTRY(unlinkat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_unlinkat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/unshare.S b/libc/arch-arm64/syscalls/unshare.S
index c9bd497..55462b4 100644
--- a/libc/arch-arm64/syscalls/unshare.S
+++ b/libc/arch-arm64/syscalls/unshare.S
@@ -4,14 +4,18 @@
 
 ENTRY(unshare)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_unshare
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/utimensat.S b/libc/arch-arm64/syscalls/utimensat.S
index 62c98a6..aa5cfbf 100644
--- a/libc/arch-arm64/syscalls/utimensat.S
+++ b/libc/arch-arm64/syscalls/utimensat.S
@@ -4,14 +4,18 @@
 
 ENTRY(utimensat)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_utimensat
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/wait4.S b/libc/arch-arm64/syscalls/wait4.S
index 7431535..93183e5 100644
--- a/libc/arch-arm64/syscalls/wait4.S
+++ b/libc/arch-arm64/syscalls/wait4.S
@@ -4,14 +4,18 @@
 
 ENTRY(wait4)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_wait4
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/write.S b/libc/arch-arm64/syscalls/write.S
index 2f95f5d..b7288d1 100644
--- a/libc/arch-arm64/syscalls/write.S
+++ b/libc/arch-arm64/syscalls/write.S
@@ -4,14 +4,18 @@
 
 ENTRY(write)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_write
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-arm64/syscalls/writev.S b/libc/arch-arm64/syscalls/writev.S
index 015c1d3..13af454 100644
--- a/libc/arch-arm64/syscalls/writev.S
+++ b/libc/arch-arm64/syscalls/writev.S
@@ -4,14 +4,18 @@
 
 ENTRY(writev)
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, __NR_writev
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/arch-mips/bionic/__get_sp.S b/libc/arch-mips/bionic/__get_sp.S
index d4b278b..5f5d32e 100644
--- a/libc/arch-mips/bionic/__get_sp.S
+++ b/libc/arch-mips/bionic/__get_sp.S
@@ -28,8 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-// void* __get_sp()
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
   move v0, sp
   j ra
 END(__get_sp)
diff --git a/libc/arch-mips/bionic/futex_mips.S b/libc/arch-mips/bionic/futex_mips.S
index 7626a7c..5a09f32 100644
--- a/libc/arch-mips/bionic/futex_mips.S
+++ b/libc/arch-mips/bionic/futex_mips.S
@@ -28,74 +28,8 @@
 
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-ENTRY(__futex_wait)
-	subu	sp,4*6
-	sw	$0,20(sp)	/* val3 */
-	sw	$0,16(sp)	/* addr2 */
-	move	a3,a2		/* timespec */
-	move	a2,a1		/* val */
-	li	a1,FUTEX_WAIT	/* op */
-#	move	a0,a0		/* ftx */
-	li	v0,__NR_futex
-	syscall
-	.set noreorder
-	bnez	a3, 1f		/* Check for error */
-         neg	v0		/* Negate error number if it's valid */
-	move	v0,$0		/* Otherwise return 0 */
-1:
-	.set reorder
-	addu	sp,4*6
-	j	ra
-END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-ENTRY(__futex_wake)
-	subu	sp,4*6
-	sw	$0,20(sp)	/* val3 */
-	sw	$0,16(sp)	/* addr2 */
-	move	a3,$0		/* timespec */
-	move	a2,a1		/* val */
-	li	a1,FUTEX_WAKE	/* op */
-#	move	a0,a0		/* ftx */
-	li	v0,__NR_futex
-	syscall
-	.set noreorder
-	bnez	a3, 1f		/* Check for error */
-         neg	v0		/* Negate error number if it's valid */
-	move	v0,$0		/* Otherwise return 0 */
-1:
-	.set reorder
-	addu	sp,4*6
-	j	ra
-END(__futex_wake)
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-ENTRY(__futex_syscall3)
-	subu	sp,4*6
-	sw	$0,20(sp)	/* val3 */
-	sw	$0,16(sp)	/* addr2 */
-	move	a3,$0		/* timespec */
-#	move	a2,a2		/* val */
-#	li	a1,a1		/* op */
-#	move	a0,a0		/* ftx */
-	li	v0,__NR_futex
-	syscall
-	.set noreorder
-	bnez	a3, 1f		/* Check for error */
-         neg	v0		/* Negate error number if it's valid */
-	move	v0,$0		/* Otherwise return 0 */
-1:
-	.set reorder
-	addu	sp,4*6
-	j	ra
-END(__futex_syscall3)
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
-ENTRY(__futex_syscall4)
+ENTRY_PRIVATE(__futex_syscall4)
 	subu	sp,4*6
 	sw	$0,20(sp)	/* val3 */
 	sw	$0,16(sp)	/* addr2 */
diff --git a/libc/arch-mips/syscalls/__syslog.S b/libc/arch-mips/syscalls/__syslog.S
deleted file mode 100644
index ace69c7..0000000
--- a/libc/arch-mips/syscalls/__syslog.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    .set noreorder
-    .cpload t9
-    li v0, __NR_syslog
-    syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
-    nop
-1:
-    la t9,__set_errno
-    j t9
-    nop
-    .set reorder
-END(__syslog)
diff --git a/libc/arch-mips/syscalls/perf_event_open.S b/libc/arch-mips/syscalls/perf_event_open.S
deleted file mode 100644
index a0e4416..0000000
--- a/libc/arch-mips/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    .set noreorder
-    .cpload t9
-    li v0, __NR_perf_event_open
-    syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
-    nop
-1:
-    la t9,__set_errno
-    j t9
-    nop
-    .set reorder
-END(perf_event_open)
diff --git a/libc/arch-mips64/bionic/__get_sp.S b/libc/arch-mips64/bionic/__get_sp.S
index 8488102..5f5d32e 100644
--- a/libc/arch-mips64/bionic/__get_sp.S
+++ b/libc/arch-mips64/bionic/__get_sp.S
@@ -28,7 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
   move v0, sp
   j ra
 END(__get_sp)
diff --git a/libc/arch-mips64/bionic/futex_mips.S b/libc/arch-mips64/bionic/futex_mips.S
index 81f2f22..60c218c 100644
--- a/libc/arch-mips64/bionic/futex_mips.S
+++ b/libc/arch-mips64/bionic/futex_mips.S
@@ -28,9 +28,6 @@
 
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
 FRAMESZ		=	MKFSIZ(NARGSAVE+2,0)
 FRAME_A4	=	4*REGSZ
@@ -39,84 +36,6 @@
 FRAMESZ		=	0
 #endif
 
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-LEAF(__futex_wait, FRAMESZ)
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_SUBU sp, FRAMESZ
-	REG_S	$0,FRAME_A5(sp)	/* val3 */
-	REG_S	$0,FRAME_A4(sp)	/* addr2 */
-#else
-	move	a5,$0		/* val3 */
-	move	a4,$0		/* addr2 */
-#endif
-	move	a3,a2		/* timespec */
-	move	a2,a1		/* val */
-	LI	a1,FUTEX_WAIT	/* op */
-#	move	a0,a0		/* ftx */
-	LI	v0,__NR_futex
-	syscall
-	neg	v0		/* Negate errno */
-	bnez	a3,1f		/* Check for error */
-	move	v0,$0		/* Return 0 if no error */
-1:
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_ADDU sp,FRAMESZ
-#endif
-	j	ra
-	END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-LEAF(__futex_wake,FRAMESZ)
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_SUBU sp, FRAMESZ
-	REG_S	$0,FRAME_A5(sp)	/* val3 */
-	REG_S	$0,FRAME_A4(sp)	/* addr2 */
-#else
-	move	a5,$0		/* val3 */
-	move	a4,$0		/* addr2 */
-#endif
-	move	a3,$0		/* timespec */
-	move	a2,a1		/* val */
-	LI	a1,FUTEX_WAKE	/* op */
-#	move	a0,a0		/* ftx */
-	LI	v0,__NR_futex
-	syscall
-	neg	v0		/* Negate errno */
-	bnez	a3,1f		/* Check for error */
-	move	v0,$0		/* Return 0 if no error */
-1:
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_ADDU sp,FRAMESZ
-#endif
-	j	ra
-	END(__futex_wake)
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-LEAF(__futex_syscall3,FRAMESZ)
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_SUBU sp, FRAMESZ
-	REG_S	$0,FRAME_A5(sp)	/* val3 */
-	REG_S	$0,FRAME_A4(sp)	/* addr2 */
-#else
-	move	a5,$0		/* val3 */
-	move	a4,$0		/* addr2 */
-#endif
-	move	a3,$0		/* timespec */
-#	move	a2,a2		/* val */
-#	move	a1,a1		/* op */
-#	move	a0,a0		/* ftx */
-	LI	v0,__NR_futex
-	syscall
-	neg	v0		/* Negate errno */
-	bnez	a3,1f		/* Check for error */
-	move	v0,$0		/* Return 0 if no error */
-1:
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_ADDU sp,FRAMESZ
-#endif
-	j	ra
-	END(__futex_syscall3)
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
 LEAF(__futex_syscall4,FRAMESZ)
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
@@ -142,3 +61,4 @@
 #endif
 	j	ra
 	END(__futex_syscall4)
+.hidden __futex_syscall4
diff --git a/libc/arch-mips64/syscalls/__syslog.S b/libc/arch-mips64/syscalls/__syslog.S
deleted file mode 100644
index 70eed3a..0000000
--- a/libc/arch-mips64/syscalls/__syslog.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    .set push
-    .set noreorder
-    li v0, __NR_syslog
-    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
-    .cpreturn
-    j t9
-    move ra, t0
-    .set pop
-END(__syslog)
-.hidden __syslog
diff --git a/libc/arch-mips64/syscalls/perf_event_open.S b/libc/arch-mips64/syscalls/perf_event_open.S
deleted file mode 100644
index d796a16..0000000
--- a/libc/arch-mips64/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    .set push
-    .set noreorder
-    li v0, __NR_perf_event_open
-    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
-    .cpreturn
-    j t9
-    move ra, t0
-    .set pop
-END(perf_event_open)
diff --git a/libc/arch-x86/bionic/__get_sp.S b/libc/arch-x86/bionic/__get_sp.S
index 31ec6bc..aea6ac6 100644
--- a/libc/arch-x86/bionic/__get_sp.S
+++ b/libc/arch-x86/bionic/__get_sp.S
@@ -28,7 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
   mov  %esp, %eax
   ret
 END(__get_sp)
diff --git a/libc/arch-x86/bionic/__set_tls.c b/libc/arch-x86/bionic/__set_tls.c
index 722ec6f..38ed3c9 100644
--- a/libc/arch-x86/bionic/__set_tls.c
+++ b/libc/arch-x86/bionic/__set_tls.c
@@ -57,7 +57,7 @@
   result->useable = 1;
 }
 
-int __set_tls(void* ptr) {
+__LIBC_HIDDEN__ int __set_tls(void* ptr) {
   struct user_desc tls_descriptor;
   __init_user_desc(&tls_descriptor, true, ptr);
 
diff --git a/libc/arch-x86/bionic/futex_x86.S b/libc/arch-x86/bionic/futex_x86.S
index 8dd2ad0..94647ca 100644
--- a/libc/arch-x86/bionic/futex_x86.S
+++ b/libc/arch-x86/bionic/futex_x86.S
@@ -1,49 +1,7 @@
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-ENTRY(__futex_wait)
-    pushl   %ebx
-    pushl   %esi
-    mov     12(%esp), %ebx           /* ftx */
-    movl    $FUTEX_WAIT, %ecx
-    mov     16(%esp), %edx           /* val */
-    mov     20(%esp), %esi           /* timeout */
-    movl    $__NR_futex, %eax
-    int     $0x80
-    popl    %esi
-    popl    %ebx
-    ret
-END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-ENTRY(__futex_wake)
-    pushl   %ebx
-    mov     8(%esp), %ebx            /* ftx */
-    movl    $FUTEX_WAKE, %ecx
-    mov     12(%esp), %edx           /* count */
-    movl    $__NR_futex, %eax
-    int     $0x80
-    popl    %ebx
-    ret
-END(__futex_wake)
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-ENTRY(__futex_syscall3)
-    pushl   %ebx
-    movl    8(%esp), %ebx      /* ftx */
-    movl    12(%esp), %ecx      /* op */
-    movl    16(%esp), %edx      /* value */
-    movl    $__NR_futex, %eax
-    int     $0x80
-    popl    %ebx
-    ret
-END(__futex_syscall3)
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
-ENTRY(__futex_syscall4)
+ENTRY_PRIVATE(__futex_syscall4)
     pushl   %ebx
     pushl   %esi
     movl    12(%esp), %ebx      /* ftx */
diff --git a/libc/arch-x86/syscalls/__syslog.S b/libc/arch-x86/syscalls/__syslog.S
deleted file mode 100644
index 1da01be..0000000
--- a/libc/arch-x86/syscalls/__syslog.S
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    pushl   %ebx
-    pushl   %ecx
-    pushl   %edx
-    .cfi_def_cfa_offset 12
-    .cfi_rel_offset ebx, 0
-    .cfi_rel_offset ecx, 4
-    .cfi_rel_offset edx, 8
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_syslog, %eax
-    int     $0x80
-    cmpl    $-MAX_ERRNO, %eax
-    jb      1f
-    negl    %eax
-    pushl   %eax
-    call    __set_errno
-    addl    $4, %esp
-    orl     $-1, %eax
-1:
-    popl    %edx
-    popl    %ecx
-    popl    %ebx
-    ret
-END(__syslog)
diff --git a/libc/arch-x86/syscalls/perf_event_open.S b/libc/arch-x86/syscalls/perf_event_open.S
deleted file mode 100644
index ebbe1f0..0000000
--- a/libc/arch-x86/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    pushl   %ebx
-    pushl   %ecx
-    pushl   %edx
-    pushl   %esi
-    pushl   %edi
-    .cfi_def_cfa_offset 20
-    .cfi_rel_offset ebx, 0
-    .cfi_rel_offset ecx, 4
-    .cfi_rel_offset edx, 8
-    .cfi_rel_offset esi, 12
-    .cfi_rel_offset edi, 16
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
-    movl    $__NR_perf_event_open, %eax
-    int     $0x80
-    cmpl    $-MAX_ERRNO, %eax
-    jb      1f
-    negl    %eax
-    pushl   %eax
-    call    __set_errno
-    addl    $4, %esp
-    orl     $-1, %eax
-1:
-    popl    %edi
-    popl    %esi
-    popl    %edx
-    popl    %ecx
-    popl    %ebx
-    ret
-END(perf_event_open)
diff --git a/libc/arch-x86_64/bionic/__get_sp.S b/libc/arch-x86_64/bionic/__get_sp.S
index 9cc18a9..49a2406 100644
--- a/libc/arch-x86_64/bionic/__get_sp.S
+++ b/libc/arch-x86_64/bionic/__get_sp.S
@@ -28,7 +28,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(__get_sp)
+ENTRY_PRIVATE(__get_sp)
   mov  %rsp, %rax
   ret
 END(__get_sp)
diff --git a/libc/arch-x86_64/bionic/__set_tls.c b/libc/arch-x86_64/bionic/__set_tls.c
index cc7a5f4..10fd36f 100644
--- a/libc/arch-x86_64/bionic/__set_tls.c
+++ b/libc/arch-x86_64/bionic/__set_tls.c
@@ -26,11 +26,12 @@
  * SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
 #include <asm/prctl.h>
 #include <stdint.h>
 
 extern int __arch_prctl(int, unsigned long);
 
-int __set_tls(void* ptr) {
+__LIBC_HIDDEN__ int __set_tls(void* ptr) {
   return __arch_prctl(ARCH_SET_FS, (uintptr_t) ptr);
 }
diff --git a/libc/arch-x86_64/bionic/futex_x86_64.S b/libc/arch-x86_64/bionic/futex_x86_64.S
index 25cdf1b..c248439 100644
--- a/libc/arch-x86_64/bionic/futex_x86_64.S
+++ b/libc/arch-x86_64/bionic/futex_x86_64.S
@@ -28,37 +28,8 @@
 
 #include <private/bionic_asm.h>
 
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
-ENTRY_PRIVATE(__futex_wait)
-    mov     %rdx, %r10           /* timeout */
-    mov     %esi, %edx           /* val */
-    mov     $FUTEX_WAIT, %esi    /* op */
-    mov     $__NR_futex, %eax
-    syscall
-    ret
-END(__futex_wait)
-
-// int __futex_wake(volatile void* ftx, int count)
-ENTRY_PRIVATE(__futex_wake)
-    mov     %esi, %edx
-    mov     $FUTEX_WAKE, %esi
-    mov     $__NR_futex, %eax
-    syscall
-    ret
-END(__futex_wake)
-
-// int __futex_syscall3(volatile void* ftx, int op, int count)
-ENTRY(__futex_syscall3)
-    mov     $__NR_futex, %eax
-    syscall
-    ret
-END(__futex_syscall3)
-
 // int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
-ENTRY(__futex_syscall4)
+ENTRY_PRIVATE(__futex_syscall4)
     mov     %rcx, %r10      /* timeout */
     mov     $__NR_futex, %eax
     syscall
diff --git a/libc/arch-x86_64/syscalls/__syslog.S b/libc/arch-x86_64/syscalls/__syslog.S
deleted file mode 100644
index f710025..0000000
--- a/libc/arch-x86_64/syscalls/__syslog.S
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(__syslog)
-    movl    $__NR_syslog, %eax
-    syscall
-    cmpq    $-MAX_ERRNO, %rax
-    jb      1f
-    negl    %eax
-    movl    %eax, %edi
-    call    __set_errno
-    orq     $-1, %rax
-1:
-    ret
-END(__syslog)
-.hidden __syslog
diff --git a/libc/arch-x86_64/syscalls/perf_event_open.S b/libc/arch-x86_64/syscalls/perf_event_open.S
deleted file mode 100644
index d9fc71e..0000000
--- a/libc/arch-x86_64/syscalls/perf_event_open.S
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(perf_event_open)
-    movq    %rcx, %r10
-    movl    $__NR_perf_event_open, %eax
-    syscall
-    cmpq    $-MAX_ERRNO, %rax
-    jb      1f
-    negl    %eax
-    movl    %eax, %edi
-    call    __set_errno
-    orq     $-1, %rax
-1:
-    ret
-END(perf_event_open)
diff --git a/libc/bionic/debug_mapinfo.cpp b/libc/bionic/debug_mapinfo.cpp
index c5b9aa7..e81ea54 100644
--- a/libc/bionic/debug_mapinfo.cpp
+++ b/libc/bionic/debug_mapinfo.cpp
@@ -30,7 +30,13 @@
 #include <string.h>
 #include <stdlib.h>
 
+#ifdef USE_JEMALLOC
+#include "jemalloc.h"
+#define Malloc(function)  je_ ## function
+#else
 #include "dlmalloc.h"
+#define Malloc(function)  dl ## function
+#endif
 #include "debug_mapinfo.h"
 
 // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /system/lib/libcomposer.so
@@ -46,7 +52,7 @@
   if (len < 50) return 0;
   if (line[20] != 'x') return 0;
 
-  mapinfo_t* mi = static_cast<mapinfo_t*>(dlmalloc(sizeof(mapinfo_t) + (len - 47)));
+  mapinfo_t* mi = static_cast<mapinfo_t*>(Malloc(malloc)(sizeof(mapinfo_t) + (len - 47)));
   if (mi == 0) return 0;
 
   mi->start = strtoul(line, 0, 16);
@@ -79,7 +85,7 @@
   while (mi != NULL) {
     mapinfo_t* del = mi;
     mi = mi->next;
-    dlfree(del);
+    Malloc(free)(del);
   }
 }
 
diff --git a/libc/bionic/jemalloc.cpp b/libc/bionic/jemalloc.cpp
new file mode 100644
index 0000000..625d789
--- /dev/null
+++ b/libc/bionic/jemalloc.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include "jemalloc.h"
+
+void* je_pvalloc(size_t bytes) {
+  size_t pagesize = sysconf(_SC_PAGESIZE);
+  return je_memalign(pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
+}
+
+#ifdef je_memalign
+#undef je_memalign
+#endif
+
+// The man page for memalign says it fails if boundary is not a power of 2,
+// but this is not true. Both glibc and dlmalloc round up to the next power
+// of 2, so we'll do the same.
+void* je_memalign_round_up_boundary(size_t boundary, size_t size) {
+  unsigned int power_of_2 = static_cast<unsigned int>(boundary);
+  if (power_of_2 != 0) {
+    power_of_2 = 1UL << (sizeof(unsigned int)*8 - 1 - __builtin_clz(power_of_2));
+    if (power_of_2 != boundary) {
+      boundary = power_of_2 << 1;
+    }
+  } else {
+    boundary = 1;
+  }
+  return je_memalign(boundary, size);
+}
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
new file mode 100644
index 0000000..feb1f43
--- /dev/null
+++ b/libc/bionic/jemalloc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBC_BIONIC_JEMALLOC_H_
+#define LIBC_BIONIC_JEMALLOC_H_
+
+#include <jemalloc/jemalloc.h>
+
+// Need to wrap memalign since je_memalign fails on non-power of 2 alignments.
+#define je_memalign je_memalign_round_up_boundary
+
+__BEGIN_DECLS
+
+struct mallinfo je_mallinfo();
+void* je_memalign_round_up_boundary(size_t, size_t);
+void* je_pvalloc(size_t);
+
+__END_DECLS
+
+#endif  // LIBC_BIONIC_DLMALLOC_H_
diff --git a/libc/bionic/malloc_debug_check.cpp b/libc/bionic/malloc_debug_check.cpp
index 11578a3..2590ce7 100644
--- a/libc/bionic/malloc_debug_check.cpp
+++ b/libc/bionic/malloc_debug_check.cpp
@@ -47,7 +47,6 @@
 
 #include "debug_mapinfo.h"
 #include "debug_stacktrace.h"
-#include "dlmalloc.h"
 #include "private/libc_logging.h"
 #include "malloc_debug_common.h"
 #include "private/ScopedPthreadMutexLocker.h"
@@ -74,7 +73,7 @@
 
 struct hdr_t {
     uint32_t tag;
-    void* base;  // Always points to the memory allocated using dlmalloc.
+    void* base;  // Always points to the memory allocated using malloc.
                  // For memory allocated in chk_memalign, this value will
                  // not be the same as the location of the start of this
                  // structure.
@@ -321,14 +320,14 @@
     while (backlog_num > g_malloc_debug_backlog) {
         hdr_t* gone = backlog_tail;
         del_from_backlog_locked(gone);
-        dlfree(gone->base);
+        Malloc(free)(gone->base);
     }
 }
 
 extern "C" void* chk_malloc(size_t size) {
 //  log_message("%s: %s\n", __FILE__, __FUNCTION__);
 
-    hdr_t* hdr = static_cast<hdr_t*>(dlmalloc(sizeof(hdr_t) + size + sizeof(ftr_t)));
+    hdr_t* hdr = static_cast<hdr_t*>(Malloc(malloc)(sizeof(hdr_t) + size + sizeof(ftr_t)));
     if (hdr) {
         hdr->base = hdr;
         hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH);
@@ -356,7 +355,7 @@
         return NULL;
     }
 
-    void* base = dlmalloc(sizeof(hdr_t) + size + sizeof(ftr_t));
+    void* base = Malloc(malloc)(sizeof(hdr_t) + size + sizeof(ftr_t));
     if (base != NULL) {
         // Check that the actual pointer that will be returned is aligned
         // properly.
@@ -453,25 +452,25 @@
                        user(hdr), size);
             log_backtrace(bt, depth);
             // just get a whole new allocation and leak the old one
-            return dlrealloc(0, size);
-            // return dlrealloc(user(hdr), size); // assuming it was allocated externally
+            return Malloc(realloc)(0, size);
+            // return realloc(user(hdr), size); // assuming it was allocated externally
         }
     }
 
     if (hdr->base != hdr) {
         // An allocation from memalign, so create another allocation and
         // copy the data out.
-        void* newMem = dlmalloc(sizeof(hdr_t) + size + sizeof(ftr_t));
+        void* newMem = Malloc(malloc)(sizeof(hdr_t) + size + sizeof(ftr_t));
         if (newMem) {
             memcpy(newMem, hdr, sizeof(hdr_t) + hdr->size);
-            dlfree(hdr->base);
+            Malloc(free)(hdr->base);
             hdr = static_cast<hdr_t*>(newMem);
         } else {
-            dlfree(hdr->base);
+            Malloc(free)(hdr->base);
             hdr = NULL;
         }
     } else {
-        hdr = static_cast<hdr_t*>(dlrealloc(hdr, sizeof(hdr_t) + size + sizeof(ftr_t)));
+        hdr = static_cast<hdr_t*>(Malloc(realloc)(hdr, sizeof(hdr_t) + size + sizeof(ftr_t)));
     }
     if (hdr) {
         hdr->base = hdr;
@@ -486,7 +485,7 @@
 extern "C" void* chk_calloc(int nmemb, size_t size) {
 //  log_message("%s: %s\n", __FILE__, __FUNCTION__);
     size_t total_size = nmemb * size;
-    hdr_t* hdr = static_cast<hdr_t*>(dlcalloc(1, sizeof(hdr_t) + total_size + sizeof(ftr_t)));
+    hdr_t* hdr = static_cast<hdr_t*>(Malloc(calloc)(1, sizeof(hdr_t) + total_size + sizeof(ftr_t)));
     if (hdr) {
         hdr->base = hdr;
         hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH);
@@ -497,7 +496,7 @@
 }
 
 extern "C" size_t chk_malloc_usable_size(const void* ptr) {
-    // dlmalloc_usable_size returns 0 for NULL and unknown blocks.
+    // malloc_usable_size returns 0 for NULL and unknown blocks.
     if (ptr == NULL)
         return 0;
 
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
index 8ae0bb5..db3f995 100644
--- a/libc/bionic/malloc_debug_common.cpp
+++ b/libc/bionic/malloc_debug_common.cpp
@@ -46,7 +46,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "dlmalloc.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
 /*
@@ -134,7 +133,7 @@
         return;
     }
 
-    HashEntry** list = static_cast<HashEntry**>(dlmalloc(sizeof(void*) * g_hash_table.count));
+    HashEntry** list = static_cast<HashEntry**>(Malloc(malloc)(sizeof(void*) * g_hash_table.count));
 
     // get the entries into an array to be sorted
     int index = 0;
@@ -155,11 +154,11 @@
     *backtraceSize = BACKTRACE_SIZE;
 
     // now get a byte array big enough for this
-    *info = static_cast<uint8_t*>(dlmalloc(*overallSize));
+    *info = static_cast<uint8_t*>(Malloc(malloc)(*overallSize));
 
     if (*info == NULL) {
         *overallSize = 0;
-        dlfree(list);
+        Malloc(free)(list);
         return;
     }
 
@@ -181,42 +180,36 @@
         head += *infoSize;
     }
 
-    dlfree(list);
+    Malloc(free)(list);
 }
 
 // Exported for use by ddms.
 extern "C" void free_malloc_leak_info(uint8_t* info) {
-    dlfree(info);
+    Malloc(free)(info);
 }
 
 extern "C" struct mallinfo mallinfo() {
-    return dlmallinfo();
+    return Malloc(mallinfo)();
 }
 
 extern "C" void* valloc(size_t bytes) {
-    return dlvalloc(bytes);
+    return Malloc(valloc)(bytes);
 }
 
 extern "C" void* pvalloc(size_t bytes) {
-    return dlpvalloc(bytes);
+    return Malloc(pvalloc)(bytes);
 }
 
 extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size) {
-    return dlposix_memalign(memptr, alignment, size);
+    return Malloc(posix_memalign)(memptr, alignment, size);
 }
 
-/* Support for malloc debugging.
- * Note that if USE_DL_PREFIX is not defined, it's assumed that memory
- * allocation routines are implemented somewhere else, so all our custom
- * malloc routines should not be compiled at all.
- */
-#ifdef USE_DL_PREFIX
-
-/* Table for dispatching malloc calls, initialized with default dispatchers. */
+// Support for malloc debugging.
+// Table for dispatching malloc calls, initialized with default dispatchers.
 extern const MallocDebug __libc_malloc_default_dispatch;
 const MallocDebug __libc_malloc_default_dispatch __attribute__((aligned(32))) =
 {
-    dlmalloc, dlfree, dlcalloc, dlrealloc, dlmemalign, dlmalloc_usable_size,
+    Malloc(malloc), Malloc(free), Malloc(calloc), Malloc(realloc), Malloc(memalign), Malloc(malloc_usable_size),
 };
 
 /* Selector of dispatch table to use for dispatching malloc calls. */
@@ -257,7 +250,7 @@
 
 /* Table for dispatching malloc calls, depending on environment. */
 static MallocDebug g_malloc_dispatch_table __attribute__((aligned(32))) = {
-    dlmalloc, dlfree, dlcalloc, dlrealloc, dlmemalign, dlmalloc_usable_size
+    Malloc(malloc), Malloc(free), Malloc(calloc), Malloc(realloc), Malloc(memalign), Malloc(malloc_usable_size)
 };
 
 extern const char* __progname;
@@ -347,8 +340,7 @@
         g_malloc_debug_level = atoi(env);
     }
 
-    /* Debug level 0 means that we should use dlxxx allocation
-     * routines (default). */
+    /* Debug level 0 means that we should use default allocation routines. */
     if (g_malloc_debug_level == 0) {
         return;
     }
@@ -504,7 +496,6 @@
 static pthread_once_t  malloc_fini_once_ctl = PTHREAD_ONCE_INIT;
 
 #endif  // !LIBC_STATIC
-#endif  // USE_DL_PREFIX
 
 /* Initializes memory allocation framework.
  * This routine is called from __libc_init routines implemented
diff --git a/libc/bionic/malloc_debug_common.h b/libc/bionic/malloc_debug_common.h
index 28be042..c1c3c89 100644
--- a/libc/bionic/malloc_debug_common.h
+++ b/libc/bionic/malloc_debug_common.h
@@ -45,11 +45,22 @@
 
 #define MAX_SIZE_T           (~(size_t)0)
 
-// This must match the alignment used by dlmalloc.
+// This must match the alignment used by the malloc implementation.
 #ifndef MALLOC_ALIGNMENT
 #define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
 #endif
 
+#ifdef USE_JEMALLOC
+#include "jemalloc.h"
+#define Malloc(function)  je_ ## function
+#else
+#ifndef USE_DLMALLOC
+#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined."
+#endif
+#include "dlmalloc.h"
+#define Malloc(function)  dl ## function
+#endif
+
 // =============================================================================
 // Structures
 // =============================================================================
diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp
index 146cddc..035765f 100644
--- a/libc/bionic/malloc_debug_leak.cpp
+++ b/libc/bionic/malloc_debug_leak.cpp
@@ -46,7 +46,6 @@
 #include <unwind.h>
 
 #include "debug_stacktrace.h"
-#include "dlmalloc.h"
 #include "malloc_debug_common.h"
 
 #include "private/libc_logging.h"
@@ -144,7 +143,7 @@
         entry->allocations++;
     } else {
         // create a new entry
-        entry = static_cast<HashEntry*>(dlmalloc(sizeof(HashEntry) + numEntries*sizeof(uintptr_t)));
+        entry = static_cast<HashEntry*>(Malloc(malloc)(sizeof(HashEntry) + numEntries*sizeof(uintptr_t)));
         if (!entry) {
             return NULL;
         }
@@ -213,11 +212,11 @@
 #define CHK_SENTINEL_VALUE      0xeb
 
 extern "C" void* fill_calloc(size_t n_elements, size_t elem_size) {
-    return dlcalloc(n_elements, elem_size);
+    return Malloc(calloc)(n_elements, elem_size);
 }
 
 extern "C" void* fill_malloc(size_t bytes) {
-    void* buffer = dlmalloc(bytes);
+    void* buffer = Malloc(malloc)(bytes);
     if (buffer) {
         memset(buffer, CHK_SENTINEL_VALUE, bytes);
     }
@@ -225,17 +224,17 @@
 }
 
 extern "C" void fill_free(void* mem) {
-    size_t bytes = dlmalloc_usable_size(mem);
+    size_t bytes = Malloc(malloc_usable_size)(mem);
     memset(mem, CHK_FILL_FREE, bytes);
-    dlfree(mem);
+    Malloc(free)(mem);
 }
 
 extern "C" void* fill_realloc(void* mem, size_t bytes) {
-    size_t oldSize = dlmalloc_usable_size(mem);
-    void* newMem = dlrealloc(mem, bytes);
+    size_t oldSize = Malloc(malloc_usable_size)(mem);
+    void* newMem = Malloc(realloc)(mem, bytes);
     if (newMem) {
         // If this is larger than before, fill the extra with our pattern.
-        size_t newSize = dlmalloc_usable_size(newMem);
+        size_t newSize = Malloc(malloc_usable_size)(newMem);
         if (newSize > oldSize) {
             memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(newMem)+oldSize), CHK_FILL_FREE, newSize-oldSize);
         }
@@ -244,7 +243,7 @@
 }
 
 extern "C" void* fill_memalign(size_t alignment, size_t bytes) {
-    void* buffer = dlmemalign(alignment, bytes);
+    void* buffer = Malloc(memalign)(alignment, bytes);
     if (buffer) {
         memset(buffer, CHK_SENTINEL_VALUE, bytes);
     }
@@ -254,7 +253,7 @@
 extern "C" size_t fill_malloc_usable_size(const void* mem) {
     // Since we didn't allocate extra bytes before or after, we can
     // report the normal usable size here.
-    return dlmalloc_usable_size(mem);
+    return Malloc(malloc_usable_size)(mem);
 }
 
 // =============================================================================
@@ -275,7 +274,7 @@
         return NULL;
     }
 
-    void* base = dlmalloc(size);
+    void* base = Malloc(malloc)(size);
     if (base != NULL) {
         ScopedPthreadMutexLocker locker(&g_allocations_mutex);
 
@@ -316,11 +315,11 @@
             entry->allocations--;
             if (entry->allocations <= 0) {
                 remove_entry(entry);
-                dlfree(entry);
+                Malloc(free)(entry);
             }
 
             // now free the memory!
-            dlfree(header);
+            Malloc(free)(header);
         } else {
             debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
                     header->guard, header->entry);
@@ -425,7 +424,7 @@
             return 0;
         }
 
-        size_t ret = dlmalloc_usable_size(header);
+        size_t ret = Malloc(malloc_usable_size)(header);
         if (ret != 0) {
             // The usable area starts at 'mem' and stops at 'header+ret'.
             return reinterpret_cast<uintptr_t>(header) + ret - reinterpret_cast<uintptr_t>(mem);
diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp
index 5a91daa..ac60c3b 100644
--- a/libc/bionic/malloc_debug_qemu.cpp
+++ b/libc/bionic/malloc_debug_qemu.cpp
@@ -50,7 +50,6 @@
 #include <pthread.h>
 #include <unistd.h>
 #include <errno.h>
-#include "dlmalloc.h"
 #include "private/libc_logging.h"
 #include "malloc_debug_common.h"
 
@@ -344,7 +343,7 @@
  * has been initialized. */
 static uint32_t malloc_pid = 0;
 
-/* Memory allocation alignment that is used in dlmalloc.
+/* Memory allocation alignment that is used in the malloc implementation.
  * This variable is updated by memcheck_initialize routine. */
 static uint32_t malloc_alignment = 8;
 
@@ -677,14 +676,14 @@
 extern "C" void* qemu_instrumented_malloc(size_t bytes) {
     MallocDesc desc;
 
-    /* Initialize block descriptor and allocate memory. Note that dlmalloc
+    /* Initialize block descriptor and allocate memory. Note that malloc
      * returns a valid pointer on zero allocation. Lets mimic this behavior. */
     desc.prefix_size = DEFAULT_PREFIX_SIZE;
     desc.requested_bytes = bytes;
     desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    desc.ptr = dlmalloc(mallocdesc_alloc_size(&desc));
+    desc.ptr = Malloc(malloc)(mallocdesc_alloc_size(&desc));
     if (desc.ptr == NULL) {
-        qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zd): dlmalloc(%u) failed.",
+        qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zd): malloc(%u) failed.",
                   malloc_pid, getpid(), bytes, mallocdesc_alloc_size(&desc));
         return NULL;
     }
@@ -693,7 +692,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ",
                   malloc_pid, getpid());
-        dlfree(desc.ptr);
+        Malloc(free)(desc.ptr);
         return NULL;
     } else {
 #if TEST_ACCESS_VIOLATIONS
@@ -714,7 +713,7 @@
 
     if (mem == NULL) {
         // Just let go NULL free
-        dlfree(mem);
+        Malloc(free)(mem);
         return;
     }
 
@@ -745,7 +744,7 @@
     } else {
         log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ",
                   malloc_pid, getpid(), mem);
-        dlfree(desc.ptr);
+        Malloc(free)(desc.ptr);
     }
 }
 
@@ -795,9 +794,9 @@
         total_elements++;
         desc.suffix_size += (elem_size - total_size);
     }
-    desc.ptr = dlcalloc(total_elements, elem_size);
+    desc.ptr = Malloc(calloc)(total_elements, elem_size);
     if (desc.ptr == NULL) {
-        error_log("<libc_pid=%03u, pid=%03u> calloc: dlcalloc(%zd(%zd), %zd) (prx=%u, sfx=%u) failed.",
+        error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zd(%zd), %zd) (prx=%u, sfx=%u) failed.",
                    malloc_pid, getpid(), n_elements, total_elements, elem_size,
                    desc.prefix_size, desc.suffix_size);
         return NULL;
@@ -806,7 +805,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zd(%zd), %zd): notify_malloc failed for ",
                   malloc_pid, getpid(), n_elements, total_elements, elem_size);
-        dlfree(desc.ptr);
+        Malloc(free)(desc.ptr);
         return NULL;
     } else {
 #if TEST_ACCESS_VIOLATIONS
@@ -843,7 +842,7 @@
                  malloc_pid, getpid(), mem, bytes);
         qemu_instrumented_free(mem);
 
-        // This is what dlrealloc does for a "free" realloc.
+        // This is what realloc does for a "free" realloc.
         return NULL;
     }
 
@@ -877,9 +876,9 @@
     new_desc.prefix_size = DEFAULT_PREFIX_SIZE;
     new_desc.requested_bytes = bytes;
     new_desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    new_desc.ptr = dlmalloc(mallocdesc_alloc_size(&new_desc));
+    new_desc.ptr = Malloc(malloc)(mallocdesc_alloc_size(&new_desc));
     if (new_desc.ptr == NULL) {
-        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zd): dlmalloc(%u) failed on ",
+        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zd): malloc(%u) failed on ",
                   malloc_pid, getpid(), mem, bytes,
                   mallocdesc_alloc_size(&new_desc));
         return NULL;
@@ -898,7 +897,7 @@
         log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zd) notify_malloc failed -> ",
                   malloc_pid, getpid(), mem, bytes);
         log_mdesc(error, &cur_desc, "                                                                <- ");
-        dlfree(new_desc.ptr);
+        Malloc(free)(new_desc.ptr);
         return NULL;
     }
 
@@ -913,10 +912,10 @@
         /* Since we registered new decriptor with the emulator, we need
          * to unregister it before freeing newly allocated block. */
         notify_qemu_free(mallocdesc_user_ptr(&new_desc));
-        dlfree(new_desc.ptr);
+        Malloc(free)(new_desc.ptr);
         return NULL;
     }
-    dlfree(cur_desc.ptr);
+    Malloc(free)(cur_desc.ptr);
 
     log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zd) -> ",
               malloc_pid, getpid(), mem, bytes);
@@ -946,9 +945,9 @@
                                                          DEFAULT_PREFIX_SIZE;
     desc.requested_bytes = bytes;
     desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    desc.ptr = dlmemalign(desc.prefix_size, mallocdesc_alloc_size(&desc));
+    desc.ptr = Malloc(memalign)(desc.prefix_size, mallocdesc_alloc_size(&desc));
     if (desc.ptr == NULL) {
-        error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zd): dlmalloc(%u) failed.",
+        error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zd): malloc(%u) failed.",
                   malloc_pid, getpid(), alignment, bytes,
                   mallocdesc_alloc_size(&desc));
         return NULL;
@@ -956,7 +955,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zd): notify_malloc failed for ",
                   malloc_pid, getpid(), alignment, bytes);
-        dlfree(desc.ptr);
+        Malloc(free)(desc.ptr);
         return NULL;
     }
 
diff --git a/libc/bionic/pthread_internals.cpp b/libc/bionic/pthread_internals.cpp
index baa95d9..8c5d9c7 100644
--- a/libc/bionic/pthread_internals.cpp
+++ b/libc/bionic/pthread_internals.cpp
@@ -88,11 +88,3 @@
   }
   return 0;
 }
-
-int __futex_wake_ex(volatile void* ftx, int pshared, int val) {
-  return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
-}
-
-int __futex_wait_ex(volatile void* ftx, int pshared, int val, const timespec* timeout) {
-  return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
-}
diff --git a/libc/bionic/pthread_rwlock.cpp b/libc/bionic/pthread_rwlock.cpp
index dfb4315..b36adcd 100644
--- a/libc/bionic/pthread_rwlock.cpp
+++ b/libc/bionic/pthread_rwlock.cpp
@@ -26,8 +26,11 @@
  * SUCH DAMAGE.
  */
 
-#include "pthread_internal.h"
 #include <errno.h>
+#include <sys/atomics.h>
+
+#include "pthread_internal.h"
+#include "private/bionic_futex.h"
 
 /* Technical note:
  *
@@ -40,186 +43,169 @@
  * Additionally:
  *  - trying to get the write-lock while there are any readers blocks
  *  - trying to get the read-lock while there is a writer blocks
- *  - a single thread can acquire the lock multiple times in the same mode
+ *  - a single thread can acquire the lock multiple times in read mode
  *
- *  - Posix states that behavior is undefined it a thread tries to acquire
- *    the lock in two distinct modes (e.g. write after read, or read after write).
+ *  - Posix states that behavior is undefined (may deadlock) if a thread tries
+ *    to acquire the lock
+ *      - in write mode while already holding the lock (whether in read or write mode)
+ *      - in read mode while already holding the lock in write mode.
+ *  - This implementation will return EDEADLK in "write after write" and "read after
+ *    write" cases and will deadlock in write after read case.
  *
- *  - This implementation tries to avoid writer starvation by making the readers
- *    block as soon as there is a waiting writer on the lock. However, it cannot
- *    completely eliminate it: each time the lock is unlocked, all waiting threads
- *    are woken and battle for it, which one gets it depends on the kernel scheduler
- *    and is semi-random.
+ * TODO: VERY CAREFULLY convert this to use C++11 atomics when possible. All volatile
+ * members of pthread_rwlock_t should be converted to atomics<> and __atomic_cmpxchg
+ * should be changed to compare_exchange_strong accompanied by the proper ordering
+ * constraints (comments have been added with the intending ordering across the code).
+ *
+ * TODO: As it stands now, pendingReaders and pendingWriters could be merged into a
+ * a single waiters variable.  Keeping them separate adds a bit of clarity and keeps
+ * the door open for a writer-biased implementation.
  *
  */
 
 #define  RWLOCKATTR_DEFAULT     0
 #define  RWLOCKATTR_SHARED_MASK 0x0010
 
+#define RWLOCK_IS_SHARED(rwlock) ((rwlock)->attr == PTHREAD_PROCESS_SHARED)
+
 extern pthread_internal_t* __get_thread(void);
 
 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
 {
-    *attr = PTHREAD_PROCESS_PRIVATE;
-    return 0;
+  *attr = PTHREAD_PROCESS_PRIVATE;
+  return 0;
 }
 
 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
 {
-    *attr = -1;
-    return 0;
+  *attr = -1;
+  return 0;
 }
 
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int  pshared)
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
 {
-    switch (pshared) {
+  switch (pshared) {
     case PTHREAD_PROCESS_PRIVATE:
     case PTHREAD_PROCESS_SHARED:
-        *attr = pshared;
-        return 0;
+      *attr = pshared;
+      return 0;
     default:
-        return EINVAL;
-    }
+      return EINVAL;
+  }
 }
 
 int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* attr, int* pshared) {
-    *pshared = *attr;
-    return 0;
+  *pshared = *attr;
+  return 0;
 }
 
 int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
 {
-    pthread_mutexattr_t*  lock_attr = NULL;
-    pthread_condattr_t*   cond_attr = NULL;
-    pthread_mutexattr_t   lock_attr0;
-    pthread_condattr_t    cond_attr0;
-    int                   ret;
-
-    if (attr && *attr == PTHREAD_PROCESS_SHARED) {
-        lock_attr = &lock_attr0;
-        pthread_mutexattr_init(lock_attr);
-        pthread_mutexattr_setpshared(lock_attr, PTHREAD_PROCESS_SHARED);
-
-        cond_attr = &cond_attr0;
-        pthread_condattr_init(cond_attr);
-        pthread_condattr_setpshared(cond_attr, PTHREAD_PROCESS_SHARED);
+  if (attr) {
+    switch (*attr) {
+      case PTHREAD_PROCESS_SHARED:
+      case PTHREAD_PROCESS_PRIVATE:
+        rwlock->attr= *attr;
+        break;
+      default:
+        return EINVAL;
     }
+  }
 
-    ret = pthread_mutex_init(&rwlock->lock, lock_attr);
-    if (ret != 0)
-        return ret;
+  rwlock->state = 0;
+  rwlock->pendingReaders = 0;
+  rwlock->pendingWriters = 0;
+  rwlock->writerThreadId = 0;
 
-    ret = pthread_cond_init(&rwlock->cond, cond_attr);
-    if (ret != 0) {
-        pthread_mutex_destroy(&rwlock->lock);
-        return ret;
-    }
-
-    rwlock->numLocks = 0;
-    rwlock->pendingReaders = 0;
-    rwlock->pendingWriters = 0;
-    rwlock->writerThreadId = 0;
-
-    return 0;
+  return 0;
 }
 
 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
 {
-    if (rwlock->numLocks > 0)
-        return EBUSY;
+  if (rwlock->state != 0) {
+    return EBUSY;
+  }
 
-    pthread_cond_destroy(&rwlock->cond);
-    pthread_mutex_destroy(&rwlock->lock);
-    return 0;
-}
-
-/* Returns TRUE iff we can acquire a read lock. */
-static __inline__ int read_precondition(pthread_rwlock_t* rwlock, int tid)
-{
-    /* We can't have the lock if any writer is waiting for it (writer bias).
-     * This tries to avoid starvation when there are multiple readers racing.
-     */
-    if (rwlock->pendingWriters > 0)
-        return 0;
-
-    /* We can have the lock if there is no writer, or if we write-own it */
-    /* The second test avoids a self-dead lock in case of buggy code. */
-    if (rwlock->writerThreadId == 0 || rwlock->writerThreadId == tid)
-        return 1;
-
-    /* Otherwise, we can't have it */
-    return 0;
-}
-
-/* returns TRUE iff we can acquire a write lock. */
-static __inline__ int write_precondition(pthread_rwlock_t* rwlock, int tid)
-{
-    /* We can get the lock if nobody has it */
-    if (rwlock->numLocks == 0)
-        return 1;
-
-    /* Or if we already own it */
-    if (rwlock->writerThreadId == tid)
-        return 1;
-
-    /* Otherwise, not */
-    return 0;
-}
-
-/* This function is used to waken any waiting thread contending
- * for the lock. One of them should be able to grab it after
- * that.
- */
-static void _pthread_rwlock_pulse(pthread_rwlock_t *rwlock)
-{
-    if (rwlock->pendingReaders > 0 || rwlock->pendingWriters > 0)
-        pthread_cond_broadcast(&rwlock->cond);
+  return 0;
 }
 
 static int __pthread_rwlock_timedrdlock(pthread_rwlock_t* rwlock, const timespec* abs_timeout) {
-  int ret = 0;
-
-  pthread_mutex_lock(&rwlock->lock);
-  int tid = __get_thread()->tid;
-  if (__predict_false(!read_precondition(rwlock, tid))) {
-    rwlock->pendingReaders += 1;
-    do {
-      ret = pthread_cond_timedwait(&rwlock->cond, &rwlock->lock, abs_timeout);
-    } while (ret == 0 && !read_precondition(rwlock, tid));
-    rwlock->pendingReaders -= 1;
-    if (ret != 0) {
-      goto EXIT;
-    }
+  if (__predict_false(__get_thread()->tid == rwlock->writerThreadId)) {
+    return EDEADLK;
   }
-  ++rwlock->numLocks;
-EXIT:
-  pthread_mutex_unlock(&rwlock->lock);
-  return ret;
+
+  bool done = false;
+  do {
+    // This is actually a race read as there's nothing that guarantees the atomicity of integers
+    // reads / writes. However, in practice this "never" happens so until we switch to C++11 this
+    // should work fine. The same applies in the other places this idiom is used.
+    int32_t cur_state = rwlock->state;  // C++11 relaxed atomic read
+    if (__predict_true(cur_state >= 0)) {
+      // Add as an extra reader.
+      done = __atomic_cmpxchg(cur_state, cur_state + 1, &rwlock->state) == 0;  // C++11 memory_order_aquire
+    } else {
+      timespec ts;
+      timespec* tsp = NULL;
+      if (abs_timeout != NULL) {
+        if (__timespec_from_absolute(&ts, abs_timeout, CLOCK_REALTIME) < 0) {
+          return ETIMEDOUT;
+        }
+        tsp = &ts;
+      }
+      // Owner holds it in write mode, hang up.
+      // To avoid loosing wake ups the pendingReaders update and the state read should be
+      // sequentially consistent. (currently enforced by __atomic_inc which creates a full barrier)
+      __atomic_inc(&rwlock->pendingReaders);  // C++11 memory_order_relaxed (if the futex_wait ensures the ordering)
+      if (__futex_wait_ex(&rwlock->state, RWLOCK_IS_SHARED(rwlock), cur_state, tsp) != 0) {
+        if (errno == ETIMEDOUT) {
+          __atomic_dec(&rwlock->pendingReaders);  // C++11 memory_order_relaxed
+          return ETIMEDOUT;
+        }
+      }
+      __atomic_dec(&rwlock->pendingReaders);  // C++11 memory_order_relaxed
+    }
+  } while (!done);
+
+  return 0;
 }
 
 static int __pthread_rwlock_timedwrlock(pthread_rwlock_t* rwlock, const timespec* abs_timeout) {
-  int ret = 0;
-
-  pthread_mutex_lock(&rwlock->lock);
   int tid = __get_thread()->tid;
-  if (__predict_false(!write_precondition(rwlock, tid))) {
-    // If we can't read yet, wait until the rwlock is unlocked
-    // and try again. Increment pendingReaders to get the
-    // cond broadcast when that happens.
-    rwlock->pendingWriters += 1;
-    do {
-      ret = pthread_cond_timedwait(&rwlock->cond, &rwlock->lock, abs_timeout);
-    } while (ret == 0 && !write_precondition(rwlock, tid));
-    rwlock->pendingWriters -= 1;
-    if (ret != 0) {
-      goto EXIT;
-    }
+  if (__predict_false(tid == rwlock->writerThreadId)) {
+    return EDEADLK;
   }
-  ++rwlock->numLocks;
+
+  bool done = false;
+  do {
+    int32_t cur_state = rwlock->state;
+    if (__predict_true(cur_state == 0)) {
+      // Change state from 0 to -1.
+      done =  __atomic_cmpxchg(0 /* cur_state */, -1 /* new state */, &rwlock->state) == 0;  // C++11 memory_order_aquire
+    } else {
+      timespec ts;
+      timespec* tsp = NULL;
+      if (abs_timeout != NULL) {
+        if (__timespec_from_absolute(&ts, abs_timeout, CLOCK_REALTIME) < 0) {
+          return ETIMEDOUT;
+        }
+        tsp = &ts;
+      }
+      // Failed to acquire, hang up.
+      // To avoid loosing wake ups the pendingWriters update and the state read should be
+      // sequentially consistent. (currently enforced by __atomic_inc which creates a full barrier)
+      __atomic_inc(&rwlock->pendingWriters);  // C++11 memory_order_relaxed (if the futex_wait ensures the ordering)
+      if (__futex_wait_ex(&rwlock->state, RWLOCK_IS_SHARED(rwlock), cur_state, tsp) != 0) {
+        if (errno == ETIMEDOUT) {
+          __atomic_dec(&rwlock->pendingWriters);  // C++11 memory_order_relaxed
+          return ETIMEDOUT;
+        }
+      }
+      __atomic_dec(&rwlock->pendingWriters);  // C++11 memory_order_relaxed
+    }
+  } while (!done);
+
   rwlock->writerThreadId = tid;
-EXIT:
-  pthread_mutex_unlock(&rwlock->lock);
-  return ret;
+  return 0;
 }
 
 int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock) {
@@ -228,16 +214,15 @@
 
 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
 {
-    int ret = 0;
-
-    pthread_mutex_lock(&rwlock->lock);
-    if (__predict_false(!read_precondition(rwlock, __get_thread()->tid)))
-        ret = EBUSY;
-    else
-        ++rwlock->numLocks;
-    pthread_mutex_unlock(&rwlock->lock);
-
-    return ret;
+  int32_t cur_state = rwlock->state;
+  if (cur_state >= 0) {
+    if(__atomic_cmpxchg(cur_state, cur_state + 1, &rwlock->state) != 0) {  // C++11 memory_order_acquire
+      return EBUSY;
+    }
+  } else {
+    return EBUSY;
+  }
+  return 0;
 }
 
 int pthread_rwlock_timedrdlock(pthread_rwlock_t* rwlock, const timespec* abs_timeout) {
@@ -250,18 +235,18 @@
 
 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
 {
-    int ret = 0;
-
-    pthread_mutex_lock(&rwlock->lock);
-    int tid = __get_thread()->tid;
-    if (__predict_false(!write_precondition(rwlock, tid))) {
-        ret = EBUSY;
-    } else {
-        ++rwlock->numLocks;
-        rwlock->writerThreadId = tid;
+  int tid = __get_thread()->tid;
+  int32_t cur_state = rwlock->state;
+  if (cur_state == 0) {
+    if(__atomic_cmpxchg(0, -1, &rwlock->state) != 0) {  // C++11 memory_order_acquire
+      return EBUSY;
     }
-    pthread_mutex_unlock(&rwlock->lock);
-    return ret;
+  } else {
+    return EBUSY;
+  }
+
+  rwlock->writerThreadId = tid;
+  return 0;
 }
 
 int pthread_rwlock_timedwrlock(pthread_rwlock_t* rwlock, const timespec* abs_timeout) {
@@ -270,35 +255,43 @@
 
 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
 {
-    int  ret = 0;
-
-    pthread_mutex_lock(&rwlock->lock);
-
-    /* The lock must be held */
-    if (rwlock->numLocks == 0) {
-        ret = EPERM;
-        goto EXIT;
+  int tid = __get_thread()->tid;
+  bool done = false;
+  do {
+    int32_t cur_state = rwlock->state;
+    if (cur_state == 0) {
+      return EPERM;
     }
+    if (cur_state == -1) {
+      if (rwlock->writerThreadId != tid) {
+        return EPERM;
+      }
+      // We're no longer the owner.
+      rwlock->writerThreadId = 0;
+      // Change state from -1 to 0.
+      // We use __atomic_cmpxchg to achieve sequential consistency of the state store and
+      // the following pendingX loads. A simple store with memory_order_release semantics
+      // is not enough to guarantee that the pendingX loads are not reordered before the
+      // store (which may lead to a lost wakeup).
+      __atomic_cmpxchg(-1 /* cur_state*/, 0 /* new state */, &rwlock->state);  // C++11 maybe memory_order_seq_cst?
 
-    /* If it has only readers, writerThreadId is 0 */
-    if (rwlock->writerThreadId == 0) {
-        if (--rwlock->numLocks == 0)
-            _pthread_rwlock_pulse(rwlock);
-    }
-    /* Otherwise, it has only a single writer, which
-     * must be ourselves.
-     */
-    else {
-        if (rwlock->writerThreadId != __get_thread()->tid) {
-            ret = EPERM;
-            goto EXIT;
+      // Wake any waiters.
+      if (__predict_false(rwlock->pendingReaders > 0 || rwlock->pendingWriters > 0)) {
+        __futex_wake_ex(&rwlock->state, RWLOCK_IS_SHARED(rwlock), INT_MAX);
+      }
+      done = true;
+    } else { // cur_state > 0
+      // Reduce state by 1.
+      // See the above comment on why we need __atomic_cmpxchg.
+      done = __atomic_cmpxchg(cur_state, cur_state - 1, &rwlock->state) == 0;  // C++11 maybe memory_order_seq_cst?
+      if (done && (cur_state - 1) == 0) {
+        // There are no more readers, wake any waiters.
+        if (__predict_false(rwlock->pendingReaders > 0 || rwlock->pendingWriters > 0)) {
+          __futex_wake_ex(&rwlock->state, RWLOCK_IS_SHARED(rwlock), INT_MAX);
         }
-        if (--rwlock->numLocks == 0) {
-            rwlock->writerThreadId = 0;
-            _pthread_rwlock_pulse(rwlock);
-        }
+      }
     }
-EXIT:
-    pthread_mutex_unlock(&rwlock->lock);
-    return ret;
+  } while (!done);
+
+  return 0;
 }
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 46874cc..8309f08 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -309,7 +309,7 @@
       return _POSIX_THREAD_DESTRUCTOR_ITERATIONS;
 
     case _SC_THREAD_KEYS_MAX:
-      return (BIONIC_TLS_SLOTS - TLS_SLOT_FIRST_USER_SLOT - GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT);
+      return (BIONIC_TLS_SLOTS - TLS_SLOT_FIRST_USER_SLOT - BIONIC_TLS_RESERVED_SLOTS);
 
     case _SC_THREAD_STACK_MIN:    return PTHREAD_STACK_MIN;
     case _SC_THREAD_THREADS_MAX:  return SYSTEM_THREAD_THREADS_MAX;
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index 97e1a03..7618586 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -51,9 +51,8 @@
 #include <sys/_system_properties.h>
 #include <sys/system_properties.h>
 
-#include <sys/atomics.h>
-
 #include "private/bionic_atomic_inline.h"
+#include "private/bionic_futex.h"
 #include "private/bionic_macros.h"
 
 #define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
diff --git a/libc/bionic/system_properties_compat.c b/libc/bionic/system_properties_compat.c
index b4c2494..6aeaa0c 100644
--- a/libc/bionic/system_properties_compat.c
+++ b/libc/bionic/system_properties_compat.c
@@ -35,7 +35,8 @@
  */
 
 #include <string.h>
-#include <sys/atomics.h>
+
+#include "private/bionic_futex.h"
 
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>
@@ -67,7 +68,7 @@
 
 extern prop_area *__system_property_area__;
 
-const prop_info *__system_property_find_compat(const char *name)
+__LIBC_HIDDEN__ const prop_info *__system_property_find_compat(const char *name)
 {
     prop_area_compat *pa = (prop_area_compat *)__system_property_area__;
     unsigned count = pa->count;
@@ -93,7 +94,7 @@
     return 0;
 }
 
-int __system_property_read_compat(const prop_info *_pi, char *name, char *value)
+__LIBC_HIDDEN__ int __system_property_read_compat(const prop_info *_pi, char *name, char *value)
 {
     unsigned serial, len;
     const prop_info_compat *pi = (const prop_info_compat *)_pi;
@@ -115,7 +116,7 @@
     }
 }
 
-int __system_property_foreach_compat(
+__LIBC_HIDDEN__ int __system_property_foreach_compat(
         void (*propfn)(const prop_info *pi, void *cookie),
         void *cookie)
 {
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index 7daa8f7..8dde08c 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -50,15 +50,29 @@
 extern int          dladdr(const void* addr, Dl_info *info);
 
 enum {
+#if defined(__LP64__)
+  RTLD_NOW  = 2,
+#else
   RTLD_NOW  = 0,
+#endif
   RTLD_LAZY = 1,
 
   RTLD_LOCAL  = 0,
+#if defined(__LP64__)
+  RTLD_GLOBAL = 0x00100,
+#else
   RTLD_GLOBAL = 2,
+#endif
+  RTLD_NOLOAD = 4,
 };
 
+#if defined (__LP64__)
+#define RTLD_DEFAULT  ((void*) 0)
+#define RTLD_NEXT     ((void*) -1L)
+#else
 #define RTLD_DEFAULT  ((void*) 0xffffffff)
 #define RTLD_NEXT     ((void*) 0xfffffffe)
+#endif
 
 __END_DECLS
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 49f943a..346901a 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -94,16 +94,17 @@
 typedef long pthread_rwlockattr_t;
 
 typedef struct {
-  pthread_mutex_t lock;
-  pthread_cond_t cond;
-  int numLocks;
-  int writerThreadId;
-  int pendingReaders;
-  int pendingWriters;
-  void* __reserved[4];
+  pthread_mutex_t __unused_lock;
+  pthread_cond_t __unused_cond;
+  volatile int32_t state; // 0=unlock, -1=writer lock, +n=reader lock
+  volatile int32_t writerThreadId;
+  volatile int32_t pendingReaders;
+  volatile int32_t pendingWriters;
+  int32_t attr;
+  void* __reserved[3];
 } pthread_rwlock_t;
 
-#define PTHREAD_RWLOCK_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, 0, 0, { NULL, NULL, NULL, NULL } }
+#define PTHREAD_RWLOCK_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, 0, 0, 0, { NULL, NULL, NULL } }
 
 typedef int pthread_key_t;
 typedef long pthread_t;
diff --git a/libc/include/sys/atomics.h b/libc/include/sys/atomics.h
index 143bc4b..dfb5d5e 100644
--- a/libc/include/sys/atomics.h
+++ b/libc/include/sys/atomics.h
@@ -75,10 +75,6 @@
   return __sync_fetch_and_add (ptr, 1);
 }
 
-
-int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
-int __futex_wake(volatile void *ftx, int count);
-
 __END_DECLS
 
 #endif /* _SYS_ATOMICS_H */
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index f86d9f4..d6c6b43 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -60,8 +60,6 @@
 typedef int greg_t;
 typedef greg_t gregset_t[NGREG];
 
-/* TODO: fpregset_t. */
-
 #include <asm/sigcontext.h>
 typedef struct sigcontext mcontext_t;
 
@@ -77,8 +75,6 @@
 
 #elif defined(__aarch64__)
 
-/* TODO: gregset_t and fpregset_t. */
-
 #include <asm/sigcontext.h>
 typedef struct sigcontext mcontext_t;
 
@@ -202,6 +198,7 @@
   stack_t uc_stack;
   mcontext_t uc_mcontext;
   sigset_t uc_sigmask;
+  char __padding[128 - sizeof(sigset_t)];
 } ucontext_t;
 
 #elif defined(__mips64__)
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
index d01b859..11699ce 100644
--- a/libc/private/bionic_futex.h
+++ b/libc/private/bionic_futex.h
@@ -30,20 +30,30 @@
 
 #include <linux/futex.h>
 #include <sys/cdefs.h>
+#include <stdbool.h>
+#include <stddef.h>
 
 __BEGIN_DECLS
 
-extern int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
-extern int __futex_wake(volatile void *ftx, int count);
+struct timespec;
 
-extern int __futex_syscall3(volatile void *ftx, int op, int val);
-extern int __futex_syscall4(volatile void *ftx, int op, int val, const struct timespec *timeout);
+extern int __futex_syscall4(volatile void* ftx, int op, int value, const struct timespec* timeout);
 
-/* Like __futex_wait/wake, but take an additional 'pshared' argument.
- * when non-0, this will use normal futexes. Otherwise, private futexes.
- */
-__LIBC_HIDDEN__ int __futex_wake_ex(volatile void* ftx, int pshared, int val);
-__LIBC_HIDDEN__ int __futex_wait_ex(volatile void* ftx, int pshared, int val, const struct timespec* timeout);
+static inline int __futex_wake(volatile void* ftx, int count) {
+  return __futex_syscall4(ftx, FUTEX_WAKE, count, NULL);
+}
+
+static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {
+  return __futex_syscall4(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
+}
+
+static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+  return __futex_syscall4(ftx, FUTEX_WAIT, value, timeout);
+}
+
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) {
+  return __futex_syscall4(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout);
+}
 
 __END_DECLS
 
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index d0a0201..c2cf196 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -82,6 +82,13 @@
  */
 #define GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT 5
 
+#if defined(USE_JEMALLOC)
+/* jemalloc uses 5 keys for itself. */
+#define BIONIC_TLS_RESERVED_SLOTS (GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT + 5)
+#else
+#define BIONIC_TLS_RESERVED_SLOTS GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT
+#endif
+
 #define BIONIC_ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
 
 /*
@@ -89,7 +96,7 @@
  * This includes space for pthread keys and our own internal slots.
  * We need to round up to maintain stack alignment.
  */
-#define BIONIC_TLS_SLOTS BIONIC_ALIGN(PTHREAD_KEYS_MAX + TLS_SLOT_FIRST_USER_SLOT + GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT, 4)
+#define BIONIC_TLS_SLOTS BIONIC_ALIGN(PTHREAD_KEYS_MAX + TLS_SLOT_FIRST_USER_SLOT + BIONIC_TLS_RESERVED_SLOTS, 4)
 
 __END_DECLS
 
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
new file mode 100755
index 0000000..3e112a0
--- /dev/null
+++ b/libc/tools/check-symbols-glibc.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+
+import glob
+import os
+import re
+import string
+import subprocess
+import sys
+
+toolchain = os.environ['ANDROID_TOOLCHAIN']
+arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
+
+def GetSymbolsFromSo(so_file):
+
+  # Example readelf output:
+  #   264: 0001623c     4 FUNC    GLOBAL DEFAULT    8 cabsf
+  #   266: 00016244     4 FUNC    GLOBAL DEFAULT    8 dremf
+  #   267: 00019018     4 OBJECT  GLOBAL DEFAULT   11 __fe_dfl_env
+  #   268: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_dcmplt
+
+  r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
+
+  symbols = set()
+
+  for line in subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]).split('\n'):
+     if ' HIDDEN ' in line or ' UND ' in line:
+       continue
+     m = r.match(line)
+     if m:
+       symbol = m.group(2)
+       symbol = re.sub('@.*', '', symbol)
+       symbols.add(symbol)
+
+  return symbols
+
+def GetSymbolsFromAndroidSo(*files):
+  symbols = set()
+  for f in files:
+    symbols = symbols | GetSymbolsFromSo('%s/system/lib64/%s' % (os.environ['ANDROID_PRODUCT_OUT'], f))
+  return symbols
+
+def GetSymbolsFromSystemSo(*files):
+  symbols = set()
+  for f in files:
+    f = glob.glob('/lib/x86_64-linux-gnu/%s' % f)[-1]
+    symbols = symbols | GetSymbolsFromSo(f)
+  return symbols
+
+glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*')
+bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
+
+# bionic includes various BSD symbols to ease porting other BSD-licensed code.
+bsd_stuff = set([
+  'getprogname',
+  'setprogname',
+  'strlcat',
+  'strlcpy',
+  'wcslcat',
+  'wcslcpy'
+])
+# Some symbols are part of the FORTIFY implementation.
+FORTIFY_stuff = set([
+  '__FD_CLR_chk',
+  '__FD_ISSET_chk',
+  '__FD_SET_chk',
+  '__stack_chk_guard',
+  '__stpncpy_chk2',
+  '__strchr_chk',
+  '__strlcat_chk',
+  '__strlcpy_chk',
+  '__strlen_chk',
+  '__strncpy_chk2',
+  '__strrchr_chk',
+  '__umask_chk'
+])
+# Some symbols are used to implement public macros.
+macro_stuff = set([
+  '__assert2',
+  '__errno',
+  '__fe_dfl_env',
+  '__get_h_errno',
+])
+# bionic exposes various Linux features that glibc doesn't.
+linux_stuff = set([
+  'getauxval',
+  'gettid',
+  'tgkill'
+])
+# Some standard stuff isn't yet in the versions of glibc we're using.
+std_stuff = set([
+  'at_quick_exit'
+])
+# These have mangled names in glibc, with a macro taking the "obvious" name.
+weird_stuff = set([
+  'fstat',
+  'fstat64',
+  'fstatat',
+  'fstatat64',
+  'isfinite',
+  'isfinitef',
+  'isfinitel',
+  'isnormal',
+  'isnormalf',
+  'isnormall',
+  'lstat',
+  'lstat64',
+  'mknod',
+  'mknodat',
+  'stat',
+  'stat64',
+])
+
+print 'glibc:'
+for symbol in sorted(glibc):
+  print symbol
+
+print
+print 'bionic:'
+for symbol in sorted(bionic):
+  print symbol
+
+print
+print 'in bionic but not glibc:'
+allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff | std_stuff | weird_stuff)
+for symbol in sorted((bionic - allowed_stuff).difference(glibc)):
+  print symbol
+
+sys.exit(0)
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 8a5f3d2..87d51e3 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -96,14 +96,18 @@
 
 arm64_call = syscall_stub_header + """\
     stp     x29, x30, [sp, #-16]!
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset x29, 0
+    .cfi_rel_offset x30, 8
     mov     x29,  sp
-    str     x8,       [sp, #-16]!
 
     mov     x8, %(__NR_name)s
     svc     #0
 
-    ldr     x8,       [sp], #16
     ldp     x29, x30, [sp], #16
+    .cfi_def_cfa_offset 0
+    .cfi_restore x29
+    .cfi_restore x30
 
     cmn     x0, #(MAX_ERRNO + 1)
     cneg    x0, x0, hi
diff --git a/libc/tools/zoneinfo/update-tzdata.py b/libc/tools/zoneinfo/update-tzdata.py
index 8956136..3dcb210 100755
--- a/libc/tools/zoneinfo/update-tzdata.py
+++ b/libc/tools/zoneinfo/update-tzdata.py
@@ -1,36 +1,40 @@
 #!/usr/bin/python
 
-"""Updates the tzdata file."""
+"""Updates the timezone data held in bionic and ICU."""
 
 import ftplib
+import glob
 import httplib
 import os
 import re
+import shutil
 import subprocess
 import sys
 import tarfile
 import tempfile
 
-# Find the bionic directory, searching upward from this script.
-bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
-bionic_libc_tools_dir = os.path.dirname(bionic_libc_tools_zoneinfo_dir)
-bionic_libc_dir = os.path.dirname(bionic_libc_tools_dir)
-bionic_dir = os.path.dirname(bionic_libc_dir)
-bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir
-
-if not os.path.isdir(bionic_libc_tools_zoneinfo_dir):
-  print "Couldn't find bionic/libc/tools/zoneinfo!"
-  sys.exit(1)
-if not os.path.isdir(bionic_libc_zoneinfo_dir):
-  print "Couldn't find bionic/libc/zoneinfo!"
-  sys.exit(1)
-
-print 'Found bionic in %s...' % bionic_dir
-
-
 regions = ['africa', 'antarctica', 'asia', 'australasia', 'backward',
            'etcetera', 'europe', 'northamerica', 'southamerica']
 
+def CheckDirExists(dir, dirname):
+  if not os.path.isdir(dir):
+    print "Couldn't find %s (%s)!" % (dirname, dir)
+    sys.exit(1)
+
+bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+# Find the bionic directory, searching upward from this script.
+bionic_dir = os.path.realpath('%s/../../..' % bionic_libc_tools_zoneinfo_dir)
+bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir
+CheckDirExists(bionic_libc_zoneinfo_dir, 'bionic/libc/zoneinfo')
+CheckDirExists(bionic_libc_tools_zoneinfo_dir, 'bionic/libc/tools/zoneinfo')
+print 'Found bionic in %s ...' % bionic_dir
+
+# Find the icu4c directory.
+icu_dir = os.path.realpath('%s/../external/icu4c' % bionic_dir)
+CheckDirExists(icu_dir, 'external/icu4c')
+print 'Found icu in %s ...' % icu_dir
+
 
 def GetCurrentTzDataVersion():
   return open('%s/tzdata' % bionic_libc_zoneinfo_dir).read().split('\x00', 1)[0]
@@ -65,50 +69,81 @@
   print 'Created temporary directory "%s"...' % tmp_dir
 
 
-def FtpRetrieve(ftp, filename):
+def FtpRetrieveFile(ftp, filename):
   ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
 
 
-def FtpUpgrade(ftp, data_filename):
+def FtpRetrieveFileAndSignature(ftp, data_filename):
   """Downloads and repackages the given data from the given FTP server."""
-  SwitchToNewTemporaryDirectory()
-
   print 'Downloading data...'
-  FtpRetrieve(ftp, data_filename)
+  FtpRetrieveFile(ftp, data_filename)
 
   print 'Downloading signature...'
   signature_filename = '%s.asc' % data_filename
-  FtpRetrieve(ftp, signature_filename)
-
-  ExtractAndCompile(data_filename)
+  FtpRetrieveFile(ftp, signature_filename)
 
 
-def HttpRetrieve(http, path, output_filename):
+def HttpRetrieveFile(http, path, output_filename):
   http.request("GET", path)
   f = open(output_filename, 'wb')
   f.write(http.getresponse().read())
   f.close()
 
 
-def HttpUpgrade(http, data_filename):
+def HttpRetrieveFileAndSignature(http, data_filename):
   """Downloads and repackages the given data from the given HTTP server."""
-  SwitchToNewTemporaryDirectory()
-
   path = "/time-zones/repository/releases/%s" % data_filename
 
   print 'Downloading data...'
-  HttpRetrieve(http, path, data_filename)
+  HttpRetrieveFile(http, path, data_filename)
 
   print 'Downloading signature...'
   signature_filename = '%s.asc' % data_filename
-  HttpRetrieve(http, "%s.asc" % path, signature_filename)
-
-  ExtractAndCompile(data_filename)
+  HttpRetrievefile(http, "%s.asc" % path, signature_filename)
 
 
-def ExtractAndCompile(data_filename):
-  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
+def BuildIcuToolsAndData(data_filename):
+  # Keep track of the original cwd so we can go back to it at the end.
+  original_working_dir = os.getcwd()
 
+  # Create a directory to run 'make' from.
+  icu_working_dir = '%s/icu' % original_working_dir
+  os.mkdir(icu_working_dir)
+  os.chdir(icu_working_dir)
+
+  # Build the ICU tools.
+  print 'Configuring ICU tools...'
+  subprocess.check_call(['%s/runConfigureICU' % icu_dir, 'Linux'])
+  print 'Making ICU tools...'
+  subprocess.check_call(['make', '-j6'])
+
+  # Run the ICU tools.
+  os.chdir('tools/tzcode')
+  shutil.copyfile('%s/%s' % (original_working_dir, data_filename), data_filename)
+  print 'Making ICU data...'
+  subprocess.check_call(['make'])
+
+  # Copy the output files to their ultimate destination.
+  icu_txt_data_dir = '%s/data/misc' % icu_dir
+  print 'Copying zoneinfo64.txt to %s ...' % icu_txt_data_dir
+  shutil.copy('zoneinfo64.txt', icu_txt_data_dir)
+
+  os.chdir(icu_working_dir)
+  icu_dat_data_dir = '%s/stubdata' % icu_dir
+  datfiles = glob.glob('data/out/tmp/icudt??l.dat')
+  if len(datfiles) != 1:
+    print 'ERROR: Unexpectedly found %d .dat files (%s). Halting.' % (len(datfiles), datfiles)
+    sys.exit(1)
+
+  datfile = datfiles[0]
+  print 'Copying %s to %s ...' % (datfile, icu_dat_data_dir)
+  shutil.copy(datfile, icu_dat_data_dir)
+
+  # Switch back to the original working cwd.
+  os.chdir(original_working_dir)
+
+
+def CheckSignature(data_filename):
   signature_filename = '%s.asc' % data_filename
   print 'Verifying signature...'
   # If this fails for you, you probably need to import Paul Eggert's public key:
@@ -116,6 +151,10 @@
   subprocess.check_call(['gpg', '--trusted-key=ED97E90E62AA7E34', '--verify',
                          signature_filename, data_filename])
 
+
+def BuildBionicToolsAndData(data_filename):
+  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
+
   print 'Extracting...'
   os.mkdir('extracted')
   tar = tarfile.open(data_filename, 'r')
@@ -175,10 +214,16 @@
   for filename in tzdata_filenames:
     if filename > current_filename:
       print 'Found new tzdata: %s' % filename
+      SwitchToNewTemporaryDirectory()
       if use_ftp:
-        FtpUpgrade(ftp, filename)
+        FtpRetrieveFileAndSignature(ftp, filename)
       else:
-        HttpUpgrade(http, filename)
+        HttpRetrieveFileAndSignature(http, filename)
+
+      CheckSignature(filename)
+      BuildIcuToolsAndData(filename)
+      BuildBionicToolsAndData(filename)
+      print 'Look in %s and %s for new data files' % (bionic_dir, icu_dir)
       sys.exit(0)
 
   print 'You already have the latest tzdata (%s)!' % current_version
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 85e91c3..7bcb59f 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -65,10 +65,10 @@
   do_android_update_LD_LIBRARY_PATH(ld_library_path);
 }
 
-void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo)
-{
+static void* dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo, const void* caller_addr) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  soinfo* result = do_dlopen(filename, flags, extinfo);
+  soinfo* caller_soinfo = find_containing_library(caller_addr);
+  soinfo* result = do_dlopen(filename, flags, caller_soinfo, extinfo);
   if (result == NULL) {
     __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
     return NULL;
@@ -76,17 +76,26 @@
   return result;
 }
 
+void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo) {
+  void* caller_addr = __builtin_return_address(0);
+  return dlopen_ext(filename, flags, extinfo, caller_addr);
+}
+
 void* dlopen(const char* filename, int flags) {
-  return android_dlopen_ext(filename, flags, NULL);
+  void* caller_addr = __builtin_return_address(0);
+  return dlopen_ext(filename, flags, NULL, caller_addr);
 }
 
 void* dlsym(void* handle, const char* symbol) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
 
+#if !defined(__LP64__)
   if (handle == NULL) {
     __bionic_format_dlerror("dlsym library handle is null", NULL);
     return NULL;
   }
+#endif
+
   if (symbol == NULL) {
     __bionic_format_dlerror("dlsym symbol name is null", NULL);
     return NULL;
@@ -94,11 +103,11 @@
 
   soinfo* found = NULL;
   ElfW(Sym)* sym = NULL;
-  if (handle == RTLD_DEFAULT) {
+  if (handle == RTLD_DEFAULT || handle == (void*)0xffffffffL) {
     sym = dlsym_linear_lookup(symbol, &found, NULL);
-  } else if (handle == RTLD_NEXT) {
-    void* ret_addr = __builtin_return_address(0);
-    soinfo* si = find_containing_library(ret_addr);
+  } else if (handle == RTLD_NEXT || handle == (void*)0xfffffffeL) {
+    void* caller_addr = __builtin_return_address(0);
+    soinfo* si = find_containing_library(caller_addr);
 
     sym = NULL;
     if (si && si->next) {
@@ -151,7 +160,9 @@
 
 int dlclose(void* handle) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  return do_dlclose(reinterpret_cast<soinfo*>(handle));
+  do_dlclose(reinterpret_cast<soinfo*>(handle));
+  // dlclose has no defined errors.
+  return 0;
 }
 
 // name_offset: starting index of the name in libdl_info.strtab
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c5006e0..9f458b4 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -65,6 +65,19 @@
  *   and NOEXEC
  */
 
+#if defined(__LP64__)
+#define SEARCH_NAME(x) x
+#else
+// Nvidia drivers are relying on the bug:
+// http://code.google.com/p/android/issues/detail?id=6670
+// so we continue to use base-name lookup for lp32
+static const char* get_base_name(const char* name) {
+  const char* bname = strrchr(name, '/');
+  return bname ? bname + 1 : name;
+}
+#define SEARCH_NAME(x) get_base_name(x)
+#endif
+
 static bool soinfo_link_image(soinfo* si, const android_dlextinfo* extinfo);
 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
 
@@ -656,7 +669,8 @@
     }
     // ...but nvidia binary blobs (at least) rely on this behavior, so fall through for now.
 #if defined(__LP64__)
-    return -1;
+    // TODO: uncomment this after bug b/7465467 is fixed.
+    // return -1;
 #endif
   }
 
@@ -668,7 +682,7 @@
   return fd;
 }
 
-static soinfo* load_library(const char* name, const android_dlextinfo* extinfo) {
+static soinfo* load_library(const char* name, int dlflags, const android_dlextinfo* extinfo) {
     // Open the file.
     int fd = open_library(name);
     if (fd == -1) {
@@ -696,13 +710,16 @@
       }
     }
 
+    if ((dlflags & RTLD_NOLOAD) != 0) {
+      return NULL;
+    }
+
     // Read the ELF header and load the segments.
     if (!elf_reader.Load(extinfo)) {
         return NULL;
     }
 
-    const char* bname = strrchr(name, '/');
-    soinfo* si = soinfo_alloc(bname ? bname + 1 : name, &file_stat);
+    soinfo* si = soinfo_alloc(SEARCH_NAME(name), &file_stat);
     if (si == NULL) {
         return NULL;
     }
@@ -725,48 +742,47 @@
     return si;
 }
 
-static soinfo *find_loaded_library(const char* name) {
-    // TODO: don't use basename only for determining libraries
-    // http://code.google.com/p/android/issues/detail?id=6670
-
-    const char* bname = strrchr(name, '/');
-    bname = bname ? bname + 1 : name;
-
-    for (soinfo* si = solist; si != NULL; si = si->next) {
-        if (!strcmp(bname, si->name)) {
-            return si;
-        }
+static soinfo *find_loaded_library_by_name(const char* name) {
+  const char* search_name = SEARCH_NAME(name);
+  for (soinfo* si = solist; si != NULL; si = si->next) {
+    if (!strcmp(search_name, si->name)) {
+      return si;
     }
-    return NULL;
+  }
+  return NULL;
 }
 
-static soinfo* find_library_internal(const char* name, const android_dlextinfo* extinfo) {
+static soinfo* find_library_internal(const char* name, int dlflags, const android_dlextinfo* extinfo) {
   if (name == NULL) {
     return somain;
   }
 
-  soinfo* si = find_loaded_library(name);
-  if (si != NULL) {
-    if (si->flags & FLAG_LINKED) {
-      return si;
-    }
-    DL_ERR("OOPS: recursive link to \"%s\"", si->name);
+  soinfo* si = find_loaded_library_by_name(name);
+
+  // Library might still be loaded, the accurate detection
+  // of this fact is done by load_library
+  if (si == NULL) {
+    TRACE("[ '%s' has not been found by name.  Trying harder...]", name);
+    si = load_library(name, dlflags, extinfo);
+  }
+
+  if (si != NULL && (si->flags & FLAG_LINKED) == 0) {
+    DL_ERR("recursive link to \"%s\"", si->name);
     return NULL;
   }
 
-  TRACE("[ '%s' has not been loaded yet.  Locating...]", name);
-  return load_library(name, extinfo);
+  return si;
 }
 
-static soinfo* find_library(const char* name, const android_dlextinfo* extinfo) {
-  soinfo* si = find_library_internal(name, extinfo);
+static soinfo* find_library(const char* name, int dlflags, const android_dlextinfo* extinfo) {
+  soinfo* si = find_library_internal(name, dlflags, extinfo);
   if (si != NULL) {
     si->ref_count++;
   }
   return si;
 }
 
-static int soinfo_unload(soinfo* si) {
+static void soinfo_unload(soinfo* si) {
   if (si->ref_count == 1) {
     TRACE("unloading '%s'", si->name);
     si->CallDestructors();
@@ -781,7 +797,14 @@
         if (d->d_tag == DT_NEEDED) {
           const char* library_name = si->strtab + d->d_un.d_val;
           TRACE("%s needs to unload %s", si->name, library_name);
-          soinfo_unload(find_loaded_library(library_name));
+          soinfo* needed = find_library(library_name, RTLD_NOLOAD, NULL);
+          if (needed != NULL) {
+            soinfo_unload(needed);
+          } else {
+            // Not found: for example if symlink was deleted between dlopen and dlclose
+            // Since we cannot really handle errors at this point - print and continue.
+            PRINT("warning: couldn't find %s needed by %s on unload.", library_name, si->name);
+          }
         }
       }
     }
@@ -793,7 +816,6 @@
     si->ref_count--;
     TRACE("not unloading '%s', decrementing ref_count to %zd", si->name, si->ref_count);
   }
-  return 0;
 }
 
 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
@@ -806,8 +828,8 @@
   }
 }
 
-soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo) {
-  if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL)) != 0) {
+soinfo* do_dlopen(const char* name, int flags, soinfo* caller, const android_dlextinfo* extinfo) {
+  if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NOLOAD)) != 0) {
     DL_ERR("invalid flags to dlopen: %x", flags);
     return NULL;
   }
@@ -816,20 +838,21 @@
     return NULL;
   }
   protect_data(PROT_READ | PROT_WRITE);
-  soinfo* si = find_library(name, extinfo);
+  soinfo* si = find_library(name, flags, extinfo);
   if (si != NULL) {
     si->CallConstructors();
-    somain->add_child(si);
+    if (caller != NULL) {
+      caller->add_child(si);
+    }
   }
   protect_data(PROT_READ);
   return si;
 }
 
-int do_dlclose(soinfo* si) {
+void do_dlclose(soinfo* si) {
   protect_data(PROT_READ | PROT_WRITE);
-  int result = soinfo_unload(si);
+  soinfo_unload(si);
   protect_data(PROT_READ);
-  return result;
 }
 
 #if defined(USE_RELA)
@@ -889,6 +912,7 @@
         case R_X86_64_JUMP_SLOT:
         case R_X86_64_GLOB_DAT:
         case R_X86_64_32:
+        case R_X86_64_64:
         case R_X86_64_RELATIVE:
           // No need to do anything.
           break;
@@ -1427,6 +1451,10 @@
 
   // DT_FINI should be called after DT_FINI_ARRAY if both are present.
   CallFunction("DT_FINI", fini_func);
+
+  // This is needed on second call to dlopen
+  // after library has been unloaded with RTLD_NODELETE
+  constructors_called = false;
 }
 
 void soinfo::add_child(soinfo* child) {
@@ -1803,7 +1831,7 @@
         memset(g_ld_preloads, 0, sizeof(g_ld_preloads));
         size_t preload_count = 0;
         for (size_t i = 0; g_ld_preload_names[i] != NULL; i++) {
-            soinfo* lsi = find_library(g_ld_preload_names[i], NULL);
+            soinfo* lsi = find_library(g_ld_preload_names[i], 0, NULL);
             if (lsi != NULL) {
                 g_ld_preloads[preload_count++] = lsi;
             } else {
@@ -1821,7 +1849,7 @@
         if (d->d_tag == DT_NEEDED) {
             const char* library_name = si->strtab + d->d_un.d_val;
             DEBUG("%s needs %s", si->name, library_name);
-            soinfo* lsi = find_library(library_name, NULL);
+            soinfo* lsi = find_library(library_name, 0, NULL);
             if (lsi == NULL) {
                 strlcpy(tmp_err_buf, linker_get_error_buffer(), sizeof(tmp_err_buf));
                 DL_ERR("could not load library \"%s\" needed by \"%s\"; caused by %s",
diff --git a/linker/linker.h b/linker/linker.h
index e5aca6e..9d4099d 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -231,8 +231,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);
-int do_dlclose(soinfo* si);
+soinfo* do_dlopen(const char* name, int flags, soinfo* caller, const android_dlextinfo* extinfo);
+void do_dlclose(soinfo* si);
 
 ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* start);
 soinfo* find_containing_library(const void* addr);
diff --git a/tests/Android.mk b/tests/Android.mk
index 9a17c10..37aeec3 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -40,6 +40,10 @@
 
 test_cflags += -D__STDC_LIMIT_MACROS  # For glibc.
 
+ifeq ($(MALLOC_IMPL),jemalloc)
+test_cflags += -DUSE_JEMALLOC
+endif
+
 test_cppflags = \
     -std=gnu++11 \
 
@@ -267,6 +271,18 @@
 include $(LOCAL_PATH)/Android.build.mk
 
 # -----------------------------------------------------------------------------
+# Library used by dlfcn tests
+# -----------------------------------------------------------------------------
+libtest_simple_src_files := \
+    dlopen_testlib_simple.cpp
+
+module := libtest_simple
+build_type := target
+build_target := SHARED_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+
+
+# -----------------------------------------------------------------------------
 # Library used by atexit tests
 # -----------------------------------------------------------------------------
 
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 3b3c0f6..3459a56 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -50,6 +50,18 @@
   ASSERT_EQ(0, dlclose(self));
 }
 
+TEST(dlfcn, dlopen_noload) {
+  void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == NULL);
+  handle = dlopen("libtest_simple.so", RTLD_NOW);
+  void* handle2 = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle2 != NULL);
+  ASSERT_TRUE(handle == handle2);
+  ASSERT_EQ(0, dlclose(handle));
+  ASSERT_EQ(0, dlclose(handle2));
+}
+
 TEST(dlfcn, dlopen_failure) {
   void* self = dlopen("/does/not/exist", RTLD_NOW);
   ASSERT_TRUE(self == NULL);
@@ -89,6 +101,8 @@
 
   void* sym;
 
+  // lp64 RTLD_DEFAULT=(void*)0
+#if !defined(__LP64__)
   // NULL handle.
   sym = dlsym(NULL, "test");
   ASSERT_TRUE(sym == NULL);
@@ -97,6 +111,7 @@
 #else
   ASSERT_SUBSTR("undefined symbol: test", dlerror()); // glibc isn't specific about the failure.
 #endif
+#endif // !defined(__LP64__)
 
   // NULL symbol name.
 #if defined(__BIONIC__)
diff --git a/tests/dlopen_testlib_simple.cpp b/tests/dlopen_testlib_simple.cpp
new file mode 100644
index 0000000..afe54b4
--- /dev/null
+++ b/tests/dlopen_testlib_simple.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+uint32_t dlopen_testlib_taxicab_number = 1729;
+
+bool dlopen_testlib_simple_func() {
+  return true;
+}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 259853d..12a5ffa 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -46,7 +46,7 @@
   for (size_t i = 0; i <= 12; i++) {
     for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
       char *ptr = (char*)memalign(alignment, 100);
-      ASSERT_TRUE(ptr != NULL);
+      ASSERT_TRUE(ptr != NULL) << alignment;
       ASSERT_LE(100U, malloc_usable_size(ptr));
       ASSERT_EQ(0, (intptr_t)ptr % (1 << i));
 
@@ -233,3 +233,18 @@
 
   free(ptr);
 }
+
+TEST(malloc, posix_memalign_non_power2) {
+  void* ptr;
+
+  ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
+}
+
+TEST(malloc, memalign_non_power2) {
+  void* ptr;
+  for (size_t align = 0; align <= 256; align++) {
+    ptr = memalign(align, 1024);
+    ASSERT_TRUE(ptr != NULL) << "Failed at align " << align;
+    free(ptr);
+  }
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index fa66d21..8015404 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -551,12 +551,49 @@
   pthread_rwlock_t l;
   ASSERT_EQ(0, pthread_rwlock_init(&l, NULL));
 
+  // Single read lock
   ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
 
+  // Multiple read lock
+  ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_rdlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+
+  // Write lock
+   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
+   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+
+  // Try writer lock
+  ASSERT_EQ(0, pthread_rwlock_trywrlock(&l));
+  ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l));
+  ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+
+  // Try reader lock
+  ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_tryrdlock(&l));
+  ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+
+  // Try writer lock after unlock
   ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
   ASSERT_EQ(0, pthread_rwlock_unlock(&l));
 
+#ifdef __BIONIC__
+  // EDEADLK in "read after write"
+  ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
+  ASSERT_EQ(EDEADLK, pthread_rwlock_rdlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+
+  // EDEADLK in "write after write"
+  ASSERT_EQ(0, pthread_rwlock_wrlock(&l));
+  ASSERT_EQ(EDEADLK, pthread_rwlock_wrlock(&l));
+  ASSERT_EQ(0, pthread_rwlock_unlock(&l));
+#endif
+
   ASSERT_EQ(0, pthread_rwlock_destroy(&l));
 }
 
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 5ccc63d..f17e575 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -909,6 +909,56 @@
   }
 }
 
+static void verify_memmove(char* src_copy, char* dst, char* src, size_t size) {
+  memset(dst, 0, size);
+  memcpy(src, src_copy, size);
+  ASSERT_EQ(dst, memmove(dst, src, size));
+  ASSERT_EQ(0, memcmp(dst, src_copy, size));
+}
+
+#define MEMMOVE_DATA_SIZE (1024*1024*3)
+
+TEST(string, memmove_check) {
+  char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
+  ASSERT_TRUE(buffer != NULL);
+
+  char* src_data = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
+  ASSERT_TRUE(src_data != NULL);
+  // Initialize to a known pattern to copy into src for each test and
+  // to compare dst against.
+  for (size_t i = 0; i < MEMMOVE_DATA_SIZE; i++) {
+    src_data[i] = (i + 1) % 255;
+  }
+
+  // Check all different dst offsets between 0 and 127 inclusive.
+  char* src = buffer;
+  for (size_t i = 0; i < 127; i++) {
+    char* dst = buffer + 256 + i;
+    // Small copy.
+    verify_memmove(src_data, dst, src, 1024);
+
+    // Medium copy.
+    verify_memmove(src_data, dst, src, 64 * 1024);
+
+    // Medium copy.
+    verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
+  }
+
+  // Check all leftover size offsets between 1 and 127 inclusive.
+  char* dst = buffer + 256;
+  src = buffer;
+  for (size_t size = 1; size < 127; size++) {
+    // Small copy.
+    verify_memmove(src_data, dst, src, 1024);
+
+    // Medium copy.
+    verify_memmove(src_data, dst, src, 64 * 1024);
+
+    // Large copy.
+    verify_memmove(src_data, dst, src, 1024 * 1024 + 128 * 1024);
+  }
+}
+
 TEST(string, bcopy) {
   StringTestState<char> state(LARGE);
   for (size_t i = 0; i < state.n; i++) {
@@ -964,6 +1014,22 @@
   RunSrcDstBufferOverreadTest(DoMemcpyTest);
 }
 
+static void DoMemmoveTest(uint8_t* src, uint8_t* dst, size_t len) {
+  memset(src, (len % 255) + 1, len);
+  memset(dst, 0, len);
+
+  ASSERT_EQ(dst, memmove(dst, src, len));
+  ASSERT_TRUE(memcmp(src, dst, len) == 0);
+}
+
+TEST(string, memmove_align) {
+  RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
+}
+
+TEST(string, memmove_overread) {
+  RunSrcDstBufferOverreadTest(DoMemmoveTest);
+}
+
 static void DoMemsetTest(uint8_t* buf, size_t len) {
   for (size_t i = 0; i < len; i++) {
     buf[i] = 0;