Back to index

glibc  2.9
mempcpy_chk.c
Go to the documentation of this file.
00001 /* Copy memory to memory until the specified number of bytes
00002    has been copied, return pointer to following byte, with error checking.
00003    Overlap is NOT handled correctly.
00004    Copyright (C) 1991, 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
00005    This file is part of the GNU C Library.
00006    Contributed by Torbjorn Granlund (tege@sics.se).
00007 
00008    The GNU C Library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2.1 of the License, or (at your option) any later version.
00012 
00013    The GNU C Library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with the GNU C Library; if not, write to the Free
00020    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00021    02111-1307 USA.  */
00022 
00023 #include <string.h>
00024 #include <memcopy.h>
00025 #include <pagecopy.h>
00026 
00027 void *
00028 __mempcpy_chk (dstpp, srcpp, len, dstlen)
00029      void *dstpp;
00030      const void *srcpp;
00031      size_t len;
00032      size_t dstlen;
00033 {
00034   if (__builtin_expect (dstlen < len, 0))
00035     __chk_fail ();
00036 
00037   unsigned long int dstp = (long int) dstpp;
00038   unsigned long int srcp = (long int) srcpp;
00039 
00040   /* Copy from the beginning to the end.  */
00041 
00042   /* If there not too few bytes to copy, use word copy.  */
00043   if (len >= OP_T_THRES)
00044     {
00045       /* Copy just a few bytes to make DSTP aligned.  */
00046       len -= (-dstp) % OPSIZ;
00047       BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
00048 
00049       /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
00050         as much as possible.  */
00051 
00052       PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
00053 
00054       /* Copy from SRCP to DSTP taking advantage of the known alignment of
00055         DSTP.  Number of bytes remaining is put in the third argument,
00056         i.e. in LEN.  This number may vary from machine to machine.  */
00057 
00058       WORD_COPY_FWD (dstp, srcp, len, len);
00059 
00060       /* Fall out and copy the tail.  */
00061     }
00062 
00063   /* There are just a few bytes to copy.  Use byte memory operations.  */
00064   BYTE_COPY_FWD (dstp, srcp, len);
00065 
00066   return (void *) dstp;
00067 }