📄 ld.c
字号:
char *acp;{ register char *cp; register struct liblist *lp; cp = acp; if (getfile(cp) == 0) { while (*cp) cp++; while (cp >= acp && *--cp != '/'); mkfsym(++cp); load2(0, 0); return; } for (lp = libp; lp->bno != -1; lp++) { dseek(&text, lp->bno, lp->off, sizeof archdr); mget(&archdr, sizeof archdr); mkfsym(archdr.aname); load2(lp->bno, lp->off + (sizeof archdr) / 2); } libp = ++lp;}load2(bno, off){ register struct symbol *sp; register int *lp, symno; readhdr(bno, off); ctrel = torigin; cdrel =+ dorigin; cbrel =+ borigin;/* * Reread the symbol table, recording the numbering * of symbols for fixing external references. */ lp = local; symno = -1; off =+ (sizeof filhdr)/2; dseek(&text, bno, off+filhdr.tsize+filhdr.dsize, filhdr.ssize); while (text.size > 0) { symno++; mget(&cursym, sizeof cursym); symreloc(); if ((cursym.stype&EXTERN) == 0) { if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L')) mput(soutb, &cursym, sizeof cursym); continue; } if ((sp = *lookup()) == 0) error(1, "internal error: symbol not found"); if (cursym.stype == EXTERN+UNDEF) { if (lp >= &local[NSYMPR]) error(1, "Local symbol overflow"); *lp++ = symno; *lp++ = sp; continue; } if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) { printf("%.8s: ", cursym.sname); error(0, "Multiply defined"); } } dseek(&text, bno, off, filhdr.tsize); dseek(&reloc, bno, off+(filhdr.tsize+filhdr.dsize)/2, filhdr.tsize); load2td(lp, ctrel, toutb, troutb); dseek(&text, bno, off+(filhdr.tsize/2), filhdr.dsize); dseek(&reloc, bno, off+filhdr.tsize+(filhdr.dsize/2), filhdr.dsize); load2td(lp, cdrel, doutb, droutb); torigin =+ filhdr.tsize; dorigin =+ filhdr.dsize; borigin =+ filhdr.bsize;}load2td(lp, creloc, b1, b2)int *lp;{ register r, t; register struct symbol *sp; for (;;) { /* * The pickup code is copied from "get" for speed. */ if (--text.size <= 0) { if (text.size < 0) break; text.size++; t = get(&text); } else if (--text.nibuf < 0) { text.nibuf++; text.size++; t = get(&text); } else t = *text.ptr++; if (--reloc.size <= 0) { if (reloc.size < 0) error(1, "Relocation error"); reloc.size++; r = get(&reloc); } else if (--reloc.nibuf < 0) { reloc.nibuf++; reloc.size++; r = get(&reloc); } else r = *reloc.ptr++; switch (r&016) { case RTEXT: t =+ ctrel; break; case RDATA: t =+ cdrel; break; case RBSS: t =+ cbrel; break; case REXT: sp = lookloc(lp, r); if (sp->stype==EXTERN+UNDEF) { r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT; break; } t =+ sp->svalue; r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1); break; } if (r&01) t =- creloc; putw(t, b1); if (rflag) putw(r, b2); }}finishout(){ register n, *p; if (nflag||iflag) { n = torigin; while (n&077) { n =+ 2; putw(0, toutb); if (rflag) putw(0, troutb); } } copy(doutb, 'a'); if (rflag) { copy(troutb, 'c'); copy(droutb, 'd'); } if (sflag==0) { if (xflag==0) copy(soutb, 'b'); for (p=symtab; p < symp;) putw(*p++, toutb); } fflush(toutb); close(toutb[0]); unlink("a.out"); link("l.out", "a.out"); delarg = errlev; delexit();}delexit(){ register c; unlink("l.out"); for (c = 'a'; c <= 'd'; c++) { tfname[6] = c; unlink(tfname); } if (delarg==0) chmod("a.out", 0777); exit(delarg);}copy(buf, c)int *buf;{ register f, *p, n; fflush(buf); close(buf[0]); tfname[6] = c; f = open(tfname, 0); while ((n = read(f, doutb, 512)) > 1) { n =>> 1; p = doutb; do putw(*p++, toutb); while (--n); } close(f);}mkfsym(s)char *s;{ if (sflag || xflag) return; cp8c(s, cursym.sname); cursym.stype = 037; cursym.svalue = torigin; mput(soutb, &cursym, sizeof cursym);}mget(aloc, an)int *aloc;{ register *loc, n; register *p; n = an; n =>> 1; loc = aloc; if ((text.nibuf =- n) >= 0) { if ((text.size =- n) > 0) { p = text.ptr; do *loc++ = *p++; while (--n); text.ptr = p; return; } else text.size =+ n; } text.nibuf =+ n; do { *loc++ = get(&text); } while (--n);}mput(buf, aloc, an)int *aloc;{ register *loc; register n; loc = aloc; n = an>>1; do { putw(*loc++, buf); } while (--n);}dseek(asp, ab, o, s){ register struct stream *sp; register struct page *p; register b; int n; sp = asp; b = ab + ((o>>8) & 0377); o =& 0377; --sp->pno->nuser; if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b) if (p->nuser==0 || (p = &page[0])->nuser==0) { if (page[0].nuser==0 && page[1].nuser==0) if (page[0].bno < page[1].bno) p = &page[0]; p->bno = b; seek(infil, b, 3); if ((n = read(infil, p->buff, 512)>>1) < 0) n = 0; p->nibuf = n; } else error(1, "No pages"); ++p->nuser; sp->bno = b; sp->pno = p; sp->ptr = p->buff + o; if (s != -1) sp->size = (s>>1) & 077777; if ((sp->nibuf = p->nibuf-o) <= 0) sp->size = 0;}get(asp)struct stream *asp;{ register struct stream *sp; sp = asp; if (--sp->nibuf < 0) { dseek(sp, sp->bno+1, 0, -1); --sp->nibuf; } if (--sp->size <= 0) { if (sp->size < 0) error(1, premeof); ++fpage.nuser; --sp->pno->nuser; sp->pno = &fpage; } return(*sp->ptr++);}getfile(acp)char *acp;{ register char *cp; register c; cp = acp; archdr.aname[0] = '\0'; if (cp[0]=='-' && cp[1]=='l') { if ((c = cp[2]) == '\0') c = 'a'; cp = "/lib/lib?.a"; cp[8] = c; } filname = cp; if ((infil = open(cp, 0)) < 0) error(1, "cannot open"); page[0].bno = page[1].bno = -1; page[0].nuser = page[1].nuser = 0; text.pno = reloc.pno = &fpage; fpage.nuser = 2; dseek(&text, 0, 0, 2); if (text.size <= 0) error(1, premeof); return(get(&text) == ARCMAGIC);}struct symbol **lookup(){ int i; register struct symbol **hp; register char *cp, *cp1; i = 0; for (cp=cursym.sname; cp < &cursym.sname[8];) i = (i<<1) + *cp++; for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) { cp1 = (*hp)->sname; for (cp=cursym.sname; cp < &cursym.sname[8];) if (*cp++ != *cp1++) goto no; break; no: if (++hp >= &hshtab[NSYM+2]) hp = hshtab; } return(hp);}struct symbol **slookup(s)char *s;{ cp8c(s, cursym.sname); cursym.stype = EXTERN+UNDEF; cursym.svalue = 0; return(lookup());}enter(){ register struct symbol *sp; if ((sp=symp) >= &symtab[NSYM]) error(1, "Symbol table overflow"); cp8c(cursym.sname, sp->sname); sp->stype = cursym.stype; sp->svalue = cursym.svalue; symp++; return(sp);}symreloc(){ switch (cursym.stype) { case TEXT: case EXTERN+TEXT: cursym.svalue =+ ctrel; return; case DATA: case EXTERN+DATA: cursym.svalue =+ cdrel; return; case BSS: case EXTERN+BSS: cursym.svalue =+ cbrel; return; case EXTERN+UNDEF: return; } if (cursym.stype&EXTERN) cursym.stype = EXTERN+ABS;}error(n, s)char *s;{ if (filname) { printf("%s", filname); if (archdr.aname[0]) printf("(%.8s)", archdr.aname); printf(": "); } printf("%s\n", s); if (n) delexit(); errlev = 2;}lookloc(alp, r){ register int *clp, *lp; register sn; lp = alp; sn = (r>>4) & 07777; for (clp=local; clp<lp; clp =+ 2) if (clp[0] == sn) return(clp[1]); error(1, "Local symbol botch");}readhdr(bno, off){ register st, sd; dseek(&text, bno, off, sizeof filhdr); mget(&filhdr, sizeof filhdr); if (filhdr.fmagic != FMAGIC) error(1, "Bad format"); st = (filhdr.tsize+01) & ~01; filhdr.tsize = st; cdrel = -st; sd = (filhdr.dsize+01) & ~01; cbrel = - (st+sd); filhdr.bsize = (filhdr.bsize+01) & ~01;}cp8c(from, to)char *from, *to;{ register char *f, *t, *te; f = from; t = to; te = t+8; while ((*t++ = *f++) && t<te); while (t<te) *t++ = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -