Home | History | Annotate | Download | only in bits
      1 /* Copyright (C) 2004, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
      2    This file is part of the GNU C Library.
      3 
      4    The GNU C Library is free software; you can redistribute it and/or
      5    modify it under the terms of the GNU Lesser General Public
      6    License as published by the Free Software Foundation; either
      7    version 2.1 of the License, or (at your option) any later version.
      8 
      9    The GNU C Library is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12    Lesser General Public License for more details.
     13 
     14    You should have received a copy of the GNU Lesser General Public
     15    License along with the GNU C Library; if not, write to the Free
     16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     17    02111-1307 USA.  */
     18 
     19 #ifndef _STRING_H
     20 # error "Never use <bits/string3.h> directly; include <string.h> instead."
     21 #endif
     22 
     23 __warndecl (__warn_memset_zero_len,
     24 	    "memset used with constant zero length parameter; this could be due to transposed parameters");
     25 
     26 #ifndef __cplusplus
     27 /* XXX This is temporarily.  We should not redefine any of the symbols
     28    and instead integrate the error checking into the original
     29    definitions.  */
     30 # undef memcpy
     31 # undef memmove
     32 # undef memset
     33 # undef strcat
     34 # undef strcpy
     35 # undef strncat
     36 # undef strncpy
     37 # ifdef __USE_GNU
     38 #  undef mempcpy
     39 #  undef stpcpy
     40 # endif
     41 # ifdef __USE_BSD
     42 #  undef bcopy
     43 #  undef bzero
     44 # endif
     45 #endif
     46 
     47 
     48 __extern_always_inline void *
     49 __NTH (memcpy (void *__restrict __dest, __const void *__restrict __src,
     50 	       size_t __len))
     51 {
     52   return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
     53 }
     54 
     55 __extern_always_inline void *
     56 __NTH (memmove (void *__dest, __const void *__src, size_t __len))
     57 {
     58   return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
     59 }
     60 
     61 #ifdef __USE_GNU
     62 __extern_always_inline void *
     63 __NTH (mempcpy (void *__restrict __dest, __const void *__restrict __src,
     64 		size_t __len))
     65 {
     66   return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
     67 }
     68 #endif
     69 
     70 
     71 /* The first two tests here help to catch a somewhat common problem
     72    where the second and third parameter are transposed.  This is
     73    especially problematic if the intended fill value is zero.  In this
     74    case no work is done at all.  We detect these problems by referring
     75    non-existing functions.  */
     76 __extern_always_inline void *
     77 __NTH (memset (void *__dest, int __ch, size_t __len))
     78 {
     79   if (__builtin_constant_p (__len) && __len == 0
     80       && (!__builtin_constant_p (__ch) || __ch != 0))
     81     {
     82       __warn_memset_zero_len ();
     83       return __dest;
     84     }
     85   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
     86 }
     87 
     88 #ifdef __USE_BSD
     89 __extern_always_inline void
     90 __NTH (bcopy (__const void *__src, void *__dest, size_t __len))
     91 {
     92   (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
     93 }
     94 
     95 __extern_always_inline void
     96 __NTH (bzero (void *__dest, size_t __len))
     97 {
     98   (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
     99 }
    100 #endif
    101 
    102 __extern_always_inline char *
    103 __NTH (strcpy (char *__restrict __dest, __const char *__restrict __src))
    104 {
    105   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
    106 }
    107 
    108 #ifdef __USE_GNU
    109 __extern_always_inline char *
    110 __NTH (stpcpy (char *__restrict __dest, __const char *__restrict __src))
    111 {
    112   return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
    113 }
    114 #endif
    115 
    116 
    117 __extern_always_inline char *
    118 __NTH (strncpy (char *__restrict __dest, __const char *__restrict __src,
    119 		size_t __len))
    120 {
    121   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
    122 }
    123 
    124 // XXX We have no corresponding builtin yet.
    125 extern char *__stpncpy_chk (char *__dest, __const char *__src, size_t __n,
    126 			    size_t __destlen) __THROW;
    127 extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest,
    128 					       __const char *__src,
    129 					       size_t __n), stpncpy);
    130 
    131 __extern_always_inline char *
    132 __NTH (stpncpy (char *__dest, __const char *__src, size_t __n))
    133 {
    134   if (__bos (__dest) != (size_t) -1
    135       && (!__builtin_constant_p (__n) || __n <= __bos (__dest)))
    136     return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
    137   return __stpncpy_alias (__dest, __src, __n);
    138 }
    139 
    140 
    141 __extern_always_inline char *
    142 __NTH (strcat (char *__restrict __dest, __const char *__restrict __src))
    143 {
    144   return __builtin___strcat_chk (__dest, __src, __bos (__dest));
    145 }
    146 
    147 
    148 __extern_always_inline char *
    149 __NTH (strncat (char *__restrict __dest, __const char *__restrict __src,
    150 		size_t __len))
    151 {
    152   return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
    153 }
    154