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