1 /* Test strncmp and wcsncmp 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 #define TEST_LEN (getpagesize () * 3)
20 #define MIN_PAGE_SIZE (TEST_LEN + 2 * getpagesize ())
21
22 #define TEST_MAIN
23 #ifdef WIDE
24 # define TEST_NAME "wcsncmp"
25 #else
26 # define TEST_NAME "strncmp"
27 #endif
28 #define TIMEOUT (5 * 60)
29 #include "test-string.h"
30
31 #ifdef WIDE
32 # include <wchar.h>
33
34 # define L(str) L##str
35 # define STRNCMP wcsncmp
36 # define STRCPY wcscpy
37 # define STRDUP wcsdup
38 # define MEMCPY wmemcpy
39 # define SIMPLE_STRNCMP simple_wcsncmp
40 # define CHAR wchar_t
41 # define UCHAR wchar_t
42 # define CHARBYTES 4
43 # define CHAR__MAX WCHAR_MAX
44 # define CHAR__MIN WCHAR_MIN
45
46 /* Wcsncmp uses signed semantics for comparison, not unsigned.
47 Avoid using substraction since possible overflow */
48 int
simple_wcsncmp(const CHAR * s1,const CHAR * s2,size_t n)49 simple_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n)
50 {
51 wchar_t c1, c2;
52
53 while (n--)
54 {
55 c1 = *s1++;
56 c2 = *s2++;
57 if (c1 == L('\0') || c1 != c2)
58 return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0);
59 }
60 return 0;
61 }
62
63 #else
64 # define L(str) str
65 # define STRNCMP strncmp
66 # define STRCPY strcpy
67 # define STRDUP strdup
68 # define MEMCPY memcpy
69 # define SIMPLE_STRNCMP simple_strncmp
70 # define CHAR char
71 # define UCHAR unsigned char
72 # define CHARBYTES 1
73 # define CHAR__MAX CHAR_MAX
74 # define CHAR__MIN CHAR_MIN
75
76 /* Strncmp uses unsigned semantics for comparison. */
77 int
simple_strncmp(const char * s1,const char * s2,size_t n)78 simple_strncmp (const char *s1, const char *s2, size_t n)
79 {
80 int ret = 0;
81
82 while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0
83 && *s1++);
84 return ret;
85 }
86
87 #endif
88
89 typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
90
91 IMPL (STRNCMP, 1)
92
93
94 static int
check_result(impl_t * impl,const CHAR * s1,const CHAR * s2,size_t n,int exp_result)95 check_result (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n,
96 int exp_result)
97 {
98 int result = CALL (impl, s1, s2, n);
99 if ((exp_result == 0 && result != 0)
100 || (exp_result < 0 && result >= 0)
101 || (exp_result > 0 && result <= 0))
102 {
103 error (0, 0, "Wrong result in function %s %d %d", impl->name,
104 result, exp_result);
105 ret = 1;
106 return -1;
107 }
108
109 return 0;
110 }
111
112 static void
do_one_test(impl_t * impl,const CHAR * s1,const CHAR * s2,size_t n,int exp_result)113 do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n,
114 int exp_result)
115 {
116 if (check_result (impl, s1, s2, n, exp_result) < 0)
117 return;
118 }
119
120 static void
do_test_limit(size_t align1,size_t align2,size_t len,size_t n,int max_char,int exp_result)121 do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
122 int exp_result)
123 {
124 size_t i, align_n;
125 CHAR *s1, *s2;
126
127 align1 &= ~(CHARBYTES - 1);
128 align2 &= ~(CHARBYTES - 1);
129
130 if (n == 0)
131 {
132 s1 = (CHAR *) (buf1 + page_size);
133 s2 = (CHAR *) (buf2 + page_size);
134
135 FOR_EACH_IMPL (impl, 0)
136 do_one_test (impl, s1, s2, n, 0);
137
138 return;
139 }
140
141 align1 &= 15;
142 align2 &= 15;
143 align_n = (page_size - n * CHARBYTES) & 15;
144
145 s1 = (CHAR *) (buf1 + page_size - n * CHARBYTES);
146 s2 = (CHAR *) (buf2 + page_size - n * CHARBYTES);
147
148 if (align1 < align_n)
149 s1 = (CHAR *) ((char *) s1 - (align_n - align1));
150
151 if (align2 < align_n)
152 s2 = (CHAR *) ((char *) s2 - (align_n - align2));
153
154 for (i = 0; i < n; i++)
155 s1[i] = s2[i] = 1 + 23 * i % max_char;
156
157 if (len < n)
158 {
159 s1[len] = 0;
160 s2[len] = 0;
161 if (exp_result < 0)
162 s2[len] = 32;
163 else if (exp_result > 0)
164 s1[len] = 64;
165 }
166
167 FOR_EACH_IMPL (impl, 0)
168 do_one_test (impl, s1, s2, n, exp_result);
169 }
170
171 static void
do_test_n(size_t align1,size_t align2,size_t len,size_t n,int n_in_bounds,int max_char,int exp_result)172 do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds,
173 int max_char, int exp_result)
174 {
175 size_t i, buf_bound;
176 CHAR *s1, *s2, *s1_end, *s2_end;
177
178 align1 &= ~(CHARBYTES - 1);
179 align2 &= ~(CHARBYTES - 1);
180
181 if (n == 0)
182 return;
183
184 buf_bound = n_in_bounds ? n : len;
185
186 align1 &= getpagesize () - 1;
187 if (align1 + (buf_bound + 2) * CHARBYTES >= page_size)
188 return;
189
190 align2 &= getpagesize () - 1;
191 if (align2 + (buf_bound + 2) * CHARBYTES >= page_size)
192 return;
193
194 s1 = (CHAR *)(buf1 + align1);
195 s2 = (CHAR *)(buf2 + align2);
196
197 if (n_in_bounds)
198 {
199 s1[n] = 24 + exp_result;
200 s2[n] = 23;
201 }
202
203 for (i = 0; i < buf_bound; i++)
204 s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
205
206 s1[len] = 0;
207 s2[len] = 0;
208 if (exp_result < 0)
209 s2[len] = 32;
210 else if (exp_result > 0)
211 s1[len] = 64;
212 if (len >= n)
213 s2[n - 1] -= exp_result;
214
215 /* Ensure that both s1 and s2 are valid null terminated strings. This is
216 * required by the standard. */
217 s1_end = (CHAR *)(buf1 + MIN_PAGE_SIZE - CHARBYTES);
218 s2_end = (CHAR *)(buf2 + MIN_PAGE_SIZE - CHARBYTES);
219 *s1_end = 0;
220 *s2_end = 0;
221
222 FOR_EACH_IMPL (impl, 0)
223 do_one_test (impl, s1, s2, n, exp_result);
224 }
225
226 static void
do_test(size_t align1,size_t align2,size_t len,size_t n,int max_char,int exp_result)227 do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
228 int exp_result)
229 {
230 do_test_n (align1, align2, len, n, 1, max_char, exp_result);
231 }
232
233 static void
do_page_test(size_t offset1,size_t offset2,CHAR * s2)234 do_page_test (size_t offset1, size_t offset2, CHAR *s2)
235 {
236 CHAR *s1;
237 int exp_result;
238
239 if (offset1 * CHARBYTES >= page_size || offset2 * CHARBYTES >= page_size)
240 return;
241
242 s1 = (CHAR *) buf1;
243 s1 += offset1;
244 s2 += offset2;
245
246 exp_result= *s1;
247
248 FOR_EACH_IMPL (impl, 0)
249 {
250 check_result (impl, s1, s2, page_size, -exp_result);
251 check_result (impl, s2, s1, page_size, exp_result);
252 }
253 }
254
255 static void
do_random_tests(void)256 do_random_tests (void)
257 {
258 size_t i, j, n, align1, align2, pos, len1, len2, size;
259 int result;
260 long r;
261 UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES);
262 UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES);
263
264 for (n = 0; n < ITERATIONS; n++)
265 {
266 align1 = random () & 31;
267 if (random () & 1)
268 align2 = random () & 31;
269 else
270 align2 = align1 + (random () & 24);
271 pos = random () & 511;
272 size = random () & 511;
273 j = align1 > align2 ? align1 : align2;
274 if (pos + j >= 511)
275 pos = 510 - j - (random () & 7);
276 len1 = random () & 511;
277 if (pos >= len1 && (random () & 1))
278 len1 = pos + (random () & 7);
279 if (len1 + j >= 512)
280 len1 = 511 - j - (random () & 7);
281 if (pos >= len1)
282 len2 = len1;
283 else
284 len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
285 j = (pos > len2 ? pos : len2) + align1 + 64;
286 if (j > 512)
287 j = 512;
288 for (i = 0; i < j; ++i)
289 {
290 p1[i] = random () & 255;
291 if (i < len1 + align1 && !p1[i])
292 {
293 p1[i] = random () & 255;
294 if (!p1[i])
295 p1[i] = 1 + (random () & 127);
296 }
297 }
298 for (i = 0; i < j; ++i)
299 {
300 p2[i] = random () & 255;
301 if (i < len2 + align2 && !p2[i])
302 {
303 p2[i] = random () & 255;
304 if (!p2[i])
305 p2[i] = 1 + (random () & 127);
306 }
307 }
308
309 result = 0;
310 MEMCPY (p2 + align2, p1 + align1, pos);
311 if (pos < len1)
312 {
313 if (p2[align2 + pos] == p1[align1 + pos])
314 {
315 p2[align2 + pos] = random () & 255;
316 if (p2[align2 + pos] == p1[align1 + pos])
317 p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127);
318 }
319
320 if (pos < size)
321 {
322 if (p1[align1 + pos] < p2[align2 + pos])
323 result = -1;
324 else
325 result = 1;
326 }
327 }
328 p1[len1 + align1] = 0;
329 p2[len2 + align2] = 0;
330
331 FOR_EACH_IMPL (impl, 1)
332 {
333 r = CALL (impl, (CHAR *) (p1 + align1), (CHAR *) (p2 + align2), size);
334 /* Test whether on 64-bit architectures where ABI requires
335 callee to promote has the promotion been done. */
336 asm ("" : "=g" (r) : "0" (r));
337 if ((r == 0 && result)
338 || (r < 0 && result >= 0)
339 || (r > 0 && result <= 0))
340 {
341 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
342 n, impl->name, align1, align2, len1, len2, pos, size, r, result, p1, p2);
343 ret = 1;
344 }
345 }
346 }
347 }
348
349 static void
check1(void)350 check1 (void)
351 {
352 CHAR *s1 = (CHAR *) (buf1 + 0xb2c);
353 CHAR *s2 = (CHAR *) (buf1 + 0xfd8);
354 size_t i, offset;
355 int exp_result;
356
357 STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"));
358 STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"));
359
360 /* Check possible overflow bug for wcsncmp */
361 s1[4] = CHAR__MAX;
362 s2[4] = CHAR__MIN;
363
364 for (offset = 0; offset < 6; offset++)
365 {
366 for (i = 0; i < 80; i++)
367 {
368 exp_result = SIMPLE_STRNCMP (s1 + offset, s2 + offset, i);
369 FOR_EACH_IMPL (impl, 0)
370 check_result (impl, s1 + offset, s2 + offset, i, exp_result);
371 }
372 }
373 }
374
375 static void
check2(void)376 check2 (void)
377 {
378 size_t i;
379 CHAR *s1, *s2;
380
381 s1 = (CHAR *) buf1;
382 for (i = 0; i < (page_size / CHARBYTES) - 1; i++)
383 s1[i] = 23;
384 s1[i] = 0;
385
386 s2 = STRDUP (s1);
387
388 for (i = 0; i < 64; ++i)
389 do_page_test ((3988 / CHARBYTES) + i, (2636 / CHARBYTES), s2);
390
391 free (s2);
392 }
393
394 static void
check3(void)395 check3 (void)
396 {
397 /* To trigger bug 25933, we need a size that is equal to the vector
398 length times 4. In the case of AVX2 for Intel, we need 32 * 4. We
399 make this test generic and run it for all architectures as additional
400 boundary testing for such related algorithms. */
401 size_t size = 32 * 4;
402 CHAR *s1 = (CHAR *) (buf1 + (BUF1PAGES - 1) * page_size);
403 CHAR *s2 = (CHAR *) (buf2 + (BUF1PAGES - 1) * page_size);
404 int exp_result;
405
406 memset (s1, 'a', page_size);
407 memset (s2, 'a', page_size);
408 s1[(page_size / CHARBYTES) - 1] = (CHAR) 0;
409
410 /* Iterate over a size that is just below where we expect the bug to
411 trigger up to the size we expect will trigger the bug e.g. [99-128].
412 Likewise iterate the start of two strings between 30 and 31 bytes
413 away from the boundary to simulate alignment changes. */
414 for (size_t s = 99; s <= size; s++)
415 for (size_t s1a = 30; s1a < 32; s1a++)
416 for (size_t s2a = 30; s2a < 32; s2a++)
417 {
418 CHAR *s1p = s1 + (page_size / CHARBYTES - s) - s1a;
419 CHAR *s2p = s2 + (page_size / CHARBYTES - s) - s2a;
420 exp_result = SIMPLE_STRNCMP (s1p, s2p, s);
421 FOR_EACH_IMPL (impl, 0)
422 check_result (impl, s1p, s2p, s, exp_result);
423 }
424 }
425
426 static void
check4(void)427 check4 (void)
428 {
429 /* To trigger bug 28895; We need 1) both s1 and s2 to be within 32 bytes of
430 the end of the page. 2) For there to be no mismatch/null byte before the
431 first page cross. 3) For length (`n`) to be large enough for one string to
432 cross the page. And 4) for there to be either mismatch/null bytes before
433 the start of the strings. */
434
435 size_t size = 10;
436 size_t addr_mask = (getpagesize () - 1) ^ (sizeof (CHAR) - 1);
437 CHAR *s1 = (CHAR *)(buf1 + (addr_mask & 0xffa));
438 CHAR *s2 = (CHAR *)(buf2 + (addr_mask & 0xfed));
439 int exp_result;
440
441 STRCPY (s1, L ("tst-tlsmod%"));
442 STRCPY (s2, L ("tst-tls-manydynamic73mod"));
443 exp_result = SIMPLE_STRNCMP (s1, s2, size);
444 FOR_EACH_IMPL (impl, 0)
445 check_result (impl, s1, s2, size, exp_result);
446 }
447
448 static void
check5(void)449 check5 (void)
450 {
451 const CHAR *s1 = L ("abc");
452 CHAR *s2 = STRDUP (s1);
453
454 FOR_EACH_IMPL (impl, 0)
455 check_result (impl, s1, s2, SIZE_MAX, 0);
456
457 free (s2);
458 }
459
460 static void
check_overflow(void)461 check_overflow (void)
462 {
463 size_t i, j, of_mask, of_idx;
464 const size_t of_masks[]
465 = { ULONG_MAX, LONG_MIN, ULONG_MAX - (ULONG_MAX >> 2),
466 ((size_t)LONG_MAX) >> 1 };
467 const size_t test_len = MIN(TEST_LEN, 3 * 4096);
468 for (of_idx = 0; of_idx < sizeof (of_masks) / sizeof (of_masks[0]); ++of_idx)
469 {
470 of_mask = of_masks[of_idx];
471 for (j = 0; j < 160; ++j)
472 {
473 for (i = 1; i <= 161; i += (32 / sizeof (CHAR)))
474 {
475 do_test_n (j, 0, i, of_mask, 0, 127, 0);
476 do_test_n (j, 0, i, of_mask, 0, 127, 1);
477 do_test_n (j, 0, i, of_mask, 0, 127, -1);
478
479 do_test_n (j, 0, i, of_mask - j / 2, 0, 127, 0);
480 do_test_n (j, 0, i, of_mask - j * 2, 0, 127, 1);
481 do_test_n (j, 0, i, of_mask - j, 0, 127, -1);
482
483 do_test_n (j / 2, j, i, of_mask, 0, 127, 0);
484 do_test_n (j / 2, j, i, of_mask, 0, 127, 1);
485 do_test_n (j / 2, j, i, of_mask, 0, 127, -1);
486
487 do_test_n (j / 2, j, i, of_mask - j, 0, 127, 0);
488 do_test_n (j / 2, j, i, of_mask - j / 2, 0, 127, 1);
489 do_test_n (j / 2, j, i, of_mask - j * 2, 0, 127, -1);
490
491 do_test_n (0, j, i, of_mask - j * 2, 0, 127, 0);
492 do_test_n (0, j, i, of_mask - j, 0, 127, 1);
493 do_test_n (0, j, i, of_mask - j / 2, 0, 127, -1);
494
495 do_test_n (getpagesize () - j - 1, 0, i, of_mask, 0, 127, 0);
496 do_test_n (getpagesize () - j - 1, 0, i, of_mask, 0, 127, 1);
497 do_test_n (getpagesize () - j - 1, 0, i, of_mask, 0, 127, -1);
498
499 do_test_n (getpagesize () - j - 1, 0, i, of_mask - j / 2, 0, 127,
500 0);
501 do_test_n (getpagesize () - j - 1, 0, i, of_mask - j * 2, 0, 127,
502 1);
503 do_test_n (getpagesize () - j - 1, 0, i, of_mask - j, 0, 127,
504 -1);
505
506 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
507 of_mask, 0, 127, 0);
508 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
509 of_mask, 0, 127, 1);
510 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
511 of_mask, 0, 127, -1);
512
513 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
514 of_mask - j, 0, 127, 0);
515 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
516 of_mask - j / 2, 0, 127, 1);
517 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1, i,
518 of_mask - j * 2, 0, 127, -1);
519 }
520
521 for (i = 1; i < test_len; i += i)
522 {
523 do_test_n (j, 0, i - 1, of_mask, 0, 127, 0);
524 do_test_n (j, 0, i - 1, of_mask, 0, 127, 1);
525 do_test_n (j, 0, i - 1, of_mask, 0, 127, -1);
526
527 do_test_n (j, 0, i - 1, of_mask - j / 2, 0, 127, 0);
528 do_test_n (j, 0, i - 1, of_mask - j * 2, 0, 127, 1);
529 do_test_n (j, 0, i - 1, of_mask - j, 0, 127, -1);
530
531 do_test_n (j / 2, j, i - 1, of_mask, 0, 127, 0);
532 do_test_n (j / 2, j, i - 1, of_mask, 0, 127, 1);
533 do_test_n (j / 2, j, i - 1, of_mask, 0, 127, -1);
534
535 do_test_n (j / 2, j, i - 1, of_mask - j, 0, 127, 0);
536 do_test_n (j / 2, j, i - 1, of_mask - j / 2, 0, 127, 1);
537 do_test_n (j / 2, j, i - 1, of_mask - j * 2, 0, 127, -1);
538
539 do_test_n (0, j, i - 1, of_mask - j * 2, 0, 127, 0);
540 do_test_n (0, j, i - 1, of_mask - j, 0, 127, 1);
541 do_test_n (0, j, i - 1, of_mask - j / 2, 0, 127, -1);
542
543 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask, 0, 127, 0);
544 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask, 0, 127, 1);
545 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask, 0, 127,
546 -1);
547
548 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask - j / 2, 0,
549 127, 0);
550 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask - j * 2, 0,
551 127, 1);
552 do_test_n (getpagesize () - j - 1, 0, i - 1, of_mask - j, 0, 127,
553 -1);
554
555 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
556 i - 1, of_mask, 0, 127, 0);
557 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
558 i - 1, of_mask, 0, 127, 1);
559 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
560 i - 1, of_mask, 0, 127, -1);
561
562 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
563 i - 1, of_mask - j, 0, 127, 0);
564 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
565 i - 1, of_mask - j / 2, 0, 127, 1);
566 do_test_n (getpagesize () - j - 1, getpagesize () - 2 * j - 1,
567 i - 1, of_mask - j * 2, 0, 127, -1);
568 }
569 }
570 }
571 }
572
573 int
test_main(void)574 test_main (void)
575 {
576 size_t i, j, k;
577 const size_t test_len = MIN(TEST_LEN, 3 * 4096);
578 test_init ();
579
580 check1 ();
581 check2 ();
582 check3 ();
583 check4 ();
584 check5 ();
585
586 printf ("%23s", "");
587 FOR_EACH_IMPL (impl, 0)
588 printf ("\t%s", impl->name);
589 putchar ('\n');
590
591 for (i =0; i < 16; ++i)
592 {
593 do_test (0, 0, 8, i, 127, 0);
594 do_test (0, 0, 8, i, 127, -1);
595 do_test (0, 0, 8, i, 127, 1);
596 do_test (i, i, 8, i, 127, 0);
597 do_test (i, i, 8, i, 127, 1);
598 do_test (i, i, 8, i, 127, -1);
599 do_test (i, 2 * i, 8, i, 127, 0);
600 do_test (2 * i, i, 8, i, 127, 1);
601 do_test (i, 3 * i, 8, i, 127, -1);
602 do_test (0, 0, 8, i, 255, 0);
603 do_test (0, 0, 8, i, 255, -1);
604 do_test (0, 0, 8, i, 255, 1);
605 do_test (i, i, 8, i, 255, 0);
606 do_test (i, i, 8, i, 255, 1);
607 do_test (i, i, 8, i, 255, -1);
608 do_test (i, 2 * i, 8, i, 255, 0);
609 do_test (2 * i, i, 8, i, 255, 1);
610 do_test (i, 3 * i, 8, i, 255, -1);
611 }
612
613 for (i = 1; i < 8; ++i)
614 {
615 do_test (0, 0, 8 << i, 16 << i, 127, 0);
616 do_test (0, 0, 8 << i, 16 << i, 127, 1);
617 do_test (0, 0, 8 << i, 16 << i, 127, -1);
618 do_test (0, 0, 8 << i, 16 << i, 255, 0);
619 do_test (0, 0, 8 << i, 16 << i, 255, 1);
620 do_test (0, 0, 8 << i, 16 << i, 255, -1);
621 do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0);
622 do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1);
623 do_test (2 * i, i, 8 << i, 16 << i, 255, 0);
624 do_test (2 * i, i, 8 << i, 16 << i, 255, 1);
625 }
626
627 do_test_limit (0, 0, 0, 0, 127, 0);
628 do_test_limit (4, 0, 21, 20, 127, 0);
629 do_test_limit (0, 4, 21, 20, 127, 0);
630 do_test_limit (8, 0, 25, 24, 127, 0);
631 do_test_limit (0, 8, 25, 24, 127, 0);
632
633 for (i = 0; i < 8; ++i)
634 {
635 do_test_limit (0, 0, 17 - i, 16 - i, 127, 0);
636 do_test_limit (0, 0, 17 - i, 16 - i, 255, 0);
637 do_test_limit (0, 0, 15 - i, 16 - i, 127, 0);
638 do_test_limit (0, 0, 15 - i, 16 - i, 127, 1);
639 do_test_limit (0, 0, 15 - i, 16 - i, 127, -1);
640 do_test_limit (0, 0, 15 - i, 16 - i, 255, 0);
641 do_test_limit (0, 0, 15 - i, 16 - i, 255, 1);
642 do_test_limit (0, 0, 15 - i, 16 - i, 255, -1);
643 }
644
645 for (j = 0; j < 160; ++j)
646 {
647 for (i = 0; i < test_len;)
648 {
649 do_test_n (getpagesize () - j - 1, 0, i, i + 1, 0, 127, 0);
650 do_test_n (getpagesize () - j - 1, 0, i, i + 1, 0, 127, 1);
651 do_test_n (getpagesize () - j - 1, 0, i, i + 1, 0, 127, -1);
652
653 do_test_n (getpagesize () - j - 1, 0, i, i, 0, 127, 0);
654 do_test_n (getpagesize () - j - 1, 0, i, i - 1, 0, 127, 0);
655
656 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX, 0, 127, 0);
657 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX, 0, 127, 1);
658 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX, 0, 127, -1);
659
660 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX - i, 0, 127, 0);
661 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX - i, 0, 127, 1);
662 do_test_n (getpagesize () - j - 1, 0, i, ULONG_MAX - i, 0, 127, -1);
663
664 do_test_n (getpagesize () - j - 1, j, i, i + 1, 0, 127, 0);
665 do_test_n (getpagesize () - j - 1, j, i, i + 1, 0, 127, 1);
666 do_test_n (getpagesize () - j - 1, j, i, i + 1, 0, 127, -1);
667
668 do_test_n (getpagesize () - j - 1, j, i, i, 0, 127, 0);
669 do_test_n (getpagesize () - j - 1, j, i, i - 1, 0, 127, 0);
670
671 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX, 0, 127, 0);
672 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX, 0, 127, 1);
673 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX, 0, 127, -1);
674
675 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX - i, 0, 127, 0);
676 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX - i, 0, 127, 1);
677 do_test_n (getpagesize () - j - 1, j, i, ULONG_MAX - i, 0, 127, -1);
678
679 do_test_n (0, getpagesize () - j - 1, i, i + 1, 0, 127, 0);
680 do_test_n (0, getpagesize () - j - 1, i, i + 1, 0, 127, 1);
681 do_test_n (0, getpagesize () - j - 1, i, i + 1, 0, 127, -1);
682
683 do_test_n (0, getpagesize () - j - 1, i, i, 0, 127, 0);
684 do_test_n (0, getpagesize () - j - 1, i, i - 1, 0, 127, 0);
685
686 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, 0);
687 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, 1);
688 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, -1);
689
690 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, 0);
691 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, 1);
692 do_test_n (0, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, -1);
693
694 do_test_n (j, getpagesize () - j - 1, i, i + 1, 0, 127, 0);
695 do_test_n (j, getpagesize () - j - 1, i, i + 1, 0, 127, 1);
696 do_test_n (j, getpagesize () - j - 1, i, i + 1, 0, 127, -1);
697
698 do_test_n (j, getpagesize () - j - 1, i, i, 0, 127, 0);
699 do_test_n (j, getpagesize () - j - 1, i, i - 1, 0, 127, 0);
700
701 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, 0);
702 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, 1);
703 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX, 0, 127, -1);
704
705 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, 0);
706 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, 1);
707 do_test_n (j, getpagesize () - j - 1, i, ULONG_MAX - i, 0, 127, -1);
708
709 for (k = 2; k <= 128; k += k)
710 {
711 do_test (getpagesize () - k, getpagesize () - j - 1, i - 1, i,
712 127, 0);
713 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i - 1,
714 i, 127, 0);
715 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
716 127, 0);
717 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
718 i, 127, 0);
719 do_test (getpagesize () - k, getpagesize () - j - 1, i, i, 127,
720 0);
721 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i, i,
722 127, 0);
723 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
724 127, -1);
725 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
726 i, 127, -1);
727 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
728 127, 1);
729 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
730 i, 127, 1);
731 }
732
733 if (i < 32)
734 {
735 i += 1;
736 }
737 else if (i < 161)
738 {
739 i += 7;
740 }
741 else if (i + 161 < test_len)
742 {
743 i += 31;
744 i *= 17;
745 i /= 16;
746 if (i + 161 > test_len)
747 {
748 i = test_len - 160;
749 }
750 }
751 else if (i + 32 < test_len)
752 {
753 i += 7;
754 }
755 else
756 {
757 i += 1;
758 }
759 }
760 }
761
762 check_overflow ();
763 do_random_tests ();
764 return ret;
765 }
766
767 #include <support/test-driver.c>
768