Merge "Merge pie-platform-release (PPRL.181105.017, history only) into master"
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/libc/Android.bp b/libc/Android.bp
index 6b46ba0..486373c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -714,8 +714,8 @@
                 "arch-arm/cortex-a53/bionic/__strcat_chk.S",
                 "arch-arm/cortex-a53/bionic/__strcpy_chk.S",
 
-                "arch-arm/denver/bionic/__strcat_chk.S",
-                "arch-arm/denver/bionic/__strcpy_chk.S",
+                "arch-arm/cortex-a55/bionic/__strcat_chk.S",
+                "arch-arm/cortex-a55/bionic/__strcpy_chk.S",
             ],
         },
         arm64: {
@@ -786,11 +786,9 @@
                 "arch-arm/cortex-a15/bionic/strlen.S",
 
                 "arch-arm/cortex-a7/bionic/memcpy.S",
-                "arch-arm/cortex-a7/bionic/memmove.S",
                 "arch-arm/cortex-a7/bionic/memset.S",
 
                 "arch-arm/cortex-a9/bionic/memcpy.S",
-                "arch-arm/cortex-a9/bionic/memmove.S",
                 "arch-arm/cortex-a9/bionic/memset.S",
                 "arch-arm/cortex-a9/bionic/stpcpy.S",
                 "arch-arm/cortex-a9/bionic/strcat.S",
@@ -799,19 +797,14 @@
                 "arch-arm/cortex-a9/bionic/strlen.S",
 
                 "arch-arm/krait/bionic/memcpy.S",
-                "arch-arm/krait/bionic/memmove.S",
                 "arch-arm/krait/bionic/memset.S",
                 "arch-arm/krait/bionic/strcmp.S",
 
                 "arch-arm/cortex-a53/bionic/memcpy.S",
-                "arch-arm/cortex-a53/bionic/memmove.S",
 
-                "arch-arm/denver/bionic/memcpy.S",
-                "arch-arm/denver/bionic/memmove.S",
-                "arch-arm/denver/bionic/memset.S",
+                "arch-arm/cortex-a55/bionic/memcpy.S",
 
                 "arch-arm/kryo/bionic/memcpy.S",
-                "arch-arm/kryo/bionic/memmove.S",
             ],
         },
         arm64: {
@@ -1142,7 +1135,6 @@
         "bionic/stdlib_l.cpp",
         "bionic/strchrnul.cpp",
         "bionic/strerror.cpp",
-        "bionic/strerror_r.cpp",
         "bionic/string_l.cpp",
         "bionic/strings_l.cpp",
         "bionic/strsignal.cpp",
@@ -1623,9 +1615,15 @@
     ],
     name: "libstdc++",
     static_ndk_lib: true,
-    system_shared_libs: ["libc"],
     static_libs: ["libasync_safe"],
 
+    static: {
+        system_shared_libs: [],
+    },
+    shared: {
+        system_shared_libs: ["libc"],
+    },
+
     //TODO (dimitry): This is to work around b/24465209. Remove after root cause is fixed
     arch: {
         arm: {
diff --git a/libc/NOTICE b/libc/NOTICE
index 314b936..40a5704 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -808,35 +808,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (C) 2013 The Android Open Source Project
-Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
-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.
-
--------------------------------------------------------------------
-
 Copyright (C) 2014 The Android Open Source Project
 
 Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/libc/arch-arm/cortex-a15/bionic/memmove.S b/libc/arch-arm/cortex-a15/bionic/memmove.S
index 2b12de0..92eba8d 100644
--- a/libc/arch-arm/cortex-a15/bionic/memmove.S
+++ b/libc/arch-arm/cortex-a15/bionic/memmove.S
@@ -1,6 +1,7 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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
@@ -26,7 +27,254 @@
  * SUCH DAMAGE.
  */
 
-#define MEMMOVE memmove_a15
-#define MEMCPY __memcpy_a15
+#include <private/bionic_asm.h>
 
-#include <arch-arm/denver/bionic/memmove.S>
+        .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_a15)
+        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_a15)
diff --git a/libc/arch-arm/cortex-a53/bionic/memmove.S b/libc/arch-arm/cortex-a53/bionic/memmove.S
deleted file mode 100644
index 741acb3..0000000
--- a/libc/arch-arm/cortex-a53/bionic/memmove.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define MEMMOVE memmove_a53
-#define MEMCPY __memcpy_a53
-
-#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/denver/bionic/__strcat_chk.S b/libc/arch-arm/cortex-a55/bionic/__strcat_chk.S
similarity index 96%
rename from libc/arch-arm/denver/bionic/__strcat_chk.S
rename to libc/arch-arm/cortex-a55/bionic/__strcat_chk.S
index 1899908..eec1005 100644
--- a/libc/arch-arm/denver/bionic/__strcat_chk.S
+++ b/libc/arch-arm/cortex-a55/bionic/__strcat_chk.S
@@ -40,7 +40,7 @@
 // Get the length of src string, then get the source of the dst string.
 // Check that the two lengths together don't exceed the threshold, then
 // do a memcpy of the data.
