DF-5706 / fixed_driver.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | /* * Fix-validation driver: differential vs naive reference on the FIXED * (fix.diff) instrumented copy, plus the zero-overread assertion. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stddef.h> extern unsigned long g_below_start, g_past_end, g_in; extern unsigned long g_max_below, g_max_past, g_filtered, g_outside_granule; void *memcchr_fixed_instr(const void *, int, size_t); #define ASZ (1 << 20) static unsigned char *A; static uint64_t s_state = 0x243f6a8885a308d3ULL; static uint64_t prng(void) { s_state ^= s_state << 13; s_state ^= s_state >> 7; s_state ^= s_state << 17; return s_state; } static void *ref(const unsigned char *b, int c, size_t n) { size_t i; for (i = 0; i < n; i++) if (b[i] != (unsigned char)c) return ((unsigned char *)(uintptr_t)(b + i)); return (NULL); } static long fails, total; static void check(unsigned char *b, int c, size_t n) { void *r = memcchr_fixed_instr(b, c, n); void *e = ref(b, c, n); total++; if (r != e) { if (fails < 10) printf("DIFF FAIL n=%zu c=%#x off=%td got=%p want=%p\n", (size_t)n, c, (ptrdiff_t)(b - A), r, e); fails++; } } int main(void) { int ok = 1; A = malloc(ASZ); if (!A) { perror("malloc"); return 2; } memset(A, 0x5a, ASZ); { int off, len, mpos, ci; int cs[4] = { 0x00, 0xff, 0x41, 0x80 }; for (off = 0; off < 32; off++) for (len = 0; len <= 96; len++) for (ci = 0; ci < 4; ci++) for (mpos = 0; mpos <= len; mpos++) { unsigned char *b = A + 64 + off; int c = cs[ci]; size_t i; for (i = 0; i < (size_t)len; i++) b[i] = (unsigned char)c; b[-1] = (unsigned char)~c; b[len] = (unsigned char)~c; if (mpos < len) b[mpos] = (unsigned char)~c; check(b, c, (size_t)len); } } { long i; for (i = 0; i < 2000000; i++) { size_t off = (size_t)(prng() & 0xffff); size_t n = (size_t)(prng() % 8193); int c = (int)(prng() & 0xff); size_t j; unsigned char *b = A + 128 + off; if (128 + off + n + 128 > ASZ) n = 0; for (j = 0; j < n; j++) b[j] = (prng() & 4) ? (unsigned char)c : (unsigned char)prng(); check(b, c, n); } } printf("fixed differential: %ld cases, %ld failures\n", total, fails); printf("fixed loads: below-start=%lu past-end=%lu in-range=%lu" " outside-granule=%lu done-filter-rejections=%lu\n", g_below_start, g_past_end, g_in, g_outside_granule, g_filtered); if (fails != 0) ok = 0; if (g_below_start != 0 || g_past_end != 0 || g_outside_granule != 0) ok = 0; printf("RESULT: %s\n", ok ? "FIX-PASS - zero loads outside [begin,begin+n), semantics exact" : "FIX-FAIL"); return ok ? 0 : 1; } |