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 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. 38ENTRY(__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, r1, #7 49 beq .L_mainloop 50 51 // Align to a double word (64 bits). 52 rsb r3, r3, #8 53 lsls ip, r3, #31 54 beq .L_align_to_32 55 56 ldrb r2, [r0], #1 57 cbz r2, .L_update_count_and_finish 58 59.L_align_to_32: 60 bcc .L_align_to_64 61 ands ip, r3, #2 62 beq .L_align_to_64 63 64 ldrb r2, [r0], #1 65 cbz r2, .L_update_count_and_finish 66 ldrb r2, [r0], #1 67 cbz r2, .L_update_count_and_finish 68 69.L_align_to_64: 70 tst r3, #4 71 beq .L_mainloop 72 ldr r3, [r0], #4 73 74 sub ip, r3, #0x01010101 75 bic ip, ip, r3 76 ands ip, ip, #0x80808080 77 bne .L_zero_in_second_register 78 79 .p2align 2 80.L_mainloop: 81 ldrd r2, r3, [r0], #8 82 83 pld [r0, #64] 84 85 sub ip, r2, #0x01010101 86 bic ip, ip, r2 87 ands ip, ip, #0x80808080 88 bne .L_zero_in_first_register 89 90 sub ip, r3, #0x01010101 91 bic ip, ip, r3 92 ands ip, ip, #0x80808080 93 bne .L_zero_in_second_register 94 b .L_mainloop 95 96.L_update_count_and_finish: 97 sub r3, r0, r1 98 sub r3, r3, #1 99 b .L_check_size 100 101.L_zero_in_first_register: 102 sub r3, r0, r1 103 lsls r2, ip, #17 104 bne .L_sub8_and_finish 105 bcs .L_sub7_and_finish 106 lsls ip, ip, #1 107 bne .L_sub6_and_finish 108 109 sub r3, r3, #5 110 b .L_check_size 111 112.L_sub8_and_finish: 113 sub r3, r3, #8 114 b .L_check_size 115 116.L_sub7_and_finish: 117 sub r3, r3, #7 118 b .L_check_size 119 120.L_sub6_and_finish: 121 sub r3, r3, #6 122 b .L_check_size 123 124.L_zero_in_second_register: 125 sub r3, r0, r1 126 lsls r2, ip, #17 127 bne .L_sub4_and_finish 128 bcs .L_sub3_and_finish 129 lsls ip, ip, #1 130 bne .L_sub2_and_finish 131 132 sub r3, r3, #1 133 b .L_check_size 134 135.L_sub4_and_finish: 136 sub r3, r3, #4 137 b .L_check_size 138 139.L_sub3_and_finish: 140 sub r3, r3, #3 141 b .L_check_size 142 143.L_sub2_and_finish: 144 sub r3, r3, #2 145 146.L_check_size: 147 pld [r1, #0] 148 pld [r1, #64] 149 ldr r0, [sp] 150 151 // Add 1 for copy length to get the string terminator. 152 add r2, r3, #1 153 154 cmp r2, lr 155 itt hi 156 movhi r0, r2 157 bhi __strcpy_chk_fail 158 159#include "memcpy_base.S" 160 161END(__strcpy_chk) 162