Improve diagnostics from the assembler __memcpy_chk routines.

Change-Id: Iec16c92ed80beee505cba2121ea33e3550197b02
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy_common.S b/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
index 955ffb8..4d1167f 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
@@ -60,10 +60,14 @@
         .fpu    neon
 
 ENTRY(__memcpy_chk)
-        cmp     r2, r3
-        bhi     .L_memcpy_chk_fail
+        cmp r2, r3
+        bls memcpy
 
-        // Fall through to memcpy...
+        // Preserve lr for backtrace.
+        push        {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+        bl          __memcpy_chk_fail
 END(__memcpy_chk)
 
 // Prototype: void *memcpy (void *dst, const void *src, size_t count).
@@ -75,25 +79,4 @@
         .cfi_rel_offset lr, 4
 
 #include MEMCPY_BASE
-
-        // Undo the cfi instructions from above.
-        .cfi_def_cfa_offset 0
-        .cfi_restore r0
-        .cfi_restore lr
-.L_memcpy_chk_fail:
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_adjust_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-1:
-        add     r0, pc
-        bl      __fortify_fatal
-error_message:
-        .word   error_string-(1b+8)
 END(memcpy)
-
-        .data
-error_string:
-        .string "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy.S b/libc/arch-arm/cortex-a9/bionic/memcpy.S
index fc0bba1..93a8629 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy.S
@@ -41,9 +41,14 @@
 
 ENTRY(__memcpy_chk)
         cmp         r2, r3
-        bhi         __memcpy_chk_fail
+        bls         memcpy
 
-        // Fall through to memcpy...
+        // Preserve lr for backtrace.
+        push        {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        bl          __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
@@ -58,21 +63,3 @@
 #define MEMCPY_BASE         __memcpy_base
 #define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
 #include "memcpy_base.S"
-
-ENTRY_PRIVATE(__memcpy_chk_fail)
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-1:
-        add     r0, pc
-        bl      __fortify_fatal
-error_message:
-        .word   error_string-(1b+4)
-END(__memcpy_chk_fail)
-
-        .data
-error_string:
-        .string     "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/denver/bionic/memcpy.S b/libc/arch-arm/denver/bionic/memcpy.S
index c1db06c..d4e0fb4 100644
--- a/libc/arch-arm/denver/bionic/memcpy.S
+++ b/libc/arch-arm/denver/bionic/memcpy.S
@@ -63,9 +63,14 @@
 
 ENTRY(__memcpy_chk)
         cmp     r2, r3
-        bhi     __memcpy_chk_fail
+        bls     memcpy
 
-        // Fall through to memcpy...
+        // Preserve lr for backtrace.
+        push    {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        bl      __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
@@ -79,21 +84,3 @@
 #define MEMCPY_BASE         __memcpy_base
 #define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
 #include "memcpy_base.S"
-
-ENTRY_PRIVATE(__memcpy_chk_fail)
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-1:
-        add     r0, pc
-        bl      __fortify_fatal
-error_message:
-        .word   error_string-(1b+8)
-END(__memcpy_chk_fail)
-
-        .data
-error_string:
-        .string "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/generic/bionic/memcpy.S b/libc/arch-arm/generic/bionic/memcpy.S
index 54c3060..f5e97f2 100644
--- a/libc/arch-arm/generic/bionic/memcpy.S
+++ b/libc/arch-arm/generic/bionic/memcpy.S
@@ -40,9 +40,14 @@
 
 ENTRY(__memcpy_chk)
         cmp         r2, r3
-        bhi         __memcpy_chk_fail
+        bls         memcpy
 
-        // Fall through to memcpy...
+        // Preserve lr for backtrace.
+        push        {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        bl          __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
@@ -385,22 +390,3 @@
         add         sp,  sp, #28
         ldmfd       sp!, {r0, r4, pc}
 END(memcpy)
-
-        // Only reached when the __memcpy_chk check fails.
-ENTRY_PRIVATE(__memcpy_chk_fail)
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-1:
-        add     r0, pc
-        bl      __fortify_fatal
-error_message:
-        .word   error_string-(1b+8)
-END(__memcpy_chk_fail)
-
-        .data
-error_string:
-        .string     "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/krait/bionic/memcpy.S b/libc/arch-arm/krait/bionic/memcpy.S
index 189a097..de6f432 100644
--- a/libc/arch-arm/krait/bionic/memcpy.S
+++ b/libc/arch-arm/krait/bionic/memcpy.S
@@ -44,9 +44,14 @@
 
 ENTRY(__memcpy_chk)
         cmp         r2, r3
-        bhi         .L_memcpy_chk_fail
+        bls         memcpy
 
-        // Fall through to memcpy...
+        // Preserve lr for backtrace.
+        push        {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        bl          __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
@@ -57,25 +62,4 @@
         .cfi_rel_offset lr, 4
 
 #include "memcpy_base.S"
-
-        // Undo the cfi directives from above.
-        .cfi_adjust_cfa_offset -8
-        .cfi_restore r0
-        .cfi_restore lr
-.L_memcpy_chk_fail:
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_adjust_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-1:
-        add     r0, pc
-        bl      __fortify_fatal
-error_message:
-        .word   error_string-(1b+4)
 END(memcpy)
-
-        .data
-error_string:
-        .string     "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm64/denver64/bionic/memcpy.S b/libc/arch-arm64/denver64/bionic/memcpy.S
index 83ab5d1..0be2aac 100644
--- a/libc/arch-arm64/denver64/bionic/memcpy.S
+++ b/libc/arch-arm64/denver64/bionic/memcpy.S
@@ -31,29 +31,18 @@
 #include <private/bionic_asm.h>
 
 ENTRY(__memcpy_chk)
-  cmp   x2, x3
-  b.hi  __memcpy_chk_fail
+  cmp x2, x3
+  bls memcpy
 
-  // Fall through to memcpy...
+  // Preserve for accurate backtrace.
+  stp x29, x30, [sp, -16]!
+  .cfi_def_cfa_offset 16
+  .cfi_rel_offset x29, 0
+  .cfi_rel_offset x30, 8
+
+  bl __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
   #include "memcpy_base.S"
 END(memcpy)
-
-ENTRY_PRIVATE(__memcpy_chk_fail)
-  // Preserve for accurate backtrace.
-  stp  x29, x30, [sp, -16]!
-  .cfi_def_cfa_offset 16
-  .cfi_rel_offset x29, 0
-  .cfi_rel_offset x30, 8
-
-  adrp  x0, error_string
-  add   x0, x0, :lo12:error_string
-  bl    __fortify_fatal
-END(__memcpy_chk_fail)
-
-  .data
-  .align 2
-error_string:
-  .string "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm64/generic/bionic/memcpy.S b/libc/arch-arm64/generic/bionic/memcpy.S
index 83ab5d1..0be2aac 100644
--- a/libc/arch-arm64/generic/bionic/memcpy.S
+++ b/libc/arch-arm64/generic/bionic/memcpy.S
@@ -31,29 +31,18 @@
 #include <private/bionic_asm.h>
 
 ENTRY(__memcpy_chk)
-  cmp   x2, x3
-  b.hi  __memcpy_chk_fail
+  cmp x2, x3
+  bls memcpy
 
-  // Fall through to memcpy...
+  // Preserve for accurate backtrace.
+  stp x29, x30, [sp, -16]!
+  .cfi_def_cfa_offset 16
+  .cfi_rel_offset x29, 0
+  .cfi_rel_offset x30, 8
+
+  bl __memcpy_chk_fail
 END(__memcpy_chk)
 
 ENTRY(memcpy)
   #include "memcpy_base.S"
 END(memcpy)
-
-ENTRY_PRIVATE(__memcpy_chk_fail)
-  // Preserve for accurate backtrace.
-  stp  x29, x30, [sp, -16]!
-  .cfi_def_cfa_offset 16
-  .cfi_rel_offset x29, 0
-  .cfi_rel_offset x30, 8
-
-  adrp  x0, error_string
-  add   x0, x0, :lo12:error_string
-  bl    __fortify_fatal
-END(__memcpy_chk_fail)
-
-  .data
-  .align 2
-error_string:
-  .string "memcpy: prevented write past end of buffer"
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 1b9f951..ad7aa04 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -140,6 +140,14 @@
   return memmove(dst, src, len);
 }
 
+// memcpy is performance-critical enough that we have assembler __memcpy_chk implementations.
+// This function is used to give better diagnostics than we can easily do from assembler.
+extern "C" void* __memcpy_chk_fail(void* /*dst*/, const void* /*src*/, size_t count, size_t dst_len) {
+  __check_count("memcpy", "count", count);
+  __check_buffer_access("memcpy", "write into", count, dst_len);
+  abort(); // One of the above is supposed to have failed, otherwise we shouldn't have been called.
+}
+
 void* __memrchr_chk(const void* s, int c, size_t n, size_t actual_size) {
   __check_buffer_access("memrchr", "read from", n, actual_size);
   return memrchr(s, c, n);