aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/mkgenome.c30
-rw-r--r--tests/drivers/tools_contract_test.py5
2 files changed, 28 insertions, 7 deletions
diff --git a/src/tools/mkgenome.c b/src/tools/mkgenome.c
index 9720760..051de62 100644
--- a/src/tools/mkgenome.c
+++ b/src/tools/mkgenome.c
@@ -40,15 +40,33 @@ int main(int argc, char **argv)
}
}
if (ferror(stdin)) { fputs("mkgenome: read failed\n", stderr); return 1; }
- int ok = n >= 8 * 7 && n % 8 == 0;
+ int ok = n >= 8 * 7 && n % 8 == 0, bad[3] = {0, 0, 0};
+ uint64_t got3[3] = {0, 0, 0}, want[3] = {(uint64_t)FTOP * 2 + 1, (uint64_t)ZFP * 2 + 1, 4};
for (int i = 0; ok && i < 3; i++) {
- uint64_t u = 0;
- for (int k = 0; k < 8; k++) u |= (uint64_t)b[i * 8 + k] << (k * 8);
- if (u != (i == 0 ? (uint64_t)FTOP * 2 + 1 : i == 1 ? (uint64_t)ZFP * 2 + 1 : 4)) ok = 0;
+ for (int k = 0; k < 8; k++) got3[i] |= (uint64_t)b[i * 8 + k] << (k * 8);
+ if (got3[i] != want[i]) bad[i] = 1;
}
+ int text = n >= 4 && !memcmp(b, "zc: ", 4);
+ if (ok && (bad[0] || bad[1] || bad[2])) ok = 0;
if (!ok) {
- if (n >= 4 && !memcmp(b, "zc: ", 4)) fwrite(b, 1, n, stderr);
- fprintf(stderr, n % 8 || n < 8 * 7 ? "mkgenome: incomplete genome\n" : "mkgenome: input is not a genome for this map\n");
+ if (text) fwrite(b, 1, n, stderr);
+ if (n % 8 || n < 8 * 7) { fputs("mkgenome: incomplete genome\n", stderr); return 1; }
+ fputs("mkgenome: input is not a genome for this map\n", stderr);
+ if (!text) {
+ /* the header: FTOP and ZFP as literal words (2v+1), then 4. say which differ
+ and by what, since a mismatch usually means rt.zc and the map disagree */
+ static const char *names[3] = {"FTOP (frame stack top)", "ZFP (zero page)", "the header's third word"};
+ for (int i = 0; i < 3; i++) {
+ if (!bad[i]) continue;
+ if (i < 2 && (got3[i] & 1)) fprintf(stderr, " word %d, %s: image has 0x%llX, the map has 0x%llX\n", i, names[i], (unsigned long long)(got3[i] >> 1), (unsigned long long)(want[i] >> 1));
+ else if (i < 2) fprintf(stderr, " word %d, %s: image has the raw word 0x%llX, not a literal; the map has 0x%llX\n", i, names[i], (unsigned long long)got3[i], (unsigned long long)(want[i] >> 1));
+ else fprintf(stderr, " word 2, %s: image has 0x%llX, expected 4\n", names[i], (unsigned long long)got3[i]);
+ }
+ if (bad[0] || bad[1])
+ fputs(" the compiler read a different layout than the one in build/core/map: check that FTOP and ZFP in\n"
+ " src/runtime/rt.zc match the map (a stale src/runtime/rt.zc, e.g. a zip unpacked over an older\n"
+ " checkout, or a stale build/core/map: run make clean, then make)\n", stderr);
+ }
return 1;
}
if (fwrite(b, 1, n, stdout) != n || fflush(stdout)) { fputs("mkgenome: write failed\n", stderr); return 1; }
diff --git a/tests/drivers/tools_contract_test.py b/tests/drivers/tools_contract_test.py
index 6a98678..9323a47 100644
--- a/tests/drivers/tools_contract_test.py
+++ b/tests/drivers/tools_contract_test.py
@@ -28,9 +28,12 @@ if args.group == 'image':
changed = words[:]; changed[index] ^= 2
r = command(['build/bin/mkgenome'], pack(changed))
assert r.returncode != 0 and b'not a genome' in r.stderr and not r.stdout
+ # the header words are named, with both values, and a layout mismatch points at rt.zc and the map
+ assert [b'FTOP', b'ZFP', b'third word'][index] in r.stderr, r.stderr
+ if index < 2: assert b'the map has 0x' in r.stderr and b'src/runtime/rt.zc' in r.stderr and b'make clean' in r.stderr, r.stderr
r = command(['build/bin/mkgenome'], b'zc: line 1: something is wrong\nzc: 1 error\n')
assert r.returncode != 0 and b'something is wrong' in r.stderr and not r.stdout
- print('ok mkgenome roundtrip, truncation, alignment, map-header mutation and diagnostic contracts')
+ print('ok mkgenome roundtrip, truncation, alignment, map-header mutation (naming FTOP, ZFP and both values) and diagnostic contracts')
elif args.group == 'map':
for preset in ['default', 'small', 'run', 'lsp', 'fixed']:
with tempfile.TemporaryDirectory(prefix='tinyvm preset ') as directory: