Annotation of researchv10no/cmd/sml/src/runtime/linkdata.c, revision 1.1

1.1     ! root        1: /* Copyright 1989 by AT&T Bell Laboratories */
        !             2: /* linkdata.c -- group files into the text segment of a .o file */
        !             3: 
        !             4: #define SYMBOL     "_datalist"
        !             5: #define END_SYMBOL  "_endmo"
        !             6: 
        !             7: #include <stdio.h>
        !             8: #include <a.out.h>
        !             9: #include <assert.h>
        !            10: #include <sys/types.h>
        !            11: #include <sys/stat.h>
        !            12: #include "tags.h"
        !            13: 
        !            14: #define LONG       (sizeof(long))
        !            15: #define align(x)    (((x) + (LONG - 1)) & ~(LONG - 1))
        !            16: 
        !            17: #ifdef SPARC
        !            18: #define relocation_info reloc_info_sparc
        !            19: #endif
        !            20: 
        !            21: #define RELINFO_SZ  (sizeof (struct relocation_info))
        !            22: 
        !            23: struct relocation_info rconst, *rel;
        !            24: struct nlist nlconst, *nl;
        !            25: 
        !            26: struct str_table {  /* The string table buffer. */
        !            27:     int            len;    /* length including this word */
        !            28:     char    strs[4];
        !            29: } *str_tbl;
        !            30: char *str_ptr; /* the next location in the string table. */
        !            31: 
        !            32: /* add_name:
        !            33:  * Extract the structure name from the file name and add it to the string table
        !            34:  * buffer (with an initial "_").
        !            35:  */
        !            36: void add_name (file)
        !            37:     char *file;
        !            38: {
        !            39:     register char   *p, *begin;
        !            40:     int                    len, res;
        !            41: 
        !            42:   /* find the beginning of the file name. */
        !            43:     for (p = begin = file;  *p;         p++) {
        !            44:        if (*p == '/')
        !            45:            begin = p+1;
        !            46:     }
        !            47: 
        !            48:   /* find the ".mo" */
        !            49:     for (p = begin, len = 0;  *p && (*p != '.');  p++, len++)
        !            50:        continue;
        !            51: 
        !            52:     *str_ptr++ = '_';
        !            53:     strncpy(str_ptr, begin, len);
        !            54:     str_ptr += len;
        !            55:     *str_ptr++ = '\0';
        !            56:     str_tbl->len += (len+2);
        !            57: }
        !            58: 
        !            59: void die(s)
        !            60:     char *s;
        !            61: {
        !            62:     perror(s);
        !            63:     exit(1);
        !            64: }
        !            65: 
        !            66: extern long *malloc(); /* wrong but convenient */
        !            67: 
        !            68: 
        !            69: /* link:
        !            70:  * append the code from file to linked code.  pc is the relative starting address,
        !            71:  * last = 1, if this is the last file to link.
        !            72:  */
        !            73: int link (file, pc, last)
        !            74:     char *file; long pc; int last;
        !            75: {
        !            76:     int fd;
        !            77:     long i, len, n, nbytes;
        !            78:     char *s;
        !            79:     struct stat st;
        !            80:     static int bufsize = 0;
        !            81:     static long *buf;
        !            82: 
        !            83:     if ((fd = open(file, 0)) == -1) {
        !            84:        char    buf[64];
        !            85:        sprintf(buf, "open: %s", file);
        !            86:        die(buf);
        !            87:     }
        !            88:     if (fstat(fd, &st) == -1)
        !            89:        die("stat");
        !            90: 
        !            91:     n = st.st_size;
        !            92:     len = strlen(file);
        !            93:     nbytes = align(n) + align(len) + 6 * LONG;
        !            94: 
        !            95:     if (n + len + 40 > bufsize) {
        !            96:        bufsize = n + len + 4096;
        !            97:        if (buf != NULL)
        !            98:            free(buf);
        !            99:        buf = malloc(bufsize);
        !           100:        if (buf == NULL)
        !           101:            die("malloc(buf)");
        !           102:     }
        !           103: 
        !           104:   /* initialize the header record and add its fields to the list of
        !           105:    * relocatable addresses.
        !           106:    */
        !           107:     buf[0] = mak_desc(3, tag_record);
        !           108: #ifdef SPARC
        !           109: #define REL(addr, addend)   \
        !           110:     (*rel = rconst, rel->r_addend = (addend), (rel++)->r_address = (addr))
        !           111: 
        !           112:     buf[1] = 0;
        !           113:     REL(pc + LONG, pc + 5 * LONG);
        !           114:     buf[2] = 0;
        !           115:     REL(pc + 2 * LONG, pc + 6 * LONG + align(len));
        !           116:     if (last)
        !           117:        buf[3] = 1;                        /* either ML 0 */
        !           118:     else {
        !           119:        buf[3] = 0;
        !           120:        REL(pc + 3 * LONG, pc + nbytes + LONG);
        !           121:     }
        !           122: #else
        !           123: 
        !           124: #define REL(addr)   (*rel = rconst, (rel++)->r_address = (addr))
        !           125: 
        !           126:     buf[1] = pc + 5 * LONG;               /* address of file name */
        !           127:     REL(pc + LONG);
        !           128:     buf[2] = buf[1] + LONG + align(len);   /* address of code */
        !           129:     REL(pc + 2 * LONG);
        !           130:     if (last)
        !           131:        buf[3] = 1;                        /* either ML 0 */
        !           132:     else {
        !           133:        buf[3] = pc + nbytes + LONG;       /* or the address of next module */
        !           134:        REL(pc + 3 * LONG);
        !           135:     }
        !           136: #endif
        !           137: 
        !           138:     buf[4] = mak_desc(len, tag_string);           /* tag for file name */
        !           139:     strcpy(&buf[5], file);
        !           140:     s = ((char *) &buf[5]) + len;
        !           141:     for (i = align(len); i > len; i--)
        !           142:        *s++ = 0;
        !           143: 
        !           144:     *((long *) s) = mak_desc(n, tag_string);  /* tag for code */
        !           145:     s += LONG;
        !           146: 
        !           147:   /* record this structure in the symbol and string tables */
        !           148:     *nl = nlconst;
        !           149:     nl->n_un.n_strx = str_tbl->len;
        !           150:     nl->n_value = pc + 6*LONG + align(len);  /* relative code address */
        !           151:     nl++;
        !           152:     add_name(file);
        !           153: 
        !           154:     if (read(fd, s, n) != n)
        !           155:        die("read");
        !           156:     s += n;
        !           157:     for (i = align(n); i > n; i--)
        !           158:        *s++ = 0;
        !           159: 
        !           160:     if (close(fd) == -1)
        !           161:        die("close");
        !           162: 
        !           163:     assert(s - nbytes == (char *) buf);
        !           164:     write(1, buf, nbytes);
        !           165:     return nbytes;
        !           166: }
        !           167: 
        !           168: int main(argc, argv)
        !           169:     int argc;
        !           170:     char *argv[];
        !           171: {
        !           172:     long pc = 0;
        !           173:     struct exec exec;
        !           174:     struct nlist *nlbase;
        !           175:     struct relocation_info *relbase;
        !           176:     int i, sz;
        !           177: 
        !           178:   /* allocate space for the string table */
        !           179:     sz = strlen(SYMBOL)+strlen(END_SYMBOL)+LONG+1;
        !           180:     for (i = 1;         i < argc;  i++)
        !           181:        sz += strlen(argv[i])+2;
        !           182:     str_tbl = (struct str_table *) malloc(align(sz));
        !           183:     if ((long)str_tbl == NULL)
        !           184:        die("malloc(str_tbl)");
        !           185: 
        !           186:   /* initialize the string table buffer with the "_datalist" string */
        !           187:     str_ptr = str_tbl->strs;
        !           188:     strcpy(str_ptr, SYMBOL);
        !           189:     str_ptr += strlen(SYMBOL)+1;
        !           190:     str_tbl->len = LONG + strlen(SYMBOL)+1;
        !           191: 
        !           192:   /* Allocate space for nlist and reloc info buffers */
        !           193:     nl = nlbase = (struct nlist *) malloc((argc+1) * sizeof(struct nlist));
        !           194:     if ((long) nl == NULL)
        !           195:        die("malloc(nl)");
        !           196:     rel = relbase = (struct relocation_info *) malloc(3 * argc * RELINFO_SZ);
        !           197:     if ((long) rel == NULL)
        !           198:        die("malloc(rel)");
        !           199: 
        !           200:   /* build a nlist constant to initialize from, and initialize the datalist entry. */
        !           201:     nlconst.n_other    = 0;
        !           202:     nlconst.n_desc     = 0;
        !           203:     if (argc > 1) {
        !           204:        nlconst.n_type  = N_EXT | N_TEXT;       /* global in text area */
        !           205:        nlconst.n_value = 4;                    /* for datalist */
        !           206:     }
        !           207:     else {
        !           208:       /* Actually, there is only one symbol (ie., datalist) */
        !           209:        nlconst.n_type  = N_EXT | N_ABS;
        !           210:        nlconst.n_value = 1;    /* ML zero */
        !           211:     }
        !           212:     *nl = nlconst; (nl++)->n_un.n_strx = 4; /* datalist, first string table entry */
        !           213: 
        !           214:   /* build a relocation constant to assign from */
        !           215: #ifdef SPARC
        !           216:     rconst.r_address   = 0;
        !           217:     rconst.r_index     = N_TEXT;
        !           218:     rconst.r_extern    = 0;       /* r_index is the segment (text) */
        !           219:     rconst.r_type      = RELOC_32;
        !           220:     rconst.r_addend    = 0;
        !           221: #else
        !           222:     rconst.r_address   = 0;
        !           223:     rconst.r_symbolnum = 4; /* i don't know why this works.  magic? */
        !           224:     rconst.r_pcrel     = 0;
        !           225:     rconst.r_length    = 2; /* long */
        !           226:     rconst.r_extern    = 0;
        !           227: #endif
        !           228: 
        !           229:   /* initialize the header, we fill in the text size info later */
        !           230: #ifdef M68
        !           231:     exec.a_machtype = M_68020;
        !           232: #endif
        !           233: #ifdef SPARC
        !           234:     exec.a_dynamic     = 0;
        !           235:     exec.a_machtype    = M_SPARC;
        !           236:     exec.a_toolversion = 1;
        !           237: #endif
        !           238:     exec.a_magic    = OMAGIC;
        !           239:     exec.a_data            = 0;
        !           240:     exec.a_bss     = 0;
        !           241:   /* one per mo plus "datalist" and "_endmo" */
        !           242:     exec.a_syms            = (argc+1) * sizeof(struct nlist);
        !           243:     exec.a_entry    = 0;
        !           244:     exec.a_drsize   = 0;
        !           245:     if (write(1, &exec, sizeof exec) == -1)
        !           246:        die("write");
        !           247: 
        !           248:     for (i=1; i<argc; i++)
        !           249:        pc += link(argv[i], pc, i==argc-1);
        !           250: 
        !           251:     exec.a_text            = pc;
        !           252:     exec.a_trsize   = (rel - relbase) * RELINFO_SZ;
        !           253: 
        !           254:     if (write(1, relbase, exec.a_trsize) == -1)
        !           255:        die("write(rel)");
        !           256: 
        !           257:   /* Add "_endmo" to the name list and string table */
        !           258:     *nl = nlconst;
        !           259:     nl->n_un.n_strx = str_tbl->len;
        !           260:     nl->n_type     = N_EXT | N_TEXT;
        !           261:     nl->n_value            = pc;
        !           262:     nl++;
        !           263:     strcpy(str_ptr, END_SYMBOL);
        !           264:     str_tbl->len += strlen(END_SYMBOL)+1;
        !           265: 
        !           266:   /* write out the symbol table. */
        !           267:     if (write(1, nlbase, exec.a_syms) == -1)
        !           268:        die("write(nl)");
        !           269: 
        !           270:   /* write out the string table */
        !           271:     if (write(1, str_tbl, str_tbl->len) == -1)
        !           272:        die("write(str_tbl)");
        !           273:     
        !           274:   /* update the header to reflect the true text size */
        !           275:     if (lseek(1, 0, 0L) == -1)
        !           276:        die("lseek");
        !           277:     if (write(1, &exec, sizeof exec) == -1)
        !           278:        die("write(exec)");
        !           279: 
        !           280:     return 0;
        !           281: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.