-ENTRY(__strcat_chk_denver)
+ENTRY(__strcat_chk_a55)
     pld     [r0, #0]
     push    {r0, lr}
     .cfi_def_cfa_offset 8
@@ -190,9 +190,9 @@
     mov     r2, r4
     add     r0, r0, r3
     pop     {r4, r5}
-END(__strcat_chk_denver)
+END(__strcat_chk_a55)
 
-#define MEMCPY_BASE         __strcat_chk_denver_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcat_chk_denver_memcpy_base_aligned
+#define MEMCPY_BASE         __strcat_chk_a55_memcpy_base
+#define MEMCPY_BASE_ALIGNED __strcat_chk_a55_memcpy_base_aligned
 
 #include "memcpy_base.S"
diff --git a/libc/arch-arm/denver/bionic/__strcpy_chk.S b/libc/arch-arm/cortex-a55/bionic/__strcpy_chk.S
similarity index 95%
rename from libc/arch-arm/denver/bionic/__strcpy_chk.S
rename to libc/arch-arm/cortex-a55/bionic/__strcpy_chk.S
index 9910c76..dfcc589 100644
--- a/libc/arch-arm/denver/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/cortex-a55/bionic/__strcpy_chk.S
@@ -39,7 +39,7 @@
 
 // Get the length of the source string first, then do a memcpy of the data
 // instead of a strcpy.
-ENTRY(__strcpy_chk_denver)
+ENTRY(__strcpy_chk_a55)
     pld     [r0, #0]
     push    {r0, lr}
     .cfi_def_cfa_offset 8
@@ -161,8 +161,8 @@
     bhi     __strcpy_chk_fail
 
     // Fall through into the memcpy_base function.
-END(__strcpy_chk_denver)
+END(__strcpy_chk_a55)
 
-#define MEMCPY_BASE         __strcpy_chk_denver_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcpy_chk_denver_memcpy_base_aligned
+#define MEMCPY_BASE         __strcpy_chk_a55_memcpy_base
+#define MEMCPY_BASE_ALIGNED __strcpy_chk_a55_memcpy_base_aligned
 #include "memcpy_base.S"
diff --git a/libc/arch-arm/denver/bionic/memcpy.S b/libc/arch-arm/cortex-a55/bionic/memcpy.S
similarity index 95%
rename from libc/arch-arm/denver/bionic/memcpy.S
rename to libc/arch-arm/cortex-a55/bionic/memcpy.S
index 5edee1e..ac9675f 100644
--- a/libc/arch-arm/denver/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a55/bionic/memcpy.S
@@ -65,14 +65,14 @@
         // arch. The code generated is exactly the same.
         .arch armv7-a
 
-ENTRY(__memcpy_denver)
+ENTRY(__memcpy_a55)
         pld     [r1, #64]
         push    {r0, lr}
         .cfi_def_cfa_offset 8
         .cfi_rel_offset r0, 0
         .cfi_rel_offset lr, 4
-END(__memcpy_denver)
+END(__memcpy_a55)
 
-#define MEMCPY_BASE         __memcpy_base_denver
-#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned_denver
+#define MEMCPY_BASE         __memcpy_base_a55
+#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned_a55
 #include "memcpy_base.S"
diff --git a/libc/arch-arm/denver/bionic/memcpy_base.S b/libc/arch-arm/cortex-a55/bionic/memcpy_base.S
similarity index 100%
rename from libc/arch-arm/denver/bionic/memcpy_base.S
rename to libc/arch-arm/cortex-a55/bionic/memcpy_base.S
diff --git a/libc/arch-arm/cortex-a7/bionic/memmove.S b/libc/arch-arm/cortex-a7/bionic/memmove.S
deleted file mode 100644
index 17ead5a..0000000
--- a/libc/arch-arm/cortex-a7/bionic/memmove.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define MEMMOVE memmove_a7
-#define MEMCPY __memcpy_a7
-
-#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/cortex-a9/bionic/memmove.S b/libc/arch-arm/cortex-a9/bionic/memmove.S
deleted file mode 100644
index a457633..0000000
--- a/libc/arch-arm/cortex-a9/bionic/memmove.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define MEMMOVE memmove_a9
-#define MEMCPY __memcpy_a9
-
-#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/denver/bionic/memmove.S b/libc/arch-arm/denver/bionic/memmove.S
deleted file mode 100644
index 13c90ef..0000000
--- a/libc/arch-arm/denver/bionic/memmove.S
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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>
-
-#ifndef MEMMOVE
-# define MEMMOVE memmove_denver
-#endif
-
-#ifndef MEMCPY
-# define MEMCPY __memcpy_denver
-#endif
-
-        .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/bionic/memset.S b/libc/arch-arm/denver/bionic/memset.S
deleted file mode 100644
index 198ecf3..0000000
--- a/libc/arch-arm/denver/bionic/memset.S
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
- * 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>
-
-        /*
-         * Optimized memset() for ARM.
-         *
-         * memset() returns its first argument.
-         */
-
-        .cpu        cortex-a15
-        .fpu        neon
-        .syntax     unified
-
-ENTRY(__memset_chk_denver)
-        cmp         r2, r3
-        bls         memset
-
-        // Preserve lr for backtrace.
-        push        {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        bl          __memset_chk_fail
-END(__memset_chk_denver)
-
-ENTRY(memset_denver)
-        pldw        [r0]
-        mov         r3, r0
-
-        // Duplicate the low byte of r1
-        mov         r1, r1, lsl #24
-        orr         r1, r1, r1, lsr #8
-        orr         r1, r1, r1, lsr #16
-
-        cmp         r2, #16
-        blo         .L_less_than_16
-
-        // This section handles regions 16 bytes or larger
-        //
-        // Use aligned vst1.8 and vstm when possible.  Register values will be:
-        //   ip is scratch
-        //   q0, q1, and r1 contain the memset value
-        //   r2 is the number of bytes to set
-        //   r3 is the advancing destination pointer
-        vdup.32     q0, r1
-
-        ands        ip, r3, 0xF
-        beq         .L_memset_aligned
-
-        // Align dest pointer to 16-byte boundary.
-        pldw        [r0, #64]
-        rsb         ip, ip, #16
-
-        // Pre-adjust the byte count to reflect post-aligment value.  Expecting
-        // 8-byte alignment to be rather common so we special case that one.
-        sub         r2, r2, ip
-
-        /* set 1 byte */
-        tst         ip, #1
-        it          ne
-        strbne      r1, [r3], #1
-        /* set 2 bytes */
-        tst         ip, #2
-        it          ne
-        strhne      r1, [r3], #2
-        /* set 4 bytes */
-        movs        ip, ip, lsl #29
-        it          mi
-        strmi       r1, [r3], #4
-        /* set 8 bytes */
-        itt         cs
-        strcs       r1, [r3], #4
-        strcs       r1, [r3], #4
-
-.L_memset_aligned:
-        // Destination is now 16-byte aligned.  Determine how to handle
-        // remaining bytes.
-        vmov        q1, q0
-        cmp         r2, #128
-        blo         .L_less_than_128
-
-        // We need to set a larger block of memory.  Use four Q regs to
-        // set a full cache line in one instruction.  Pre-decrement
-        // r2 to simplify end-of-loop detection
-        vmov        q2, q0
-        vmov        q3, q0
-        pldw        [r0, #128]
-        sub         r2, r2, #128
-        .align 4
-.L_memset_loop_128:
-        pldw        [r3, #192]
-        vstm        r3!, {q0, q1, q2, q3}
-        vstm        r3!, {q0, q1, q2, q3}
-        subs        r2, r2, #128
-        bhs         .L_memset_loop_128
-
-        // Un-bias r2 so it contains the number of bytes left.  Early
-        // exit if we are done.
-        adds        r2, r2, #128
-        beq         2f
-
-        .align 4
-.L_less_than_128:
-        // set 64 bytes
-        movs        ip, r2, lsl #26
-        bcc         1f
-        vst1.8      {q0, q1}, [r3, :128]!
-        vst1.8      {q0, q1}, [r3, :128]!
-        beq         2f
-1:
-        // set 32 bytes
-        bpl         1f
-        vst1.8      {q0, q1}, [r3, :128]!
-1:
-        // set 16 bytes
-        movs        ip, r2, lsl #28
-        bcc         1f
-        vst1.8      {q0}, [r3, :128]!
-        beq         2f
-1:
-        // set 8 bytes
-        bpl         1f
-        vst1.8      {d0}, [r3, :64]!
-1:
-        // set 4 bytes
-        tst         r2, #4
-        it          ne
-        strne       r1, [r3], #4
-1:
-        // set 2 bytes
-        movs        ip, r2, lsl #31
-        it          cs
-        strhcs      r1, [r3], #2
-        // set 1 byte
-        it          mi
-        strbmi      r1, [r3]
-2:
-        bx          lr
-
-.L_less_than_16:
-        // Store up to 15 bytes without worrying about byte alignment
-        movs        ip, r2, lsl #29
-        bcc         1f
-        str         r1, [r3], #4
-        str         r1, [r3], #4
-        beq         2f
-1:
-        it          mi
-        strmi       r1, [r3], #4
-        movs        ip, r2, lsl #31
-        it          mi
-        strbmi      r1, [r3], #1
-        itt         cs
-        strbcs      r1, [r3], #1
-        strbcs      r1, [r3]
-2:
-        bx          lr
-END(memset_denver)
diff --git a/libc/arch-arm/dynamic_function_dispatch.cpp b/libc/arch-arm/dynamic_function_dispatch.cpp
index 822581c..72fb41c 100644
--- a/libc/arch-arm/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm/dynamic_function_dispatch.cpp
@@ -38,7 +38,6 @@
     kCortexA9,
     kCortexA53,
     kCortexA55,
-    kDenver,
     kKrait,
     kKryo,
 };
@@ -59,7 +58,6 @@
     {"krait", kKrait},
     {"cortex-a9", kCortexA9},
     {"cortex-a7", kCortexA7},
-    {"denver", kDenver},
     // kUnknown indicates the end of this array.
     {"", kUnknown},
 };
@@ -157,23 +155,7 @@
 
 typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
 DEFINE_IFUNC(memmove) {
-    switch(get_cpu_variant()) {
-        case kCortexA7:
-            RETURN_FUNC(memmove_func, memmove_a7);
-        case kCortexA9:
-            RETURN_FUNC(memmove_func, memmove_a9);
-        case kKrait:
-            RETURN_FUNC(memmove_func, memmove_krait);
-        case kCortexA53:
-            RETURN_FUNC(memmove_func, memmove_a53);
-        case kCortexA55:
-        case kDenver:
-            RETURN_FUNC(memmove_func, memmove_denver);
-        case kKryo:
-            RETURN_FUNC(memmove_func, memmove_kryo);
-        default:
-            RETURN_FUNC(memmove_func, memmove_a15);
-    }
+    RETURN_FUNC(memmove_func, memmove_a15);
 }
 
 typedef void* memcpy_func(void*, const void*, size_t);
@@ -181,6 +163,26 @@
     return memmove_resolver();
 }
 
+typedef void* __memcpy_func(void*, const void*, size_t);
+DEFINE_IFUNC(__memcpy) {
+    switch(get_cpu_variant()) {
+        case kCortexA7:
+            RETURN_FUNC(__memcpy_func, __memcpy_a7);
+        case kCortexA9:
+            RETURN_FUNC(__memcpy_func, __memcpy_a9);
+        case kKrait:
+            RETURN_FUNC(__memcpy_func, __memcpy_krait);
+        case kCortexA53:
+            RETURN_FUNC(__memcpy_func, __memcpy_a53);
+        case kCortexA55:
+            RETURN_FUNC(__memcpy_func, __memcpy_a55);
+        case kKryo:
+            RETURN_FUNC(__memcpy_func, __memcpy_kryo);
+        default:
+            RETURN_FUNC(__memcpy_func, __memcpy_a15);
+    }
+}
+
 typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
 DEFINE_IFUNC(__memset_chk) {
     switch(get_cpu_variant()) {
@@ -193,8 +195,6 @@
             RETURN_FUNC(__memset_chk_func, __memset_chk_a9);
         case kKrait:
             RETURN_FUNC(__memset_chk_func, __memset_chk_krait);
-        case kDenver:
-            RETURN_FUNC(__memset_chk_func, __memset_chk_denver);
         default:
             RETURN_FUNC(__memset_chk_func, __memset_chk_a15);
     }
@@ -212,8 +212,6 @@
              RETURN_FUNC(memset_func, memset_a9);
         case kKrait:
              RETURN_FUNC(memset_func, memset_krait);
-        case kDenver:
-             RETURN_FUNC(memset_func, memset_denver);
         default:
              RETURN_FUNC(memset_func, memset_a15);
     }
@@ -242,8 +240,7 @@
         case kCortexA53:
             RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a53);
         case kCortexA55:
-        case kDenver:
-            RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_denver);
+            RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a55);
         default:
             RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a15);
     }
