test-strncmp.c 24 KB

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