FreeCalypso > hg > freecalypso-tools
view miscutil/srec-regions.c @ 921:74d284add54d
fc-fsio: guard against bogus readdir results from the target
If the FFS being operated on contains SE K2x0 extended filenames,
readdir will return strings that are bad for printing. We need to
guard against this possibility, and also against possible other
bogosity that could be sent by other alien firmwares.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 31 Dec 2022 22:55:23 +0000 |
parents | 7ef3343161d6 |
children |
line wrap: on
line source
/* * This program parses an S-record file (TI's *.m0 or otherwise), identifies * the set of discontiguous regions into which this SREC image deposits bits, * and lists these identified regions. */ #include <sys/types.h> #include <stdio.h> #include <ctype.h> #include <string.h> #include <strings.h> #include <stdlib.h> char *infname; FILE *inf; char srecbuf[1024]; u_char srecbin[256]; int lineno, state; u_long region_start, region_end; decode_hex_byte(s) char *s; { register int u, l; if (!isxdigit(s[0]) || !isxdigit(s[1])) return(-1); if (isdigit(s[0])) u = s[0] - '0'; else if (isupper(s[0])) u = s[0] - 'A' + 10; else u = s[0] - 'a' + 10; if (isdigit(s[1])) l = s[1] - '0'; else if (isupper(s[1])) l = s[1] - 'A' + 10; else l = s[1] - 'a' + 10; return((u << 4) | l); } srec2bin() { register int i, l, b; l = decode_hex_byte(srecbuf + 2); if (l < 1) { fprintf(stderr, "%s line %d: S-record length octet is bad\n", infname, lineno); exit(1); } srecbin[0] = l; for (i = 1; i <= l; i++) { b = decode_hex_byte(srecbuf + i*2 + 2); if (b < 0) { fprintf(stderr, "%s line %d: hex decode error\n", infname, lineno); exit(1); } srecbin[i] = b; } return(0); } srec_cksum() { u_char accum; register int i, len; len = srecbin[0] + 1; accum = 0; for (i = 0; i < len; i++) accum += srecbin[i]; if (accum != 0xFF) { fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno); exit(1); } return(0); } main(argc, argv) char **argv; { register int i; u_long curaddr; int datalen; if (argc != 2) { fprintf(stderr, "usage: %s image.m0\n", argv[0]); exit(1); } infname = argv[1]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(1); } state = 0; for (lineno = 1; ; lineno++) { if (!fgets(srecbuf, sizeof srecbuf, inf)) { fprintf(stderr, "%s: premature EOF\n", infname); exit(1); } if (srecbuf[0] != 'S') { fprintf(stderr, "%s line %d: not an S-record\n", infname, lineno); exit(1); } switch (srecbuf[1]) { case '0': if (state == 0) break; else goto badtype; case '3': if (state == 0) goto badtype; else break; case '7': if (state == 2) break; else goto badtype; default: badtype: fprintf(stderr, "%s line %d: S-record type unexpected\n", infname, lineno); exit(1); } srec2bin(); srec_cksum(); switch (srecbuf[1]) { case '0': state = 1; continue; case '3': if (srecbin[0] < 6) { fprintf(stderr, "%s line %d: S3 record is too short\n", infname, lineno); exit(1); } curaddr = (srecbin[1] << 24) | (srecbin[2] << 16) | (srecbin[3] << 8) | srecbin[4]; datalen = srecbin[0] - 5; if (state < 2) { region_start = curaddr; region_end = curaddr + datalen; state = 2; continue; } if (curaddr != region_end) { printf("0x%08lX to 0x%08lX (%lu bytes)\n", region_start, region_end, region_end - region_start); region_start = curaddr; } region_end = curaddr + datalen; continue; case '7': if (srecbin[0] < 5) { fprintf(stderr, "%s line %d: S7 record is too short\n", infname, lineno); exit(1); } printf("0x%08lX to 0x%08lX (%lu bytes)\n", region_start, region_end, region_end - region_start); printf("S7 address 0x%02X%02X%02X%02X\n", srecbin[1], srecbin[2], srecbin[3], srecbin[4]); exit(0); default: abort(); } } }