BSD 3 development
[unix-history] / usr / src / cmd / ld.c
index fec3bd8..90e8895 100644 (file)
@@ -1,4 +1,3 @@
-#
 char LD[] = "@(#)ld.c 1.10 78/12/07 15:34:58"; /* sccs ident */
 /*
  *  link editor for VAX
 char LD[] = "@(#)ld.c 1.10 78/12/07 15:34:58"; /* sccs ident */
 /*
  *  link editor for VAX
@@ -7,7 +6,7 @@ char LD[] = "@(#)ld.c 1.10 78/12/07 15:34:58";  /* sccs ident */
 /*     layout of a.out file:
  *
  *     header of 8 words       magic number 0410:
 /*     layout of a.out file:
  *
  *     header of 8 words       magic number 0410:
-                                       data starts at 1st 0777
+                                       data starts at 1st (PAGSIZ)
                                        boundary above text
                                magic number 0407:
                                        data starts immediately after
                                        boundary above text
                                magic number 0407:
                                        data starts immediately after
@@ -33,6 +32,7 @@ char LD[] = "@(#)ld.c 1.10 78/12/07 15:34:58";        /* sccs ident */
 #include <stdio.h>
 #include <ar.h>
 #include <a.out.h>
 #include <stdio.h>
 #include <ar.h>
 #include <a.out.h>
+#include <pagsiz.h>
 
 struct {short hiword; short loword;}; /* stupid fp-11 */
 fixl(p) register long *p;{
 
 struct {short hiword; short loword;}; /* stupid fp-11 */
 fixl(p) register long *p;{
@@ -102,7 +102,6 @@ typedef     int BOOL;
 #define        FW      03
 #define        DW      07
 
 #define        FW      03
 #define        DW      07
 
-#define        PAGRND  0777
 
 #define        TYPMASK 0x1E
 #define        TYMASK  (0x1E)
 
 #define        TYPMASK 0x1E
 #define        TYMASK  (0x1E)
@@ -150,7 +149,7 @@ typedef struct {
        int     bno;
        int     nibuf;
        int     nuser;
        int     bno;
        int     nibuf;
        int     nuser;
-       char    buff[512];
+       char    buff[BSIZE];
 } PAGE;
 
 PAGE   page[2];
 } PAGE;
 
 PAGE   page[2];
@@ -227,6 +226,7 @@ int nflag = 1;      /* pure procedure */
 int    dflag;          /* define common even with rflag */
 int    iflag;          /* I/D space separated */
 BOOL   vflag;          /* overlays used */
 int    dflag;          /* define common even with rflag */
 int    iflag;          /* I/D space separated */
 BOOL   vflag;          /* overlays used */
+int    zflag;
 
 int    ofilfnd;
 char   *ofilename      = "l.out";
 
 int    ofilfnd;
 char   *ofilename      = "l.out";
@@ -295,7 +295,7 @@ delexit()
        unlink(droutn);
        unlink(soutn);
        if (delarg==0)
        unlink(droutn);
        unlink(soutn);
        if (delarg==0)
-               chmod(ofilename, 0777);
+               chmod(ofilename, 0777 &~ umask(0));
        exit(delarg);
 }
 
        exit(delarg);
 }
 
@@ -423,6 +423,10 @@ char **argv;
                                trace++;
                                continue;
 
                                trace++;
                                continue;
 
+                       case 'z':
+                               zflag++;
+                               continue;
+
                        default:
                                error(1, "bad flag");
                        } /*endsw*/
                        default:
                                error(1, "bad flag");
                        } /*endsw*/
@@ -549,7 +553,9 @@ register char *cp;
                        dseek(&text, loc, (long)sizeof(archdr));
                        if (text.size <= 0) {
                                libp->loc = -1;
                        dseek(&text, loc, (long)sizeof(archdr));
                        if (text.size <= 0) {
                                libp->loc = -1;
-                               libp++;
+                               if( ++libp >= liblist + NROUT)
+                                       error(1,"liblist overflow");
+                                       /* thanks to Dennis Wasley */
                                return;
                        }
                        mget((short *)&archdr, sizeof archdr, &text);
                                return;
                        }
                        mget((short *)&archdr, sizeof archdr, &text);
