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*  rindex(const char *, int) __purefunc;
49a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strchr(const char *, int) __purefunc;
50a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strrchr(const char *, int) __purefunc;
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
52a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strlen(const char *) __purefunc;
53a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcmp(const char *, const char *) __purefunc;
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strcpy(char *, const char *);
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strcat(char *, const char *);
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
57a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcasecmp(const char *, const char *) __purefunc;
58a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strncasecmp(const char *, const char *, size_t) __purefunc;
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strdup(const char *);
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
61a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strstr(const char *, const char *) __purefunc;
62a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strtok(char *, const char *);
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strtok_r(char *, const char *, char**);
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strerror(int);
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern int    strerror_r(int errnum, char *buf, size_t n);
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
69a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strnlen(const char *, size_t) __purefunc;
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strncat(char *, const char *, size_t);
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strndup(const char *, size_t);
72a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strncmp(const char *, const char *, size_t) __purefunc;
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strncpy(char *, const char *, size_t);
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strlcat(char *, const char *, size_t);
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strlcpy(char *, const char *, size_t);
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
78a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern size_t strcspn(const char *, const char *) __purefunc;
79a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern char*  strpbrk(const char *, const char *) __purefunc;
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strsep(char **, const char *);
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strspn(const char *, const char *);
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char*  strsignal(int  sig);
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
85a677907ee8ecca034318fdb97902fa73e7392c4fNick Kralevichextern int    strcoll(const char *, const char *) __purefunc;
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern size_t strxfrm(char *, const char *, size_t);
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8871a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich#if defined(__BIONIC_FORTIFY_INLINE)
890a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
90f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichextern void __memcpy_dest_size_error()
91f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    __attribute__((__error__("memcpy called with size bigger than destination")));
92f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichextern void __memcpy_src_size_error()
93f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    __attribute__((__error__("memcpy called with size bigger than source")));
94f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichextern void __memcpy_overlap_error()
95f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    __attribute__((__error__("memcpy called with overlapping regions")));
96f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
970a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
98f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevichvoid *memcpy (void *dest, const void *src, size_t copy_amount) {
99f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    char *d = (char *) dest;
100f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    const char *s = (const char *) src;
101f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    size_t s_len = __builtin_object_size(s, 0);
102f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    size_t d_len = __builtin_object_size(d, 0);
103f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
104f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    if (__builtin_constant_p(copy_amount) && (copy_amount > d_len)) {
105f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich        __memcpy_dest_size_error();
106f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    }
107f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
108f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    if (__builtin_constant_p(copy_amount) && (copy_amount > s_len)) {
109f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich        __memcpy_src_size_error();
110f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    }
111f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
112f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    if (__builtin_constant_p(d - s) && __builtin_constant_p(copy_amount)
113f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich            && (((size_t)(d - s) < copy_amount) || ((size_t)(s - d) < copy_amount))) {
114f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich        __memcpy_overlap_error();
115f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich    }
116f3913b5b68347ce9a4cb17977df2c33f1e8f6000Nick Kralevich
117c37fc1ab6a3ac3956a8c9ba3ac089d41969815edNick Kralevich    return __builtin___memcpy_chk(dest, src, copy_amount, d_len);
1180a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1190a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1200a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1210a2301598c207fd1b50015984942fee5e8511593Nick Kralevichvoid *memmove (void *dest, const void *src, size_t len) {
12271a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___memmove_chk(dest, src, len, __builtin_object_size (dest, 0));
1230a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1240a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1250a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1260a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strcpy(char *dest, const char *src) {
12771a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___strcpy_chk(dest, src, __builtin_object_size (dest, 0));
1280a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1290a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1300a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1310a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strncpy(char *dest, const char *src, size_t n) {
1320a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    return __builtin___strncpy_chk(dest, src, n, __builtin_object_size (dest, 0));
1330a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1340a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1350a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1360a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strcat(char *dest, const char *src) {
13771a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___strcat_chk(dest, src, __builtin_object_size (dest, 0));
1380a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1390a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
1400a2301598c207fd1b50015984942fee5e8511593Nick Kralevich__BIONIC_FORTIFY_INLINE
1410a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *strncat(char *dest, const char *src, size_t n) {
1420a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    return __builtin___strncat_chk(dest, src, n, __builtin_object_size (dest, 0));
1430a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
1440a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
14571a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich__BIONIC_FORTIFY_INLINE
14671a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevichvoid *memset (void *s, int c, size_t n) {
14771a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich    return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
14871a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich}
14971a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich
150cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevichextern size_t __strlcpy_real(char *, const char *, size_t)
1518df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    __asm__(__USER_LABEL_PREFIX__ "strlcpy");
1528df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern void __strlcpy_error()
153cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich    __attribute__((__error__("strlcpy called with size bigger than buffer")));
1548df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
1558df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1568df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich__BIONIC_FORTIFY_INLINE
1578df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichsize_t strlcpy(char *dest, const char *src, size_t size) {
1588df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    size_t bos = __builtin_object_size(dest, 0);
1598df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1608df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler doesn't know destination size. Don't call __strlcpy_chk
1619b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
162cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcpy_real(dest, src, size);
1638df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1648df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1658df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1668df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always <= the actual object size. Don't call __strlcpy_chk
1678df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size <= bos)) {
168cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcpy_real(dest, src, size);
1698df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1708df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1718df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1728df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always > the actual object size. Force a compiler error.
1738df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size > bos)) {
1748df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich        __strlcpy_error();
1758df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1768df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1778df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    return __strlcpy_chk(dest, src, size, bos);
1788df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich}
1798df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
180cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevichextern size_t __strlcat_real(char *, const char *, size_t)
1818df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    __asm__(__USER_LABEL_PREFIX__ "strlcat");
1828df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern void __strlcat_error()
183cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich    __attribute__((__error__("strlcat called with size bigger than buffer")));
1848df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichextern size_t __strlcat_chk(char *, const char *, size_t, size_t);
1858df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1868df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1878df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich__BIONIC_FORTIFY_INLINE
1888df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevichsize_t strlcat(char *dest, const char *src, size_t size) {
1898df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    size_t bos = __builtin_object_size(dest, 0);
1908df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1918df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler doesn't know destination size. Don't call __strlcat_chk
1929b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
193cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcat_real(dest, src, size);
1948df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
1958df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
1968df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
1978df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always <= the actual object size. Don't call __strlcat_chk
1988df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size <= bos)) {
199cb228fb4a91bdccfd974b8a4f45e2b6002e90728Nick Kralevich        return __strlcat_real(dest, src, size);
2008df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
2018df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
2028df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // Compiler can prove, at compile time, that the passed in size
2038df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    // is always > the actual object size. Force a compiler error.
2048df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    if (__builtin_constant_p(size) && (size > bos)) {
2058df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich        __strlcat_error();
2068df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    }
2078df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
2088df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich    return __strlcat_chk(dest, src, size, bos);
2098df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich}
2108df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
211260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich__purefunc extern size_t __strlen_real(const char *)
212260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    __asm__(__USER_LABEL_PREFIX__ "strlen");
213260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevichextern size_t __strlen_chk(const char *, size_t);
214260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich
215260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich__BIONIC_FORTIFY_INLINE
216260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevichsize_t strlen(const char *s) {
217260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    size_t bos = __builtin_object_size(s, 0);
2189b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich
2199b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    // Compiler doesn't know destination size. Don't call __strlen_chk
2209b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
221260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich        return __strlen_real(s);
222260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    }
2239b6cc223a36835c4367a036d4cfeff14d25bc742Nick Kralevich
224260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich    return __strlen_chk(s, bos);
225260bf8cfe00f83bc579dfe81c78b75bd9973f051Nick Kralevich}
2268df49ad2467ec2d48f94a925162185c34bf6e68bNick Kralevich
22771a18dd435e96564539b5af71b8ea5093a2109a1Nick Kralevich#endif /* defined(__BIONIC_FORTIFY_INLINE) */
2280a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__END_DECLS
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* _STRING_H_ */
232