6 #ifdef HAVE_GETTIMEOFDAY
16 #ifdef HAVE_SYS_MMAN_H
29 /*----------------------------------------------------------------------------*\
30 * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
32 * This program generates the CRC-32 values for the files named in the
33 * command-line arguments. These are the same CRC-32 values used by GZIP,
34 * PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and
37 * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
39 * Based on the byte-oriented implementation "File Verification Using CRC"
40 * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
42 * v1.0.0: original release.
43 * v1.0.1: fixed printf formats.
44 * v1.0.2: fixed something else.
45 * v1.0.3: replaced CRC constant table by generator function.
46 * v1.0.4: reformatted code, made ANSI C. 1994-12-05.
47 * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
48 \*----------------------------------------------------------------------------*/
50 /*----------------------------------------------------------------------------*\
52 * Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
54 * Computes or accumulates the CRC-32 value for a memory buffer.
55 * The 'inCrc32' gives a previously accumulated CRC-32 value to allow
56 * a CRC to be generated for multiple sequential buffer-fuls of data.
57 * The 'inCrc32' for the first buffer must be zero.
59 * inCrc32 - accumulated CRC-32 value, must be 0 on first call
60 * buf - buffer to compute CRC-32 value for
61 * bufLen - number of bytes in buffer
63 * crc32 - computed CRC-32 value
65 * (no errors are possible)
66 \*----------------------------------------------------------------------------*/
69 compute_crc32 (uint32_t in_crc32,
73 static const uint32_t crc_table[256] = {
74 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
75 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
76 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
77 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
78 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
79 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
80 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
81 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
82 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
83 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
84 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
85 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
86 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
87 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
88 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
89 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
90 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
91 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
92 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
93 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
94 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
95 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
96 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
97 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
98 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
99 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
100 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
101 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
102 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
103 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
104 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
105 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
106 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
107 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
108 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
109 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
110 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
111 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
112 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
113 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
114 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
115 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
116 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
120 unsigned char * byte_buf;
123 /* accumulate crc32 for buffer */
124 crc32 = in_crc32 ^ 0xFFFFFFFF;
125 byte_buf = (unsigned char*) buf;
127 for (i = 0; i < buf_len; i++)
128 crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
130 return (crc32 ^ 0xFFFFFFFF);
134 is_little_endian (void)
136 volatile uint16_t endian_check_var = 0x1234;
138 return (*(volatile uint8_t *)&endian_check_var == 0x34);
141 /* perform endian conversion of pixel data
144 image_endian_swap (pixman_image_t *img)
146 int stride = pixman_image_get_stride (img);
147 uint32_t *data = pixman_image_get_data (img);
148 int height = pixman_image_get_height (img);
149 int bpp = PIXMAN_FORMAT_BPP (pixman_image_get_format (img));
152 /* swap bytes only on big endian systems */
153 if (is_little_endian())
159 for (i = 0; i < height; i++)
161 uint8_t *line_data = (uint8_t *)data + stride * i;
166 for (j = 0; j < stride; j++)
169 ((line_data[j] & 0x80) >> 7) |
170 ((line_data[j] & 0x40) >> 5) |
171 ((line_data[j] & 0x20) >> 3) |
172 ((line_data[j] & 0x10) >> 1) |
173 ((line_data[j] & 0x08) << 1) |
174 ((line_data[j] & 0x04) << 3) |
175 ((line_data[j] & 0x02) << 5) |
176 ((line_data[j] & 0x01) << 7);
180 for (j = 0; j < stride; j++)
182 line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
186 for (j = 0; j + 2 <= stride; j += 2)
188 char t1 = line_data[j + 0];
189 char t2 = line_data[j + 1];
191 line_data[j + 1] = t1;
192 line_data[j + 0] = t2;
196 for (j = 0; j + 3 <= stride; j += 3)
198 char t1 = line_data[j + 0];
199 char t2 = line_data[j + 1];
200 char t3 = line_data[j + 2];
202 line_data[j + 2] = t1;
203 line_data[j + 1] = t2;
204 line_data[j + 0] = t3;
208 for (j = 0; j + 4 <= stride; j += 4)
210 char t1 = line_data[j + 0];
211 char t2 = line_data[j + 1];
212 char t3 = line_data[j + 2];
213 char t4 = line_data[j + 3];
215 line_data[j + 3] = t1;
216 line_data[j + 2] = t2;
217 line_data[j + 1] = t3;
218 line_data[j + 0] = t4;
228 #define N_LEADING_PROTECTED 10
229 #define N_TRAILING_PROTECTED 10
239 #if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP)
241 /* This is apparently necessary on at least OS X */
242 #ifndef MAP_ANONYMOUS
243 #define MAP_ANONYMOUS MAP_ANON
247 fence_malloc (int64_t len)
249 unsigned long page_size = getpagesize();
250 unsigned long page_mask = page_size - 1;
251 uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
253 (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
254 n_payload_bytes) & ~page_mask;
255 uint8_t *initial_page;
256 uint8_t *leading_protected;
257 uint8_t *trailing_protected;
264 addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
267 if (addr == MAP_FAILED)
269 printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
273 initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask);
274 leading_protected = initial_page + page_size;
275 payload = leading_protected + N_LEADING_PROTECTED * page_size;
276 trailing_protected = payload + n_payload_bytes;
278 ((info_t *)initial_page)->addr = addr;
279 ((info_t *)initial_page)->len = len;
280 ((info_t *)initial_page)->trailing = trailing_protected;
281 ((info_t *)initial_page)->n_bytes = n_bytes;
283 if ((mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
285 (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
288 munmap (addr, n_bytes);
296 fence_free (void *data)
298 uint32_t page_size = getpagesize();
299 uint8_t *payload = data;
300 uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
301 uint8_t *initial_page = leading_protected - page_size;
302 info_t *info = (info_t *)initial_page;
304 munmap (info->addr, info->n_bytes);
310 fence_malloc (int64_t len)
316 fence_free (void *data)
324 make_random_bytes (int n_bytes)
326 uint8_t *bytes = fence_malloc (n_bytes);
332 for (i = 0; i < n_bytes; ++i)
333 bytes[i] = lcg_rand () & 0xff;
339 * A function, which can be used as a core part of the test programs,
340 * intended to detect various problems with the help of fuzzing input
341 * to pixman API (according to some templates, aka "smart" fuzzing).
342 * Some general information about such testing can be found here:
343 * http://en.wikipedia.org/wiki/Fuzz_testing
345 * It may help detecting:
346 * - crashes on bad handling of valid or reasonably invalid input to
348 * - deviations from the behavior of older pixman releases.
349 * - deviations from the behavior of the same pixman release, but
350 * configured in a different way (for example with SIMD optimizations
351 * disabled), or running on a different OS or hardware.
353 * The test is performed by calling a callback function a huge number
354 * of times. The callback function is expected to run some snippet of
355 * pixman code with pseudorandom variations to the data feeded to
356 * pixman API. A result of running each callback function should be
357 * some deterministic value which depends on test number (test number
358 * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
359 * callback function is expected to print to stdout some information
360 * about what it does.
362 * Return values from many small tests are accumulated together and
363 * used as final checksum, which can be compared to some expected
364 * value. Running the tests not individually, but in a batch helps
365 * to reduce process start overhead and also allows to parallelize
366 * testing and utilize multiple CPU cores.
368 * The resulting executable can be run without any arguments. In
369 * this case it runs a batch of tests starting from 1 and up to
370 * 'default_number_of_iterations'. The resulting checksum is
371 * compared with 'expected_checksum' and FAIL or PASS verdict
372 * depends on the result of this comparison.
374 * If the executable is run with 2 numbers provided as command line
375 * arguments, they specify the starting and ending numbers for a test
378 * If the executable is run with only one number provided as a command
379 * line argument, then this number is used to call the callback function
380 * once, and also with verbose flag set.
383 fuzzer_test_main (const char *test_name,
384 int default_number_of_iterations,
385 uint32_t expected_checksum,
386 uint32_t (*test_function)(int testnum, int verbose),
390 int i, n1 = 1, n2 = 0;
391 uint32_t checksum = 0;
392 int verbose = getenv ("VERBOSE") != NULL;
400 printf ("invalid test range\n");
407 checksum = test_function (n2, 1);
408 printf ("%d: checksum=%08X\n", n2, checksum);
414 n2 = default_number_of_iterations;
418 #pragma omp parallel for reduction(+:checksum) default(none) \
419 shared(n1, n2, test_function, verbose)
421 for (i = n1; i <= n2; i++)
423 uint32_t crc = test_function (i, 0);
425 printf ("%d: %08X\n", i, crc);
429 if (n1 == 1 && n2 == default_number_of_iterations)
431 if (checksum == expected_checksum)
433 printf ("%s test passed (checksum=%08X)\n",
434 test_name, checksum);
438 printf ("%s test failed! (checksum=%08X, expected %08X)\n",
439 test_name, checksum, expected_checksum);
445 printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
451 /* Try to obtain current time in seconds */
455 #ifdef HAVE_GETTIMEOFDAY
458 gettimeofday (&tv, NULL);
459 return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
461 return (double)clock() / (double)CLOCKS_PER_SEC;
466 get_random_seed (void)
468 double d = gettime();
470 lcg_srand (*(uint32_t *)&d);
472 return lcg_rand_u32 ();
475 static const char *global_msg;
480 printf ("%s\n", global_msg);
485 fail_after (int seconds, const char *msg)
487 #ifdef HAVE_SIGACTION
489 struct sigaction action;
493 memset (&action, 0, sizeof (action));
494 action.sa_handler = on_alarm;
498 sigaction (SIGALRM, &action, NULL);
504 enable_fp_exceptions (void)
507 #ifdef HAVE_FEENABLEEXCEPT
508 /* Note: we don't enable the FE_INEXACT trap because
509 * that happens quite commonly. It is possible that
510 * over- and underflow should similarly be considered
511 * okay, but for now the test suite passes with them
512 * enabled, and it's useful to know if they start
515 feenableexcept (FE_DIVBYZERO |
524 aligned_malloc (size_t align, size_t size)
528 #ifdef HAVE_POSIX_MEMALIGN
529 if (posix_memalign (&result, align, size) != 0)
532 result = malloc (size);
538 #define CONVERT_15(c, is_rgb) \
540 ((((c) >> 3) & 0x001f) | \
541 (((c) >> 6) & 0x03e0) | \
542 (((c) >> 9) & 0x7c00)) : \
543 (((((c) >> 16) & 0xff) * 153 + \
544 (((c) >> 8) & 0xff) * 301 + \
545 (((c) ) & 0xff) * 58) >> 2))
548 initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
551 uint32_t mask = (1 << depth) - 1;
553 for (i = 0; i < 32768; ++i)
554 palette->ent[i] = lcg_rand() & mask;
556 memset (palette->rgba, 0, sizeof (palette->rgba));
558 for (i = 0; i < mask + 1; ++i)
564 /* We filled the rgb->index map with random numbers, but we
565 * do need the ability to round trip, that is if some indexed
566 * color expands to an argb24, then the 15 bit version of that
567 * color must map back to the index. Anything else, we don't
568 * care about too much.
575 i15 = CONVERT_15 (rgba24, is_rgb);
577 old_idx = palette->ent[i15];
578 if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
584 palette->rgba[i] = rgba24;
585 palette->ent[i15] = i;
588 for (i = 0; i < mask + 1; ++i)
590 assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);