Improve diagnostics from the assembler __strcpy_chk routines.

Change-Id: Ib95b598f7f8338cc1a618c00232a4259dc4a6319
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
index 215e6c2..377e720 100644
--- a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
+++ b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
@@ -147,23 +147,15 @@
     pld     [r1, #0]
     pld     [r1, #64]
     ldr     r0, [sp]
-    cmp     r3, lr
-    bhs     .L_strcpy_chk_failed
 
     // Add 1 for copy length to get the string terminator.
     add     r2, r3, #1
 
+    cmp     r2, lr
+    itt     hi
+    movhi   r0, r2
+    bhi     __strcpy_chk_fail
+
 #include MEMCPY_BASE
 
-.L_strcpy_chk_failed:
-    ldr     r0, error_message
-1:
-    add     r0, pc
-    bl      __fortify_fatal
-error_message:
-    .word   error_string-(1b+4)
 END(__strcpy_chk)
-
-    .data
-error_string:
-    .string "strcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a9/bionic/__strcpy_chk.S b/libc/arch-arm/cortex-a9/bionic/__strcpy_chk.S
index 14741b6..1d5e70b 100644
--- a/libc/arch-arm/cortex-a9/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/cortex-a9/bionic/__strcpy_chk.S
@@ -149,33 +149,18 @@
     pld     [r1, #0]
     pld     [r1, #64]
     ldr     r0, [sp]
-    cmp     r3, lr
-    bhs     __strcpy_chk_fail
 
     // Add 1 for copy length to get the string terminator.
     add     r2, r3, #1
 
+    cmp     r2, lr
+    itt     hi
+    movhi   r0, r2
+    bhi     __strcpy_chk_fail
+
     // Fall through into the memcpy_base function.
 END(__strcpy_chk)
 
 #define MEMCPY_BASE         __strcpy_chk_memcpy_base
 #define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned
 #include "memcpy_base.S"
-
-ENTRY_PRIVATE(__strcpy_chk_fail)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-
-    ldr     r0, error_message
-1:
-    add     r0, pc
-    bl      __fortify_fatal
-
-error_message:
-    .word   error_string-(1b+4)
-END(__strcpy_chk_fail)
-
-    .data
-error_string:
-    .string "strcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/denver/bionic/__strcpy_chk.S b/libc/arch-arm/denver/bionic/__strcpy_chk.S
index 36188b0..9b7ea91 100644
--- a/libc/arch-arm/denver/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/denver/bionic/__strcpy_chk.S
@@ -147,30 +147,18 @@
     pld     [r1, #0]
     pld     [r1, #64]
     ldr     r0, [sp]
-    cmp     r3, lr
-    bhs     __strcpy_chk_failed
 
     // Add 1 for copy length to get the string terminator.
     add     r2, r3, #1
+
+    cmp     r2, lr
+    itt     hi
+    movhi   r0, r2
+    bhi     __strcpy_chk_fail
+
+    // Fall through into the memcpy_base function.
 END(__strcpy_chk)
 
 #define MEMCPY_BASE         __strcpy_chk_memcpy_base
 #define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned
 #include "memcpy_base.S"
-
-ENTRY_PRIVATE(__strcpy_chk_failed)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-
-    ldr     r0, error_message
-1:
-    add     r0, pc
-    bl      __fortify_fatal
-error_message:
-    .word   error_string-(1b+4)
-END(__strcpy_chk_failed)
-
-    .data
-error_string:
-    .string "strcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/krait/bionic/__strcpy_chk.S b/libc/arch-arm/krait/bionic/__strcpy_chk.S
index ef908e6..9c2f66a 100644
--- a/libc/arch-arm/krait/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/krait/bionic/__strcpy_chk.S
@@ -147,23 +147,15 @@
     pld     [r1, #0]
     pld     [r1, #64]
     ldr     r0, [sp]
-    cmp     r3, lr
-    bhs     .L_strcpy_chk_failed
 
     // Add 1 for copy length to get the string terminator.
     add     r2, r3, #1
 
+    cmp     r2, lr
+    itt     hi
+    movhi   r0, r2
+    bhi     __strcpy_chk_fail
+
 #include "memcpy_base.S"
 
-.L_strcpy_chk_failed:
-    ldr     r0, error_message
-1:
-    add     r0, pc
-    bl      __fortify_fatal
-error_message:
-    .word   error_string-(1b+4)
 END(__strcpy_chk)
-
-    .data
-error_string:
-    .string "strcpy: prevented write past end of buffer"
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 278c606..11abeb1 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -288,6 +288,12 @@
   }
 }
 
+// strcpy is performance-critical enough that we have assembler __strcpy_chk implementations.
+// This function is used to give better diagnostics than we can easily do from assembler.
+extern "C" void __strcpy_chk_fail(size_t dst_buf_size) {
+  __fortify_fatal("strcpy: prevented write past end of %zu-byte buffer", dst_buf_size);
+}
+
 size_t __strlcat_chk(char* dst, const char* src,
                      size_t supplied_size, size_t dst_len_from_compiler) {
   __check_buffer_access("strlcat", "write into", supplied_size, dst_len_from_compiler);