Annotation of researchv10no/cmd/sml/src/runtime/linkdata.c, revision 1.1.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.