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 29 #ifndef _STRING_H 30 #define _STRING_H 31 32 #include <sys/cdefs.h> 33 #include <stddef.h> 34 #include <xlocale.h> 35 36 __BEGIN_DECLS 37 38 #if defined(__USE_BSD) 39 #include <strings.h> 40 #endif 41 42 extern void* memccpy(void* __restrict, const void* __restrict, int, size_t); 43 extern void* memchr(const void *, int, size_t) __purefunc; 44 extern void* memrchr(const void *, int, size_t) __purefunc; 45 extern int memcmp(const void *, const void *, size_t) __purefunc; 46 extern void* memcpy(void* __restrict, const void* __restrict, size_t); 47 #if defined(__USE_GNU) 48 extern void* mempcpy(void* __restrict, const void* __restrict, size_t); 49 #endif 50 extern void* memmove(void *, const void *, size_t); 51 extern void* memset(void *, int, size_t); 52 extern void* memmem(const void *, size_t, const void *, size_t) __purefunc; 53 54 extern char* strchr(const char *, int) __purefunc; 55 extern char* __strchr_chk(const char *, int, size_t); 56 57 extern char* strrchr(const char *, int) __purefunc; 58 extern char* __strrchr_chk(const char *, int, size_t); 59 60 extern size_t strlen(const char *) __purefunc; 61 extern size_t __strlen_chk(const char *, size_t); 62 extern int strcmp(const char *, const char *) __purefunc; 63 extern char* stpcpy(char* __restrict, const char* __restrict); 64 extern char* strcpy(char* __restrict, const char* __restrict); 65 extern char* strcat(char* __restrict, const char* __restrict); 66 67 int strcasecmp(const char*, const char*) __purefunc; 68 int strcasecmp_l(const char*, const char*, locale_t) __purefunc; 69 int strncasecmp(const char*, const char*, size_t) __purefunc; 70 int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc; 71 72 extern char* strdup(const char *); 73 74 extern char* strstr(const char *, const char *) __purefunc; 75 extern char* strcasestr(const char *haystack, const char *needle) __purefunc; 76 extern char* strtok(char* __restrict, const char* __restrict); 77 extern char* strtok_r(char* __restrict, const char* __restrict, char** __restrict); 78 79 extern char* strerror(int); 80 extern char* strerror_l(int, locale_t); 81 #if defined(__USE_GNU) 82 extern char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r); 83 #else /* POSIX */ 84 extern int strerror_r(int, char*, size_t); 85 #endif 86 87 extern size_t strnlen(const char *, size_t) __purefunc; 88 extern char* strncat(char* __restrict, const char* __restrict, size_t); 89 extern char* strndup(const char *, size_t); 90 extern int strncmp(const char *, const char *, size_t) __purefunc; 91 extern char* stpncpy(char* __restrict, const char* __restrict, size_t); 92 extern char* strncpy(char* __restrict, const char* __restrict, size_t); 93 94 extern size_t strlcat(char* __restrict, const char* __restrict, size_t); 95 extern size_t strlcpy(char* __restrict, const char* __restrict, size_t); 96 97 extern size_t strcspn(const char *, const char *) __purefunc; 98 extern char* strpbrk(const char *, const char *) __purefunc; 99 extern char* strsep(char** __restrict, const char* __restrict); 100 extern size_t strspn(const char *, const char *); 101 102 extern char* strsignal(int sig); 103 104 extern int strcoll(const char *, const char *) __purefunc; 105 extern size_t strxfrm(char* __restrict, const char* __restrict, size_t); 106 107 extern int strcoll_l(const char *, const char *, locale_t) __purefunc; 108 extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t); 109 110 #if defined(__USE_GNU) && !defined(__bionic_using_posix_basename) 111 /* 112 * glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>. 113 * It doesn't modify its argument, and in C++ it's const-correct. 114 */ 115 #if defined(__cplusplus) 116 extern "C++" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1)); 117 extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1)); 118 #else 119 extern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1)); 120 #endif 121 #define __bionic_using_gnu_basename 122 #endif 123 124 extern void* __memchr_chk(const void*, int, size_t, size_t); 125 __errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); 126 127 extern void* __memrchr_chk(const void*, int, size_t, size_t); 128 __errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); 129 extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr); 130 131 extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 132 extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 133 extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcpy); 134 extern size_t __strlcpy_chk(char *, const char *, size_t, size_t); 135 extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcat); 136 extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t); 137 138 #if defined(__BIONIC_FORTIFY) 139 140 __BIONIC_FORTIFY_INLINE 141 void* memchr(const void *s, int c, size_t n) { 142 size_t bos = __bos(s); 143 144 #if !defined(__clang__) 145 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 146 return __builtin_memchr(s, c, n); 147 } 148 149 if (__builtin_constant_p(n) && (n > bos)) { 150 __memchr_buf_size_error(); 151 } 152 153 if (__builtin_constant_p(n) && (n <= bos)) { 154 return __builtin_memchr(s, c, n); 155 } 156 #endif 157 158 return __memchr_chk(s, c, n, bos); 159 } 160 161 __BIONIC_FORTIFY_INLINE 162 void* memrchr(const void *s, int c, size_t n) { 163 size_t bos = __bos(s); 164 165 #if !defined(__clang__) 166 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 167 return __memrchr_real(s, c, n); 168 } 169 170 if (__builtin_constant_p(n) && (n > bos)) { 171 __memrchr_buf_size_error(); 172 } 173 174 if (__builtin_constant_p(n) && (n <= bos)) { 175 return __memrchr_real(s, c, n); 176 } 177 #endif 178 179 return __memrchr_chk(s, c, n, bos); 180 } 181 182 __BIONIC_FORTIFY_INLINE 183 void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) { 184 return __builtin___memcpy_chk(dest, src, copy_amount, __bos0(dest)); 185 } 186 187 __BIONIC_FORTIFY_INLINE 188 void* memmove(void *dest, const void *src, size_t len) { 189 return __builtin___memmove_chk(dest, src, len, __bos0(dest)); 190 } 191 192 __BIONIC_FORTIFY_INLINE 193 char* stpcpy(char* __restrict dest, const char* __restrict src) { 194 return __builtin___stpcpy_chk(dest, src, __bos(dest)); 195 } 196 197 __BIONIC_FORTIFY_INLINE 198 char* strcpy(char* __restrict dest, const char* __restrict src) { 199 return __builtin___strcpy_chk(dest, src, __bos(dest)); 200 } 201 202 __BIONIC_FORTIFY_INLINE 203 char* stpncpy(char* __restrict dest, const char* __restrict src, size_t n) { 204 size_t bos_dest = __bos(dest); 205 size_t bos_src = __bos(src); 206 207 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 208 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 209 } 210 211 if (__builtin_constant_p(n) && (n <= bos_src)) { 212 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 213 } 214 215 size_t slen = __builtin_strlen(src); 216 if (__builtin_constant_p(slen)) { 217 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 218 } 219 220 return __stpncpy_chk2(dest, src, n, bos_dest, bos_src); 221 } 222 223 __BIONIC_FORTIFY_INLINE 224 char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) { 225 size_t bos_dest = __bos(dest); 226 size_t bos_src = __bos(src); 227 228 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 229 return __builtin___strncpy_chk(dest, src, n, bos_dest); 230 } 231 232 if (__builtin_constant_p(n) && (n <= bos_src)) { 233 return __builtin___strncpy_chk(dest, src, n, bos_dest); 234 } 235 236 size_t slen = __builtin_strlen(src); 237 if (__builtin_constant_p(slen)) { 238 return __builtin___strncpy_chk(dest, src, n, bos_dest); 239 } 240 241 return __strncpy_chk2(dest, src, n, bos_dest, bos_src); 242 } 243 244 __BIONIC_FORTIFY_INLINE 245 char* strcat(char* __restrict dest, const char* __restrict src) { 246 return __builtin___strcat_chk(dest, src, __bos(dest)); 247 } 248 249 __BIONIC_FORTIFY_INLINE 250 char *strncat(char* __restrict dest, const char* __restrict src, size_t n) { 251 return __builtin___strncat_chk(dest, src, n, __bos(dest)); 252 } 253 254 __BIONIC_FORTIFY_INLINE 255 void* memset(void *s, int c, size_t n) { 256 return __builtin___memset_chk(s, c, n, __bos0(s)); 257 } 258 259 __BIONIC_FORTIFY_INLINE 260 size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) { 261 size_t bos = __bos(dest); 262 263 #if !defined(__clang__) 264 // Compiler doesn't know destination size. Don't call __strlcpy_chk 265 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 266 return __strlcpy_real(dest, src, size); 267 } 268 269 // Compiler can prove, at compile time, that the passed in size 270 // is always <= the actual object size. Don't call __strlcpy_chk 271 if (__builtin_constant_p(size) && (size <= bos)) { 272 return __strlcpy_real(dest, src, size); 273 } 274 #endif /* !defined(__clang__) */ 275 276 return __strlcpy_chk(dest, src, size, bos); 277 } 278 279 280 __BIONIC_FORTIFY_INLINE 281 size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) { 282 size_t bos = __bos(dest); 283 284 #if !defined(__clang__) 285 // Compiler doesn't know destination size. Don't call __strlcat_chk 286 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 287 return __strlcat_real(dest, src, size); 288 } 289 290 // Compiler can prove, at compile time, that the passed in size 291 // is always <= the actual object size. Don't call __strlcat_chk 292 if (__builtin_constant_p(size) && (size <= bos)) { 293 return __strlcat_real(dest, src, size); 294 } 295 #endif /* !defined(__clang__) */ 296 297 return __strlcat_chk(dest, src, size, bos); 298 } 299 300 __BIONIC_FORTIFY_INLINE 301 size_t strlen(const char *s) { 302 size_t bos = __bos(s); 303 304 #if !defined(__clang__) 305 // Compiler doesn't know destination size. Don't call __strlen_chk 306 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 307 return __builtin_strlen(s); 308 } 309 310 size_t slen = __builtin_strlen(s); 311 if (__builtin_constant_p(slen)) { 312 return slen; 313 } 314 #endif /* !defined(__clang__) */ 315 316 return __strlen_chk(s, bos); 317 } 318 319 __BIONIC_FORTIFY_INLINE 320 char* strchr(const char *s, int c) { 321 size_t bos = __bos(s); 322 323 #if !defined(__clang__) 324 // Compiler doesn't know destination size. Don't call __strchr_chk 325 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 326 return __builtin_strchr(s, c); 327 } 328 329 size_t slen = __builtin_strlen(s); 330 if (__builtin_constant_p(slen) && (slen < bos)) { 331 return __builtin_strchr(s, c); 332 } 333 #endif /* !defined(__clang__) */ 334 335 return __strchr_chk(s, c, bos); 336 } 337 338 __BIONIC_FORTIFY_INLINE 339 char* strrchr(const char *s, int c) { 340 size_t bos = __bos(s); 341 342 #if !defined(__clang__) 343 // Compiler doesn't know destination size. Don't call __strrchr_chk 344 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 345 return __builtin_strrchr(s, c); 346 } 347 348 size_t slen = __builtin_strlen(s); 349 if (__builtin_constant_p(slen) && (slen < bos)) { 350 return __builtin_strrchr(s, c); 351 } 352 #endif /* !defined(__clang__) */ 353 354 return __strrchr_chk(s, c, bos); 355 } 356 357 358 #endif /* defined(__BIONIC_FORTIFY) */ 359 360 __END_DECLS 361 362 #endif /* _STRING_H */ 363