11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions of source code must retain the above copyright
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    the documentation and/or other materials provided with the
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    distribution.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _STRING_H_
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define _STRING_H_
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h>
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <malloc.h>
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__BEGIN_DECLS
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void*  memccpy(void *, const void *, int, size_t);
38a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern void*  memchr(const void *, int, size_t) __purefunc;
39a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern void*  memrchr(const void *, int, size_t) __purefunc;
40a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    memcmp(const void *, const void *, size_t) __purefunc;
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void*  memcpy(void *, const void *, size_t);
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void*  memmove(void *, const void *, size_t);
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void*  memset(void *, int, size_t);
44a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern void   memswap(void *, void *, size_t);
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
47a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  index(const char *, int) __purefunc;
48a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strchr(const char *, int) __purefunc;
49a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strrchr(const char *, int) __purefunc;
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
51a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strlen(const char *) __purefunc;
52a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcmp(const char *, const char *) __purefunc;
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strcpy(char *, const char *);
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strcat(char *, const char *);
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
56a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcasecmp(const char *, const char *) __purefunc;
57a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strncasecmp(const char *, const char *, size_t) __purefunc;
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strdup(const char *);
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
60a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strstr(const char *, const char *) __purefunc;
61a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strtok(char *, const char *);
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strtok_r(char *, const char *, char**);
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strerror(int);
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern int    strerror_r(int errnum, char *buf, size_t n);
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
68a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strnlen(const char *, size_t) __purefunc;
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strncat(char *, const char *, size_t);
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strndup(const char *, size_t);
71a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strncmp(const char *, const char *, size_t) __purefunc;
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strncpy(char *, const char *, size_t);
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strlcat(char *, const char *, size_t);
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strlcpy(char *, const char *, size_t);
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
77a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strcspn(const char *, const char *) __purefunc;
78a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strpbrk(const char *, const char *) __purefunc;
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strsep(char **, const char *);
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strspn(const char *, const char *);
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strsignal(int  sig);
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
84a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcoll(const char *, const char *) __purefunc;
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strxfrm(char *, const char *, size_t);
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
87890c8ed6ef773160cd6840a92e0d469fe530871fElliott Hughes#if defined(__BIONIC_FORTIFY)
880a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
89f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichextern void __memcpy_dest_size_error()
90f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    __attribute__((__error__("memcpy called with size bigger than destination")));
91f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichextern void __memcpy_src_size_error()
92f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    __attribute__((__error__("memcpy called with size bigger than source")));
93f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
940a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
95f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichvoid *memcpy (void *dest, const void *src, size_t copy_amount) {
96f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    char *d = (char *) dest;
97f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    const char *s = (const char *) src;
98f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    size_t s_len = __builtin_object_size(s, 0);
99f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    size_t d_len = __builtin_object_size(d, 0);
100f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
101f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    if (__builtin_constant_p(copy_amount) && (copy_amount > d_len)) {
102f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich        __memcpy_dest_size_error();
103f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    }
104f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
105f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
106f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich        __memcpy_src_size_error();
107f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    }
108f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
109c37fc1ab6a3ac3956a8c9ba3ac089d41969815edNick Kralevich    return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
1100a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1110a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1120a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1130a2301598c207fd1b50015984942fee5e8511593Nick Kralevichvoid *memmove (void *dest, const void *src, size_t len) {
11471a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___memmove_chk(dest, src, len, __builtin_object_size (dest, 0));
1150a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1160a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1170a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1180a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strcpy(char *dest, const char *src) {
11971a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___strcpy_chk(dest, src, __builtin_object_size (dest, 0));
1200a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1210a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1220a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1230a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strncpy(char *dest, const char *src, size_t n) {
1240a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    return __builtin___strncpy_chk(dest, src, n, __builtin_object_size (dest, 0));
1250a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1260a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1270a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1280a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strcat(char *dest, const char *src) {
12971a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___strcat_chk(dest, src, __builtin_object_size (dest, 0));
1300a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1310a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1320a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1330a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strncat(char *dest, const char *src, size_t n) {
1340a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    return __builtin___strncat_chk(dest, src, n, __builtin_object_size (dest, 0));
1350a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1360a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
13771a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich__BIONIC_FORTIFY_INLINE
13871a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevichvoid *memset (void *s, int c, size_t n) {
13971a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
14071a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich}
14171a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich
142cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevichextern size_t __strlcpy_real(char *, const char *, size_t)
1438df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    __asm__(__USER_LABEL_PREFIX__ "strlcpy");
1448df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern void __strlcpy_error()
145cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich    __attribute__((__error__("strlcpy called with size bigger than buffer")));
1468df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
1478df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1488df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich__BIONIC_FORTIFY_INLINE
1498df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichsize_t strlcpy(char *dest, const char *src, size_t size) {
1508df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    size_t bos = __builtin_object_size(dest, 0);
1518df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1528df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler doesn't know destination size. Don't call __strlcpy_chk
1539b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
154cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcpy_real(dest, src, size);
1558df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1568df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1578df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1588df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always <= the actual object size. Don't call __strlcpy_chk
1598df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size <= bos)) {
160cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcpy_real(dest, src, size);
1618df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1628df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1638df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1648df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always > the actual object size. Force a compiler error.
1658df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size > bos)) {
1668df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich        __strlcpy_error();
1678df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1688df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1698df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    return __strlcpy_chk(dest, src, size, bos);
1708df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich}
1718df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
172cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevichextern size_t __strlcat_real(char *, const char *, size_t)
1738df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    __asm__(__USER_LABEL_PREFIX__ "strlcat");
1748df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern void __strlcat_error()
175cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich    __attribute__((__error__("strlcat called with size bigger than buffer")));
1768df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern size_t __strlcat_chk(char *, const char *, size_t, size_t);
1778df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1788df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1798df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich__BIONIC_FORTIFY_INLINE
1808df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichsize_t strlcat(char *dest, const char *src, size_t size) {
1818df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    size_t bos = __builtin_object_size(dest, 0);
1828df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1838df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler doesn't know destination size. Don't call __strlcat_chk
1849b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
185cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcat_real(dest, src, size);
1868df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1878df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1888df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1898df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always <= the actual object size. Don't call __strlcat_chk
1908df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size <= bos)) {
191cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcat_real(dest, src, size);
1928df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1938df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1948df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1958df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always > the actual object size. Force a compiler error.
1968df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size > bos)) {
1978df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich        __strlcat_error();
1988df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1998df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
2008df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    return __strlcat_chk(dest, src, size, bos);
2018df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich}
2028df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
203260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevichextern size_t __strlen_chk(const char *, size_t);
204260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich
205260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich__BIONIC_FORTIFY_INLINE
206260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevichsize_t strlen(const char *s) {
207260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    size_t bos = __builtin_object_size(s, 0);
2089b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich
2099b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    // Compiler doesn't know destination size. Don't call __strlen_chk
2109b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
211a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return __builtin_strlen(s);
212a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    }
213a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich
214a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    size_t slen = __builtin_strlen(s);
215a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    if (__builtin_constant_p(slen)) {
216a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return slen;
217260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    }
2189b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich
219260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    return __strlen_chk(s, bos);
220260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich}
2218df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
222049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevichextern char* __strchr_chk(const char *, int, size_t);
223049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich
224049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich__BIONIC_FORTIFY_INLINE
225049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevichchar* strchr(const char *s, int c) {
226049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich    size_t bos = __builtin_object_size(s, 0);
227049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich
228049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich    // Compiler doesn't know destination size. Don't call __strchr_chk
229049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
230a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return __builtin_strchr(s, c);
231a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    }
232a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich
233a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    size_t slen = __builtin_strlen(s);
234a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    if (__builtin_constant_p(slen) && (slen < bos)) {
235a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return __builtin_strchr(s, c);
236049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich    }
237049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich
238049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich    return __strchr_chk(s, c, bos);
239049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich}
240049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich
2419a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevichextern char* __strrchr_chk(const char *, int, size_t);
2429a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich
2439a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich__BIONIC_FORTIFY_INLINE
2449a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevichchar* strrchr(const char *s, int c) {
2459a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich    size_t bos = __builtin_object_size(s, 0);
2469a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich
2479a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich    // Compiler doesn't know destination size. Don't call __strrchr_chk
2489a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
249a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return __builtin_strrchr(s, c);
250a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    }
251a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich
252a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    size_t slen = __builtin_strlen(s);
253a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich    if (__builtin_constant_p(slen) && (slen < bos)) {
254a44e9afdd16105d6f36319cb538666d9cc78435aNick Kralevich        return __builtin_strrchr(s, c);
2559a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich    }
2569a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich
2579a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich    return __strrchr_chk(s, c, bos);
2589a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich}
2599a4d305340e6ce2fc6c3f371f2d7ede446f8c6d4Nick Kralevich
260049e58369c37fdeacd0380a6bf1e078d9baf819fNick Kralevich
261890c8ed6ef773160cd6840a92e0d469fe530871fElliott Hughes#endif /* defined(__BIONIC_FORTIFY) */
2620a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__END_DECLS
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* _STRING_H_ */
266