blob: 4516d3005782196aa4279620c8a2ed2a376445da [file] [log] [blame]
Christopher Ferris5f45d582013-08-07 13:09:51 -07001/*
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 <machine/asm.h>
30#include "libc_events.h"
31
32 .syntax unified
33
34 .thumb
35 .thumb_func
36
37// Get the length of src string, then get the source of the dst string.
38// Check that the two lengths together don't exceed the threshold, then
39// do a memcpy of the data.
40ENTRY(__strcat_chk)
41 .cfi_startproc
42 pld [r0, #0]
43 push {r0, lr}
44 .cfi_def_cfa_offset 8
45 .cfi_rel_offset r0, 0
46 .cfi_rel_offset lr, 4
47 push {r4, r5}
48 .cfi_adjust_cfa_offset 8
49 .cfi_rel_offset r4, 0
50 .cfi_rel_offset r5, 4
51
52 mov lr, r2
53
54 // Save the dst register to r5
55 mov r5, r0
56
57 // Zero out r4
58 eor r4, r4, r4
59
60 // r1 contains the address of the string to count.
61.L_strlen_start:
62 mov r0, r1
63 ands r3, r1, #7
64 beq .L_mainloop
65
66 // Align to a double word (64 bits).
67 rsb r3, r3, #8
68 lsls ip, r3, #31
69 beq .L_align_to_32
70
71 ldrb r2, [r1], #1
72 cbz r2, .L_update_count_and_finish
73
74.L_align_to_32:
75 bcc .L_align_to_64
76 ands ip, r3, #2
77 beq .L_align_to_64
78
79 ldrb r2, [r1], #1
80 cbz r2, .L_update_count_and_finish
81 ldrb r2, [r1], #1
82 cbz r2, .L_update_count_and_finish
83
84.L_align_to_64:
85 tst r3, #4
86 beq .L_mainloop
87 ldr r3, [r1], #4
88
89 sub ip, r3, #0x01010101
90 bic ip, ip, r3
91 ands ip, ip, #0x80808080
92 bne .L_zero_in_second_register
93
94 .p2align 2
95.L_mainloop:
96 ldrd r2, r3, [r1], #8
97
98 pld [r1, #64]
99
100 sub ip, r2, #0x01010101
101 bic ip, ip, r2
102 ands ip, ip, #0x80808080
103 bne .L_zero_in_first_register
104
105 sub ip, r3, #0x01010101
106 bic ip, ip, r3
107 ands ip, ip, #0x80808080
108 bne .L_zero_in_second_register
109 b .L_mainloop
110
111.L_update_count_and_finish:
112 sub r3, r1, r0
113 sub r3, r3, #1
114 b .L_finish
115
116.L_zero_in_first_register:
117 sub r3, r1, r0
118 lsls r2, ip, #17
119 bne .L_sub8_and_finish
120 bcs .L_sub7_and_finish
121 lsls ip, ip, #1
122 bne .L_sub6_and_finish
123
124 sub r3, r3, #5
125 b .L_finish
126
127.L_sub8_and_finish:
128 sub r3, r3, #8
129 b .L_finish
130
131.L_sub7_and_finish:
132 sub r3, r3, #7
133 b .L_finish
134
135.L_sub6_and_finish:
136 sub r3, r3, #6
137 b .L_finish
138
139.L_zero_in_second_register:
140 sub r3, r1, r0
141 lsls r2, ip, #17
142 bne .L_sub4_and_finish
143 bcs .L_sub3_and_finish
144 lsls ip, ip, #1
145 bne .L_sub2_and_finish
146
147 sub r3, r3, #1
148 b .L_finish
149
150.L_sub4_and_finish:
151 sub r3, r3, #4
152 b .L_finish
153
154.L_sub3_and_finish:
155 sub r3, r3, #3
156 b .L_finish
157
158.L_sub2_and_finish:
159 sub r3, r3, #2
160
161.L_finish:
162 cmp r4, #0
163 bne .L_strlen_done
164
165 // Time to get the dst string length.
166 mov r1, r5
167
168 // Save the original source address to r5.
169 mov r5, r0
170
171 // Save the current length (adding 1 for the terminator).
172 add r4, r3, #1
173 b .L_strlen_start
174
175 // r0 holds the pointer to the dst string.
176 // r3 holds the dst string length.
177 // r4 holds the src string length + 1.
178.L_strlen_done:
179 add r2, r3, r4
180 cmp r2, lr
181 bgt .L_fortify_check_failed
182
183 // Set up the registers for the memcpy code.
184 mov r1, r5
185 pld [r1, #64]
186 mov r2, r4
187 add r0, r0, r3
188 pop {r4, r5}
189 .cfi_adjust_cfa_offset -8
190 .cfi_restore r4
191 .cfi_restore r5
192
193 #include "memcpy_base.S"
194
195.L_fortify_check_failed:
196 .cfi_adjust_cfa_offset 8
197 .cfi_rel_offset r4, 0
198 .cfi_rel_offset r5, 4
199
200 ldr r0, error_message
201 ldr r1, error_code
2021:
203 add r0, pc
204 bl __fortify_chk_fail
205error_code:
206 .word BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW
207error_message:
208 .word error_string-(1b+4)
209
210 .cfi_endproc
211END(__strcat_chk)
212
213 .data
214error_string:
215 .string "strcat buffer overflow"