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
|
/* checks a genome image (little-endian 64-bit words on stdin, as written by
zc0 or src/tools/build.zc) against the memory map it was built with, and
copies it to stdout unchanged. the cores #embed the result (src/core/genome.h),
so this is the gate that keeps a compiler's diagnostics out of a core: when
the input is not an image for this map, nothing is written and the input is
shown on stderr, since it is usually the compiler's error report. */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
#include "memmap.h"
int main(int argc, char **argv)
{
if (argc == 2 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) {
fputs("usage: mkgenome [--help|-h] < image.bin > genome.bin\n"
"checks little-endian 64-bit image words against this memory map and copies them\n"
"to stdout. input that is not an image is reported on stderr and nothing is written.\n"
"the image must match the memory layout selected when mkgenome is built.\n"
"options:\n --help, -h show this help and exit\n", stdout);
return 0;
}
if (argc != 1) { fputs("mkgenome: unexpected arguments; use --help for usage\n", stderr); return 2; }
#ifdef _WIN32
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
#endif
size_t n = 0, cap = 1 << 20, got;
unsigned char *b = malloc(cap);
if (!b) { fputs("mkgenome: out of memory\n", stderr); return 1; }
while ((got = fread(b + n, 1, cap - n, stdin)) > 0) {
n += got;
if (n == cap) {
unsigned char *next = cap > ((size_t)1 << 30) ? 0 : realloc(b, cap * 2);
if (!next) { fputs("mkgenome: image too large\n", stderr); return 1; }
b = next; cap *= 2;
}
}
if (ferror(stdin)) { fputs("mkgenome: read failed\n", stderr); return 1; }
int ok = n >= 8 * 7 && n % 8 == 0;
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;
}
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");
return 1;
}
if (fwrite(b, 1, n, stdout) != n || fflush(stdout)) { fputs("mkgenome: write failed\n", stderr); return 1; }
return 0;
}
|