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 42extern void* memccpy(void* __restrict, const void* __restrict, int, size_t); 43extern void* memchr(const void *, int, size_t) __purefunc; 44extern void* memrchr(const void *, int, size_t) __purefunc; 45extern int memcmp(const void *, const void *, size_t) __purefunc; 46extern void* memcpy(void* __restrict, const void* __restrict, size_t); 47#if defined(__USE_GNU) 48extern void* mempcpy(void* __restrict, const void* __restrict, size_t); 49#endif 50extern void* memmove(void *, const void *, size_t); 51extern void* memset(void *, int, size_t); 52extern void* memmem(const void *, size_t, const void *, size_t) __purefunc; 53 54extern char* strchr(const char *, int) __purefunc; 55extern char* __strchr_chk(const char *, int, size_t); 56 57extern char* strrchr(const char *, int) __purefunc; 58extern char* __strrchr_chk(const char *, int, size_t); 59 60extern size_t strlen(const char *) __purefunc; 61extern size_t __strlen_chk(const char *, size_t); 62extern int strcmp(const char *, const char *) __purefunc; 63extern char* stpcpy(char* __restrict, const char* __restrict); 64extern char* strcpy(char* __restrict, const char* __restrict); 65extern char* strcat(char* __restrict, const char* __restrict); 66 67int strcasecmp(const char*, const char*) __purefunc; 68int strcasecmp_l(const char*, const char*, locale_t) __purefunc; 69int strncasecmp(const char*, const char*, size_t) __purefunc; 70int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc; 71 72extern char* strdup(const char *); 73 74extern char* strstr(const char *, const char *) __purefunc; 75extern char* strcasestr(const char *haystack, const char *needle) __purefunc; 76extern char* strtok(char* __restrict, const char* __restrict); 77extern char* strtok_r(char* __restrict, const char* __restrict, char** __restrict); 78 79extern char* strerror(int); 80extern char* strerror_l(int, locale_t); 81#if defined(__USE_GNU) 82extern char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r); 83#else /* POSIX */ 84extern int strerror_r(int, char*, size_t); 85#endif 86 87extern size_t strnlen(const char *, size_t) __purefunc; 88extern char* strncat(char* __restrict, const char* __restrict, size_t); 89extern char* strndup(const char *, size_t); 90extern int strncmp(const char *, const char *, size_t) __purefunc; 91extern char* stpncpy(char* __restrict, const char* __restrict, size_t); 92extern char* strncpy(char* __restrict, const char* __restrict, size_t); 93 94extern size_t strlcat(char* __restrict, const char* __restrict, size_t); 95extern size_t strlcpy(char* __restrict, const char* __restrict, size_t); 96 97extern size_t strcspn(const char *, const char *) __purefunc; 98extern char* strpbrk(const char *, const char *) __purefunc; 99extern char* strsep(char** __restrict, const char* __restrict); 100extern size_t strspn(const char *, const char *); 101 102extern char* strsignal(int sig); 103 104extern int strcoll(const char *, const char *) __purefunc; 105extern size_t strxfrm(char* __restrict, const char* __restrict, size_t); 106 107extern int strcoll_l(const char *, const char *, locale_t) __purefunc; 108extern 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) 116extern "C++" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1)); 117extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1)); 118#else 119extern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1)); 120#endif 121#define __bionic_using_gnu_basename 122#endif 123 124extern void* __memchr_chk(const void*, int, size_t, size_t); 125__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); 126 127extern void* __memrchr_chk(const void*, int, size_t, size_t); 128__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); 129extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr); 130 131extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 132extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t); 133extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcpy); 134extern size_t __strlcpy_chk(char *, const char *, size_t, size_t); 135extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcat); 136extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t); 137 138#if defined(__BIONIC_FORTIFY) 139 140__BIONIC_FORTIFY_INLINE 141void* 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 162void* 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 183void* 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 188void* 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 193char* stpcpy(char* __restrict dest, const char* __restrict src) { 194 return __builtin___stpcpy_chk(dest, src, __bos(dest)); 195} 196 197__BIONIC_FORTIFY_INLINE 198char* strcpy(char* __restrict dest, const char* __restrict src) { 199 return __builtin___strcpy_chk(dest, src, __bos(dest)); 200} 201 202__BIONIC_FORTIFY_INLINE 203char* 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 224char* 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 245char* strcat(char* __restrict dest, const char* __restrict src) { 246 return __builtin___strcat_chk(dest, src, __bos(dest)); 247} 248 249__BIONIC_FORTIFY_INLINE 250char *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 255void* memset(void *s, int c, size_t n) { 256 return __builtin___memset_chk(s, c, n, __bos0(s)); 257} 258 259__BIONIC_FORTIFY_INLINE 260size_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 281size_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 301size_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 320char* 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 339char* 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