1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include <assert.h>
6 #include "pixman-private.h" /* For 'inline' definition */
7 #include "utils-prng.h"
8
9 #if defined(_MSC_VER)
10 #define snprintf _snprintf
11 #define strcasecmp _stricmp
12 #endif
13
14 #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
15
16 /* A primitive pseudorandom number generator,
17 * taken from POSIX.1-2001 example
18 */
19
20 extern prng_t prng_state_data;
21 extern prng_t *prng_state;
22 #ifdef USE_OPENMP
23 #pragma omp threadprivate(prng_state_data)
24 #pragma omp threadprivate(prng_state)
25 #endif
26
27 static inline uint32_t
prng_rand(void)28 prng_rand (void)
29 {
30 return prng_rand_r (prng_state);
31 }
32
33 static inline void
prng_srand(uint32_t seed)34 prng_srand (uint32_t seed)
35 {
36 if (!prng_state)
37 {
38 /* Without setting a seed, PRNG does not work properly (is just
39 * returning zeros). So we only initialize the pointer here to
40 * make sure that 'prng_srand' is always called before any
41 * other 'prng_*' function. The wrongdoers violating this order
42 * will get a segfault. */
43 prng_state = &prng_state_data;
44 }
45 prng_srand_r (prng_state, seed);
46 }
47
48 static inline uint32_t
prng_rand_n(int max)49 prng_rand_n (int max)
50 {
51 return prng_rand () % max;
52 }
53
54 static inline void
prng_randmemset(void * buffer,size_t size,prng_randmemset_flags_t flags)55 prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
56 {
57 prng_randmemset_r (prng_state, buffer, size, flags);
58 }
59
60 /* CRC 32 computation
61 */
62 uint32_t
63 compute_crc32 (uint32_t in_crc32,
64 const void *buf,
65 size_t buf_len);
66
67 uint32_t
68 compute_crc32_for_image (uint32_t in_crc32,
69 pixman_image_t *image);
70
71 /* Print the image in hexadecimal */
72 void
73 print_image (pixman_image_t *image);
74
75 /* Returns TRUE if running on a little endian system
76 */
77 static force_inline pixman_bool_t
is_little_endian(void)78 is_little_endian (void)
79 {
80 unsigned long endian_check_var = 1;
81 return *(unsigned char *)&endian_check_var == 1;
82 }
83
84 /* perform endian conversion of pixel data
85 */
86 void
87 image_endian_swap (pixman_image_t *img);
88
89 #if defined (HAVE_MPROTECT) && defined (HAVE_GETPAGESIZE) && \
90 defined (HAVE_SYS_MMAN_H) && defined (HAVE_MMAP)
91 /* fence_malloc and friends have working fence implementation.
92 * Without this, fence_malloc still allocs but does not catch
93 * out-of-bounds accesses.
94 */
95 #define FENCE_MALLOC_ACTIVE 1
96 #else
97 #define FENCE_MALLOC_ACTIVE 0
98 #endif
99
100 /* Allocate memory that is bounded by protected pages,
101 * so that out-of-bounds access will cause segfaults
102 */
103 void *
104 fence_malloc (int64_t len);
105
106 void
107 fence_free (void *data);
108
109 pixman_image_t *
110 fence_image_create_bits (pixman_format_code_t format,
111 int min_width,
112 int height,
113 pixman_bool_t stride_fence);
114
115 /* Return the page size if FENCE_MALLOC_ACTIVE, or zero otherwise */
116 unsigned long
117 fence_get_page_size ();
118
119 /* Generate n_bytes random bytes in fence_malloced memory */
120 uint8_t *
121 make_random_bytes (int n_bytes);
122 float *
123 make_random_floats (int n_bytes);
124
125 /* Return current time in seconds */
126 double
127 gettime (void);
128
129 uint32_t
130 get_random_seed (void);
131
132 /* main body of the fuzzer test */
133 int
134 fuzzer_test_main (const char *test_name,
135 int default_number_of_iterations,
136 uint32_t expected_checksum,
137 uint32_t (*test_function)(int testnum, int verbose),
138 int argc,
139 const char *argv[]);
140
141 void
142 fail_after (int seconds, const char *msg);
143
144 /* If possible, enable traps for floating point exceptions */
145 void enable_divbyzero_exceptions(void);
146 void enable_invalid_exceptions(void);
147
148 /* Converts a8r8g8b8 pixels to pixels that
149 * - are not premultiplied,
150 * - are stored in this order in memory: R, G, B, A, regardless of
151 * the endianness of the computer.
152 * It is allowed for @src and @dst to point to the same memory buffer.
153 */
154 void
155 a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels);
156
157 pixman_bool_t
158 write_png (pixman_image_t *image, const char *filename);
159
160 void
161 draw_checkerboard (pixman_image_t *image,
162 int check_size,
163 uint32_t color1, uint32_t color2);
164
165 /* A pair of macros which can help to detect corruption of
166 * floating point registers after a function call. This may
167 * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
168 * path code, or ARM NEON assembly optimized function forgets
169 * to save/restore d8-d15 registers before use.
170 */
171
172 #define FLOAT_REGS_CORRUPTION_DETECTOR_START() \
173 static volatile double frcd_volatile_constant1 = 123451; \
174 static volatile double frcd_volatile_constant2 = 123452; \
175 static volatile double frcd_volatile_constant3 = 123453; \
176 static volatile double frcd_volatile_constant4 = 123454; \
177 static volatile double frcd_volatile_constant5 = 123455; \
178 static volatile double frcd_volatile_constant6 = 123456; \
179 static volatile double frcd_volatile_constant7 = 123457; \
180 static volatile double frcd_volatile_constant8 = 123458; \
181 double frcd_canary_variable1 = frcd_volatile_constant1; \
182 double frcd_canary_variable2 = frcd_volatile_constant2; \
183 double frcd_canary_variable3 = frcd_volatile_constant3; \
184 double frcd_canary_variable4 = frcd_volatile_constant4; \
185 double frcd_canary_variable5 = frcd_volatile_constant5; \
186 double frcd_canary_variable6 = frcd_volatile_constant6; \
187 double frcd_canary_variable7 = frcd_volatile_constant7; \
188 double frcd_canary_variable8 = frcd_volatile_constant8;
189
190 #define FLOAT_REGS_CORRUPTION_DETECTOR_FINISH() \
191 assert (frcd_canary_variable1 == frcd_volatile_constant1); \
192 assert (frcd_canary_variable2 == frcd_volatile_constant2); \
193 assert (frcd_canary_variable3 == frcd_volatile_constant3); \
194 assert (frcd_canary_variable4 == frcd_volatile_constant4); \
195 assert (frcd_canary_variable5 == frcd_volatile_constant5); \
196 assert (frcd_canary_variable6 == frcd_volatile_constant6); \
197 assert (frcd_canary_variable7 == frcd_volatile_constant7); \
198 assert (frcd_canary_variable8 == frcd_volatile_constant8);
199
200 /* Try to get an aligned memory chunk */
201 void *
202 aligned_malloc (size_t align, size_t size);
203
204 double
205 convert_srgb_to_linear (double component);
206
207 double
208 convert_linear_to_srgb (double component);
209
210 void
211 initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
212
213 pixman_format_code_t
214 format_from_string (const char *s);
215
216 void
217 list_formats (void);
218
219 void
220 list_operators (void);
221
222 void list_dithers (void);
223
224 pixman_op_t
225 operator_from_string (const char *s);
226
227 pixman_dither_t
228 dither_from_string (const char *s);
229
230 const char *
231 operator_name (pixman_op_t op);
232
233 const char *
234 format_name (pixman_format_code_t format);
235
236 const char *
237 dither_name (pixman_dither_t dither);
238
239 typedef struct
240 {
241 double r, g, b, a;
242 } color_t;
243
244 void
245 do_composite (pixman_op_t op,
246 const color_t *src,
247 const color_t *mask,
248 const color_t *dst,
249 color_t *result,
250 pixman_bool_t component_alpha);
251
252 void
253 round_color (pixman_format_code_t format, color_t *color);
254
255 typedef struct
256 {
257 pixman_format_code_t format;
258 uint32_t am, rm, gm, bm;
259 uint32_t as, rs, gs, bs;
260 uint32_t aw, rw, gw, bw;
261 float ad, rd, gd, bd;
262 } pixel_checker_t;
263
264 void
265 pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format);
266
267 void
268 pixel_checker_allow_dither (pixel_checker_t *checker);
269
270 void
271 pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel,
272 int *a, int *r, int *g, int *b);
273
274 void
275 pixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
276 int *a, int *r, int *g, int *b);
277
278 void
279 pixel_checker_get_min (const pixel_checker_t *checker, color_t *color,
280 int *a, int *r, int *g, int *b);
281
282 pixman_bool_t
283 pixel_checker_check (const pixel_checker_t *checker,
284 uint32_t pixel, color_t *color);
285
286 void
287 pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker,
288 uint32_t pixel, color_t *color);
289
290 void
291 pixel_checker_get_masks (const pixel_checker_t *checker,
292 uint32_t *am,
293 uint32_t *rm,
294 uint32_t *gm,
295 uint32_t *bm);
296