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 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 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 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 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 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 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 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 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 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 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 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 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 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 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