@@ -282,8 +279,7 @@
         case kCortexA53:
             RETURN_FUNC(__strcat_chk_func, __strcat_chk_a53);
         case kCortexA55:
-        case kDenver:
-            RETURN_FUNC(__strcat_chk_func, __strcat_chk_denver);
+            RETURN_FUNC(__strcat_chk_func, __strcat_chk_a55);
         default:
             RETURN_FUNC(__strcat_chk_func, __strcat_chk_a15);
     }
diff --git a/libc/arch-arm/krait/bionic/memmove.S b/libc/arch-arm/krait/bionic/memmove.S
deleted file mode 100644
index af85ea6..0000000
--- a/libc/arch-arm/krait/bionic/memmove.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define MEMMOVE memmove_krait
-#define MEMCPY __memcpy_krait
-
-#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/kryo/bionic/memmove.S b/libc/arch-arm/kryo/bionic/memmove.S
deleted file mode 100644
index d0fdd8f..0000000
--- a/libc/arch-arm/kryo/bionic/memmove.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define MEMMOVE memmove_kryo
-#define MEMCPY __memcpy_kryo
-
-#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 528ffb0..d530fa4 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -44,6 +44,7 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#include <private/bionic_defs.h>
 #include <private/bionic_config.h>
 #include <private/bionic_globals.h>
 #include <private/bionic_malloc_dispatch.h>
