📄 gensrec.c
字号:
/************************************************************* * File: tools/gensrec.c * Purpose: Generate Motorola S-records from a MIPS COFF file * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970313 Added -e option * 970327 Changed RMON to IMON in help */#include <stdio.h>#include "mipscoff.h"#define ALIGN 16 /* alignment for start of section data */#define DATASIZE 32 /* data size specified in bytes */#define ADDRSIZE 4 /* address size specified in bytes 2 = S1recs, 3 = S2recs, 4 = S3 recs */#define swap(x,y) ((y==2)?byte_swap(x,y):word_swap(x,y))#define RECSIZE (DATASIZE + ADDRSIZE + 1)unsigned long addr;int sflag = 0; int bflag = 0; /* generate binary memory image */int Bflag = 0;int Sflag = 0;int Dflag = 0;int eflag = 0;int debug = 0; /* debug switch */int prom = 0; /* prom version */int omit_text = 0;int leflag;char *usage[] = { "usage: gensrec [-opts] file", "\t-p\tprom mode, start addresses at zero", "\t-t\tomit text section", "\t-d\tdebug mode", "\t-b\tgenerate binary memory image file", "\t-B\temulate nm -B", "\t-s\tinclude symbols", "\t-S\tprint ROM/RAM sizes", "\t-D\tmark the file as a TDD for IMON", "\t-e\tgenerate symbols exclusively", 0};#if 0 /*PERL*/#endifchar *sckey[] = {"0x00","T","D","B","0x04","A","0x06","0x07", "0x08","0x09","0x0a","0x0b","0x0c","G","S","0x0f", "0x10","0x11","0x12","0x13","0x14","0x15","I","0x17", "0x18","0x19","0x1a","0x1b","0x1c","0x1d","0x1e","0x1f", };/*** MIPS magic numbers:** fread(&fhdr,sizeof(fhdr),1,fp)** fhdr.f_magic HOST TARGET** 0540 BE BE** 061001 BE LE (swap req'd)** 0542 LE LE** 060001 LE BE (swap req'd)** 0543 BE BE (mips2)** 063001 BE LE (mips2, swap req'd)*//************************************************************** main(argc,argv)*/main(argc,argv)int argc;char *argv[];{int i,j,num_files;FILE *fp;for (i=1;i<argc;i++) { if (argv[i][0] == '-') { for (j=1;argv[i][j] != 0;j++) { if (argv[i][j] == 's') sflag = 1; else if (argv[i][j] == 'd') debug = 1; else if (argv[i][j] == 'p') prom = 1; else if (argv[i][j] == 'b') bflag = 1; else if (argv[i][j] == 'B') Bflag = 1; else if (argv[i][j] == 'S') Sflag = 1; else if (argv[i][j] == 'D') Dflag = 1; else if (argv[i][j] == 'e') eflag = 1; else if (argv[i][j] == 't') omit_text = 1; else { fprintf(stderr,"%c: bad option\n",argv[i][j]); for (j=0;usage[j];j++) fprintf(stderr,"%s\n",usage[j]); exit(-1); } } } else num_files++; }if (num_files == 0) do_file(stdin);else { for (i=1;i<argc;i++) { if (argv[i][0] != '-') { fp = fopen(argv[i],"r"); if (! fp) { fprintf(stderr,"can't open %s\n",argv[i]); exit(-1); } do_file(fp); fclose(fp); } } }exit(0);} /************************************************************** do_file(fp)*/do_file(fp)FILE *fp;{struct aouthdr ohdr;unsigned long offset;struct filehdr fhdr;fread(&fhdr,sizeof(fhdr),1,fp);if (fhdr.f_magic == 060001 || fhdr.f_magic == 061001 || fhdr.f_magic == 063001) { /* reverse endian */ leflag = 1; swap(&fhdr.f_magic,sizeof(fhdr.f_magic)); swap(&fhdr.f_nscns,sizeof(fhdr.f_nscns)); swap(&fhdr.f_opthdr,sizeof(fhdr.f_opthdr)); swap(&fhdr.f_nsyms,sizeof(fhdr.f_nsyms)); swap(&fhdr.f_symptr,sizeof(fhdr.f_symptr)); }else leflag = 0;if (debug) printf("fhdrsz=%d magic=0%o nscns=%d ohdrsz=%d nsyms=%d\n", sizeof(fhdr),fhdr.f_magic,fhdr.f_nscns,fhdr.f_opthdr,fhdr.f_nsyms);if (fhdr.f_magic != 0540 && fhdr.f_magic != 0542 && fhdr.f_magic != 0543 && fhdr.f_magic != 0546) { fprintf(stderr,"gensrec: 0%o Bad magic number\n",fhdr.f_magic); exit(1); }fread(&ohdr,sizeof(ohdr),1,fp);if (leflag) { swap(&ohdr.entry,sizeof(ohdr.entry)); swap(&ohdr.tsize,sizeof(ohdr.tsize)); swap(&ohdr.text_start,sizeof(ohdr.text_start)); swap(&ohdr.dsize,sizeof(ohdr.dsize)); swap(&ohdr.data_start,sizeof(ohdr.data_start)); swap(&ohdr.bsize,sizeof(ohdr.bsize)); }if (Sflag) { printf("ROMSIZE %d RAMSIZE %d\n", ohdr.tsize+ohdr.dsize,ohdr.dsize+ohdr.bsize); return; }if (Dflag) printf("SD\n");if (sflag || Bflag || eflag) do_syms(fp,&fhdr);if (Bflag || eflag) return;if (debug) printf("entry=%lx tsize=%lx tbase=%lx dsize=%lx dbase=%lx\n", ohdr.entry,ohdr.tsize,ohdr.text_start,ohdr.dsize,ohdr.data_start);offset = ((fhdr.f_nscns*sizeof(struct scnhdr))+sizeof(fhdr)+ sizeof(ohdr)+(ALIGN-1))&~(ALIGN-1);if (!prom) addr = ohdr.text_start;else addr = 0;if (omit_text) fseek(fp,offset+ohdr.tsize,0);else { fseek(fp,offset,0); do_sect(fp,ohdr.tsize); }if (!prom) addr = ohdr.data_start;do_sect(fp,ohdr.dsize);if (!bflag) do_erec(ohdr.entry);}/************************************************************** do_sect(infile,scnsize)*/do_sect(infile,scnsize)FILE *infile;long scnsize;{int j,chksum,n;long cnt;unsigned char buf[DATASIZE],byte;if (bflag) { for (cnt=0;cnt<scnsize;cnt++) { byte = getc(infile); putc(byte,stdout); } return; }for (cnt=0;cnt<scnsize;cnt+=n) { chksum = 0; if ((scnsize-cnt) >= DATASIZE) n = fread(buf,1,DATASIZE,infile); else n = fread(buf,1,scnsize-cnt,infile); if (n == 0) break; /* hack for MSDOS */ printf("S%1d%02X",ADDRSIZE-1,n+ADDRSIZE+1); chksum += n+ADDRSIZE+1; for (j=ADDRSIZE-1;j>=0;j--) { byte = (addr>>(j*8)) & 0xff; printf("%02X",byte); chksum += byte; } for (j=0;j<n;j++) { printf("%02X",buf[j]); chksum += buf[j]; } printf("%02X\n",(~chksum)&0xff); addr += n; }}/************************************************************** do_erec(entry)*/do_erec(entry)unsigned long entry;{int j,chksum;unsigned char byte;if (prom) entry = 0;chksum = 0;printf("S%1d%02X",7,5);chksum += 5;for (j=ADDRSIZE-1;j>=0;j--) { byte = (entry>>(j*8)) & 0xff; printf("%02X",byte); chksum += byte; }printf("%02X\n",(~chksum)&0xff);}/************************************************************** word_swap(vp)*/word_swap(vp)unsigned long *vp;{unsigned short v1,v2;v1 = (*vp)>>16;byte_swap(&v1);v2 = (*vp)&0xffff;byte_swap(&v2);*vp = (((unsigned long)v2)<<16)+v1;}/************************************************************** byte_swap(vp)*/byte_swap(vp)unsigned short *vp;{*vp = ((*vp)<<8)+((*vp)>>8);}/************************************************************** do_syms(fp,fhdr)*/do_syms(fp,fhdr)FILE *fp;struct filehdr *fhdr;{int i,size,len,csum;EXTR sym;HDRR symh;char buf[100];long p;fseek(fp,fhdr->f_symptr,0);fread(&symh,sizeof(HDRR),1,fp);if (leflag) { swap(&symh.cbExtOffset,sizeof(symh.cbExtOffset)); swap(&symh.cbSsExtOffset,sizeof(symh.cbSsExtOffset)); swap(&symh.iextMax,sizeof(symh.iextMax)); }if (debug) { printf("HDRR offset=%08lx size=0x%02x\n",fhdr->f_symptr,sizeof(HDRR)); printf("cbSsExtOffset=%08lx iextMax=%d cbExtOffset=%08lx\n", symh.cbSsExtOffset,symh.iextMax,symh.cbExtOffset); printf("EXTR size=0x%02x\n",sizeof(EXTR)); printf("%5s %10s %10s %10s %2s %5s %10s\n", "#","adr","iss", "value","st","sc","index"); }p = symh.cbExtOffset;for (i=0;i<=symh.iextMax;i++) { fseek(fp,p,0); if (fread(&sym,sizeof(EXTR),1,fp) != 1) break; if (leflag) { swap(&sym.asym.iss,sizeof(sym.asym.iss)); swap(&sym.asym.value,sizeof(sym.asym.value)); sym.asym.sc = getsc(*((&sym.asym.value)+1)); } p = ftell(fp); fseek(fp,sym.asym.iss+symh.cbSsExtOffset,0); getsym(buf,fp); if (debug) { printf("[%3d] ",i); printf("0x%08lx ",sym.asym.iss); printf("0x%08lx ",sym.asym.value); printf("%02x[%s] ",sym.asym.sc,sckey[sym.asym.sc]); printf("sym=%s\n",buf); } if (Bflag) printf("%08lx %s %s\n",sym.asym.value,sckey[sym.asym.sc],buf); else { csum = 0; /* no checksum generated for symbols */ len = strlen(buf)+8+2; printf("S4%02X%08X%s,%02x\n",len,sym.asym.value,buf,csum); } }}/************************************************************** getsc(w)* A somewhat ad-hoc solution for the sc bit field*/getsc(w)unsigned long w;{return(((w>>16)<<2)|(w>>30));}/************************************************************** getsym(p,fp)*/getsym(p,fp)char *p;FILE *fp;{int c;for (;;) { c = getc(fp); if (c == EOF) break; if (c == 0) break; *p++ = c; }*p = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -