📄 ld.c
字号:
cursym.n_value = torigin; symwrite(&cursym, sout);}getarhdr(){ register char *cp; mget((char *)&archdr, sizeof archdr, &text); for (cp=archdr.ar_name; cp<&archdr.ar_name[sizeof(archdr.ar_name)];) if (*cp++ == ' ') { cp[-1] = 0; return; }}mget(loc, n, sp)register STREAM *sp;register char *loc;{ register char *p; register int take;top: if (n == 0) return; if (sp->size && sp->nibuf) { p = sp->ptr; take = sp->size; if (take > sp->nibuf) take = sp->nibuf; if (take > n) take = n; n -= take; sp->size -= take; sp->nibuf -= take; sp->pos += take; do *loc++ = *p++; while (--take > 0); sp->ptr = p; goto top; } if (n > p_blksize) { take = n - n % p_blksize; lseek(infil, (sp->bno+1)<<p_blkshift, 0); if (take > sp->size || read(infil, loc, take) != take) error(1, "premature EOF"); loc += take; n -= take; sp->size -= take; sp->pos += take; dseek(sp, (sp->bno+1+(take>>p_blkshift))<<p_blkshift, -1); goto top; } *loc++ = get(sp); --n; goto top;}symwrite(sp, bp) struct nlist *sp; struct biobuf *bp;{ register int len; register char *str; str = sp->n_un.n_name; if (str) { sp->n_un.n_strx = offset; len = strlen(str) + 1; bwrite(str, len, strout); offset += len; } bwrite(sp, sizeof (*sp), bp); sp->n_un.n_name = str;}dseek(sp, loc, s)register STREAM *sp;long loc, s;{ register PAGE *p; register b, o; int n; b = loc>>p_blkshift; o = loc&p_blkmask; if (o&01) error(1, "loader error; odd offset"); --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; lseek(infil, loc & ~(long)p_blkmask, 0); if ((n = read(infil, p->buff, p_blksize)) < 0) n = 0; p->nibuf = n; } else error(1, "botch: no pages"); ++p->nuser; sp->bno = b; sp->pno = p; if (s != -1) {sp->size = s; sp->pos = 0;} sp->ptr = (char *)(p->buff + o); if ((sp->nibuf = p->nibuf-o) <= 0) sp->size = 0;}charget(asp)STREAM *asp;{ register STREAM *sp; sp = asp; if ((sp->nibuf -= sizeof(char)) < 0) { dseek(sp, ((long)(sp->bno+1)<<p_blkshift), (long)-1); sp->nibuf -= sizeof(char); } if ((sp->size -= sizeof(char)) <= 0) { if (sp->size < 0) error(1, "premature EOF"); ++fpage.nuser; --sp->pno->nuser; sp->pno = (PAGE *) &fpage; } sp->pos += sizeof(char); return(*sp->ptr++);}getfile(acp)char *acp;{ register int c; char arcmag[SARMAG+1]; struct stat stb; archdr.ar_name[0] = '\0'; filname = acp; if (filname[0] == '-' && filname[1] == 'l') infil = libopen(filname + 2, O_RDONLY); else infil = open(filname, O_RDONLY); if (infil < 0) error(1, "cannot open"); fstat(infil, &stb); page[0].bno = page[1].bno = -1; page[0].nuser = page[1].nuser = 0; c = stb.st_blksize; if (c == 0 || (c & (c - 1)) != 0) { /* use default size if not a power of two */ c = BLKSIZE; } if (p_blksize != c) { p_blksize = c; p_blkmask = c - 1; for (p_blkshift = 0; c > 1 ; p_blkshift++) c >>= 1; if (page[0].buff != NULL) free(page[0].buff); page[0].buff = (char *)malloc(p_blksize); if (page[0].buff == NULL) error(1, "ran out of memory (getfile)"); if (page[1].buff != NULL) free(page[1].buff); page[1].buff = (char *)malloc(p_blksize); if (page[1].buff == NULL) error(1, "ran out of memory (getfile)"); } text.pno = reloc.pno = (PAGE *) &fpage; fpage.nuser = 2; dseek(&text, 0L, SARMAG); if (text.size <= 0) error(1, "premature EOF"); mget((char *)arcmag, SARMAG, &text); arcmag[SARMAG] = 0; if (strcmp(arcmag, ARMAG)) return (0); dseek(&text, SARMAG, sizeof archdr); if (text.size <= 0) return (1); getarhdr(); if (strncmp(archdr.ar_name, "__.SYMDEF", sizeof(archdr.ar_name)) != 0) return (1); return (stb.st_mtime > atol(archdr.ar_date) ? 3 : 2);}/* * Search for a library with given name * using the directory search array. */libopen(name, oflags) char *name; int oflags;{ register char *p, *cp; register int i; static char buf[MAXPATHLEN+1]; int fd = -1; if (*name == '\0') /* backwards compat */ name = "a"; else if ((name[0] == 'g') && (name[1] == '\0')) gflag = 1; /* -lg for dbx */ for (i = 0; i < ndir && fd == -1; i++) { p = buf; for (cp = dirs[i]; *cp; *p++ = *cp++) ; *p++ = '/'; for (cp = "lib"; *cp; *p++ = *cp++) ; for (cp = name; *cp; *p++ = *cp++) ; cp = ".a"; while (*p++ = *cp++) ; fd = open(buf, oflags); } if (fd != -1) filname = buf; return (fd);}struct nlist **lookup(){ register int sh; register struct nlist **hp; register char *cp, *cp1; register struct symseg *gp; register int i; sh = 0; for (cp = cursym.n_un.n_name; *cp;) sh = (sh<<1) + *cp++; sh = (sh & 0x7fffffff) % HSIZE; for (gp = symseg; gp < &symseg[NSEG]; gp++) { if (gp->sy_first == 0) { gp->sy_first = (struct nlist *) calloc(NSYM, sizeof (struct nlist)); gp->sy_hfirst = (struct nlist **) calloc(HSIZE, sizeof (struct nlist *)); if (gp->sy_first == 0 || gp->sy_hfirst == 0) error(1, "ran out of space for symbol table"); gp->sy_last = gp->sy_first + NSYM; gp->sy_hlast = gp->sy_hfirst + HSIZE; } if (gp > csymseg) csymseg = gp; hp = gp->sy_hfirst + sh; i = 1; do { if (*hp == 0) { if (gp->sy_used == NSYM) break; return (hp); } cp1 = (*hp)->n_un.n_name; for (cp = cursym.n_un.n_name; *cp == *cp1++;) if (*cp++ == 0) return (hp); hp += i; i += 2; if (hp >= gp->sy_hlast) hp -= HSIZE; } while (i < HSIZE); if (i > HSIZE) error(1, "hash table botch"); } error(1, "symbol table overflow"); /*NOTREACHED*/}symfree(saved) struct nlist *saved;{ register struct symseg *gp; register struct nlist *sp; for (gp = csymseg; gp >= symseg; gp--, csymseg--) { sp = gp->sy_first + gp->sy_used; if (sp == saved) { nextsym = sp; return; } for (sp--; sp >= gp->sy_first; sp--) { gp->sy_hfirst[sp->n_hash] = 0; gp->sy_used--; if (sp == saved) { nextsym = sp; return; } } } if (saved == 0) return; error(1, "symfree botch");}struct nlist **slookup(s) char *s;{ cursym.n_un.n_name = s; cursym.n_type = N_EXT+N_UNDF; cursym.n_value = 0; return (lookup());}enter(hp)register struct nlist **hp;{ register struct nlist *sp; if (*hp==0) { if (hp < csymseg->sy_hfirst || hp >= csymseg->sy_hlast) error(1, "enter botch"); *hp = lastsym = sp = csymseg->sy_first + csymseg->sy_used; csymseg->sy_used++; sp->n_un.n_name = cursym.n_un.n_name; sp->n_type = cursym.n_type; sp->n_hash = hp - csymseg->sy_hfirst; sp->n_value = cursym.n_value; nextsym = lastsym + 1; return(1); } else { lastsym = *hp; return(0); }}symx(sp) struct nlist *sp;{ register struct symseg *gp; if (sp == 0) return (0); for (gp = csymseg; gp >= symseg; gp--) /* <= is sloppy so nextsym will always work */ if (sp >= gp->sy_first && sp <= gp->sy_last) return ((gp - symseg) * NSYM + sp - gp->sy_first); error(1, "symx botch"); /*NOTREACHED*/}symreloc(){ if(funding) return; switch (cursym.n_type & 017) { case N_TEXT: case N_EXT+N_TEXT: cursym.n_value += ctrel; /* Count the number of functions in the symbol table. * This information is supplied for dbx. */ nfun++; return; case N_DATA: case N_EXT+N_DATA: cursym.n_value += cdrel; return; case N_BSS: case N_EXT+N_BSS: cursym.n_value += cbrel; return; case N_EXT+N_UNDF: return; default: if (cursym.n_type&N_EXT) cursym.n_type = N_EXT+N_ABS; return; }}error(n, s)char *s;{ if (errlev==0) printf("ld:"); if (filname) { printf("%s", filname); if (n != -1 && archdr.ar_name[0]) printf("(%s)", archdr.ar_name); printf(": "); } printf("%s\n", s); if (n == -1) return; if (n) delexit(); errlev = 2;}readhdr(loc)off_t loc;{ dseek(&text, loc, (long)sizeof(filhdr)); mget((short *)&filhdr, sizeof(filhdr), &text); if (N_BADMAG(filhdr)) { if (filhdr.a_magic == OARMAG) error(1, "old archive"); error(1, "bad magic number"); } if (filhdr.a_text&01 || filhdr.a_data&01) error(1, "text/data size odd"); if (filhdr.a_magic == NMAGIC || filhdr.a_magic == ZMAGIC) { cdrel = -round(filhdr.a_text, pagesize); cbrel = cdrel - filhdr.a_data; } else if (filhdr.a_magic == OMAGIC) { cdrel = -filhdr.a_text; cbrel = cdrel - filhdr.a_data; } else error(1, "bad format");}round(v, r) int v; u_long r;{ r--; v += r; v &= ~(long)r; return(v);}#define NSAVETAB 8192char *savetab;int saveleft;char *savestr(cp) register char *cp;{ register int len; len = strlen(cp) + 1; if (len > saveleft) { saveleft = NSAVETAB; if (len > saveleft) saveleft = len; savetab = malloc(saveleft); if (savetab == 0) error(1, "ran out of memory (savestr)"); } strncpy(savetab, cp, len); cp = savetab; savetab += len; saveleft -= len; return (cp);}bopen(bp, off, bufsize) register struct biobuf *bp;{ bp->b_ptr = bp->b_buf = malloc(bufsize); if (bp->b_ptr == (char *)0) error(1, "ran out of memory (bopen)"); bp->b_bufsize = bufsize; bp->b_nleft = bufsize - (off % bufsize); bp->b_off = off; bp->b_link = biobufs; biobufs = bp;}int bwrerror;bwrite(p, cnt, bp) register char *p; register int cnt; register struct biobuf *bp;{ register int put; register char *to;top: if (cnt == 0) return; if (bp->b_nleft) { put = bp->b_nleft; if (put > cnt) put = cnt; bp->b_nleft -= put; to = bp->b_ptr; bcopy(p, to, put); bp->b_ptr += put; p += put; cnt -= put; goto top; } if (cnt >= bp->b_bufsize) { if (bp->b_ptr != bp->b_buf) bflush1(bp); put = cnt - cnt % bp->b_bufsize; if (boffset != bp->b_off) lseek(biofd, bp->b_off, 0); if (write(biofd, p, put) != put) { bwrerror = 1; error(1, "output write error"); } bp->b_off += put; boffset = bp->b_off; p += put; cnt -= put; goto top; } bflush1(bp); goto top;}bflush(){ register struct biobuf *bp; if (bwrerror) return; for (bp = biobufs; bp; bp = bp->b_link) bflush1(bp);}bflush1(bp) register struct biobuf *bp;{ register int cnt = bp->b_ptr - bp->b_buf; if (cnt == 0) return; if (boffset != bp->b_off) lseek(biofd, bp->b_off, 0); if (write(biofd, bp->b_buf, cnt) != cnt) { bwrerror = 1; error(1, "output write error"); } bp->b_off += cnt; boffset = bp->b_off; bp->b_ptr = bp->b_buf; bp->b_nleft = bp->b_bufsize;}bflushc(bp, c) register struct biobuf *bp;{ bflush1(bp); bputc(c, bp);}bseek(bp, off) register struct biobuf *bp; register off_t off;{ bflush1(bp); bp->b_nleft = bp->b_bufsize - (off % bp->b_bufsize); bp->b_off = off;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -