# HG changeset patch # User Mychaela Falconia # Date 1686365729 0 # Node ID bfcc8180cf3c69b9200c1e0c21dbeb6a07f4da7a # Parent 304ac8119c8a257b622b42e639e694be721ee44e bootmatch compiler written diff -r 304ac8119c8a -r bfcc8180cf3c .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,5 @@ +syntax: regexp + +\.[oa]$ + +^bootmatch/bm-comp$ diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/Makefile Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,12 @@ +CC= gcc +CFLAGS= -O2 +BMC_PROG=bm-comp +BMC_OBJS=comp_main.o comp_output.o comp_ranges.o comp_readbin.o + +all: ${BMC_PROG} + +${BMC_PROG}: ${BMC_OBJS} + ${CC} ${CFLAGS} -o $@ ${BMC_OBJS} + +clean: + rm -f *.o ${BMC_PROG} diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/comp_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/comp_defs.h Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,11 @@ +/* + * This header file contains global definitions for our bootmatch compiler. + */ + +#define BOOT_BLOCK_SIZE 0x2000 +#define MAX_RANGES 32 + +struct range { + unsigned offset; + unsigned nbytes; +}; diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/comp_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/comp_main.c Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,29 @@ +/* + * This C module is the main for our bootmatch compiler. + */ + +#include +#include +#include +#include "comp_defs.h" + +u_char boot_image[BOOT_BLOCK_SIZE]; +struct range range_list[MAX_RANGES]; +unsigned range_count; +char *output_array_name; + +main(argc, argv) + char **argv; +{ + if (argc != 5) { + fprintf(stderr, + "usage: %s bin-file ranges-file array-name output-file\n", + argv[0]); + exit(1); + } + read_bin_file(argv[1]); + read_ranges_file(argv[2]); + output_array_name = argv[3]; + emit_output_file(argv[4]); + exit(0); +} diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/comp_output.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/comp_output.c Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,86 @@ +/* + * This module is the output stage of our bootmatch compiler. + */ + +#include +#include +#include +#include "comp_defs.h" + +extern u_char boot_image[BOOT_BLOCK_SIZE]; +extern struct range range_list[MAX_RANGES]; +extern unsigned range_count; +extern char *output_array_name; + +static FILE *outf; + +static void +emit_header() +{ + fputs("#include \n", outf); + fputs("#include \"bootmatch.h\"\n", outf); + putc('\n', outf); +} + +static void +emit_refbytes_chunk(rp) + struct range *rp; +{ + u_char *dp, *endp; + unsigned linelen; + + fprintf(outf, "static u_char refbytes_%04X[%u] = {\n", rp->offset, + rp->nbytes); + dp = boot_image + rp->offset; + endp = dp + rp->nbytes; + linelen = 0; + while (dp < endp) { + if (linelen >= 16) { + putc('\n', outf); + linelen = 0; + } + fprintf(outf, "0x%02X", *dp++); + if (dp < endp) + putc(',', outf); + } + fputs("\n};\n\n", outf); +} + +static void +emit_refbytes_all() +{ + unsigned n; + + for (n = 0; n < range_count; n++) + emit_refbytes_chunk(range_list + n); +} + +static void +emit_bootmatch_array() +{ + unsigned n; + struct range *rp; + + fprintf(outf, "struct bootmatch %s[] = {\n", output_array_name); + for (n = 0; n < range_count; n++) { + rp = range_list + n; + fprintf(outf, "\t{0x%04X, 0x%04X, refbytes_%04X},\n", + rp->offset, rp->nbytes, rp->offset); + } + fputs("\t{0, 0, 0}\n};\n", outf); +} + +void +emit_output_file(filename) + char *filename; +{ + outf = fopen(filename, "w"); + if (!outf) { + perror(filename); + exit(1); + } + emit_header(); + emit_refbytes_all(); + emit_bootmatch_array(); + fclose(outf); +} diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/comp_ranges.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/comp_ranges.c Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,92 @@ +/* + * Bootmatch compiler: here we read and parse the *.ranges file. + */ + +#include +#include +#include +#include +#include "comp_defs.h" + +extern struct range range_list[MAX_RANGES]; +extern unsigned range_count; + +static void +process_line(line, filename, lineno) + char *line, *filename; +{ + char *cp; + struct range *rp; + u_long hex_start, hex_end; + + for (cp = line; isspace(*cp); cp++) + ; + if (*cp == '\0' || *cp == '#') + return; + if (!isxdigit(*cp)) { +inv_syntax: fprintf(stderr, "%s line %d: invalid syntax\n", + filename, lineno); + exit(1); + } + hex_start = strtoul(cp, &cp, 16); + if (!isspace(*cp)) + goto inv_syntax; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) + goto inv_syntax; + hex_end = strtoul(cp, &cp, 16); + if (*cp && !isspace(*cp)) + goto inv_syntax; + while (isspace(*cp)) + cp++; + if (*cp && *cp != '#') + goto inv_syntax; + if (hex_start >= BOOT_BLOCK_SIZE) { + fprintf(stderr, "%s line %d: start offset is out of range\n", + filename, lineno); + exit(1); + } + if (hex_end >= BOOT_BLOCK_SIZE) { + fprintf(stderr, "%s line %d: end offset is out of range\n", + filename, lineno); + exit(1); + } + if (hex_start >= hex_end) { + fprintf(stderr, + "%s line %d: end offset must be greater than start offset\n", + filename, lineno); + exit(1); + } + if (range_count >= MAX_RANGES) { + fprintf(stderr, "%s line %d: too many ranges defined\n", + filename, lineno); + exit(1); + } + rp = range_list + range_count; + rp->offset = hex_start; + rp->nbytes = hex_end - hex_start; + range_count++; +} + +void +read_ranges_file(filename) + char *filename; +{ + FILE *inf; + char linebuf[256]; + int lineno; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + exit(1); + } + for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) + process_line(linebuf, filename, lineno); + fclose(inf); + if (!range_count) { + fprintf(stderr, "error: no ranges defined in %s\n", filename); + exit(1); + } +} diff -r 304ac8119c8a -r bfcc8180cf3c bootmatch/comp_readbin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootmatch/comp_readbin.c Sat Jun 10 02:55:29 2023 +0000 @@ -0,0 +1,38 @@ +/* + * Bootmatch compiler: here we read the binary file. + */ + +#include +#include +#include +#include +#include +#include +#include "comp_defs.h" + +extern u_char boot_image[BOOT_BLOCK_SIZE]; + +void +read_bin_file(filename) + char *filename; +{ + int fd; + struct stat st; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + exit(1); + } + fstat(fd, &st); + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "error: %s is not a regular file\n", filename); + exit(1); + } + if (st.st_size != BOOT_BLOCK_SIZE) { + fprintf(stderr, "error: %s has wrong length\n", filename); + exit(1); + } + read(fd, boot_image, BOOT_BLOCK_SIZE); + close(fd); +}