root/common/libc/string/memmove.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. memmove

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * This file is shared between libc and the kernel, so don't put anything
  32  * in here that won't work in both contexts.
  33  */
  34 
  35 #ifdef _KERNEL
  36 #include <types.h>
  37 #include <lib.h>
  38 #else
  39 #include <stdint.h>
  40 #include <string.h>
  41 #endif
  42 
  43 /*
  44  * C standard function - copy a block of memory, handling overlapping
  45  * regions correctly.
  46  */
  47 
  48 void *
  49 memmove(void *dst, const void *src, size_t len)
  50 {
  51         size_t i;
  52 
  53         /*
  54          * If the buffers don't overlap, it doesn't matter what direction
  55          * we copy in. If they do, it does, so just assume they always do.
  56          * We don't concern ourselves with the possibility that the region
  57          * to copy might roll over across the top of memory, because it's
  58          * not going to happen.
  59          *
  60          * If the destination is above the source, we have to copy
  61          * back to front to avoid overwriting the data we want to
  62          * copy.
  63          *
  64          *      dest:       dddddddd
  65          *      src:    ssssssss   ^
  66          *              |   ^  |___|
  67          *              |___|
  68          *
  69          * If the destination is below the source, we have to copy
  70          * front to back.
  71          *
  72          *      dest:   dddddddd
  73          *      src:    ^   ssssssss
  74          *              |___|  ^   |
  75          *                     |___|
  76          */
  77 
  78         if ((uintptr_t)dst < (uintptr_t)src) {
  79                 /*
  80                  * As author/maintainer of libc, take advantage of the
  81                  * fact that we know memcpy copies forwards.
  82                  */
  83                 return memcpy(dst, src, len);
  84         }
  85 
  86         /*
  87          * Copy by words in the common case. Look in memcpy.c for more
  88          * information.
  89          */
  90 
  91         if ((uintptr_t)dst % sizeof(long) == 0 &&
  92             (uintptr_t)src % sizeof(long) == 0 &&
  93             len % sizeof(long) == 0) {
  94 
  95                 long *d = dst;
  96                 const long *s = src;
  97 
  98                 /*
  99                  * The reason we copy index i-1 and test i>0 is that
 100                  * i is unsigned -- so testing i>=0 doesn't work.
 101                  */
 102 
 103                 for (i=len/sizeof(long); i>0; i--) {
 104                         d[i-1] = s[i-1];
 105                 }
 106         }
 107         else {
 108                 char *d = dst;
 109                 const char *s = src;
 110 
 111                 for (i=len; i>0; i--) {
 112                         d[i-1] = s[i-1];
 113                 }
 114         }
 115 
 116         return dst;
 117 }

/* [<][>][^][v][top][bottom][index][help] */