/* File: symbol.c * * These are the symbol table routines. * */ #include "link.h" extern FILE *mapfile; extern unsigned int relo[]; extern unsigned int ofset1; extern unsigned int errcnt; extern unsigned int symcnt; /* index of current symbol */ extern unsigned int symmax; extern unsigned int noref; extern unsigned int nosym; extern unsigned int nopsect; extern unsigned int ltruncate; extern unsigned int adrefc[]; extern unsigned char mode; extern unsigned int transaddr; extern unsigned int adrsave; extern unsigned int fullflag; extern unsigned int psectcount; extern unsigned char saveflag; extern unsigned char *head1; extern unsigned char *head2; extern unsigned char nullx[]; extern unsigned char symname[]; extern unsigned char line[]; extern SYM *symbas; /* pointer to base of symbol table */ extern SYM *symprv; /* pointer to previous symbol */ static PSECT *psbas; static PSECT *psprv; static unsigned char headx[] = "----------------\t----------------\t----------------\t----------------\t----------------"; static unsigned char sheadx[] = "----------------\t----------------\t----------------"; unsigned char *mktemp(); SYM *locate(); SYM *insert(); setent(name, addr) register unsigned char *name; register unsigned int addr; { register SYM *sp; sp = locate(name); if(sp) { if(sp->flag & LNKENT) { sp->flag |= LNKMDF; multiple(name); } else { sp->flag |= LNKENT; sp->value = addr; } } else insert(name, addr, LNKENT); } adjust(value) unsigned int value; { return(value += (relo[mode] + ofset1)); } symchk(name, addr) register unsigned char *name; register unsigned int addr; { register SYM *sp; sp = locate(name); if(mode == DSEG) { if(sp) sp->value = addr; } else if(sp && (sp->value != addr)) different(name); } /* locate --- locate a symbol in the symbol table SYM *locate(name) char *name; returns a pointer to the symbol if found in the table. if not found, returns a null pointer. additionally sets up the index of the entry in the global variable "symcnt", and the pointer to the previous entry in the global variable "symprv". */ SYM *locate(name) register unsigned char *name; { register SYM *symcur, *symret; register int symcmp; symcnt = 0; symprv = SYMNUL; symret = SYMNUL; for (symcur = symbas; symcur != SYMNUL; symcur = symcur->nxtsym) { symcnt++; symcmp = strcmp(name,symcur->name); if (symcmp > 0) /* not there yet */ { symprv = symcur; /* remember previous symbol */ continue; } if (symcmp < 0) /* past it, not in table */ break; symret = symcur; /* found it */ break; } return(symret); } /* insert --- insert a new entry into the symbol table SYM *insert(name,value,flag) char *name, flag; short value; returns pointer to inserted entry, or a null pointer if one of the following occurs: 1. asked to insert a null name. 2. name already exists in table. 3. couldn't allocate memory for entry. */ SYM *insert(name,value,flag) register unsigned char *name; unsigned char flag; unsigned short value; { register SYM *symcur; if ((name[0] == '\0') || (locate(name) != SYMNUL)) return(SYMNUL); symcur = (SYM *)malloc(SYMSIZ); /* space for entry */ if (symcur != SYMNUL) /* allocate successful */ { clrbuf(symcur->name, 20); (void) strcpy(symcur->name, name); /* put name in entry */ symcur->value = value; /* ditto value... */ symcur->flag = flag; /* and flag */ symcur->nxtref = 0; /* no refferences yet */ ++symmax; if (symprv == SYMNUL) /* first entry in list */ { symcur->nxtsym = symbas; symbas = symcur; } else /* link into list */ { symcur->nxtsym = symprv->nxtsym; symprv->nxtsym = symcur; } } return(symcur); } PSECT *insertp(name, value, flag) register unsigned char *name; unsigned char flag; register unsigned int value; { register PSECT *pscur; pscur = (PSECT *)malloc(PSSIZ); /* allocate space for entry */ if (pscur != PSNUL) /* allocate successful */ { clrbuf(pscur->name, 8); (void) strncpy(pscur->name, name, 6); pscur->flag = flag; pscur->value = value; pscur->nxtp = PSNUL; if (psprv == PSNUL) /* first entry in list */ psbas = pscur; else /* link into list */ psprv->nxtp = pscur; psprv = pscur; } else { printf("Can't allocate psect table.\n"); if(mapfile) (void) fprintf(mapfile, "Can't allocate psect table.\n"); return(PSNUL); } return(pscur); } outref(sp) SYM *sp; { REF *rp, *xp, *zp; if(!noref) return; rp = (REF *)malloc(REFSIZ); rp->value = adrefc[mode]; rp->nextref = 0; if(xp = sp->nxtref) { while(xp) { if(xp->nextref == 0) break; xp = xp->nextref; } xp->nextref = rp; } else sp->nxtref = rp; } /* output the cross references to the listing file */ dspref() { register REF *rp; register SYM *symcur = symbas; register unsigned int count; unsigned char buffx[50]; if(!noref) return; head1 = (unsigned char *)"Cross Reference Symbol Listing"; head2 = (unsigned char *)"Addr Name\t\tReferences"; eject(); line[0] = 0; for(symcnt = 0; symcnt < symmax; symcnt++) { if(isdefined(symcur->flag)) { (void) sprintf(line, "%04.4X %-14s", symcur->value, symcur->name); count = 0; rp = symcur->nxtref; while(rp) { if(++count == (ltruncate ? 7 : 14)) { list(line); (void) sprintf(line, "\t\t"); count = 1; } (void) sprintf(buffx, "\t%04.4X", rp->value); (void) strcat(line, buffx); rp = rp->nextref; } list(line); } symcur = symcur->nxtsym; } head1 = nullx; head2 = nullx; } /* output symbol listing to listing file */ dspsym() { register SYM *symcur; unsigned char flag; unsigned char buffx[50]; if(!nosym) return; head1 = (unsigned char *)"Symbol Listing"; eject(); flag = 0; line[0] = 0; list(ltruncate ? sheadx : headx); symcur = symbas; for(symcnt = 0; symcnt < symmax; symcnt++) { if(defines(symcur->flag)) { if(flag == (ltruncate ? 3 : 5)) { list(line); line[0] = 0; flag = 0; } if(flag) (void) strcat(line, "\t"); (void) sprintf(buffx, "%04.4X %-14s", symcur->value, symcur->name); (void) strcat(line, buffx); ++flag; } symcur = symcur->nxtsym; } if(flag) list(line); list(ltruncate ? sheadx : headx); head1 = nullx; } dspmap() { register PSECT *pscur = psbas; unsigned char buffx[50]; if(!nopsect || !psectcount) return; head1 = (unsigned char *)"Psect Map"; eject(); do { (void) sprintf(line, "%s%-6s\t%04.4X", pscur->flag ? "Lib: " : " ", pscur->name, pscur->value); list(line); } while(pscur = pscur->nxtp); list(""); list(""); (void) sprintf(line, "Start Address: %04.4X\tLast Address: %04.4X\tTransfer Address: %04.4X", relo[mode], adrefc[mode], saveflag ? adrsave : transaddr); list(line); head1 = nullx; }