@@ -671,6 +672,7 @@
 
 // Initializes memory allocation framework.
 // This routine is called from __libc_init routines in libc_init_dynamic.cpp.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 __LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals) {
   malloc_init_impl(globals);
 }
diff --git a/libc/bionic/strerror.cpp b/libc/bionic/strerror.cpp
index 99692ca..38d8191 100644
--- a/libc/bionic/strerror.cpp
+++ b/libc/bionic/strerror.cpp
@@ -26,11 +26,188 @@
  * SUCH DAMAGE.
  */
 
+// G++ automatically defines _GNU_SOURCE, which then means that <string.h>
+// gives us the GNU variant.
+#undef _GNU_SOURCE
+
+#include <string.h>
+
+#include <errno.h>
+#include <limits.h>
+
+#include <async_safe/log.h>
+
+#include "private/ErrnoRestorer.h"
+
 #include <string.h>
 
 #include "bionic/pthread_internal.h"
 
-extern "C" const char* __strerror_lookup(int);
+static const char* __sys_error_strings[] = {
+    [0] = "Success",
+    [EPERM] = "Operation not permitted",
+    [ENOENT] = "No such file or directory",
+    [ESRCH] = "No such process",
+    [EINTR] = "Interrupted system call",
+    [EIO] = "I/O error",
+    [ENXIO] = "No such device or address",
+    [E2BIG] = "Argument list too long",
+    [ENOEXEC] = "Exec format error",
+    [EBADF] = "Bad file descriptor",
+    [ECHILD] = "No child processes",
+    [EAGAIN] = "Try again",
+    [ENOMEM] = "Out of memory",
+    [EACCES] = "Permission denied",
+    [EFAULT] = "Bad address",
+    [ENOTBLK] = "Block device required",
+    [EBUSY] = "Device or resource busy",
+    [EEXIST] = "File exists",
+    [EXDEV] = "Cross-device link",
+    [ENODEV] = "No such device",
+    [ENOTDIR] = "Not a directory",
+    [EISDIR] = "Is a directory",
+    [EINVAL] = "Invalid argument",
+    [ENFILE] = "File table overflow",
+    [EMFILE] = "Too many open files",
+    [ENOTTY] = "Not a typewriter",
+    [ETXTBSY] = "Text file busy",
+    [EFBIG] = "File too large",
+    [ENOSPC] = "No space left on device",
+    [ESPIPE] = "Illegal seek",
+    [EROFS] = "Read-only file system",
+    [EMLINK] = "Too many links",
+    [EPIPE] = "Broken pipe",
+    [EDOM] = "Math argument out of domain of func",
+    [ERANGE] = "Math result not representable",
+    [EDEADLK] = "Resource deadlock would occur",
+    [ENAMETOOLONG] = "File name too long",
+    [ENOLCK] = "No record locks available",
+    [ENOSYS] = "Function not implemented",
+    [ENOTEMPTY] = "Directory not empty",
+    [ELOOP] = "Too many symbolic links encountered",
+    [ENOMSG] = "No message of desired type",
+    [EIDRM] = "Identifier removed",
+    [ECHRNG] = "Channel number out of range",
+    [EL2NSYNC] = "Level 2 not synchronized",
+    [EL3HLT] = "Level 3 halted",
+    [EL3RST] = "Level 3 reset",
+    [ELNRNG] = "Link number out of range",
+    [EUNATCH] = "Protocol driver not attached",
+    [ENOCSI] = "No CSI structure available",
+    [EL2HLT] = "Level 2 halted",
+    [EBADE] = "Invalid exchange",
+    [EBADR] = "Invalid request descriptor",
+    [EXFULL] = "Exchange full",
+    [ENOANO] = "No anode",
+    [EBADRQC] = "Invalid request code",
+    [EBADSLT] = "Invalid slot",
+    [EBFONT] = "Bad font file format",
+    [ENOSTR] = "Device not a stream",
+    [ENODATA] = "No data available",
+    [ETIME] = "Timer expired",
+    [ENOSR] = "Out of streams resources",
+    [ENONET] = "Machine is not on the network",
+    [ENOPKG] = "Package not installed",
+    [EREMOTE] = "Object is remote",
+    [ENOLINK] = "Link has been severed",
+    [EADV] = "Advertise error",
+    [ESRMNT] = "Srmount error",
+    [ECOMM] = "Communication error on send",
+    [EPROTO] = "Protocol error",
+    [EMULTIHOP] = "Multihop attempted",
+    [EDOTDOT] = "RFS specific error",
+    [EBADMSG] = "Not a data message",
+    [EOVERFLOW] = "Value too large for defined data type",
+    [ENOTUNIQ] = "Name not unique on network",
+    [EBADFD] = "File descriptor in bad state",
+    [EREMCHG] = "Remote address changed",
+    [ELIBACC] = "Can not access a needed shared library",
+    [ELIBBAD] = "Accessing a corrupted shared library",
+    [ELIBSCN] = ".lib section in a.out corrupted",
+    [ELIBMAX] = "Attempting to link in too many shared libraries",
+    [ELIBEXEC] = "Cannot exec a shared library directly",
+    [EILSEQ] = "Illegal byte sequence",
+    [ERESTART] = "Interrupted system call should be restarted",
+    [ESTRPIPE] = "Streams pipe error",
+    [EUSERS] = "Too many users",
+    [ENOTSOCK] = "Socket operation on non-socket",
+    [EDESTADDRREQ] = "Destination address required",
+    [EMSGSIZE] = "Message too long",
+    [EPROTOTYPE] = "Protocol wrong type for socket",
+    [ENOPROTOOPT] = "Protocol not available",
+    [EPROTONOSUPPORT] = "Protocol not supported",
+    [ESOCKTNOSUPPORT] = "Socket type not supported",
+    [EOPNOTSUPP] = "Operation not supported on transport endpoint",
+    [EPFNOSUPPORT] = "Protocol family not supported",
+    [EAFNOSUPPORT] = "Address family not supported by protocol",
+    [EADDRINUSE] = "Address already in use",
+    [EADDRNOTAVAIL] = "Cannot assign requested address",
+    [ENETDOWN] = "Network is down",
+    [ENETUNREACH] = "Network is unreachable",
+    [ENETRESET] = "Network dropped connection because of reset",
+    [ECONNABORTED] = "Software caused connection abort",
+    [ECONNRESET] = "Connection reset by peer",
+    [ENOBUFS] = "No buffer space available",
+    [EISCONN] = "Transport endpoint is already connected",
+    [ENOTCONN] = "Transport endpoint is not connected",
+    [ESHUTDOWN] = "Cannot send after transport endpoint shutdown",
+    [ETOOMANYREFS] = "Too many references: cannot splice",
+    [ETIMEDOUT] = "Connection timed out",
+    [ECONNREFUSED] = "Connection refused",
+    [EHOSTDOWN] = "Host is down",
+    [EHOSTUNREACH] = "No route to host",
+    [EALREADY] = "Operation already in progress",
+    [EINPROGRESS] = "Operation now in progress",
+    [ESTALE] = "Stale NFS file handle",
+    [EUCLEAN] = "Structure needs cleaning",
+    [ENOTNAM] = "Not a XENIX named type file",
+    [ENAVAIL] = "No XENIX semaphores available",
+    [EISNAM] = "Is a named type file",
+    [EREMOTEIO] = "Remote I/O error",
+    [EDQUOT] = "Quota exceeded",
+    [ENOMEDIUM] = "No medium found",
+    [EMEDIUMTYPE] = "Wrong medium type",
+    [ECANCELED] = "Operation Canceled",
+    [ENOKEY] = "Required key not available",
+    [EKEYEXPIRED] = "Key has expired",
+    [EKEYREVOKED] = "Key has been revoked",
+    [EKEYREJECTED] = "Key was rejected by service",
+    [EOWNERDEAD] = "Owner died",
+    [ENOTRECOVERABLE] = "State not recoverable",
+    [ERFKILL] = "Operation not possible due to RF-kill",
+    [EHWPOISON] = "Memory page has hardware error",
+};
+
+static inline const char* __strerror_lookup(int error_number) {
+  if (error_number < 0 || error_number >= static_cast<int>(arraysize(__sys_error_strings))) {
+    return nullptr;
+  }
+  return __sys_error_strings[error_number];
+}
+
+int strerror_r(int error_number, char* buf, size_t buf_len) {
+  ErrnoRestorer errno_restorer;
+  size_t length;
+
+  const char* error_name = __strerror_lookup(error_number);
+  if (error_name != nullptr) {
+    length = strlcpy(buf, error_name, buf_len);
+  } else {
+    length = async_safe_format_buffer(buf, buf_len, "Unknown error %d", error_number);
+  }
+  if (length >= buf_len) {
+    errno_restorer.override(ERANGE);
+    return -1;
+  }
+
+  return 0;
+}
+
+extern "C" char* __gnu_strerror_r(int error_number, char* buf, size_t buf_len) {
+  ErrnoRestorer errno_restorer; // The glibc strerror_r doesn't set errno if it truncates...
+  strerror_r(error_number, buf, buf_len);
+  return buf; // ...and just returns whatever fit.
+}
 
 char* strerror(int error_number) {
   // Just return the original constant in the easy cases.
diff --git a/libc/bionic/strerror_r.cpp b/libc/bionic/strerror_r.cpp
deleted file mode 100644
index 326d4b1..0000000
--- a/libc/bionic/strerror_r.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $OpenBSD: strerror_r.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
-/* Public Domain <marc@snafu.org> */
-
-// G++ automatically defines _GNU_SOURCE, which then means that <string.h>
-// gives us the GNU variant.
-#undef _GNU_SOURCE
-
-#include <string.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-
-#include <async_safe/log.h>
-
-#include "private/ErrnoRestorer.h"
-
-struct Pair {
-  int code;
-  const char* msg;
-};
-
-static const char* __code_string_lookup(const Pair* strings, int code) {
-  for (size_t i = 0; strings[i].msg != nullptr; ++i) {
-    if (strings[i].code == code) {
-      return strings[i].msg;
-    }
-  }
-  return nullptr;
-}
-
-static const Pair _sys_error_strings[] = {
-    {0, "Success"},
-    {EPERM, "Operation not permitted"},
-    {ENOENT, "No such file or directory"},
-    {ESRCH, "No such process"},
-    {EINTR, "Interrupted system call"},
-    {EIO, "I/O error"},
-    {ENXIO, "No such device or address"},
-    {E2BIG, "Argument list too long"},
-    {ENOEXEC, "Exec format error"},
-    {EBADF, "Bad file descriptor"},
-    {ECHILD, "No child processes"},
-    {EAGAIN, "Try again"},
-    {ENOMEM, "Out of memory"},
-    {EACCES, "Permission denied"},
-    {EFAULT, "Bad address"},
-    {ENOTBLK, "Block device required"},
-    {EBUSY, "Device or resource busy"},
-    {EEXIST, "File exists"},
-    {EXDEV, "Cross-device link"},
-    {ENODEV, "No such device"},
-    {ENOTDIR, "Not a directory"},
-    {EISDIR, "Is a directory"},
-    {EINVAL, "Invalid argument"},
-    {ENFILE, "File table overflow"},
-    {EMFILE, "Too many open files"},
-    {ENOTTY, "Not a typewriter"},
-    {ETXTBSY, "Text file busy"},
-    {EFBIG, "File too large"},
-    {ENOSPC, "No space left on device"},
-    {ESPIPE, "Illegal seek"},
-    {EROFS, "Read-only file system"},
-    {EMLINK, "Too many links"},
-    {EPIPE, "Broken pipe"},
-    {EDOM, "Math argument out of domain of func"},
-    {ERANGE, "Math result not representable"},
-    {EDEADLK, "Resource deadlock would occur"},
-    {ENAMETOOLONG, "File name too long"},
-    {ENOLCK, "No record locks available"},
-    {ENOSYS, "Function not implemented"},
-    {ENOTEMPTY, "Directory not empty"},
-    {ELOOP, "Too many symbolic links encountered"},
-    {ENOMSG, "No message of desired type"},
-    {EIDRM, "Identifier removed"},
-    {ECHRNG, "Channel number out of range"},
-    {EL2NSYNC, "Level 2 not synchronized"},
-    {EL3HLT, "Level 3 halted"},
-    {EL3RST, "Level 3 reset"},
-    {ELNRNG, "Link number out of range"},
-    {EUNATCH, "Protocol driver not attached"},
-    {ENOCSI, "No CSI structure available"},
-    {EL2HLT, "Level 2 halted"},
-    {EBADE, "Invalid exchange"},
-    {EBADR, "Invalid request descriptor"},
-    {EXFULL, "Exchange full"},
-    {ENOANO, "No anode"},
-    {EBADRQC, "Invalid request code"},
-    {EBADSLT, "Invalid slot"},
-    {EBFONT, "Bad font file format"},
-    {ENOSTR, "Device not a stream"},
-    {ENODATA, "No data available"},
-    {ETIME, "Timer expired"},
-    {ENOSR, "Out of streams resources"},
-    {ENONET, "Machine is not on the network"},
-    {ENOPKG, "Package not installed"},
-    {EREMOTE, "Object is remote"},
-    {ENOLINK, "Link has been severed"},
-    {EADV, "Advertise error"},
-    {ESRMNT, "Srmount error"},
-    {ECOMM, "Communication error on send"},
-    {EPROTO, "Protocol error"},
-    {EMULTIHOP, "Multihop attempted"},
-    {EDOTDOT, "RFS specific error"},
-    {EBADMSG, "Not a data message"},
-    {EOVERFLOW, "Value too large for defined data type"},
-    {ENOTUNIQ, "Name not unique on network"},
-    {EBADFD, "File descriptor in bad state"},
-    {EREMCHG, "Remote address changed"},
-    {ELIBACC, "Can not access a needed shared library"},
-    {ELIBBAD, "Accessing a corrupted shared library"},
-    {ELIBSCN, ".lib section in a.out corrupted"},
-    {ELIBMAX, "Attempting to link in too many shared libraries"},
-    {ELIBEXEC, "Cannot exec a shared library directly"},
-    {EILSEQ, "Illegal byte sequence"},
-    {ERESTART, "Interrupted system call should be restarted"},
-    {ESTRPIPE, "Streams pipe error"},
-    {EUSERS, "Too many users"},
-    {ENOTSOCK, "Socket operation on non-socket"},
-    {EDESTADDRREQ, "Destination address required"},
-    {EMSGSIZE, "Message too long"},
-    {EPROTOTYPE, "Protocol wrong type for socket"},
-    {ENOPROTOOPT, "Protocol not available"},
-    {EPROTONOSUPPORT, "Protocol not supported"},
-    {ESOCKTNOSUPPORT, "Socket type not supported"},
-    {EOPNOTSUPP, "Operation not supported on transport endpoint"},
-    {EPFNOSUPPORT, "Protocol family not supported"},
-    {EAFNOSUPPORT, "Address family not supported by protocol"},
-    {EADDRINUSE, "Address already in use"},
-    {EADDRNOTAVAIL, "Cannot assign requested address"},
-    {ENETDOWN, "Network is down"},
-    {ENETUNREACH, "Network is unreachable"},
-    {ENETRESET, "Network dropped connection because of reset"},
-    {ECONNABORTED, "Software caused connection abort"},
-    {ECONNRESET, "Connection reset by peer"},
-    {ENOBUFS, "No buffer space available"},
-    {EISCONN, "Transport endpoint is already connected"},
-    {ENOTCONN, "Transport endpoint is not connected"},
-    {ESHUTDOWN, "Cannot send after transport endpoint shutdown"},
-    {ETOOMANYREFS, "Too many references: cannot splice"},
-    {ETIMEDOUT, "Connection timed out"},
-    {ECONNREFUSED, "Connection refused"},
-    {EHOSTDOWN, "Host is down"},
-    {EHOSTUNREACH, "No route to host"},
-    {EALREADY, "Operation already in progress"},
-    {EINPROGRESS, "Operation now in progress"},
-    {ESTALE, "Stale NFS file handle"},
-    {EUCLEAN, "Structure needs cleaning"},
-    {ENOTNAM, "Not a XENIX named type file"},
-    {ENAVAIL, "No XENIX semaphores available"},
-    {EISNAM, "Is a named type file"},
-    {EREMOTEIO, "Remote I/O error"},
-    {EDQUOT, "Quota exceeded"},
-    {ENOMEDIUM, "No medium found"},
-    {EMEDIUMTYPE, "Wrong medium type"},
-    {ECANCELED, "Operation Canceled"},
-    {ENOKEY, "Required key not available"},
-    {EKEYEXPIRED, "Key has expired"},
-    {EKEYREVOKED, "Key has been revoked"},
-    {EKEYREJECTED, "Key was rejected by service"},
-    {EOWNERDEAD, "Owner died"},
-    {ENOTRECOVERABLE, "State not recoverable"},
-    {ERFKILL, "Operation not possible due to RF-kill"},
-    {EHWPOISON, "Memory page has hardware error"},
-    {0, nullptr}
-};
-
-extern "C" __LIBC_HIDDEN__ const char* __strerror_lookup(int error_number) {
-  return __code_string_lookup(_sys_error_strings, error_number);
-}
-
-int strerror_r(int error_number, char* buf, size_t buf_len) {
-  ErrnoRestorer errno_restorer;
-  size_t length;
-
-  const char* error_name = __strerror_lookup(error_number);
-  if (error_name != nullptr) {
-    length = strlcpy(buf, error_name, buf_len);
-  } else {
-    length = async_safe_format_buffer(buf, buf_len, "Unknown error %d", error_number);
-  }
-  if (length >= buf_len) {
-    errno_restorer.override(ERANGE);
-    return -1;
-  }
-
-  return 0;
-}
-
-extern "C" char* __gnu_strerror_r(int error_number, char* buf, size_t buf_len) {
-  ErrnoRestorer errno_restorer; // The glibc strerror_r doesn't set errno if it truncates...
-  strerror_r(error_number, buf, buf_len);
-  return buf; // ...and just returns whatever fit.
-}
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 13c8714..656d3ab 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -22,6 +22,7 @@
     include_dirs: ["bionic/libc"],
 
     stl: "none",
+    system_shared_libs: [],
 
     sanitize: {
         never: true,
diff --git a/linker/Android.bp b/linker/Android.bp
index a9907ca..0e3484a 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -283,6 +283,7 @@
             suffix: "64",
         },
     },
