summaryrefslogtreecommitdiffstats
path: root/tools/build/src/unhex.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build/src/unhex.c')
-rw-r--r--tools/build/src/unhex.c719
1 files changed, 0 insertions, 719 deletions
diff --git a/tools/build/src/unhex.c b/tools/build/src/unhex.c
deleted file mode 100644
index 540095d6f4..0000000000
--- a/tools/build/src/unhex.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * unhex
- * convert a hex file to binary equivalent. If more than one file name
- * is given, then the output will be logically concatenated together.
- * stdin and stdout are defaults. Verbose will enable checksum output.
- *
- * Supported input formats are Intel hex, Motorola S records, and TI 'B'
- * records.
- *
- * Intel hex input format is
- * Byte
- * 1 Colon :
- * 2..3 Record length, eg: "20"
- * 4..7 load address nibbles
- * 8..9 record type: "00" (data) or "02" base addr
- * 10..x data bytes in ascii-hex
- * x+1..x+2 cksum (2's compl of (len+addr+data))
- * x+3 \n -- newline
- */
-
-char *USAGE = "\
-usage: unhex [-va] [ -o file ] [ file [file ... ] ]\n\
- -v -- verbose\n\
- -a base -- 1st byte of output corresponds to this address\n\
- -l -- linear, just writes data out\n\
- -o file -- output file; must not be input file\n\
- -F k_bits -- \"holes\" in input will be filled with 0xFF's\n\
- up to \"k_bits\" * 1024 bits\n\
-";
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#define OK 0
-#define FAILURE (-1)
-#define Failed(x) ((x) == FAILURE)
-#define TRUE 1
-#define FALSE 0
-typedef char bool;
-#define STREQ(a,b) (strcmp(a,b) == 0)
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned long u32;
-
-/*
- * Pick out designated bytes
- */
-
-#define B0(x) ((x) & 0xff)
-#define B1(x) B0((x) >> 8)
-#define B2(x) B0((x) >> 16)
-#define B3(x) B0((x) >> 24)
-
-typedef struct buffer_rec {
- u32 dl_destaddr;
- u32 dl_jumpaddr;
- int dl_count;
- u8 dl_buf[512];
-} buffer_rec;
-
-/*
- * vars controlled by command line options
- */
-
-bool verbose = FALSE; /* be verbose */
-bool linear = FALSE; /* just write out linear data */
-char *outfilename = "-"; /* default output is stdout */
-u32 base = 0L; /* base address */
-u32 FFfill = 0L; /* how far to fill w 0xFF's */
-
-extern char *optarg; /* getopt(3) control vars */
-extern int optind;
-extern int errno;
-
-char *progname; /* for error() */
-
-void error(int errn, ...);
-#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
-#define ERR_FATAL (ERR_ERRNO / 2) /* error is fatal; no return */
-#define ERR_ABORT (ERR_ERRNO / 4) /* error is fatal; abort */
-#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
-
-#define stol(p) strtol(p, (char **) NULL, 0)
-
-int unhex(FILE *ifp, char *inm, FILE *ofp, char *onm);
-int convert_Intel_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
-int convert_S_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
-int convert_TI_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
-void write_record(buffer_rec *tb, FILE *fp);
-int getnibble(char **p);
-int getbyte(char **p);
-long getNbytes(char **p, int n);
-void badformat(char *s, char *fname, char *msg);
-
-#define get1bytes(p) ((int) getbyte(p))
-#define get2bytes(p) ((int) getNbytes(p, 2))
-#define get3bytes(p) getNbytes(p, 3)
-#define get4bytes(p) getNbytes(p, 4)
-
-char *BADADDR = "Invalid record address";
-char *BADLEN = "Invalid record length";
-char *BADBASE = "Bad base or starting address";
-char *BADFMT = "Unrecognized record type";
-char *BADDATA = "Invalid data byte";
-char *BADCSUM = "Invalid checksum";
-char *MISCSUM = "Checksum mismatch";
-char *BADTYPE = "Unrecognized record type";
-char *MISTYPE = "Incompatible record types";
-
-int
-main(argc, argv)
-int argc;
-char **argv;
-{
- register int c;
- bool showusage = FALSE; /* usage error? */
- int rc = 0;
- FILE *outfp, *infp;
-
- /*
- * figure out invocation leaf-name
- */
-
- if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
- progname = argv[0];
- else
- progname++;
-
- argv[0] = progname; /* for getopt err reporting */
-
- /*
- * Check options and arguments.
- */
-
- progname = argv[0];
- while ((c = getopt(argc, argv, "F:a:o:vl")) != EOF)
- switch (c)
- {
- case 'a': /* base address */
- base = stol(optarg);
- break;
-
- case 'l': /* linear output */
- linear = TRUE;
- break;
-
- case 'v': /* toggle verbose */
- verbose = ! verbose;
- break;
-
- case 'o': /* output file */
- outfilename = optarg;
- break;
-
- case 'F': /* 0xFF fill amount (bytes) */
- FFfill = stol(optarg) * 1024L / 8L;
- break;
-
- case '?':
- showusage = TRUE;
- }
-
- if (showusage)
- {
- (void) fprintf(stderr, "%s", USAGE);
- exit(1);
- }
-
- if (linear && (base != 0))
- {
- error(0, "-l and -a may not be specified in combination");
- exit(1);
- }
-
- if (STREQ(outfilename, "-"))
- {
- outfp = stdout;
- outfilename = "stdout";
- }
- else
- if ((outfp = fopen(outfilename, "w")) == (FILE *) NULL)
- {
- error(-1, "couldn't open '%s' for output", outfilename);
- exit(1);
- }
-
- /*
- * Now process the input files (or stdin, if none specified)
- */
-
- if (argv[optind] == (char *) NULL) /* just stdin */
- exit(unhex(stdin, "stdin", outfp, outfilename));
- else
- for (; (optarg = argv[optind]); optind++)
- {
- if (STREQ(optarg, "-"))
- rc += unhex(stdin, "stdin", outfp, outfilename);
- else
- {
- if ((infp = fopen(optarg, "r")) == (FILE *) NULL)
- {
- error(-1, "couldn't open '%s' for input", optarg);
- exit(1);
- }
- rc += unhex(infp, optarg, outfp, outfilename);
- }
- }
-
- return(rc);
-}
-
-u16 filesum;
-
-int
-unhex(FILE *ifp,
- char *inm,
- FILE *ofp,
- char *onm)
-{
- int c;
-
- filesum = 0;
-
- /*
- * Make sure holes will be filled with 0xFF's if requested. We
- * do this the easy way by just filling the file with FF's before
- * getting started. To do it more optimally would be quite a bit
- * more difficult since the user can skip around as much as he/she
- * likes in the input hex file addressing.
- *
- * We'll clean this up later (after this program has run) with
- * 'stripffs'
- */
-
- if (FFfill)
- {
- (void) fseek(ofp, 0, 0);
- for (c = FFfill; c > 0; c--)
- (void) fputc(0xFF, ofp);
- }
-
- /*
- * Read the first char from file and determine record types
- */
-
- if ((c = getc(ifp)) != EOF)
- {
- ungetc(c, ifp);
- switch(c)
- {
- case 'S':
- convert_S_records(ifp, inm, ofp, onm);
- break;
-
- case ':':
- convert_Intel_records(ifp, inm, ofp, onm);
- break;
-
- case '9':
- case 'B':
- convert_TI_records(ifp, inm, ofp, onm);
- break;
-
- default:
- {
- char tmp[2];
- tmp[0] = c; tmp[1] = 0;
- badformat(tmp, inm, BADFMT);
- }
- }
- }
-
- if (verbose)
- fprintf(stderr, "'%s' checksum is 0x%04x\n", inm, filesum);
-
- return 0;
-}
-
-int
-convert_Intel_records(
- FILE *ifp,
- char *inm,
- FILE *ofp,
- char *onm)
-{
- char buff[512];
- char *p;
- u8 cksum;
- int incksum;
- int c;
- int rectype; /* record type */
- int len; /* data length of current line */
- u32 addr;
- u32 base_address = 0;
- bool endrecord = FALSE;
- buffer_rec tb;
-
- while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
- {
- p = &buff[0];
-
- if (p[strlen(p)-1] == '\n') /* get rid of newline */
- p[strlen(p)-1] = '\0';
-
- if (p[strlen(p)-1] == '\r') /* get rid of any CR */
- p[strlen(p)-1] = '\0';
-
- tb.dl_count = 0;
-
- if (*p != ':')
- badformat(p, inm, BADFMT);
- p++;
-
- if ((len = getbyte(&p)) == -1) /* record len */
- badformat(buff, inm, BADLEN);
-
- if ((addr = get2bytes(&p)) == -1L) /* record addr */
- badformat(buff, inm, BADADDR);
-
- rectype = getbyte(&p);
-
- cksum = len + B0(addr) + B1(addr) + rectype;
-
- switch (rectype)
- {
- case 0x00: /* normal data record */
- tb.dl_destaddr = base_address + addr;
- while (len--)
- {
- if ((c = getbyte(&p)) == -1)
- badformat(buff, inm, BADDATA);
- cksum += c;
- filesum += c;
- tb.dl_buf[tb.dl_count++] = c;
- }
- break;
-
- case 0x01: /* execution start address */
- base_address = addr;
- endrecord = TRUE;
- break;
-
- case 0x02: /* new base */
- if ((base_address = get2bytes(&p)) == -1L)
- badformat(buff, inm, BADBASE);
- cksum += B0(base_address) + B1(base_address);
- base_address <<= 4;
- break;
-
- case 0x03: /* seg/off execution start address */
- {
- u32 seg, off;
-
- seg = get2bytes(&p);
- off = get2bytes(&p);
- if ((seg == -1L) || (off == -1L))
- badformat(buff, inm, BADADDR);
-
- cksum += B0(seg) + B1(seg) + B0(off) + B1(off);
-
- tb.dl_jumpaddr = (seg << 4) + off;
- break;
- }
-
- default:
- error(0, "unknown Intel-hex record type: 0x%02x", rectype);
- badformat(buff, inm, BADTYPE);
- }
-
- /*
- * Verify checksums are correct in file.
- */
-
- cksum = (-cksum) & 0xff;
- if ((incksum = getbyte(&p)) == -1)
- badformat(buff, inm, BADCSUM);
- if (((u8) incksum) != cksum)
- badformat(buff, inm, MISCSUM);
-
- if (tb.dl_count)
- write_record(&tb, ofp);
- }
- return 0;
-}
-
-int
-convert_S_records(
- FILE *ifp,
- char *inm,
- FILE *ofp,
- char *onm)
-{
- char buff[512];
- char *p;
- u8 cksum;
- int incksum;
- int c;
- int len; /* data length of current line */
- int rectype; /* record type */
- u32 addr;
- bool endrecord = FALSE;
- buffer_rec tb;
-
- while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
- {
- p = &buff[0];
-
- if (p[strlen(p)-1] == '\n') /* get rid of newline */
- p[strlen(p)-1] = '\0';
-
- if (p[strlen(p)-1] == '\r') /* get rid of any CR */
- p[strlen(p)-1] = '\0';
-
- tb.dl_count = 0;
-
- if (*p != 'S')
- badformat(p, inm, BADFMT);
- p++;
-
- if ((rectype = getnibble(&p)) == -1) /* record type */
- badformat(buff, inm, BADTYPE);
-
- if ((len = getbyte(&p)) == -1) /* record len */
- badformat(buff, inm, BADLEN);
- cksum = len;
-
- switch (rectype)
- {
- case 0x00: /* comment field, ignored */
- goto write_it;
-
- case 0x01: /* data record, 16 bit addr */
- if ((addr = get2bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
- len -= 3;
- goto doit;
-
- case 0x02: /* ... 24 bit addr */
- if ((addr = get3bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
- len -= 4;
- goto doit;
-
- case 0x03: /* ... 32 bit addr */
- if ((addr = get4bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
- len -= 5;
- doit:
- cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
-
- tb.dl_destaddr = addr;
- while (len--)
- {
- if ((c = getbyte(&p)) == -1)
- badformat(buff, inm, BADDATA);
- cksum += c;
- filesum += c;
- tb.dl_buf[tb.dl_count++] = c;
- }
- break;
-
- case 0x07: /* 32 bit end record */
- if ((addr = get4bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
- goto end_rec;
-
- case 0x08: /* 24 bit end record */
- if ((addr = get3bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
- goto end_rec;
-
- case 0x09: /* 16 bit end record */
- if ((addr = get2bytes(&p)) == -1L)
- badformat(buff, inm, BADADDR);
-
-end_rec:
- cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
- tb.dl_jumpaddr = addr;
- break;
-
- default:
- error(0, "unknown Motorola-S record type: 0x%02x", rectype);
- badformat(buff, inm, BADTYPE);
- break;
- }
-
- /*
- * Verify checksums are correct in file.
- */
-
- cksum = (~cksum) & 0xff;
- if ((incksum = getbyte(&p)) == -1)
- badformat(buff, inm, BADCSUM);
- if (((u8) incksum) != cksum)
- badformat(buff, inm, MISCSUM);
-
-write_it:
- if (tb.dl_count)
- write_record(&tb, ofp);
- }
- return 0;
-}
-
-int
-convert_TI_records(
- FILE *ifp,
- char *inm,
- FILE *ofp,
- char *onm)
-{
- char buff[512];
- char *p;
- int c;
- bool endrecord = FALSE;
- bool eol;
- buffer_rec tb;
-
- while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
- {
- if (p[strlen(p)-1] == '\n') /* get rid of newline */
- p[strlen(p)-1] = '\0';
-
- if (p[strlen(p)-1] == '\r') /* get rid of any CR */
- p[strlen(p)-1] = '\0';
-
- tb.dl_count = 0;
-
- p = &buff[0];
- eol = FALSE;
- while ( ! eol && ! endrecord)
- {
- switch (*p++)
- {
- case '9':
- if (tb.dl_count)
- write_record(&tb, ofp);
- tb.dl_destaddr = get2bytes(&p);
- break;
-
- case 'B':
- c = getbyte(&p);
- filesum += c;
- tb.dl_buf[tb.dl_count++] = c;
- c = getbyte(&p);
- filesum += c;
- tb.dl_buf[tb.dl_count++] = c;
- break;
-
- case 'F':
- eol = TRUE;
- break;
-
- case ':':
- endrecord = TRUE;
- break;
-
- default:
- badformat(p, inm, BADFMT);
- }
- }
- if (tb.dl_count)
- write_record(&tb, ofp);
- }
- return 0;
-}
-
-void
-write_record(buffer_rec *tb,
- FILE *fp)
-{
- if ( ! linear)
- {
- if (tb->dl_destaddr < base)
- error(ERR_FATAL, "record at address 0x%x precedes base of 0x%x",
- tb->dl_destaddr, base);
- (void) fseek(fp, tb->dl_destaddr - base, 0);
- }
-
- (void) fwrite(tb->dl_buf, tb->dl_count, 1, fp);
- tb->dl_destaddr += tb->dl_count;
- tb->dl_count = 0;
-}
-
-int
-getnibble(char **p)
-{
- register int val;
-
- **p = toupper(**p);
- switch (**p)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- val = **p - '0';
- break;
-
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- val = 10 + (**p - 'A');
- break;
-
- default:
- return(-1);
- }
- *p += 1;
-
- return(val & 0x0f);
-}
-
-int
-getbyte(char **p)
-{
- int n0, n1;
-
- if ((n0 = getnibble(p)) == -1)
- return(-1);
- if ((n1 = getnibble(p)) == -1)
- return(-1);
-
- return(((n0 << 4) + n1) & 0xff);
-}
-
-long
-getNbytes(char **p,
- int n)
-{
- int t;
- u32 val = 0;
-
- while (n--)
- {
- if ((t = getbyte(p)) == -1)
- return(-1L);
- val <<= 8;
- val += t;
- }
-
- return(val);
-}
-
-void
-badformat(char *s,
- char *fname,
- char *msg)
-{
- if (s[strlen(s)-1] == '\n') /* get rid of newline */
- s[strlen(s)-1] = '\0';
- error(0, "line '%s'::\n\tfrom file '%s'; %s", s, fname, msg);
- exit(1);
-}
-
-/*
- * error(errn, arglist)
- * report an error to stderr using printf(3) conventions.
- * Any output is preceded by '<progname>: '
- *
- * Uses ERR_EXIT bit to request exit(errn)
- * ERR_ABORT to request abort()
- * ERR_ERRNO to indicate use of errno instead of argument.
- *
- * If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
- * associated error message is appended to the output.
- */
-
-/*VARARGS*/
-
-void
-error(int error_flag, ...)
-{
- va_list arglist;
- register char *format;
- extern char *sys_errlist[];
- extern int sys_nerr;
- int local_errno;
-
- extern int errno;
-
- (void) fflush(stdout); /* in case stdout/stderr same */
-
- local_errno = error_flag & ~ERR_MASK;
- if (error_flag & ERR_ERRNO) /* use errno? */
- local_errno = errno;
-
- va_start(arglist, error_flag);
- format = va_arg(arglist, char *);
- (void) fprintf(stderr, "%s: ", progname);
- (void) vfprintf(stderr, format, arglist);
- va_end(arglist);
-
- if (local_errno)
- if ((local_errno > 0) && (local_errno < sys_nerr))
- (void) fprintf(stderr, " (%s)\n", sys_errlist[local_errno]);
- else
- (void) fprintf(stderr, " (unknown errno=%d)\n", local_errno);
- else
- (void) fprintf(stderr, "\n");
-
- (void) fflush(stderr);
-
- if (error_flag & (ERR_FATAL | ERR_ABORT))
- {
- if (error_flag & ERR_FATAL)
- {
- error(0, local_errno ? "fatal error, exiting" : "exiting");
- exit(local_errno);
- }
- else
- {
- error(0, "fatal error, aborting");
- abort();
- }
- }
-}
-