1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <private/bionic_asm.h> 30 31 .syntax unified 32 .fpu neon 33 .thumb 34 .thumb_func 35 36 // Get the length of the source string first, then do a memcpy of the data 37 // instead of a strcpy. 38 ENTRY(__strcpy_chk) 39 pld [r0, #0] 40 push {r0, lr} 41 .cfi_def_cfa_offset 8 42 .cfi_rel_offset r0, 0 43 .cfi_rel_offset lr, 4 44 45 mov lr, r2 46 mov r0, r1 47 48 ands r3, r0, #7 49 bne .L_align_src 50 51 .p2align 2 52 .L_mainloop: 53 ldmia r0!, {r2, r3} 54 55 pld [r0, #64] 56 57 sub ip, r2, #0x01010101 58 bic ip, ip, r2 59 ands ip, ip, #0x80808080 60 bne .L_zero_in_first_register 61 62 sub ip, r3, #0x01010101 63 bic ip, ip, r3 64 ands ip, ip, #0x80808080 65 bne .L_zero_in_second_register 66 b .L_mainloop 67 68 .L_zero_in_first_register: 69 sub r3, r0, r1 70 // Check for zero in byte 0. 71 lsls r2, ip, #17 72 beq .L_check_byte1_reg1 73 74 sub r3, r3, #8 75 b .L_check_size 76 77 .L_check_byte1_reg1: 78 bcc .L_check_byte2_reg1 79 80 sub r3, r3, #7 81 b .L_check_size 82 83 .L_check_byte2_reg1: 84 // Check for zero in byte 2. 85 tst ip, #0x800000 86 it ne 87 subne r3, r3, #6 88 bne .L_check_size 89 sub r3, r3, #5 90 b .L_check_size 91 92 .L_zero_in_second_register: 93 sub r3, r0, r1 94 // Check for zero in byte 0. 95 lsls r2, ip, #17 96 beq .L_check_byte1_reg2 97 98 sub r3, r3, #4 99 b .L_check_size 100 101 .L_check_byte1_reg2: 102 bcc .L_check_byte2_reg2 103 104 sub r3, r3, #3 105 b .L_check_size 106 107 .L_check_byte2_reg2: 108 // Check for zero in byte 2. 109 tst ip, #0x800000 110 it ne 111 subne r3, r3, #2 112 bne .L_check_size 113 sub r3, r3, #1 114 b .L_check_size 115 116 .L_align_src: 117 // Align to a double word (64 bits). 118 rsb r3, r3, #8 119 lsls ip, r3, #31 120 beq .L_align_to_32 121 122 ldrb r2, [r0], #1 123 cbz r2, .L_done 124 125 .L_align_to_32: 126 bcc .L_align_to_64 127 128 ldrb r2, [r0], #1 129 cbz r2, .L_done 130 ldrb r2, [r0], #1 131 cbz r2, .L_done 132 133 .L_align_to_64: 134 tst r3, #4 135 beq .L_mainloop 136 ldr r2, [r0], #4 137 138 sub ip, r2, #0x01010101 139 bic ip, ip, r2 140 ands ip, ip, #0x80808080 141 bne .L_zero_in_second_register 142 b .L_mainloop 143 144 .L_done: 145 sub r3, r0, r1 146 sub r3, r3, #1 147 148 .L_check_size: 149 pld [r1, #0] 150 pld [r1, #64] 151 ldr r0, [sp] 152 153 // Add 1 for copy length to get the string terminator. 154 add r2, r3, #1 155 156 cmp r2, lr 157 itt hi 158 movhi r0, r2 159 bhi __strcpy_chk_fail 160 161 // Fall through into the memcpy_base function. 162 END(__strcpy_chk) 163 164 #define MEMCPY_BASE __strcpy_chk_memcpy_base 165 #define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned 166 #include "memcpy_base.S" 167