17 /*----------------------------------------------------------------------------*\
18 * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
20 * This program generates the CRC-32 values for the files named in the
21 * command-line arguments. These are the same CRC-32 values used by GZIP,
22 * PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and
25 * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
27 * Based on the byte-oriented implementation "File Verification Using CRC"
28 * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
30 * v1.0.0: original release.
31 * v1.0.1: fixed printf formats.
32 * v1.0.2: fixed something else.
33 * v1.0.3: replaced CRC constant table by generator function.
34 * v1.0.4: reformatted code, made ANSI C. 1994-12-05.
35 * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
36 \*----------------------------------------------------------------------------*/
38 /*----------------------------------------------------------------------------*\
40 * Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
42 * Computes or accumulates the CRC-32 value for a memory buffer.
43 * The 'inCrc32' gives a previously accumulated CRC-32 value to allow
44 * a CRC to be generated for multiple sequential buffer-fuls of data.
45 * The 'inCrc32' for the first buffer must be zero.
47 * inCrc32 - accumulated CRC-32 value, must be 0 on first call
48 * buf - buffer to compute CRC-32 value for
49 * bufLen - number of bytes in buffer
51 * crc32 - computed CRC-32 value
53 * (no errors are possible)
54 \*----------------------------------------------------------------------------*/
57 compute_crc32 (uint32_t in_crc32,
61 static const uint32_t crc_table[256] = {
62 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
63 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
64 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
65 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
66 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
67 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
68 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
69 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
70 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
71 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
72 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
73 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
74 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
75 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
76 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
77 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
78 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
79 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
80 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
81 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
82 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
83 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
84 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
85 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
86 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
87 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
88 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
89 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
90 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
91 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
92 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
93 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
94 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
95 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
96 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
97 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
98 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
99 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
100 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
101 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
102 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
103 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
104 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
108 unsigned char * byte_buf;
111 /* accumulate crc32 for buffer */
112 crc32 = in_crc32 ^ 0xFFFFFFFF;
113 byte_buf = (unsigned char*) buf;
115 for (i = 0; i < buf_len; i++)
116 crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
118 return (crc32 ^ 0xFFFFFFFF);
121 /* perform endian conversion of pixel data
124 image_endian_swap (pixman_image_t *img, int bpp)
126 int stride = pixman_image_get_stride (img);
127 uint32_t *data = pixman_image_get_data (img);
128 int height = pixman_image_get_height (img);
131 /* swap bytes only on big endian systems */
132 volatile uint16_t endian_check_var = 0x1234;
133 if (*(volatile uint8_t *)&endian_check_var != 0x12)
136 for (i = 0; i < height; i++)
138 uint8_t *line_data = (uint8_t *)data + stride * i;
139 /* swap bytes only for 16, 24 and 32 bpp for now */
143 for (j = 0; j < stride; j++)
146 ((line_data[j] & 0x80) >> 7) |
147 ((line_data[j] & 0x40) >> 5) |
148 ((line_data[j] & 0x20) >> 3) |
149 ((line_data[j] & 0x10) >> 1) |
150 ((line_data[j] & 0x08) << 1) |
151 ((line_data[j] & 0x04) << 3) |
152 ((line_data[j] & 0x02) << 5) |
153 ((line_data[j] & 0x01) << 7);
157 for (j = 0; j < stride; j++)
159 line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
163 for (j = 0; j + 2 <= stride; j += 2)
165 char t1 = line_data[j + 0];
166 char t2 = line_data[j + 1];
168 line_data[j + 1] = t1;
169 line_data[j + 0] = t2;
173 for (j = 0; j + 3 <= stride; j += 3)
175 char t1 = line_data[j + 0];
176 char t2 = line_data[j + 1];
177 char t3 = line_data[j + 2];
179 line_data[j + 2] = t1;
180 line_data[j + 1] = t2;
181 line_data[j + 0] = t3;
185 for (j = 0; j + 4 <= stride; j += 4)
187 char t1 = line_data[j + 0];
188 char t2 = line_data[j + 1];
189 char t3 = line_data[j + 2];
190 char t4 = line_data[j + 3];
192 line_data[j + 3] = t1;
193 line_data[j + 2] = t2;
194 line_data[j + 1] = t3;
195 line_data[j + 0] = t4;
204 #define N_LEADING_PROTECTED 10
205 #define N_TRAILING_PROTECTED 10
215 #if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE)
218 fence_malloc (uint32_t len)
220 unsigned long page_size = getpagesize();
221 unsigned long page_mask = page_size - 1;
222 uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
224 (page_size * (N_LEADING_PROTECTED + N_TRAILING_PROTECTED + 2) +
225 n_payload_bytes) & ~page_mask;
226 uint8_t *initial_page;
227 uint8_t *leading_protected;
228 uint8_t *trailing_protected;
232 addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
235 if (addr == (void *)MAP_FAILED)
237 printf ("mmap failed on %u %u\n", len, n_bytes);
241 initial_page = (uint8_t *)(((unsigned long)addr + page_mask) & ~page_mask);
242 leading_protected = initial_page + page_size;
243 payload = leading_protected + N_LEADING_PROTECTED * page_size;
244 trailing_protected = payload + n_payload_bytes;
246 ((info_t *)initial_page)->addr = addr;
247 ((info_t *)initial_page)->len = len;
248 ((info_t *)initial_page)->trailing = trailing_protected;
249 ((info_t *)initial_page)->n_bytes = n_bytes;
251 if (mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
258 if (mprotect (trailing_protected, N_TRAILING_PROTECTED * page_size,
261 mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
262 PROT_READ | PROT_WRITE);
272 fence_free (void *data)
274 uint32_t page_size = getpagesize();
275 uint8_t *payload = data;
276 uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
277 uint8_t *initial_page = leading_protected - page_size;
278 info_t *info = (info_t *)initial_page;
279 uint8_t *trailing_protected = info->trailing;
281 mprotect (leading_protected, N_LEADING_PROTECTED * page_size,
282 PROT_READ | PROT_WRITE);
284 mprotect (trailing_protected, N_LEADING_PROTECTED * page_size,
285 PROT_READ | PROT_WRITE);
287 munmap (info->addr, info->n_bytes);
293 fence_malloc (uint32_t len)
299 fence_free (void *data)
307 make_random_bytes (int n_bytes)
309 uint8_t *bytes = fence_malloc (n_bytes);
315 for (i = 0; i < n_bytes; ++i)
316 bytes[i] = lcg_rand () & 0xff;
322 * A function, which can be used as a core part of the test programs,
323 * intended to detect various problems with the help of fuzzing input
324 * to pixman API (according to some templates, aka "smart" fuzzing).
325 * Some general information about such testing can be found here:
326 * http://en.wikipedia.org/wiki/Fuzz_testing
328 * It may help detecting:
329 * - crashes on bad handling of valid or reasonably invalid input to
331 * - deviations from the behavior of older pixman releases.
332 * - deviations from the behavior of the same pixman release, but
333 * configured in a different way (for example with SIMD optimizations
334 * disabled), or running on a different OS or hardware.
336 * The test is performed by calling a callback function a huge number
337 * of times. The callback function is expected to run some snippet of
338 * pixman code with pseudorandom variations to the data feeded to
339 * pixman API. A result of running each callback function should be
340 * some deterministic value which depends on test number (test number
341 * can be used as a seed for PRNG). When 'verbose' argument is nonzero,
342 * callback function is expected to print to stdout some information
343 * about what it does.
345 * Return values from many small tests are accumulated together and
346 * used as final checksum, which can be compared to some expected
347 * value. Running the tests not individually, but in a batch helps
348 * to reduce process start overhead and also allows to parallelize
349 * testing and utilize multiple CPU cores.
351 * The resulting executable can be run without any arguments. In
352 * this case it runs a batch of tests starting from 1 and up to
353 * 'default_number_of_iterations'. The resulting checksum is
354 * compared with 'expected_checksum' and FAIL or PASS verdict
355 * depends on the result of this comparison.
357 * If the executable is run with 2 numbers provided as command line
358 * arguments, they specify the starting and ending numbers for a test
361 * If the executable is run with only one number provided as a command
362 * line argument, then this number is used to call the callback function
363 * once, and also with verbose flag set.
366 fuzzer_test_main (const char *test_name,
367 int default_number_of_iterations,
368 uint32_t expected_checksum,
369 uint32_t (*test_function)(int testnum, int verbose),
373 int i, n1 = 1, n2 = 0;
374 uint32_t checksum = 0;
375 int verbose = getenv ("VERBOSE") != NULL;
383 printf ("invalid test range\n");
390 checksum = test_function (n2, 1);
391 printf ("%d: checksum=%08X\n", n2, checksum);
397 n2 = default_number_of_iterations;
401 #pragma omp parallel for reduction(+:checksum) default(none) \
402 shared(n1, n2, test_function, verbose)
404 for (i = n1; i <= n2; i++)
406 uint32_t crc = test_function (i, 0);
408 printf ("%d: %08X\n", i, crc);
412 if (n1 == 1 && n2 == default_number_of_iterations)
414 if (checksum == expected_checksum)
416 printf ("%s test passed (checksum=%08X)\n",
417 test_name, checksum);
421 printf ("%s test failed! (checksum=%08X, expected %08X)\n",
422 test_name, checksum, expected_checksum);
428 printf ("%d-%d: checksum=%08X\n", n1, n2, checksum);
434 static const char *global_msg;
439 printf ("%s\n", global_msg);
444 fail_after (int seconds, const char *msg)
446 #ifdef HAVE_SIGACTION
448 struct sigaction action;
452 memset (&action, 0, sizeof (action));
453 action.sa_handler = on_alarm;
457 sigaction (SIGALRM, &action, NULL);
463 aligned_malloc (size_t align, size_t size)
467 #ifdef HAVE_POSIX_MEMALIGN
468 if (posix_memalign (&result, align, size) != 0)
471 result = malloc (size);