• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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