+    system_shared_libs: [],
     target: {
         android: {
             static_libs: ["libdebuggerd_handler_fallback"],
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 8bfa964..fd2a787 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -61,7 +61,7 @@
 
   // Invalid.
   ASSERT_STREQ("Unknown error -1", strerror(-1));
-  ASSERT_STREQ("Unknown error 1234", strerror(1234));
+  ASSERT_STREQ("Unknown error 134", strerror(EHWPOISON + 1));
 }
 
 #if defined(__BIONIC__)
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index 8ba3d42..6062240 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -41,6 +41,7 @@
 #include <llvm/ADT/IntrusiveRefCntPtr.h>
 #include <llvm/ADT/SmallVector.h>
 #include <llvm/ADT/StringRef.h>
+#include <llvm/Option/Option.h>
 #include <llvm/Support/VirtualFileSystem.h>
 
 #include "Arch.h"
@@ -168,7 +169,7 @@
   }
 
   const driver::Command& driver_cmd = llvm::cast<driver::Command>(*jobs.begin());
-  const driver::ArgStringList& cc_args = driver_cmd.getArguments();
+  const llvm::opt::ArgStringList& cc_args = driver_cmd.getArguments();
 
   if (cc_args.size() == 0) {
     errx(1, "driver returned empty command for %s", to_string(type).c_str());