15f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris/* 2fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris * Copyright (C) 2013 The Android Open Source Project 35f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * All rights reserved. 45f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * 55f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * Redistribution and use in source and binary forms, with or without 65f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * modification, are permitted provided that the following conditions 75f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * are met: 85f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * * Redistributions of source code must retain the above copyright 95f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * notice, this list of conditions and the following disclaimer. 105f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * * Redistributions in binary form must reproduce the above copyright 115f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * notice, this list of conditions and the following disclaimer in 125f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * the documentation and/or other materials provided with the 135f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * distribution. 145f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * 155f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 165f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 175f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 185f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 195f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 205f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 215f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 225f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 235f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 245f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 255f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 265f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris * SUCH DAMAGE. 275f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris */ 285f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris 29fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris#include <private/bionic_asm.h> 305f45d583b0cfb4f7bed1447e8eed003a529cc69eChristopher Ferris 31fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .syntax unified 32fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 33fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .thumb 34fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .thumb_func 35fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 36866e7b6906b71542c7ab4ce17c5943243058964fChristopher Ferris // To avoid warning about deprecated instructions, add an explicit 37866e7b6906b71542c7ab4ce17c5943243058964fChristopher Ferris // arch. The code generated is exactly the same. 38866e7b6906b71542c7ab4ce17c5943243058964fChristopher Ferris .arch armv7-a 39866e7b6906b71542c7ab4ce17c5943243058964fChristopher Ferris 40fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris// Get the length of src string, then get the source of the dst string. 41fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris// Check that the two lengths together don't exceed the threshold, then 42fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris// do a memcpy of the data. 43fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher FerrisENTRY(__strcat_chk) 44fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris pld [r0, #0] 45fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris push {r0, lr} 46fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_def_cfa_offset 8 47fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset r0, 0 48fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset lr, 4 49fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris push {r4, r5} 50fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_adjust_cfa_offset 8 51fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset r4, 0 52fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset r5, 4 53fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 54fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov lr, r2 55fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 56fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Save the dst register to r5 57fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r5, r0 58fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 59fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Zero out r4 60fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris eor r4, r4, r4 61fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 62fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // r1 contains the address of the string to count. 63fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_strlen_start: 64fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r0, r1 65fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ands r3, r1, #7 66fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris beq .L_mainloop 67fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 68fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Align to a double word (64 bits). 69fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris rsb r3, r3, #8 70fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris lsls ip, r3, #31 71fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris beq .L_align_to_32 72fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 73fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ldrb r2, [r1], #1 74fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris cbz r2, .L_update_count_and_finish 75fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 76fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_align_to_32: 77fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bcc .L_align_to_64 78fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ands ip, r3, #2 79fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris beq .L_align_to_64 80fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 81fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ldrb r2, [r1], #1 82fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris cbz r2, .L_update_count_and_finish 83fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ldrb r2, [r1], #1 84fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris cbz r2, .L_update_count_and_finish 85fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 86fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_align_to_64: 87fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris tst r3, #4 88fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris beq .L_mainloop 89fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ldr r3, [r1], #4 90fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 91fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub ip, r3, #0x01010101 92fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bic ip, ip, r3 93fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ands ip, ip, #0x80808080 94fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_zero_in_second_register 95fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 96fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .p2align 2 97fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_mainloop: 98fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ldrd r2, r3, [r1], #8 99fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 100fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris pld [r1, #64] 101fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 102fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub ip, r2, #0x01010101 103fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bic ip, ip, r2 104fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ands ip, ip, #0x80808080 105fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_zero_in_first_register 106fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 107fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub ip, r3, #0x01010101 108fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bic ip, ip, r3 109fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris ands ip, ip, #0x80808080 110fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_zero_in_second_register 111fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_mainloop 112fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 113fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_update_count_and_finish: 114fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r1, r0 115fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #1 116fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 117fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 118fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_zero_in_first_register: 119fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r1, r0 120fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris lsls r2, ip, #17 121fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_sub8_and_finish 122fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bcs .L_sub7_and_finish 123fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris lsls ip, ip, #1 124fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_sub6_and_finish 125fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 126fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #5 127fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 128fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 129fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub8_and_finish: 130fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #8 131fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 132fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 133fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub7_and_finish: 134fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #7 135fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 136fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 137fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub6_and_finish: 138fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #6 139fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 140fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 141fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_zero_in_second_register: 142fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r1, r0 143fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris lsls r2, ip, #17 144fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_sub4_and_finish 145fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bcs .L_sub3_and_finish 146fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris lsls ip, ip, #1 147fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_sub2_and_finish 148fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 149fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #1 150fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 151fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 152fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub4_and_finish: 153fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #4 154fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 155fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 156fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub3_and_finish: 157fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #3 158fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_finish 159fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 160fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_sub2_and_finish: 161fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris sub r3, r3, #2 162fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 163fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_finish: 164fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris cmp r4, #0 165fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bne .L_strlen_done 166fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 167fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Time to get the dst string length. 168fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r1, r5 169fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 170fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Save the original source address to r5. 171fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r5, r0 172fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 173fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Save the current length (adding 1 for the terminator). 174fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris add r4, r3, #1 175fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris b .L_strlen_start 176fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 177fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // r0 holds the pointer to the dst string. 178fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // r3 holds the dst string length. 179fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // r4 holds the src string length + 1. 180fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris.L_strlen_done: 181fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris add r2, r3, r4 182fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris cmp r2, lr 183fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris itt hi 184fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris movhi r0, lr 185fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris bhi __strcat_chk_fail 186fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 187fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Set up the registers for the memcpy code. 188fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r1, r5 189fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris pld [r1, #64] 190fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris mov r2, r4 191fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris add r0, r0, r3 192fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris pop {r4, r5} 193fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_adjust_cfa_offset -8 194fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_restore r4 195fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_restore r5 196fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 197fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris#include "memcpy_base.S" 198fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris 199fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris // Undo the above cfi directives 200fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_adjust_cfa_offset 8 201fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset r4, 0 202fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher Ferris .cfi_rel_offset r5, 4 203fe1af1a64b88bdb58cca7015d426af8c5b1a80d9Christopher FerrisEND(__strcat_chk) 204