1 /*
2 * Copyright (C) 2008 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 #ifndef _STRING_H_
29 #define _STRING_H_
30
31 #include <sys/cdefs.h>
32 #include <stddef.h>
33 #include <malloc.h>
34 #include <xlocale.h>
35
36 __BEGIN_DECLS
37
38 extern void* memccpy(void* __restrict, const void* __restrict, int, size_t);
39 extern void* memchr(const void *, int, size_t) __purefunc;
40 extern void* memrchr(const void *, int, size_t) __purefunc;
41 extern int memcmp(const void *, const void *, size_t) __purefunc;
42 extern void* memcpy(void* __restrict, const void* __restrict, size_t);
43 extern void* memmove(void *, const void *, size_t);
44 extern void* memset(void *, int, size_t);
45 extern void* memmem(const void *, size_t, const void *, size_t) __purefunc;
46
47 extern char* strchr(const char *, int) __purefunc;
48 extern char* __strchr_chk(const char *, int, size_t);
49
50 extern char* strrchr(const char *, int) __purefunc;
51 extern char* __strrchr_chk(const char *, int, size_t);
52
53 extern size_t strlen(const char *) __purefunc;
54 extern size_t __strlen_chk(const char *, size_t);
55 extern int strcmp(const char *, const char *) __purefunc;
56 extern char* stpcpy(char* __restrict, const char* __restrict);
57 extern char* strcpy(char* __restrict, const char* __restrict);
58 extern char* strcat(char* __restrict, const char* __restrict);
59
60 extern int strcasecmp(const char *, const char *) __purefunc;
61 extern int strncasecmp(const char *, const char *, size_t) __purefunc;
62 extern char* strdup(const char *);
63
64 extern char* strstr(const char *, const char *) __purefunc;
65 extern char* strcasestr(const char *haystack, const char *needle) __purefunc;
66 extern char* strtok(char* __restrict, const char* __restrict);
67 extern char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
68
69 extern char* strerror(int);
70 extern int strerror_r(int errnum, char *buf, size_t n);
71
72 extern size_t strnlen(const char *, size_t) __purefunc;
73 extern char* strncat(char* __restrict, const char* __restrict, size_t);
74 extern char* strndup(const char *, size_t);
75 extern int strncmp(const char *, const char *, size_t) __purefunc;
76 extern char* stpncpy(char* __restrict, const char* __restrict, size_t);
77 extern char* strncpy(char* __restrict, const char* __restrict, size_t);
78
79 extern size_t strlcat(char* __restrict, const char* __restrict, size_t);
80 extern size_t strlcpy(char* __restrict, const char* __restrict, size_t);
81
82 extern size_t strcspn(const char *, const char *) __purefunc;
83 extern char* strpbrk(const char *, const char *) __purefunc;
84 extern char* strsep(char** __restrict, const char* __restrict);
85 extern size_t strspn(const char *, const char *);
86
87 extern char* strsignal(int sig);
88
89 extern int strcoll(const char *, const char *) __purefunc;
90 extern size_t strxfrm(char* __restrict, const char* __restrict, size_t);
91
92 extern int strcoll_l(const char *, const char *, locale_t) __purefunc;
93 extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);
94
95 #if defined(__BIONIC_FORTIFY)
96
97 __BIONIC_FORTIFY_INLINE
memcpy(void * __restrict dest,const void * __restrict src,size_t copy_amount)98 void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) {
99 char *d = (char *) dest;
100 const char *s = (const char *) src;
101 size_t s_len = __bos0(s);
102 size_t d_len = __bos0(d);
103
104 return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
105 }
106
107 __BIONIC_FORTIFY_INLINE
memmove(void * dest,const void * src,size_t len)108 void* memmove(void *dest, const void *src, size_t len) {
109 return __builtin___memmove_chk(dest, src, len, __bos0(dest));
110 }
111
112 __BIONIC_FORTIFY_INLINE
stpcpy(char * __restrict dest,const char * __restrict src)113 char* stpcpy(char* __restrict dest, const char* __restrict src) {
114 return __builtin___stpcpy_chk(dest, src, __bos(dest));
115 }
116
117 __BIONIC_FORTIFY_INLINE
strcpy(char * __restrict dest,const char * __restrict src)118 char* strcpy(char* __restrict dest, const char* __restrict src) {
119 return __builtin___strcpy_chk(dest, src, __bos(dest));
120 }
121
122 extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
123
124 __BIONIC_FORTIFY_INLINE
stpncpy(char * __restrict dest,const char * __restrict src,size_t n)125 char* stpncpy(char* __restrict dest, const char* __restrict src, size_t n) {
126 size_t bos_dest = __bos(dest);
127 size_t bos_src = __bos(src);
128
129 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
130 return __builtin___stpncpy_chk(dest, src, n, bos_dest);
131 }
132
133 if (__builtin_constant_p(n) && (n <= bos_src)) {
134 return __builtin___stpncpy_chk(dest, src, n, bos_dest);
135 }
136
137 size_t slen = __builtin_strlen(src);
138 if (__builtin_constant_p(slen)) {
139 return __builtin___stpncpy_chk(dest, src, n, bos_dest);
140 }
141
142 return __stpncpy_chk2(dest, src, n, bos_dest, bos_src);
143 }
144
145 extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
146
147 __BIONIC_FORTIFY_INLINE
strncpy(char * __restrict dest,const char * __restrict src,size_t n)148 char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
149 size_t bos_dest = __bos(dest);
150 size_t bos_src = __bos(src);
151
152 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
153 return __builtin___strncpy_chk(dest, src, n, bos_dest);
154 }
155
156 if (__builtin_constant_p(n) && (n <= bos_src)) {
157 return __builtin___strncpy_chk(dest, src, n, bos_dest);
158 }
159
160 size_t slen = __builtin_strlen(src);
161 if (__builtin_constant_p(slen)) {
162 return __builtin___strncpy_chk(dest, src, n, bos_dest);
163 }
164
165 return __strncpy_chk2(dest, src, n, bos_dest, bos_src);
166 }
167
168 __BIONIC_FORTIFY_INLINE
strcat(char * __restrict dest,const char * __restrict src)169 char* strcat(char* __restrict dest, const char* __restrict src) {
170 return __builtin___strcat_chk(dest, src, __bos(dest));
171 }
172
173 __BIONIC_FORTIFY_INLINE
strncat(char * __restrict dest,const char * __restrict src,size_t n)174 char *strncat(char* __restrict dest, const char* __restrict src, size_t n) {
175 return __builtin___strncat_chk(dest, src, n, __bos(dest));
176 }
177
178 __BIONIC_FORTIFY_INLINE
memset(void * s,int c,size_t n)179 void* memset(void *s, int c, size_t n) {
180 return __builtin___memset_chk(s, c, n, __bos0(s));
181 }
182
183 extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
184 __asm__(__USER_LABEL_PREFIX__ "strlcpy");
185 extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
186
187 __BIONIC_FORTIFY_INLINE
strlcpy(char * __restrict dest,const char * __restrict src,size_t size)188 size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {
189 size_t bos = __bos(dest);
190
191 #if !defined(__clang__)
192 // Compiler does not know destination size. Do not call __strlcpy_chk
193 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
194 return __strlcpy_real(dest, src, size);
195 }
196
197 // Compiler can prove, at compile time, that the passed in size
198 // is always <= the actual object size. Do not call __strlcpy_chk
199 if (__builtin_constant_p(size) && (size <= bos)) {
200 return __strlcpy_real(dest, src, size);
201 }
202 #endif /* !defined(__clang__) */
203
204 return __strlcpy_chk(dest, src, size, bos);
205 }
206
207 extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
208 __asm__(__USER_LABEL_PREFIX__ "strlcat");
209 extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);
210
211
212 __BIONIC_FORTIFY_INLINE
strlcat(char * __restrict dest,const char * __restrict src,size_t size)213 size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
214 size_t bos = __bos(dest);
215
216 #if !defined(__clang__)
217 // Compiler does not know destination size. Do not call __strlcat_chk
218 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
219 return __strlcat_real(dest, src, size);
220 }
221
222 // Compiler can prove, at compile time, that the passed in size
223 // is always <= the actual object size. Do not call __strlcat_chk
224 if (__builtin_constant_p(size) && (size <= bos)) {
225 return __strlcat_real(dest, src, size);
226 }
227 #endif /* !defined(__clang__) */
228
229 return __strlcat_chk(dest, src, size, bos);
230 }
231
232 __BIONIC_FORTIFY_INLINE
strlen(const char * s)233 size_t strlen(const char *s) {
234 size_t bos = __bos(s);
235
236 #if !defined(__clang__)
237 // Compiler does not know destination size. Do not call __strlen_chk
238 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
239 return __builtin_strlen(s);
240 }
241
242 size_t slen = __builtin_strlen(s);
243 if (__builtin_constant_p(slen)) {
244 return slen;
245 }
246 #endif /* !defined(__clang__) */
247
248 return __strlen_chk(s, bos);
249 }
250
251 __BIONIC_FORTIFY_INLINE
strchr(const char * s,int c)252 char* strchr(const char *s, int c) {
253 size_t bos = __bos(s);
254
255 #if !defined(__clang__)
256 // Compiler does not know destination size. Do not call __strchr_chk
257 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
258 return __builtin_strchr(s, c);
259 }
260
261 size_t slen = __builtin_strlen(s);
262 if (__builtin_constant_p(slen) && (slen < bos)) {
263 return __builtin_strchr(s, c);
264 }
265 #endif /* !defined(__clang__) */
266
267 return __strchr_chk(s, c, bos);
268 }
269
270 __BIONIC_FORTIFY_INLINE
strrchr(const char * s,int c)271 char* strrchr(const char *s, int c) {
272 size_t bos = __bos(s);
273
274 #if !defined(__clang__)
275 // Compiler does not know destination size. Do not call __strrchr_chk
276 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
277 return __builtin_strrchr(s, c);
278 }
279
280 size_t slen = __builtin_strlen(s);
281 if (__builtin_constant_p(slen) && (slen < bos)) {
282 return __builtin_strrchr(s, c);
283 }
284 #endif /* !defined(__clang__) */
285
286 return __strrchr_chk(s, c, bos);
287 }
288
289
290 #endif /* defined(__BIONIC_FORTIFY) */
291
292 __END_DECLS
293
294 #endif /* _STRING_H_ */
295