DF-5700 / instr_driver.c
/* * Driver for bcmp_instr.c: measures out-of-region loads of the bcmp.c * algorithm over the exhaustive alignment/length sweep, while verifying the * instrumented copy still agrees with memcmp (instrumentation did not * perturb semantics). Region per buffer = [call_ptr, call_ptr + len). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> int bcmp_instr(const void *, const void *, size_t); extern unsigned long g_below_start[2], g_past_end[2], g_in[2], g_max_below[2], g_max_past[2]; extern const unsigned char *g_lo[2], *g_hi[2]; extern long g_last_outside_case[4]; extern int g_case[3]; #define BUF 256 static unsigned char A[BUF], B[BUF]; static uint64_t s_state = 0xd1b54a32d192ed03ULL; static uint64_t prng(void) { s_state ^= s_state << 13; s_state ^= s_state >> 7; s_state ^= s_state << 17; return s_state; } int main(void) { long mism = 0; for (size_t n = 1; n <= 96; n++) for (int off1 = 0; off1 < 8; off1++) for (int off2 = 0; off2 < 8; off2++) { for (int i = 0; i < BUF; i++) { A[i] = (unsigned char)(i * 7); B[i] = A[i]; } if (n % 3 == 0 && n > 2) B[off2 + n / 2] ^= 1; /* some mismatches */ g_case[0] = off1; g_case[1] = off2; g_case[2] = (int)n; const unsigned char *q1 = A + off1, *q2 = B + off2; g_lo[0] = q1; g_hi[0] = q1 + n; g_lo[1] = q2; g_hi[1] = q2 + n; int r = bcmp_instr(q1, q2, n); if ((r == 0) != (memcmp(q1, q2, n) == 0)) mism++; } /* randomized tail */ for (long it = 0; it < 100000; it++) { int off1 = (int)(prng() % 32), off2 = (int)(prng() % 32); size_t n = (size_t)(prng() % 192) + 1; for (int i = 0; i < BUF; i++) { A[i] = (unsigned char)prng(); B[i] = A[i]; } if (prng() & 1) B[off2 + (prng() % n)] ^= (unsigned char)prng(); g_case[0] = off1; g_case[1] = off2; g_case[2] = (int)n; const unsigned char *q1 = A + off1, *q2 = B + off2; g_lo[0] = q1; g_hi[0] = q1 + n; g_lo[1] = q2; g_hi[1] = q2 + n; int r = bcmp_instr(q1, q2, n); if ((r == 0) != (memcmp(q1, q2, n) == 0)) mism++; } printf("semantics check: %ld mismatches vs memcmp (must be 0)\n", mism); for (int i = 0; i < 2; i++) { printf("buf%d: in-region loads=%lu below-start loads=%lu (max %lu B) " "past-end loads=%lu (max %lu B, case off1=%ld off2=%ld n=%ld)\n", i, g_in[i], g_below_start[i], g_max_below[i], g_past_end[i], g_max_past[i], g_last_outside_case[0], g_last_outside_case[1], g_last_outside_case[2]); } int overread = (g_below_start[0]||g_below_start[1]||g_past_end[0]||g_past_end[1]); printf("RESULT: %s — longword loads DO%s read outside [ptr,ptr+len): " "max %lu B below start, %lu B past end\n", overread ? "OVERREAD-CONFIRMED" : "no out-of-region load", overread ? "" : " NOT", g_max_below[0] | g_max_below[1] ? (g_max_below[0] > g_max_below[1] ? g_max_below[0] : g_max_below[1]) : 0, g_max_past[0] > g_max_past[1] ? g_max_past[0] : g_max_past[1]); return mism ? 1 : 0; } |