Home | History | Annotate | Download | only in include
      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