blob: 78cf19a2e60df288a581cf4efddb4e055fa046a4 [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 .fpu neon
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}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070044 .save {r0, lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -070045 .cfi_def_cfa_offset 8
46 .cfi_rel_offset r0, 0
47 .cfi_rel_offset lr, 4
48 push {r4, r5}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070049 .save {r4, r5}
Christopher Ferris5f45d582013-08-07 13:09:51 -070050 .cfi_adjust_cfa_offset 8
51 .cfi_rel_offset r4, 0
52 .cfi_rel_offset r5, 4
53
54 mov lr, r2
55
56 // Save the dst register to r5
57 mov r5, r0
58
59 // Zero out r4
60 eor r4, r4, r4
61
62 // r1 contains the address of the string to count.
63.L_strlen_start:
64 mov r0, r1
65
66 ands r3, r0, #7
67 bne .L_align_src
68
69 .p2align 2
70.L_mainloop:
71 ldmia r1!, {r2, r3}
72
73 pld [r1, #64]
74
75 sub ip, r2, #0x01010101
76 bic ip, ip, r2
77 ands ip, ip, #0x80808080
78 bne .L_zero_in_first_register
79
80 sub ip, r3, #0x01010101
81 bic ip, ip, r3
82 ands ip, ip, #0x80808080
83 bne .L_zero_in_second_register
84 b .L_mainloop
85
86.L_zero_in_first_register:
87 sub r3, r1, r0
88 // Check for zero in byte 0.
89 lsls r2, ip, #17
90 beq .L_check_byte1_reg1
91
92 sub r3, r3, #8
93 b .L_finish
94
95.L_check_byte1_reg1:
96 bcc .L_check_byte2_reg1
97
98 sub r3, r3, #7
99 b .L_finish
100
101.L_check_byte2_reg1:
102 // Check for zero in byte 2.
103 tst ip, #0x800000
104 it ne
105 subne r3, r3, #6
106 bne .L_finish
107 sub r3, r3, #5
108 b .L_finish
109
110.L_zero_in_second_register:
111 sub r3, r1, r0
112 // Check for zero in byte 0.
113 lsls r2, ip, #17
114 beq .L_check_byte1_reg2
115
116 sub r3, r3, #4
117 b .L_finish
118
119.L_check_byte1_reg2:
120 bcc .L_check_byte2_reg2
121
122 sub r3, r3, #3
123 b .L_finish
124
125.L_check_byte2_reg2:
126 // Check for zero in byte 2.
127 tst ip, #0x800000
128 it ne
129 subne r3, r3, #2
130 bne .L_finish
131 sub r3, r3, #1
132 b .L_finish
133
134.L_align_src:
135 // Align to a double word (64 bits).
136 rsb r3, r3, #8
137 lsls ip, r3, #31
138 beq .L_align_to_32
139
140 ldrb r2, [r1], #1
141 cbz r2, .L_done
142
143.L_align_to_32:
144 bcc .L_align_to_64
145
146 ldrb r2, [r1], #1
147 cbz r2, .L_done
148 ldrb r2, [r1], #1
149 cbz r2, .L_done
150
151.L_align_to_64:
152 tst r3, #4
153 beq .L_mainloop
154 ldr r2, [r1], #4
155
156 sub ip, r2, #0x01010101
157 bic ip, ip, r2
158 ands ip, ip, #0x80808080
159 bne .L_zero_in_second_register
160 b .L_mainloop
161
162.L_done:
163 sub r3, r1, r0
164 sub r3, r3, #1
165
166.L_finish:
167 cmp r4, #0
168 bne .L_strlen_done
169
170 // Time to get the dst string length.
171 mov r1, r5
172
173 // Save the original source address to r5.
174 mov r5, r0
175
176 // Save the current length (adding 1 for the terminator).
177 add r4, r3, #1
178 b .L_strlen_start
179
180 // r0 holds the pointer to the dst string.
181 // r3 holds the dst string length.
182 // r4 holds the src string length + 1.
183.L_strlen_done:
184 add r2, r3, r4
185 cmp r2, lr
Christopher Ferris16e185c2013-09-10 16:56:34 -0700186 bhi __strcat_chk_fail
Christopher Ferris5f45d582013-08-07 13:09:51 -0700187
188 // Set up the registers for the memcpy code.
189 mov r1, r5
190 pld [r1, #64]
191 mov r2, r4
192 add r0, r0, r3
Christopher Ferris5f45d582013-08-07 13:09:51 -0700193 pop {r4, r5}
Christopher Ferris5f45d582013-08-07 13:09:51 -0700194
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700195 // Fall through into the memcpy_base function.
196 .cfi_endproc
197END(__strcat_chk)
Christopher Ferris5f45d582013-08-07 13:09:51 -0700198
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700199#define MEMCPY_BASE __strcat_chk_memcpy_base
200#define MEMCPY_BASE_ALIGNED __strcat_chk_memcpy_base_aligned
201#include "memcpy_base.S"
202
203ENTRY(__strcat_chk_fail)
204 .cfi_startproc
205
206 .save {r0, lr}
207 .save {r4, r5}
208 .cfi_def_cfa_offset 8
209 .cfi_rel_offset r0, 0
210 .cfi_rel_offset lr, 4
Christopher Ferris5f45d582013-08-07 13:09:51 -0700211 .cfi_adjust_cfa_offset 8
212 .cfi_rel_offset r4, 0
213 .cfi_rel_offset r5, 4
214
215 ldr r0, error_message
216 ldr r1, error_code
2171:
218 add r0, pc
219 bl __fortify_chk_fail
220error_code:
221 .word BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW
222error_message:
223 .word error_string-(1b+4)
224
225 .cfi_endproc
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700226END(__strcat_chk_fail)
Christopher Ferris5f45d582013-08-07 13:09:51 -0700227
228 .data
229error_string:
230 .string "strcat buffer overflow"