]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/bcopy.c
Fix SCTP socket use-after-free.
[FreeBSD/FreeBSD.git] / sys / arm64 / arm64 / bcopy.c
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Chris Torek.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  * 
32  * From: sys/powerpc/powerpc/bcopy.c
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40
41 /*
42  * sizeof(word) MUST BE A POWER OF TWO
43  * SO THAT wmask BELOW IS ALL ONES
44  */
45 typedef long    word;           /* "word" used for optimal copy speed */
46
47 #define wsize   sizeof(word)
48 #define wmask   (wsize - 1)
49
50 /*
51  * Copy a block of memory, handling overlap.
52  * This is the routine that actually implements
53  * (the portable versions of) bcopy, memcpy, and memmove.
54  */
55 void *
56 memcpy(void *dst0, const void *src0, size_t length)
57 {
58         char            *dst;
59         const char      *src;
60         size_t          t;
61
62         dst = dst0;
63         src = src0;
64
65         if (length == 0 || dst == src) {        /* nothing to do */
66                 goto done;
67         }
68
69         /*
70          * Macros: loop-t-times; and loop-t-times, t>0
71          */
72 #define TLOOP(s) if (t) TLOOP1(s)
73 #define TLOOP1(s) do { s; } while (--t)
74
75         if ((unsigned long)dst < (unsigned long)src) {
76                 /*
77                  * Copy forward.
78                  */
79                 t = (size_t)src;        /* only need low bits */
80
81                 if ((t | (uintptr_t)dst) & wmask) {
82                         /*
83                          * Try to align operands.  This cannot be done
84                          * unless the low bits match.
85                          */
86                         if ((t ^ (uintptr_t)dst) & wmask || length < wsize) {
87                                 t = length;
88                         } else {
89                                 t = wsize - (t & wmask);
90                         }
91
92                         length -= t;
93                         TLOOP1(*dst++ = *src++);
94                 }
95                 /*
96                  * Copy whole words, then mop up any trailing bytes.
97                  */
98                 t = length / wsize;
99                 TLOOP(*(word *)dst = *(const word *)src; src += wsize;
100                     dst += wsize);
101                 t = length & wmask;
102                 TLOOP(*dst++ = *src++);
103         } else {
104                 /*
105                  * Copy backwards.  Otherwise essentially the same.
106                  * Alignment works as before, except that it takes
107                  * (t&wmask) bytes to align, not wsize-(t&wmask).
108                  */
109                 src += length;
110                 dst += length;
111                 t = (uintptr_t)src;
112
113                 if ((t | (uintptr_t)dst) & wmask) {
114                         if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) {
115                                 t = length;
116                         } else {
117                                 t &= wmask;
118                         }
119
120                         length -= t;
121                         TLOOP1(*--dst = *--src);
122                 }
123                 t = length / wsize;
124                 TLOOP(src -= wsize; dst -= wsize;
125                     *(word *)dst = *(const word *)src);
126                 t = length & wmask;
127                 TLOOP(*--dst = *--src);
128         }
129 done:
130         return (dst0);
131 }
132
133 void
134 bcopy(const void *src0, void *dst0, size_t length)
135 {
136
137         memcpy(dst0, src0, length);
138 }
139