1 /* Test and measure memcpy functions.
2    Copyright (C) 1999-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 /* test-memcpy-support.h contains all test functions.  */
20 #include "test-memcpy-support.h"
21 
22 static void
do_random_tests(void)23 do_random_tests (void)
24 {
25   size_t i, j, n, align1, align2, len, size1, size2, size;
26   int c;
27   unsigned char *p1, *p2;
28   unsigned char *res;
29 
30   for (n = 0; n < ITERATIONS; n++)
31     {
32       if (n == 0)
33         {
34           len = getpagesize ();
35           size = len + 512;
36           size1 = size;
37           size2 = size;
38           align1 = 512;
39           align2 = 512;
40         }
41       else
42         {
43           if ((random () & 255) == 0)
44             size = 65536;
45           else
46             size = 768;
47           if (size > page_size)
48             size = page_size;
49           size1 = size;
50           size2 = size;
51           i = random ();
52           if (i & 3)
53             size -= 256;
54           if (i & 1)
55             size1 -= 256;
56           if (i & 2)
57             size2 -= 256;
58           if (i & 4)
59             {
60               len = random () % size;
61               align1 = size1 - len - (random () & 31);
62               align2 = size2 - len - (random () & 31);
63               if (align1 > size1)
64                 align1 = 0;
65               if (align2 > size2)
66                 align2 = 0;
67             }
68           else
69             {
70               align1 = random () & 63;
71               align2 = random () & 63;
72               len = random () % size;
73               if (align1 + len > size1)
74                 align1 = size1 - len;
75               if (align2 + len > size2)
76                 align2 = size2 - len;
77             }
78         }
79       p1 = buf1 + page_size - size1;
80       p2 = buf2 + page_size - size2;
81       c = random () & 255;
82       j = align1 + len + 256;
83       if (j > size1)
84         j = size1;
85       for (i = 0; i < j; ++i)
86         p1[i] = random () & 255;
87 
88       FOR_EACH_IMPL (impl, 1)
89       {
90         j = align2 + len + 256;
91         if (j > size2)
92           j = size2;
93         memset (p2, c, j);
94         res = (unsigned char *)CALL (impl, (char *)(p2 + align2),
95                                      (char *)(p1 + align1), len);
96         if (res != MEMCPY_RESULT (p2 + align2, len))
97           {
98             error (0, 0,
99                    "Iteration %zd - wrong result in function %s (%zd, %zd, "
100                    "%zd) %p != %p",
101                    n, impl->name, align1, align2, len, res,
102                    MEMCPY_RESULT (p2 + align2, len));
103             ret = 1;
104           }
105         for (i = 0; i < align2; ++i)
106           {
107             if (p2[i] != c)
108               {
109                 error (0, 0,
110                        "Iteration %zd - garbage before, %s (%zd, %zd, %zd)", n,
111                        impl->name, align1, align2, len);
112                 ret = 1;
113                 break;
114               }
115           }
116         for (i = align2 + len; i < j; ++i)
117           {
118             if (p2[i] != c)
119               {
120                 error (0, 0,
121                        "Iteration %zd - garbage after, %s (%zd, %zd, %zd)", n,
122                        impl->name, align1, align2, len);
123                 ret = 1;
124                 break;
125               }
126           }
127         if (memcmp (p1 + align1, p2 + align2, len))
128           {
129             error (0, 0,
130                    "Iteration %zd - different strings, %s (%zd, %zd, %zd)", n,
131                    impl->name, align1, align2, len);
132             ret = 1;
133           }
134       }
135     }
136 }
137 
138 int
test_main(void)139 test_main (void)
140 {
141   size_t i, j;
142 
143   test_init ();
144 
145   printf ("%23s", "");
146   FOR_EACH_IMPL (impl, 0)
147   printf ("\t%s", impl->name);
148   putchar ('\n');
149 
150   for (i = 0; i < 18; ++i)
151     {
152       do_test (0, 0, 1 << i);
153       do_test (i, 0, 1 << i);
154       do_test (0, i, 1 << i);
155       do_test (i, i, 1 << i);
156     }
157   for (i = 0; i < 32; ++i)
158     {
159       do_test (0, 0, i);
160       do_test (i, 0, i);
161       do_test (0, i, i);
162       do_test (i, i, i);
163     }
164 
165   for (i = 3; i < 32; ++i)
166     {
167       if ((i & (i - 1)) == 0)
168         continue;
169       do_test (0, 0, 16 * i);
170       do_test (i, 0, 16 * i);
171       do_test (0, i, 16 * i);
172       do_test (i, i, 16 * i);
173     }
174 
175   for (i = 19; i <= 25; ++i)
176     {
177       do_test (255, 0, 1 << i);
178       do_test (0, 4000, 1 << i);
179       do_test (0, 255, i);
180       do_test (0, 4000, i);
181     }
182 
183   do_test (0, 0, getpagesize ());
184   do_random_tests ();
185 
186   do_test1 (0, 0, 0x100000);
187   do_test1 (0, 0, 0x2000000);
188 
189   for (i = 4096; i < 32768; i += 4096)
190     {
191       for (j = 1; j <= 1024; j <<= 1)
192         {
193           do_test1 (0, j, i);
194           do_test1 (4095, j, i);
195           do_test1 (4096 - j, 0, i);
196 
197           do_test1 (0, j - 1, i);
198           do_test1 (4095, j - 1, i);
199           do_test1 (4096 - j - 1, 0, i);
200 
201           do_test1 (0, j + 1, i);
202           do_test1 (4095, j + 1, i);
203           do_test1 (4096 - j, 1, i);
204         }
205     }
206 
207   for (i = 0x300000; i < 0x2000000; i += 0x235689)
208     {
209       for (j = 64; j <= 1024; j <<= 1)
210         {
211           do_test1 (0, j, i);
212           do_test1 (4095, j, i);
213           do_test1 (4096 - j, 0, i);
214 
215           do_test1 (0, j - 1, i);
216           do_test1 (4095, j - 1, i);
217           do_test1 (4096 - j - 1, 0, i);
218 
219           do_test1 (0, j + 1, i);
220           do_test1 (4095, j + 1, i);
221           do_test1 (4096 - j, 1, i);
222         }
223     }
224 
225   return ret;
226 }
227 
228 #include <support/test-driver.c>
229