📄 rdfrec.c
字号:
/************************************************************* * File: tools/rdfrec.c * Purpose: Fast-format record reader * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970518 Start of revision history */#include <stdio.h>#include <malloc.h>#define TEST 1#define DEBUG 0#define loop for (;;)#define MSK 0xff#define BLKSIZE 1024#define ETX 0x03typedef struct SymRec { struct SymRec *next; char *name; unsigned long value; } SymRec;int filecount;int debug;unsigned long nextaddr;unsigned long wordbuf;int bytecnt = 0;int blkinx = 0;int blksz = 0;char curblk[BLKSIZE];int little;int nodisasm;char prnbuf[100];SymRec *symchn; /* symbols in reverse value order (highest 1st) */char exta = ',';char extb = '.';char extc = '/';char *usage[] = { "usage: rdfrec [-ln] file", "\tread a fast-format file.", "\t-l\tlittle endian, swap each word", "\t-n\tno disassembly", 0};/************************************************************** main(argc,argv)*/main(argc,argv)int argc;char *argv[];{FILE *fp;int i,j;for (i=1;i<argc;i++) { /* first find all the options */ if (argv[i][0] == '-') { /* must be an option */ for (j=1;argv[i][j] != 0;j++) { if (argv[i][j] == 'd') debug = 1; else if (argv[i][j] == 'l') little = 1; else if (argv[i][j] == 'n') nodisasm = 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 /* must be a file */ filecount++; }if (filecount == 0) dofile(stdin,"stdin");else { for (i=1;i<argc;i++) { /* do the files */ if (argv[i][0] != '-') { /* must be a filename */ fp = fopen(argv[i],"r"); if (! fp) { fprintf(stderr,"can't open %s\n",argv[i]); exit(-1); } dofile(fp,argv[i]); fclose(fp); } } }}/************************************************************** dofile(fp,fname)*/dofile(fp,fname)FILE *fp;char *fname;{int n,i,j,c;char adat[4],name[60];unsigned char buf[3];unsigned long bdat,zcnt;unsigned long addr;for (;;) { getrec(fp,adat); if (adat[0] == '/') { switch (adat[1]) { case 'D' : /* this is a TDD for RMON */ printf("RMON TDD\n"); break; case 'C' : /* checksum */ zcnt = (a2b(adat[2])<<6)+a2b(adat[3]); printf("Checksum = %lx\n",zcnt); break; case 'K' : /* klear checksum */ printf("Klear checksum\n"); break; case 'S' : /* symbol */ i = 2; for (j=0;;) { c = adat[i++]; if (c == ',') break; name[j++] = c; if (i >= 4) { getrec(fp,adat); i = 0; } } name[j] = 0; if (nodisasm) printf("%08lx: %s\n",nextaddr,name); else newsym(name,nextaddr); break; case 'Z' : zcnt = (a2b(adat[2])<<6)+a2b(adat[3]); buf[0] = buf[1] = buf[2] = 0; for (i=0;i<zcnt;i++) { memwrite(buf,3); } break; case 'B' : buf[0] = (a2b(adat[2])<<6)+a2b(adat[3]); memwrite(buf,1); break; case 'A' : addr = (a2b(adat[2])<<6)+a2b(adat[3]); addr<<=12; getrec(fp,adat); addr += (a2b(adat[0])<<6)+a2b(adat[1]); addr<<=12; addr += (a2b(adat[2])<<6)+a2b(adat[3]); nextaddr = addr; break; case 'E' : printf("Entry Address = %08lx\n",nextaddr); return; break; default : printf("Bad Record = "); for (i=0;i<4;i++) printf("%c",adat[i]); printf("\n"); return; } continue; } bdat = 0; for (i=0;i<4;i++) { bdat<<=6; bdat += a2b(adat[i]); } for (i=2;i>=0;i--) { buf[i] = bdat&MSK; bdat>>= 8; } memwrite(buf,3); }}/************************************************************** getrec(fp,p)*/getrec(fp,p)FILE *fp;char *p;{int i;if (blkinx >= blksz) { blksz = getblk(fp,curblk); blkinx = 0; }for (i=0;i<4;i++) { p[i] = curblk[blkinx++]; }}/************************************************************** int getblk(fp,p)*/int getblk(fp,p)FILE *fp;char *p;{int i,c;i = 0;loop { c = getc(fp); if (c == ETX || c == '\n') break; p[i] = c; i++; }return(i);}/************************************************************** memwrite(dat,n)*/memwrite(dat,n)unsigned char *dat;int n;{int i;for (i=0;i<n;i++) { wordbuf<<=8; wordbuf += dat[i]; bytecnt++; if (bytecnt >= 4) { if (little) word_swap(&wordbuf); if (nodisasm) printf("%08lx: %08lx\n",nextaddr,wordbuf); else { disasm(prnbuf,nextaddr,wordbuf); printf("%s\n",prnbuf); } nextaddr += 4; bytecnt = 0; } }}/************************************************************** int a2b(c)*/int a2b(c)int c;{/* translate base64 (tx form) to binaryA-Z 0..25a-z 26..510-9 52..61exta 62extb 63*/if (c >= 'A' && c <= 'Z') return(c-'A');if (c >= 'a' && c <= 'z') return(c-'a'+26);if (c >= '0' && c <= '9') return(c-'0'+52);if (c == exta) return(62);if (c == extb) return(63);printf("a2b: Bad input value\n");return(0);}/************************************************************** 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);}/************************************************************** char *strccat(dst,c) * concatinate char to dst string */char *strccat(dst,c)char *dst,c;{int len;if (!dst) return(dst);len = strlen(dst);dst[len] = c;dst[len+1] = 0;return(dst);}/************************************************************** adr2symoff(dest,value,width)*/adr2symoff(dest,value,width)char *dest;unsigned long value;int width;{SymRec *p;char *nam,tmp[16];long offset;if (!symchn) return(0);dest[0] = 0;for (p=symchn;p;p=p->next) { if (value >= p->value) break; }if (p == 0) return(0);else { nam = p->name; if (width == 0) sprintf(dest,"%s",nam); else sprintf(dest,"%*.*s",width,width,nam); offset = value-(p->value); if (offset == 0) strcat(dest," "); else { sprintf(tmp,"+0x%-4x",offset); strcat(dest,tmp); } }return(1);}/************************************************************** newsym(name,value)*/newsym(name,value)char *name;unsigned long value;{SymRec *p,*q,*pr;p = (SymRec *)malloc(sizeof(SymRec));p->name = malloc(strlen(name)+1);strcpy(p->name,name);p->next = 0;p->value = value;/* empty chain */if (!symchn) { symchn = p; return(1); }/* insert before first item? */if (symchn->value < p->value) { p->next = symchn; symchn = p; return(1); }/* one item on chain */if (symchn->next == 0) { symchn->next = p; return(1); } /* n items on chain */for (q=symchn->next,pr=symchn;q;q=q->next) { if (q->value < p->value) break; pr = q; }p->next = pr->next;pr->next = p;return(1);}/************************************************************** prsyms()*/prsyms(){SymRec *p;for (p=symchn;p;p=p->next) { printf("%08lx %s\n",p->value,p->name); }}/* stubs */getGpr() {return(0);} write_target() {}read_target() {return(0);}flushDcache() {}matchenv() {}flush_target() {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -