DF-2675 / findfield.c
/* * DF-2675 findfield: snapshot the buf array, run `ls /mnt/D13`, snapshot * again; for every changed record dump the 4-byte fields that changed * (old -> new). Lets us identify b_loffset (0xD1800), b_bufsize (65536), * xio_npages (17), b_vp, b_flags offsets by value. */ #include <sys/types.h> #include <err.h> #include <fcntl.h> #include <kvm.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { kvm_t *kd; struct nlist nl[] = { { "_buf" }, { NULL } }; unsigned char *a, *b; long nbuf = 12634, szbuf = 1352, n; uint64_t bufva; kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "findfield"); if (!kd) return 1; if (kvm_nlist(kd, nl) != 0) errx(1, "nlist"); if (kvm_read(kd, nl[0].n_value, &bufva, 8) != 8) errx(1, "ptr"); a = malloc(nbuf * szbuf); b = malloc(nbuf * szbuf); if (!a || !b) err(1, "malloc"); if (kvm_read(kd, bufva, a, nbuf * szbuf) != nbuf * szbuf) errx(1, "snapA"); kvm_close(kd); if (system(argc > 1 ? argv[1] : "ls /mnt/D13 > /dev/null") != 0) errx(1, "cmd failed"); kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "findfield2"); if (kvm_read(kd, bufva, b, nbuf * szbuf) != nbuf * szbuf) errx(1, "snapB"); kvm_close(kd); for (n = 0; n < nbuf; n++) { int off, changed = 0; for (off = 0; off < szbuf; off += 4) if (memcmp(a + n*szbuf + off, b + n*szbuf + off, 4)) { changed++; } if (!changed) continue; printf("=== record %ld changed (%d ints)\n", n, changed); for (off = 0; off < szbuf; off += 4) { uint32_t va_, vb_; if (!memcmp(a + n*szbuf + off, b + n*szbuf + off, 4)) continue; memcpy(&va_, a + n*szbuf + off, 4); memcpy(&vb_, b + n*szbuf + off, 4); printf(" off %4d: %#010x -> %#010x\n", off, va_, vb_); } } return 0; } |