114b11b2bSmrg#ifdef HAVE_CONFIG_H 214b11b2bSmrg#include <pixman-config.h> 314b11b2bSmrg#endif 414b11b2bSmrg 514b11b2bSmrg#include <assert.h> 614b11b2bSmrg#include "pixman-private.h" /* For 'inline' definition */ 714b11b2bSmrg#include "utils-prng.h" 814b11b2bSmrg 914b11b2bSmrg#if defined(_MSC_VER) 1014b11b2bSmrg#define snprintf _snprintf 1114b11b2bSmrg#define strcasecmp _stricmp 1214b11b2bSmrg#endif 1314b11b2bSmrg 1414b11b2bSmrg#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) 1514b11b2bSmrg 1614b11b2bSmrg/* A primitive pseudorandom number generator, 1714b11b2bSmrg * taken from POSIX.1-2001 example 1814b11b2bSmrg */ 1914b11b2bSmrg 2014b11b2bSmrgextern prng_t prng_state_data; 2114b11b2bSmrgextern prng_t *prng_state; 2214b11b2bSmrg#ifdef USE_OPENMP 2314b11b2bSmrg#pragma omp threadprivate(prng_state_data) 2414b11b2bSmrg#pragma omp threadprivate(prng_state) 2514b11b2bSmrg#endif 2614b11b2bSmrg 2714b11b2bSmrgstatic inline uint32_t 2814b11b2bSmrgprng_rand (void) 2914b11b2bSmrg{ 3014b11b2bSmrg return prng_rand_r (prng_state); 3114b11b2bSmrg} 3214b11b2bSmrg 3314b11b2bSmrgstatic inline void 3414b11b2bSmrgprng_srand (uint32_t seed) 3514b11b2bSmrg{ 3614b11b2bSmrg if (!prng_state) 3714b11b2bSmrg { 3814b11b2bSmrg /* Without setting a seed, PRNG does not work properly (is just 3914b11b2bSmrg * returning zeros). So we only initialize the pointer here to 4014b11b2bSmrg * make sure that 'prng_srand' is always called before any 4114b11b2bSmrg * other 'prng_*' function. The wrongdoers violating this order 4214b11b2bSmrg * will get a segfault. */ 4314b11b2bSmrg prng_state = &prng_state_data; 4414b11b2bSmrg } 4514b11b2bSmrg prng_srand_r (prng_state, seed); 4614b11b2bSmrg} 4714b11b2bSmrg 4814b11b2bSmrgstatic inline uint32_t 4914b11b2bSmrgprng_rand_n (int max) 5014b11b2bSmrg{ 5114b11b2bSmrg return prng_rand () % max; 5214b11b2bSmrg} 5314b11b2bSmrg 5414b11b2bSmrgstatic inline void 5514b11b2bSmrgprng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags) 5614b11b2bSmrg{ 5714b11b2bSmrg prng_randmemset_r (prng_state, buffer, size, flags); 5814b11b2bSmrg} 5914b11b2bSmrg 6014b11b2bSmrg/* CRC 32 computation 6114b11b2bSmrg */ 6214b11b2bSmrguint32_t 6314b11b2bSmrgcompute_crc32 (uint32_t in_crc32, 6414b11b2bSmrg const void *buf, 6514b11b2bSmrg size_t buf_len); 6614b11b2bSmrg 6714b11b2bSmrguint32_t 6814b11b2bSmrgcompute_crc32_for_image (uint32_t in_crc32, 6914b11b2bSmrg pixman_image_t *image); 7014b11b2bSmrg 7114b11b2bSmrg/* Print the image in hexadecimal */ 7214b11b2bSmrgvoid 7314b11b2bSmrgprint_image (pixman_image_t *image); 7414b11b2bSmrg 7514b11b2bSmrg/* Returns TRUE if running on a little endian system 7614b11b2bSmrg */ 7714b11b2bSmrgstatic force_inline pixman_bool_t 7814b11b2bSmrgis_little_endian (void) 7914b11b2bSmrg{ 8014b11b2bSmrg unsigned long endian_check_var = 1; 8114b11b2bSmrg return *(unsigned char *)&endian_check_var == 1; 8214b11b2bSmrg} 8314b11b2bSmrg 8414b11b2bSmrg/* perform endian conversion of pixel data 8514b11b2bSmrg */ 8614b11b2bSmrgvoid 8714b11b2bSmrgimage_endian_swap (pixman_image_t *img); 8814b11b2bSmrg 8914b11b2bSmrg#if defined (HAVE_MPROTECT) && defined (HAVE_GETPAGESIZE) && \ 9014b11b2bSmrg defined (HAVE_SYS_MMAN_H) && defined (HAVE_MMAP) 9114b11b2bSmrg/* fence_malloc and friends have working fence implementation. 9214b11b2bSmrg * Without this, fence_malloc still allocs but does not catch 9314b11b2bSmrg * out-of-bounds accesses. 9414b11b2bSmrg */ 9514b11b2bSmrg#define FENCE_MALLOC_ACTIVE 1 9614b11b2bSmrg#else 9714b11b2bSmrg#define FENCE_MALLOC_ACTIVE 0 9814b11b2bSmrg#endif 9914b11b2bSmrg 10014b11b2bSmrg/* Allocate memory that is bounded by protected pages, 10114b11b2bSmrg * so that out-of-bounds access will cause segfaults 10214b11b2bSmrg */ 10314b11b2bSmrgvoid * 10414b11b2bSmrgfence_malloc (int64_t len); 10514b11b2bSmrg 10614b11b2bSmrgvoid 10714b11b2bSmrgfence_free (void *data); 10814b11b2bSmrg 10914b11b2bSmrgpixman_image_t * 11014b11b2bSmrgfence_image_create_bits (pixman_format_code_t format, 11114b11b2bSmrg int min_width, 11214b11b2bSmrg int height, 11314b11b2bSmrg pixman_bool_t stride_fence); 11414b11b2bSmrg 11514b11b2bSmrg/* Return the page size if FENCE_MALLOC_ACTIVE, or zero otherwise */ 11614b11b2bSmrgunsigned long 11714b11b2bSmrgfence_get_page_size (); 11814b11b2bSmrg 11914b11b2bSmrg/* Generate n_bytes random bytes in fence_malloced memory */ 12014b11b2bSmrguint8_t * 12114b11b2bSmrgmake_random_bytes (int n_bytes); 12214b11b2bSmrgfloat * 12314b11b2bSmrgmake_random_floats (int n_bytes); 12414b11b2bSmrg 12514b11b2bSmrg/* Return current time in seconds */ 12614b11b2bSmrgdouble 12714b11b2bSmrggettime (void); 12814b11b2bSmrg 12914b11b2bSmrguint32_t 13014b11b2bSmrgget_random_seed (void); 13114b11b2bSmrg 13214b11b2bSmrg/* main body of the fuzzer test */ 13314b11b2bSmrgint 13414b11b2bSmrgfuzzer_test_main (const char *test_name, 13514b11b2bSmrg int default_number_of_iterations, 13614b11b2bSmrg uint32_t expected_checksum, 13714b11b2bSmrg uint32_t (*test_function)(int testnum, int verbose), 13814b11b2bSmrg int argc, 13914b11b2bSmrg const char *argv[]); 14014b11b2bSmrg 14114b11b2bSmrgvoid 14214b11b2bSmrgfail_after (int seconds, const char *msg); 14314b11b2bSmrg 14414b11b2bSmrg/* If possible, enable traps for floating point exceptions */ 14514b11b2bSmrgvoid enable_divbyzero_exceptions(void); 14614b11b2bSmrgvoid enable_invalid_exceptions(void); 14714b11b2bSmrg 14814b11b2bSmrg/* Converts a8r8g8b8 pixels to pixels that 14914b11b2bSmrg * - are not premultiplied, 15014b11b2bSmrg * - are stored in this order in memory: R, G, B, A, regardless of 15114b11b2bSmrg * the endianness of the computer. 15214b11b2bSmrg * It is allowed for @src and @dst to point to the same memory buffer. 15314b11b2bSmrg */ 15414b11b2bSmrgvoid 15514b11b2bSmrga8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels); 15614b11b2bSmrg 15714b11b2bSmrgpixman_bool_t 15814b11b2bSmrgwrite_png (pixman_image_t *image, const char *filename); 15914b11b2bSmrg 16014b11b2bSmrgvoid 16114b11b2bSmrgdraw_checkerboard (pixman_image_t *image, 16214b11b2bSmrg int check_size, 16314b11b2bSmrg uint32_t color1, uint32_t color2); 16414b11b2bSmrg 16514b11b2bSmrg/* A pair of macros which can help to detect corruption of 16614b11b2bSmrg * floating point registers after a function call. This may 16714b11b2bSmrg * happen if _mm_empty() call is forgotten in MMX/SSE2 fast 16814b11b2bSmrg * path code, or ARM NEON assembly optimized function forgets 16914b11b2bSmrg * to save/restore d8-d15 registers before use. 17014b11b2bSmrg */ 17114b11b2bSmrg 17214b11b2bSmrg#define FLOAT_REGS_CORRUPTION_DETECTOR_START() \ 17314b11b2bSmrg static volatile double frcd_volatile_constant1 = 123451; \ 17414b11b2bSmrg static volatile double frcd_volatile_constant2 = 123452; \ 17514b11b2bSmrg static volatile double frcd_volatile_constant3 = 123453; \ 17614b11b2bSmrg static volatile double frcd_volatile_constant4 = 123454; \ 17714b11b2bSmrg static volatile double frcd_volatile_constant5 = 123455; \ 17814b11b2bSmrg static volatile double frcd_volatile_constant6 = 123456; \ 17914b11b2bSmrg static volatile double frcd_volatile_constant7 = 123457; \ 18014b11b2bSmrg static volatile double frcd_volatile_constant8 = 123458; \ 18114b11b2bSmrg double frcd_canary_variable1 = frcd_volatile_constant1; \ 18214b11b2bSmrg double frcd_canary_variable2 = frcd_volatile_constant2; \ 18314b11b2bSmrg double frcd_canary_variable3 = frcd_volatile_constant3; \ 18414b11b2bSmrg double frcd_canary_variable4 = frcd_volatile_constant4; \ 18514b11b2bSmrg double frcd_canary_variable5 = frcd_volatile_constant5; \ 18614b11b2bSmrg double frcd_canary_variable6 = frcd_volatile_constant6; \ 18714b11b2bSmrg double frcd_canary_variable7 = frcd_volatile_constant7; \ 18814b11b2bSmrg double frcd_canary_variable8 = frcd_volatile_constant8; 18914b11b2bSmrg 19014b11b2bSmrg#define FLOAT_REGS_CORRUPTION_DETECTOR_FINISH() \ 19114b11b2bSmrg assert (frcd_canary_variable1 == frcd_volatile_constant1); \ 19214b11b2bSmrg assert (frcd_canary_variable2 == frcd_volatile_constant2); \ 19314b11b2bSmrg assert (frcd_canary_variable3 == frcd_volatile_constant3); \ 19414b11b2bSmrg assert (frcd_canary_variable4 == frcd_volatile_constant4); \ 19514b11b2bSmrg assert (frcd_canary_variable5 == frcd_volatile_constant5); \ 19614b11b2bSmrg assert (frcd_canary_variable6 == frcd_volatile_constant6); \ 19714b11b2bSmrg assert (frcd_canary_variable7 == frcd_volatile_constant7); \ 19814b11b2bSmrg assert (frcd_canary_variable8 == frcd_volatile_constant8); 19914b11b2bSmrg 20014b11b2bSmrg/* Try to get an aligned memory chunk */ 20114b11b2bSmrgvoid * 20214b11b2bSmrgaligned_malloc (size_t align, size_t size); 20314b11b2bSmrg 20414b11b2bSmrgdouble 20514b11b2bSmrgconvert_srgb_to_linear (double component); 20614b11b2bSmrg 20714b11b2bSmrgdouble 20814b11b2bSmrgconvert_linear_to_srgb (double component); 20914b11b2bSmrg 21014b11b2bSmrgvoid 21114b11b2bSmrginitialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb); 21214b11b2bSmrg 21314b11b2bSmrgpixman_format_code_t 21414b11b2bSmrgformat_from_string (const char *s); 21514b11b2bSmrg 21614b11b2bSmrgvoid 21714b11b2bSmrglist_formats (void); 21814b11b2bSmrg 21914b11b2bSmrgvoid 22014b11b2bSmrglist_operators (void); 22114b11b2bSmrg 22214b11b2bSmrgvoid list_dithers (void); 22314b11b2bSmrg 22414b11b2bSmrgpixman_op_t 22514b11b2bSmrgoperator_from_string (const char *s); 22614b11b2bSmrg 22714b11b2bSmrgpixman_dither_t 22814b11b2bSmrgdither_from_string (const char *s); 22914b11b2bSmrg 23014b11b2bSmrgconst char * 23114b11b2bSmrgoperator_name (pixman_op_t op); 23214b11b2bSmrg 23314b11b2bSmrgconst char * 23414b11b2bSmrgformat_name (pixman_format_code_t format); 23514b11b2bSmrg 23614b11b2bSmrgconst char * 23714b11b2bSmrgdither_name (pixman_dither_t dither); 23814b11b2bSmrg 23914b11b2bSmrgtypedef struct 24014b11b2bSmrg{ 24114b11b2bSmrg double r, g, b, a; 24214b11b2bSmrg} color_t; 24314b11b2bSmrg 24414b11b2bSmrgvoid 24514b11b2bSmrgdo_composite (pixman_op_t op, 24614b11b2bSmrg const color_t *src, 24714b11b2bSmrg const color_t *mask, 24814b11b2bSmrg const color_t *dst, 24914b11b2bSmrg color_t *result, 25014b11b2bSmrg pixman_bool_t component_alpha); 25114b11b2bSmrg 25214b11b2bSmrgvoid 25314b11b2bSmrground_color (pixman_format_code_t format, color_t *color); 25414b11b2bSmrg 25514b11b2bSmrgtypedef struct 25614b11b2bSmrg{ 25714b11b2bSmrg pixman_format_code_t format; 25814b11b2bSmrg uint32_t am, rm, gm, bm; 25914b11b2bSmrg uint32_t as, rs, gs, bs; 26014b11b2bSmrg uint32_t aw, rw, gw, bw; 26114b11b2bSmrg float ad, rd, gd, bd; 26214b11b2bSmrg} pixel_checker_t; 26314b11b2bSmrg 26414b11b2bSmrgvoid 26514b11b2bSmrgpixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format); 26614b11b2bSmrg 26714b11b2bSmrgvoid 26814b11b2bSmrgpixel_checker_allow_dither (pixel_checker_t *checker); 26914b11b2bSmrg 27014b11b2bSmrgvoid 27114b11b2bSmrgpixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel, 27214b11b2bSmrg int *a, int *r, int *g, int *b); 27314b11b2bSmrg 27414b11b2bSmrgvoid 27514b11b2bSmrgpixel_checker_get_max (const pixel_checker_t *checker, color_t *color, 27614b11b2bSmrg int *a, int *r, int *g, int *b); 27714b11b2bSmrg 27814b11b2bSmrgvoid 27914b11b2bSmrgpixel_checker_get_min (const pixel_checker_t *checker, color_t *color, 28014b11b2bSmrg int *a, int *r, int *g, int *b); 28114b11b2bSmrg 28214b11b2bSmrgpixman_bool_t 28314b11b2bSmrgpixel_checker_check (const pixel_checker_t *checker, 28414b11b2bSmrg uint32_t pixel, color_t *color); 28514b11b2bSmrg 28614b11b2bSmrgvoid 28714b11b2bSmrgpixel_checker_convert_pixel_to_color (const pixel_checker_t *checker, 28814b11b2bSmrg uint32_t pixel, color_t *color); 28914b11b2bSmrg 29014b11b2bSmrgvoid 29114b11b2bSmrgpixel_checker_get_masks (const pixel_checker_t *checker, 29214b11b2bSmrg uint32_t *am, 29314b11b2bSmrg uint32_t *rm, 29414b11b2bSmrg uint32_t *gm, 29514b11b2bSmrg uint32_t *bm); 296