📄 ld.c
字号:
#/* * link editor */#define SIGINT 2#define ARCMAGIC 0177555#define FMAGIC 0407#define NMAGIC 0410#define IMAGIC 0411#define EXTERN 040#define UNDEF 00#define ABS 01#define TEXT 02#define DATA 03#define BSS 04#define COMM 05 /* internal use only */#define RABS 00#define RTEXT 02#define RDATA 04#define RBSS 06#define REXT 010#define RELFLG 01#define NROUT 256#define NSYM 501#define NSYMPR 500#define RONLY 0400char premeof[] "Premature EOF on %s";struct page { int nuser; int bno; int nibuf; int buff[256];} page[2];struct { int nuser; int bno;} fpage;struct stream { int *ptr; int bno; int nibuf; int size; struct page *pno;};struct stream text;struct stream reloc;struct archdr { char aname[8]; int atime[2]; char auid, amode; int asize;} archdr;struct filhdr { int fmagic; int tsize; int dsize; int bsize; int ssize; int entry; int pad; int relflg;} filhdr;struct liblist { int off; int bno;};struct liblist liblist[NROUT];struct liblist *libp { &liblist[0] };struct symbol { char sname[8]; char stype; char spad; int svalue;};struct symbol cursym;struct symbol symtab[NSYM];struct symbol *hshtab[NSYM+2];struct symbol *symp { symtab };struct symbol **local[NSYMPR];struct symbol *p_etext;struct symbol *p_edata;struct symbol *p_end;int xflag; /* discard local symbols */int Xflag; /* discard locals starting with 'L' */int rflag; /* preserve relocation bits, don't define common */int arflag; /* original copy of rflag */int sflag; /* discard all symbols */int nflag; /* pure procedure */int dflag; /* define common even with rflag */int iflag; /* I/D space separated */int infil;char *filname;int tsize;int dsize;int bsize;int ssize;int nsym;int torigin;int dorigin;int borigin;int ctrel;int cdrel;int cbrel;int errlev;int delarg 4;char tfname[] "/tmp/lxyyyyy";int toutb[259];int doutb[259];int troutb[259];int droutb[259];int soutb[259];struct symbol **lookup();struct symbol **slookup();main(argc, argv)char **argv;{ extern int delexit(); register c; register char *ap, **p; struct symbol **hp; if ((signal(SIGINT, 1) & 01) == 0) signal(SIGINT, delexit); if (argc == 1) exit(4); p = argv + 1; for (c = 1; c<argc; c++) { filname = 0; ap = *p++; if (*ap == '-') switch (ap[1]) { case 'u': if (++c >= argc) error(1, "Bad 'use'"); if (*(hp = slookup(*p++)) == 0) { *hp = symp; enter(); } continue; case 'l': break; case 'x': xflag++; continue; case 'X': Xflag++; continue; case 'r': rflag++; arflag++; continue; case 's': sflag++; xflag++; continue; case 'n': nflag++; continue; case 'd': dflag++; continue; case 'i': iflag++; continue; } load1arg(ap); close(infil); } middle(); setupout(); p = argv+1; libp = liblist; for (c=1; c<argc; c++) { ap = *p++; if (*ap == '-') switch (ap[1]) { case 'u': ++c; ++p; default: continue; case 'l': break; } load2arg(ap); close(infil); } finishout();}load1arg(acp)char *acp;{ register char *cp; register noff, nbno; cp = acp; if (getfile(cp)==0) { load1(0, 0, 0); return; } nbno = 0; noff = 1; for (;;) { dseek(&text, nbno, noff, sizeof archdr); if (text.size <= 0) { libp->bno = -1; libp++; return; } mget(&archdr, sizeof archdr); if (load1(1, nbno, noff + (sizeof archdr) / 2)) { libp->bno = nbno; libp->off = noff; libp++; } noff =+ (archdr.asize + sizeof archdr)>>1; nbno =+ (noff >> 8) & 0377; noff =& 0377; }}load1(libflg, bno, off){ register struct symbol *sp, **hp, ***cp; struct symbol *ssymp; int ndef, nloc; readhdr(bno, off); ctrel = tsize; cdrel =+ dsize; cbrel =+ bsize; ndef = 0; nloc = sizeof cursym; cp = local; ssymp = symp; if ((filhdr.relflg&RELFLG)==1) { error(0, "No relocation bits"); return(0); } off =+ (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize; dseek(&text, bno, off, filhdr.ssize); while (text.size > 0) { mget(&cursym, sizeof cursym); if ((cursym.stype&EXTERN)==0) { if (Xflag==0 || cursym.sname[0]!='L') nloc =+ sizeof cursym; continue; } symreloc(); hp = lookup(); if ((sp = *hp) == 0) { *hp = enter(); *cp++ = hp; continue; } if (sp->stype != EXTERN+UNDEF) continue; if (cursym.stype == EXTERN+UNDEF) { if (cursym.svalue > sp->svalue) sp->svalue = cursym.svalue; continue; } if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT) continue; ndef++; sp->stype = cursym.stype; sp->svalue = cursym.svalue; } if (libflg==0 || ndef) { tsize =+ filhdr.tsize; dsize =+ filhdr.dsize; bsize =+ filhdr.bsize; ssize =+ nloc; return(1); }/* * No symbols defined by this library member. * Rip out the hash table entries and reset the symbol table. */ symp = ssymp; while (cp > local) **--cp = 0; return(0);}middle(){ register struct symbol *sp; register t, csize; int nund, corigin; p_etext = *slookup("_etext"); p_edata = *slookup("_edata"); p_end = *slookup("_end");/* * If there are any undefined symbols, save the relocation bits. */ if (rflag==0) for (sp=symtab; sp<symp; sp++) if (sp->stype==EXTERN+UNDEF && sp->svalue==0 && sp!=p_end && sp!=p_edata && sp!=p_etext) { rflag++; dflag = 0; nflag = 0; iflag = 0; sflag = 0; break; }/* * Assign common locations. */ csize = 0; if (dflag || rflag==0) { for (sp=symtab; sp<symp; sp++) if (sp->stype==EXTERN+UNDEF && (t=sp->svalue)!=0) { t = (t+1) & ~01; sp->svalue = csize; sp->stype = EXTERN+COMM; csize =+ t; } if (p_etext && p_etext->stype==EXTERN+UNDEF) { p_etext->stype = EXTERN+TEXT; p_etext->svalue = tsize; } if (p_edata && p_edata->stype==EXTERN+UNDEF) { p_edata->stype = EXTERN+DATA; p_edata->svalue = dsize; } if (p_end && p_end->stype==EXTERN+UNDEF) { p_end->stype = EXTERN+BSS; p_end->svalue = bsize; } }/* * Now set symbols to their final value */ if (nflag || iflag) tsize = (tsize + 077) & ~077; dorigin = tsize; if (nflag) dorigin = (tsize+017777) & ~017777; if (iflag) dorigin = 0; corigin = dorigin + dsize; borigin = corigin + csize; nund = 0; for (sp=symtab; sp<symp; sp++) switch (sp->stype) { case EXTERN+UNDEF: errlev =| 01; if (arflag==0 && sp->svalue==0) { if (nund==0) printf("Undefined:\n"); nund++; printf("%.8s\n", sp->sname); } continue; case EXTERN+ABS: default: continue; case EXTERN+TEXT: sp->svalue =+ torigin; continue; case EXTERN+DATA: sp->svalue =+ dorigin; continue; case EXTERN+BSS: sp->svalue =+ borigin; continue; case EXTERN+COMM: sp->stype = EXTERN+BSS; sp->svalue =+ corigin; continue; } if (sflag || xflag) ssize = 0; bsize =+ csize; nsym = ssize / (sizeof cursym);}setupout(){ register char *p; register pid; if ((toutb[0] = creat("l.out", 0666)) < 0) error(1, "Can't create l.out"); pid = getpid(); for (p = &tfname[12]; p > &tfname[7];) { *--p = (pid&07) + '0'; pid =>> 3; } tcreat(doutb, 'a'); if (sflag==0 || xflag==0) tcreat(soutb, 'b'); if (rflag) { tcreat(troutb, 'c'); tcreat(droutb, 'd'); } filhdr.fmagic = FMAGIC; if (nflag) filhdr.fmagic = NMAGIC; if (iflag) filhdr.fmagic = IMAGIC; filhdr.tsize = tsize; filhdr.dsize = dsize; filhdr.bsize = bsize; filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*(symp-symtab)); filhdr.entry = 0; filhdr.pad = 0; filhdr.relflg = (rflag==0); mput(toutb, &filhdr, sizeof filhdr); return;}tcreat(buf, letter)int *buf;{ tfname[6] = letter; if ((buf[0] = creat(tfname, RONLY)) < 0) error(1, "Can't create temp");}load2arg(acp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -