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
35 __BEGIN_DECLS
36
37 extern void* memccpy(void *, const void *, int, size_t);
38 extern void* memchr(const void *, int, size_t) __purefunc;
39 extern void* memrchr(const void *, int, size_t) __purefunc;
40 extern int memcmp(const void *, const void *, size_t) __purefunc;
41 extern void* memcpy(void *, const void *, size_t);
42 extern void* memmove(void *, const void *, size_t);
43 extern void* memset(void *, int, size_t);
44 extern void* memmem(const void *, size_t, const void *, size_t) __purefunc;
45 extern void memswap(void *, void *, size_t);
46
47 extern char* index(const char *, int) __purefunc;
48 extern char* strchr(const char *, int) __purefunc;
49 extern char* strrchr(const char *, int) __purefunc;
50
51 extern size_t strlen(const char *) __purefunc;
52 extern int strcmp(const char *, const char *) __purefunc;
53 extern char* strcpy(char *, const char *);
54 extern char* strcat(char *, const char *);
55
56 extern int strcasecmp(const char *, const char *) __purefunc;
57 extern int strncasecmp(const char *, const char *, size_t) __purefunc;
58 extern char* strdup(const char *);
59
60 extern char* strstr(const char *, const char *) __purefunc;
61 extern char* strcasestr(const char *haystack, const char *needle) __purefunc;
62 extern char* strtok(char *, const char *);
63 extern char* strtok_r(char *, const char *, char**);
64
65 extern char* strerror(int);
66 extern int strerror_r(int errnum, char *buf, size_t n);
67
68 extern size_t strnlen(const char *, size_t) __purefunc;
69 extern char* strncat(char *, const char *, size_t);
70 extern char* strndup(const char *, size_t);
71 extern int strncmp(const char *, const char *, size_t) __purefunc;
72 extern char* strncpy(char *, const char *, size_t);
73
74 extern size_t strlcat(char *, const char *, size_t);
75 extern size_t strlcpy(char *, const char *, size_t);
76
77 extern size_t strcspn(const char *, const char *) __purefunc;
78 extern char* strpbrk(const char *, const char *) __purefunc;
79 extern char* strsep(char **, const char *);
80 extern size_t strspn(const char *, const char *);
81
82 extern char* strsignal(int sig);
83
84 extern int strcoll(const char *, const char *) __purefunc;
85 extern size_t strxfrm(char *, const char *, size_t);
86
87 #if defined(__BIONIC_FORTIFY)
88
89 extern void __memcpy_dest_size_error()
90 __attribute__((__error__("memcpy called with size bigger than destination")));
91 extern void __memcpy_src_size_error()
92 __attribute__((__error__("memcpy called with size bigger than source")));
93
94 __BIONIC_FORTIFY_INLINE
memcpy(void * dest,const void * src,size_t copy_amount)95 void *memcpy (void *dest, const void *src, size_t copy_amount) {
96 char *d = (char *) dest;
97 const char *s = (const char *) src;
98 size_t s_len = __builtin_object_size(s, 0);
99 size_t d_len = __builtin_object_size(d, 0);
100
101 if (__builtin_constant_p(copy_amount) && (copy_amount > d_len)) {
102 __memcpy_dest_size_error();
103 }
104
105 if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
106 __memcpy_src_size_error();
107 }
108
109 return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
110 }
111
112 __BIONIC_FORTIFY_INLINE
memmove(void * dest,const void * src,size_t len)113 void *memmove (void *dest, const void *src, size_t len) {
114 return __builtin___memmove_chk(dest, src, len, __builtin_object_size (dest, 0));
115 }
116
117 __BIONIC_FORTIFY_INLINE
strcpy(char * dest,const char * src)118 char *strcpy(char *dest, const char *src) {
119 return __builtin___strcpy_chk(dest, src, __builtin_object_size (dest, 0));
120 }
121
122 __BIONIC_FORTIFY_INLINE
strncpy(char * dest,const char * src,size_t n)123 char *strncpy(char *dest, const char *src, size_t n) {
124 return __builtin___strncpy_chk(dest, src, n, __builtin_object_size (dest, 0));
125 }
126
127 __BIONIC_FORTIFY_INLINE
strcat(char * dest,const char * src)128 char *strcat(char *dest, const char *src) {
129 return __builtin___strcat_chk(dest, src, __builtin_object_size (dest, 0));
130 }
131
132 __BIONIC_FORTIFY_INLINE
strncat(char * dest,const char * src,size_t n)133 char *strncat(char *dest, const char *src, size_t n) {
134 return __builtin___strncat_chk(dest, src, n, __builtin_object_size (dest, 0));
135 }
136
137 __BIONIC_FORTIFY_INLINE
memset(void * s,int c,size_t n)138 void *memset (void *s, int c, size_t n) {
139 return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
140 }
141
142 extern size_t __strlcpy_real(char *, const char *, size_t)
143 __asm__(__USER_LABEL_PREFIX__ "strlcpy");
144 extern void __strlcpy_error()
145 __attribute__((__error__("strlcpy called with size bigger than buffer")));
146 extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
147
148 __BIONIC_FORTIFY_INLINE
strlcpy(char * dest,const char * src,size_t size)149 size_t strlcpy(char *dest, const char *src, size_t size) {
150 size_t bos = __builtin_object_size(dest, 0);
151
152 // Compiler doesn't know destination size. Don't call __strlcpy_chk
153 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
154 return __strlcpy_real(dest, src, size);
155 }
156
157 // Compiler can prove, at compile time, that the passed in size
158 // is always <= the actual object size. Don't call __strlcpy_chk
159 if (__builtin_constant_p(size) && (size <= bos)) {
160 return __strlcpy_real(dest, src, size);
161 }
162
163 // Compiler can prove, at compile time, that the passed in size
164 // is always > the actual object size. Force a compiler error.
165 if (__builtin_constant_p(size) && (size > bos)) {
166 __strlcpy_error();
167 }
168
169 return __strlcpy_chk(dest, src, size, bos);
170 }
171
172 extern size_t __strlcat_real(char *, const char *, size_t)
173 __asm__(__USER_LABEL_PREFIX__ "strlcat");
174 extern void __strlcat_error()
175 __attribute__((__error__("strlcat called with size bigger than buffer")));
176 extern size_t __strlcat_chk(char *, const char *, size_t, size_t);
177
178
179 __BIONIC_FORTIFY_INLINE
strlcat(char * dest,const char * src,size_t size)180 size_t strlcat(char *dest, const char *src, size_t size) {
181 size_t bos = __builtin_object_size(dest, 0);
182
183 // Compiler doesn't know destination size. Don't call __strlcat_chk
184 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
185 return __strlcat_real(dest, src, size);
186 }
187
188 // Compiler can prove, at compile time, that the passed in size
189 // is always <= the actual object size. Don't call __strlcat_chk
190 if (__builtin_constant_p(size) && (size <= bos)) {
191 return __strlcat_real(dest, src, size);
192 }
193
194 // Compiler can prove, at compile time, that the passed in size
195 // is always > the actual object size. Force a compiler error.
196 if (__builtin_constant_p(size) && (size > bos)) {
197 __strlcat_error();
198 }
199
200 return __strlcat_chk(dest, src, size, bos);
201 }
202
203 extern size_t __strlen_chk(const char *, size_t);
204
205 __BIONIC_FORTIFY_INLINE
strlen(const char * s)206 size_t strlen(const char *s) {
207 size_t bos = __builtin_object_size(s, 0);
208
209 // Compiler doesn't know destination size. Don't call __strlen_chk
210 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
211 return __builtin_strlen(s);
212 }
213
214 size_t slen = __builtin_strlen(s);
215 if (__builtin_constant_p(slen)) {
216 return slen;
217 }
218
219 return __strlen_chk(s, bos);
220 }
221
222 extern char* __strchr_chk(const char *, int, size_t);
223
224 __BIONIC_FORTIFY_INLINE
strchr(const char * s,int c)225 char* strchr(const char *s, int c) {
226 size_t bos = __builtin_object_size(s, 0);
227
228 // Compiler doesn't know destination size. Don't call __strchr_chk
229 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
230 return __builtin_strchr(s, c);
231 }
232
233 size_t slen = __builtin_strlen(s);
234 if (__builtin_constant_p(slen) && (slen < bos)) {
235 return __builtin_strchr(s, c);
236 }
237
238 return __strchr_chk(s, c, bos);
239 }
240
241 extern char* __strrchr_chk(const char *, int, size_t);
242
243 __BIONIC_FORTIFY_INLINE
strrchr(const char * s,int c)244 char* strrchr(const char *s, int c) {
245 size_t bos = __builtin_object_size(s, 0);
246
247 // Compiler doesn't know destination size. Don't call __strrchr_chk
248 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
249 return __builtin_strrchr(s, c);
250 }
251
252 size_t slen = __builtin_strlen(s);
253 if (__builtin_constant_p(slen) && (slen < bos)) {
254 return __builtin_strrchr(s, c);
255 }
256
257 return __strrchr_chk(s, c, bos);
258 }
259
260
261 #endif /* defined(__BIONIC_FORTIFY) */
262
263 __END_DECLS
264
265 #endif /* _STRING_H_ */
266