@@ -593,7 +599,7 @@ long loc;
                symget(&cursym, &text);
                type = cursym.stype;
                if ((type&EXTERN)==0) {
                symget(&cursym, &text);
                type = cursym.stype;
                if ((type&EXTERN)==0) {
-                       if (Xflag==0 || cursym.sname[0]!='L' || type&STABTYPS)
+                       if (Xflag==0 || cursym.sname[0]!='L' || type & STABTYPS)
                                nlocal += sizeof cursym;
                        continue;
                }
                                nlocal += sizeof cursym;
                        continue;
                }
@@ -700,6 +706,10 @@ middle()
        dorigin = database;
        corigin = dorigin + dsize;
        borigin = corigin + csize;
        dorigin = database;
        corigin = dorigin + dsize;
        borigin = corigin + csize;
+/*
+       if (zflag)
+               borigin = round(borigin, PAGRND);
+*/
        cdorel = 0;
        cborel = dsize+csize;
        nund = 0;
        cdorel = 0;
        cborel = dsize+csize;
        nund = 0;
@@ -762,6 +772,7 @@ extern char _sibuf[BUFSIZ]; /* the space is forced upon us; might as well use it
 
 setupout()
 {
 
 setupout()
 {
+       int bss;
        tout = fopen(ofilename, "w");
        if (tout==NULL)
                error(1, "cannot create output");
        tout = fopen(ofilename, "w");
        if (tout==NULL)
                error(1, "cannot create output");
@@ -774,9 +785,18 @@ setupout()
                drout = tcreat(&droutn, "/tmp/lddaXXXXX");
        }
        filhdr.a_magic = nflag? NMAGIC:OMAGIC;
                drout = tcreat(&droutn, "/tmp/lddaXXXXX");
        }
        filhdr.a_magic = nflag? NMAGIC:OMAGIC;
+       if (zflag)
+               filhdr.a_magic = nflag?0413:0412;
        filhdr.a_text = nflag? tsize:round(tsize, FW);
        filhdr.a_text = nflag? tsize:round(tsize, FW);
+       if (zflag)
+               filhdr.a_text = round(tsize, PAGRND);
        filhdr.a_data = dsize;
        filhdr.a_data = dsize;
-       filhdr.a_bss = bsize;
+       if (zflag)
+               filhdr.a_data = round(dsize, PAGRND);
+       bss = bsize - (filhdr.a_data - dsize);
+       if (bss < 0)
+               bss = 0;
+       filhdr.a_bss = bss;
        filhdr.a_trsize = trsize;
        filhdr.a_drsize = drsize;
        filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*(nextsym-symtab));
        filhdr.a_trsize = trsize;
        filhdr.a_drsize = drsize;
        filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*(nextsym-symtab));
@@ -790,6 +810,8 @@ setupout()
        filhdr.a_trsize = (rflag ? trsize:0);
        filhdr.a_drsize = (rflag ? drsize:0);
        writel(&filhdr,8,tout);
        filhdr.a_trsize = (rflag ? trsize:0);
        filhdr.a_drsize = (rflag ? drsize:0);
        writel(&filhdr,8,tout);
+       if (zflag)
+               fseek(tout, PAGSIZ, 0);
 }
 
 FILE *
 }
 
 FILE *
@@ -859,7 +881,8 @@ long loc;
                symreloc();
                type = cursym.stype;
                if ((type&EXTERN) == 0) {
                symreloc();
                type = cursym.stype;
                if ((type&EXTERN) == 0) {
-                       if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L'||type&STABTYPS))
+                       if (!sflag&&!xflag&&
+                               (!Xflag||cursym.sname[0]!='L'||type&STABTYPS))
                                symwrite(&cursym, 1, sout);
                        continue;
                }
                                symwrite(&cursym, 1, sout);
                        continue;
                }
@@ -977,6 +1000,14 @@ finishout()
                while (tsize&FW) {
                        putc(0, tout); tsize++;
                }
                while (tsize&FW) {
                        putc(0, tout); tsize++;
                }
+       if (zflag) {
+               while (tsize&PAGRND) {
+                       putc(0, tout); tsize++;
+               }
+               while (dsize&PAGRND) {
+                       putc(0, dout); dsize++;
+               }
+       }
        fclose(dout);
        copy(doutn);
        if (rflag) {
        fclose(dout);
        copy(doutn);
        if (rflag) {
@@ -1090,8 +1121,8 @@ long loc, s;
        register b, o;
        int n;
 
        register b, o;
        int n;
 
-       b = loc>>9;
-       o = loc&0777;
+       b = loc>>BSHIFT;
+       o = loc&BMASK;
        if (o&01)
                error(1, "loader error; odd offset");
        --sp->pno->nuser;
        if (o&01)
                error(1, "loader error; odd offset");
        --sp->pno->nuser;
@@ -1101,7 +1132,7 @@ long loc, s;
                                if (page[0].bno < page[1].bno)
                                        p = &page[0];
                        p->bno = b;
                                if (page[0].bno < page[1].bno)
                                        p = &page[0];
                        p->bno = b;
-                       lseek(infil, loc & ~0777L, 0);
+                       lseek(infil, loc & ~(long)BMASK, 0);
                        if ((n = read(infil, p->buff, sizeof(p->buff))) < 0)
                                n = 0;
                        p->nibuf = n;
                        if ((n = read(infil, p->buff, sizeof(p->buff))) < 0)
                                n = 0;
                        p->nibuf = n;
@@ -1124,7 +1155,7 @@ STREAM *asp;
 
        sp = asp;
        if ((sp->nibuf -= sizeof(char)) < 0) {
 
        sp = asp;
        if ((sp->nibuf -= sizeof(char)) < 0) {
-               dseek(sp, ((long)(sp->bno+1)<<9), (long)-1);
+               dseek(sp, ((long)(sp->bno+1)<<BSHIFT), (long)-1);
                sp->nibuf -= sizeof(char);
        }
        if ((sp->size -= sizeof(char)) <= 0) {
                sp->nibuf -= sizeof(char);
        }
        if ((sp->size -= sizeof(char)) <= 0) {
@@ -1150,16 +1181,21 @@ STRING acp;
        archdr.ar_name[0] = '\0';
        filname = cp;
        if (cp[0]=='-' && cp[1]=='l') {
        archdr.ar_name[0] = '\0';
        filname = cp;
        if (cp[0]=='-' && cp[1]=='l') {
+               char *locfilname = "/usr/local/lib/libxxxxxxxxxxxxxxx";
                if(cp[2] == '\0')
                        cp = "-la";
                filname = "/usr/lib/libxxxxxxxxxxxxxxx";
                if(cp[2] == '\0')
                        cp = "-la";
                filname = "/usr/lib/libxxxxxxxxxxxxxxx";
-               for(c=0; cp[c+2]; c++)
+               for(c=0; cp[c+2]; c++) {
                        filname[c+12] = cp[c+2];
                        filname[c+12] = cp[c+2];
-               filname[c+12] = '.';
-               filname[c+13] = 'a';
-               filname[c+14] = '\0';
+                       locfilname[c+18] = cp[c+2];
+               }
+               filname[c+12] = locfilname[c+18] = '.';
+               filname[c+13] = locfilname[c+19] = 'a';
+               filname[c+14] = locfilname[c+20] = '\0';
                if ((infil = open(filname+4, 0)) >= 0) {
                        filname += 4;
                if ((infil = open(filname+4, 0)) >= 0) {
                        filname += 4;
+               } else if ((infil = open(filname, 0)) < 0) {
+                       filname = locfilname;
                }
        }
        if (infil == -1 && (infil = open(filname, 0)) < 0)
                }
        }
        if (infil == -1 && (infil = open(filname, 0)) < 0)