date and time created 88/07/22 16:08:01 by bostic
[unix-history] / usr / src / old / as.vax / asmain.c
index 8747263..f8d32cc 100644 (file)
@@ -1,28 +1,37 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char sccsid[] = "@(#)asmain.c 4.3 %G%";
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1982 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)asmain.c   5.3 (Berkeley) %G%";
+#endif not lint
+
 #include <stdio.h>
 #include <ctype.h>
 #include <signal.h>
 
 #include "as.h"
 #include "assyms.h"
 #include <stdio.h>
 #include <ctype.h>
 #include <signal.h>
 
 #include "as.h"
 #include "assyms.h"
-#include "asexpr.h"
 #include "asscan.h"
 #include "asscan.h"
+#include "asexpr.h"
 
 
-#ifdef UNIX
-#define        unix_lang_name "VAX/UNIX Assembler Vasmain.c"
-#endif
-
-#ifdef VMS
-#define vms_lang_name "VAX/VMS C Assembler V1.00"
-#endif VMS
+#include <sys/stat.h>
 
 
+#define        unix_lang_name "VAX/UNIX Assembler V%G% 5.3"
 /*
  *     variables to manage reading the assembly source files
  */
 char   *dotsname;      /*the current file name; managed by the parser*/
 int    lineno;         /*current line number; managed by the parser*/
 /*
  *     variables to manage reading the assembly source files
  */
 char   *dotsname;      /*the current file name; managed by the parser*/
 int    lineno;         /*current line number; managed by the parser*/
-char   *innames[32];   /*names of the files being assembled*/
+char   **innames;      /*names of the files being assembled*/
 int    ninfiles;       /*how many interesting files there are*/
 /*
  *     Flags settable from the argv process argument list
 int    ninfiles;       /*how many interesting files there are*/
 /*
  *     Flags settable from the argv process argument list
@@ -30,23 +39,24 @@ int ninfiles;       /*how many interesting files there are*/
 int    silent = 0;     /*don't complain about any errors*/
 int    savelabels = 0; /*write the labels to the a.out file*/
 int    d124 = 4;       /*default allocate 4 bytes for unknown pointers*/
 int    silent = 0;     /*don't complain about any errors*/
 int    savelabels = 0; /*write the labels to the a.out file*/
 int    d124 = 4;       /*default allocate 4 bytes for unknown pointers*/
+int    maxalign = 2;   /*default .align maximum*/
 int    anyerrs = 0;    /*no errors yet*/
 int    anyerrs = 0;    /*no errors yet*/
+int    anywarnings=0;  /*no warnings yet*/
 int    orgwarn = 0;    /*Bad origins*/
 int    passno = 1;     /* current pass*/
 int    jxxxJUMP = 0;   /* in jxxxes that branch too far, use jmp instead of brw */
 int    orgwarn = 0;    /*Bad origins*/
 int    passno = 1;     /* current pass*/
 int    jxxxJUMP = 0;   /* in jxxxes that branch too far, use jmp instead of brw */
+int    readonlydata = 0;       /* initialzed data -> text space */
+
+int    nGHnumbers = 0;         /* GH numbers used */
+int    nGHopcodes = 0;         /* GH opcodes used */
+int    nnewopcodes = 0;        /* new opcodes used */
 
 #ifdef DEBUG
 int    debug = 0;
 int    toktrace = 0;
 #endif
 
 
 #ifdef DEBUG
 int    debug = 0;
 int    toktrace = 0;
 #endif
 
-int    useVM =         /*put the temp file in virtual memory*/
-#ifdef VMS
-       1;              /*VMS has virtual memory (duh)*/
-#endif VMS
-#ifdef UNIX
-       0;
-#endif
+int    useVM = 0;
 
 char   *endcore;       /*where to get more symbol space*/
 
 
 char   *endcore;       /*where to get more symbol space*/
 
@@ -54,7 +64,7 @@ char  *endcore;       /*where to get more symbol space*/
  *     Managers of the a.out file.
  */
 struct exec    hdr;
  *     Managers of the a.out file.
  */
 struct exec    hdr;
-#define        MAGIC   0410
+#define        MAGIC   0407
 u_long tsize;          /* total text size */
 u_long dsize;          /* total data size */
 u_long datbase;        /* base of the data segment */
 u_long tsize;          /* total text size */
 u_long dsize;          /* total data size */
 u_long datbase;        /* base of the data segment */
@@ -71,11 +81,19 @@ u_long      drsize;         /* total data relocation size */
 struct exp     usedot[NLOC+NLOC];      /* info about all segments */
 struct exp     *dotp;                  /* data/text location pointer */
 /*
 struct exp     usedot[NLOC+NLOC];      /* info about all segments */
 struct exp     *dotp;                  /* data/text location pointer */
 /*
- *     The inter pass temporary file is opened and closed by stdio, but
+ *     The inter pass temporary token file is opened and closed by stdio, but
  *     is written to using direct read/write, as the temporary file
  *     is composed of buffers exactly BUFSIZ long.
  */
  *     is written to using direct read/write, as the temporary file
  *     is composed of buffers exactly BUFSIZ long.
  */
-FILE   *tmpfil;                        /* interpass communication file */
+FILE   *tokfile;                       /* interpass communication file */
+char   tokfilename[TNAMESIZE];
+/*
+ *     The string file is the string table
+ *     cat'ed to the end of the built up a.out file
+ */
+FILE   *strfile;                       /* interpass string file */
+char   strfilename[TNAMESIZE];
+int    strfilepos = 0;                 /* position within the string file */
 /*
  *     a.out is created during the second pass.
  *     It is opened by stdio, but is filled with the parallel
 /*
  *     a.out is created during the second pass.
  *     It is opened by stdio, but is filled with the parallel
@@ -152,26 +170,18 @@ BFILE     *relocfile;                     /* concatnated relocation info */
  *
  *     We use relfil to output the symbol table information.
  */
  *
  *     We use relfil to output the symbol table information.
  */
-
-char   *tmpdirprefix =
-#ifdef UNIX
-                       "/tmp/";
-#else VMS
-                       "/usr/tmp/";
-#endif
-
-#define                TMP_SUFFIX      "asXXXXXX"
-char           tmpn1[TNAMESIZE];
-
+char   *tmpdirprefix = "/tmp/";
 int delexit();
 
 main(argc, argv)
        int     argc;
        char    **argv;
 {
 int delexit();
 
 main(argc, argv)
        int     argc;
        char    **argv;
 {
+       char    *sbrk();
 
 
-       tmpn1[0] = 0;
-       endcore = (char *)sbrk(0);
+       tokfilename[0] = 0;
+       strfilename[0] = 0;
+       endcore = sbrk(0);
 
        argprocess(argc, argv);         /* process argument lists */
        if (anyerrs) exit(1);
 
        argprocess(argc, argv);         /* process argument lists */
        if (anyerrs) exit(1);
@@ -205,8 +215,18 @@ main(argc, argv)
 
        if (anyerrs == 0 && orgwarn)
                yyerror("Caution: absolute origins.\n");
 
        if (anyerrs == 0 && orgwarn)
                yyerror("Caution: absolute origins.\n");
+
+       if (nGHnumbers)
+               yywarning("Caution: G or H format floating point numbers");
+       if (nGHopcodes)
+               yywarning("Caution: G or H format floating point operators");
+       if (nnewopcodes)
+               yywarning("Caution: New Opcodes");
+       if (nGHnumbers || nGHopcodes || nnewopcodes)
+               yywarning("These are not defined for all implementations of the VAX architecture.\n");
+
        exit(anyerrs != 0);
        exit(anyerrs != 0);
-}      /*end of UNIX main*/
+}
 
 argprocess(argc, argv)
        int     argc;
 
 argprocess(argc, argv)
        int     argc;
@@ -219,9 +239,12 @@ argprocess(argc, argv)
 #ifdef DEBUG
        debug = 0;
 #endif
 #ifdef DEBUG
        debug = 0;
 #endif
+       innames = (char **)ClearCalloc(argc+1, sizeof (innames[0]));
        dotsname = "<argv error>";
        while (argc > 1) {
        dotsname = "<argv error>";
        while (argc > 1) {
-               if (argv[1][0] == '-'){
+               if (argv[1][0] != '-')
+                       innames[ninfiles++] = argv[1];
+               else {
                        cp = argv[1] + 1;
                        /*
                         *      We can throw away single minus signs, so
                        cp = argv[1] + 1;
                        /*
                         *      We can throw away single minus signs, so
@@ -234,6 +257,9 @@ argprocess(argc, argv)
                                        yyerror("Unknown flag: %c", *--cp);
                                        cp++;
                                        break;
                                        yyerror("Unknown flag: %c", *--cp);
                                        cp++;
                                        break;
+                                case 'v':
+                                       selfwhat(stdout);
+                                       exit(1);
                                 case 'd':
                                        d124 = *cp++ - '0';
                                        if ( (d124 != 1) && (d124 != 2) && 
                                 case 'd':
                                        d124 = *cp++ - '0';
                                        if ( (d124 != 1) && (d124 != 2) && 
@@ -242,6 +268,15 @@ argprocess(argc, argv)
                                                exit(1);
                                        }
                                        break;
                                                exit(1);
                                        }
                                        break;
+                                case 'a':
+                                       maxalign = atoi(cp+1);
+                                       for (cp++; isdigit(*cp); cp++)
+                                               /*VOID*/;
+                                       if ( (maxalign > 16) || (maxalign < 0)){
+                                               yyerror("-a: 0<=align<=16");
+                                               exit(1);
+                                       }
+                                       break;
                                 case 'o':
                                        if (argc < 3){
                                                yyerror("-o what???");
                                 case 'o':
                                        if (argc < 3){
                                                yyerror("-o what???");
@@ -281,19 +316,47 @@ argprocess(argc, argv)
                                        toktrace = 1;
                                        break;
 #endif
                                        toktrace = 1;
                                        break;
 #endif
+                                case 'R':
+                                       readonlydata = 1;
+                                       break;
                                }       /*end of the switch*/
                        }       /*end of pulling out all arguments*/
                }       /*end of a flag argument*/
                                }       /*end of the switch*/
                        }       /*end of pulling out all arguments*/
                }       /*end of a flag argument*/
-               else {  /*file name*/
-                       if (ninfiles > 32){
-                               yyerror("More than 32 file names");
-                               exit(3);
-                       }
-                       innames[ninfiles++] = argv[1];
-               }
                --argc; ++argv;
           nextarg:;
        }
                --argc; ++argv;
           nextarg:;
        }
+       /* innames[ninfiles] = 0; */
+}
+/*
+ *     poke through the data space and find all sccs identifiers.
+ *     We assume:
+ *     a) that extern char **environ; is the first thing in the bss
+ *     segment (true, if one is using the new version of cmgt.crt0.c)
+ *     b) that the sccsid's have not been put into text space.
+ */
+selfwhat(place)
+       FILE    *place;
+{
+       extern  char **environ;
+       register        char    *ub;
+       register        char *cp;
+       register        char    *pat;
+       char    *sbrk();
+
+       for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){
+               if (cp[0] != '@') continue;
+               if (cp[1] != '(') continue;
+               if (cp[2] != '#') continue;
+               if (cp[3] != ')') continue;
+               fputc('\t', place);
+               for (cp += 4; cp < ub; cp++){
+                       if (*cp == 0) break;
+                       if (*cp == '>') break;
+                       if (*cp == '\n') break;
+                       fputc(*cp, place);
+               }
+               fputc('\n', place);
+       }
 }
 
 initialize()
 }
 
 initialize()
@@ -323,8 +386,6 @@ zeroorigins()
                usedot[NLOC + locindex].e_xtype = XDATA;
                usedot[locindex].e_xvalue = 0;
                usedot[NLOC + locindex].e_xvalue = 0;
                usedot[NLOC + locindex].e_xtype = XDATA;
                usedot[locindex].e_xvalue = 0;
                usedot[NLOC + locindex].e_xvalue = 0;
-               usedot[locindex].e_yvalue = 0;
-               usedot[NLOC + locindex].e_yvalue = 0;
        }
 }
 
        }
 }
 
@@ -340,21 +401,40 @@ zerolocals()
 
 i_pass1()
 {
 
 i_pass1()
 {
-       if (useVM == 0){
-               strcat(tmpn1, tmpdirprefix);
-               strcat(tmpn1, TMP_SUFFIX);
-               mktemp(tmpn1);
-               tmpfil = fopen(tmpn1, "w");
-               if (tmpfil==NULL) {
-                 yyerror("Bad pass 1 temporary file for writing %s", tmpn1);
-                 delexit();
-               }
-       }
+       FILE    *tempopen();
+       if (useVM == 0)
+               tokfile = tempopen(tokfilename, "T");
+       strfile = tempopen(strfilename, "S");
+       /*
+        *      write out the string length.
+        *      This will be overwritten when the
+        *      strings are tacked onto the growing a.out file
+        */
+       strfilepos = sizeof(int);
+       fwrite(&strfilepos, sizeof(int), 1, strfile);
 
 
-       inittmpfile();
+       inittokfile();
        initijxxx();
 }
 
        initijxxx();
 }
 
+FILE *tempopen(tname, part)
+       char    *tname;
+       char    *part;
+{
+       FILE    *file;
+       (void)sprintf(tname, "%s%sas%s%05d",
+               tmpdirprefix,
+               (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : "",
+               part,
+               getpid());
+       file = fopen(tname, "w");
+       if (file == NULL) {
+               yyerror("Bad pass 1 temporary file for writing %s", tname);
+               delexit();
+       }
+       return(file);
+}
+
 pass1()
 {
        register        int     i;
 pass1()
 {
        register        int     i;
@@ -383,7 +463,7 @@ pass1()
                }
        }
 
                }
        }
 
-       closetmpfile();         /*kick out the last buffered intermediate text*/
+       closetokfile();         /*kick out the last buffered intermediate text*/
 }
 
 testlocals()
 }
 
 testlocals()
@@ -411,6 +491,8 @@ pass1_5()
 
 open_a_out()
 {
 
 open_a_out()
 {
+       struct stat stb;
+
        /*
         *      Open up the a.out file now, and get set to build
         *      up offsets into it for all of the various text,data
        /*
         *      Open up the a.out file now, and get set to build
         *      up offsets into it for all of the various text,data
@@ -422,6 +504,8 @@ open_a_out()
                delexit();
        }
        biofd = a_out_file->_file;
                delexit();
        }
        biofd = a_out_file->_file;
+       fstat(biofd, &stb);
+       biobufsize = stb.st_blksize;
        a_out_off = 0;
 }
 
        a_out_off = 0;
 }
 
@@ -451,7 +535,7 @@ roundsegments()
        /*
         *              Round and assign data segment origins.
         */
        /*
         *              Round and assign data segment origins.
         */
-       datbase = round(tsize, PAGRND);
+       datbase = round(tsize, FW);
        for (locindex=0; locindex<NLOC; locindex++) {
                v = round(usedot[NLOC+locindex].e_xvalue, FW);
                usedot[NLOC+locindex].e_xvalue = datbase + dsize;
        for (locindex=0; locindex<NLOC; locindex++) {
                v = round(usedot[NLOC+locindex].e_xvalue, FW);
                usedot[NLOC+locindex].e_xvalue = datbase + dsize;
@@ -504,13 +588,15 @@ build_hdr()
 i_pass2()
 {
        if (useVM == 0) {
 i_pass2()
 {
        if (useVM == 0) {
-               fclose(tmpfil);
-               tmpfil = fopen(tmpn1, "r");
-               if (tmpfil==NULL) {
-                  yyerror("Bad pass 2 temporary file for reading %s", tmpn1);
+               fclose(tokfile);
+               tokfile = fopen(tokfilename, "r");
+               if (tokfile==NULL) {
+                  yyerror("Bad pass 2 temporary file for reading %s", tokfilename);
                   delexit();
                }
        }
                   delexit();
                }
        }
+       fclose(strfile);
+       strfile = fopen(strfilename, "r");
 }
 
 pass2()
 }
 
 pass2()
@@ -526,11 +612,11 @@ pass2()
        relfil = 0;             /* outrel takes care of the rest */
        initoutrel();
 
        relfil = 0;             /* outrel takes care of the rest */
        initoutrel();
 
-       inittmpfile();
+       inittokfile();
 
        yyparse();
 
 
        yyparse();
 
-       closetmpfile();
+       closetokfile();
 }
 
 fillsegments()
 }
 
 fillsegments()
@@ -563,16 +649,26 @@ reloc_syms()
 
        hdr.a_trsize = trsize;
        hdr.a_drsize = drsize;
 
        hdr.a_trsize = trsize;
        hdr.a_drsize = drsize;
+       if (readonlydata) {
+               hdr.a_text += hdr.a_data;
+               hdr.a_data = 0;
+               hdr.a_trsize += hdr.a_drsize;
+               hdr.a_drsize = 0;
+       }
        /*
        /*
-        *      Output the symbol table
-        *      and if FLEXNAMES is set, the string pool
+        *      Output the symbol table and the string pool
+        *
+        *      We must first rewind the string pool file to its beginning,
+        *      in case it was seek'ed into for fetching ascii and asciz
+        *      strings.
         */
         */
+       fseek(strfile, 0, 0);
        symwrite(relocfile);
 }
 
 fix_a_out()
 {
        symwrite(relocfile);
 }
 
 fix_a_out()
 {
-       if (lseek(a_out_file->_file, 0L, 0) < 0)
+       if (lseek(a_out_file->_file, 0L, 0) < 0L)
                yyerror("Reposition for header rewrite fails");
        if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0)
                yyerror("Rewrite of header fails");
                yyerror("Reposition for header rewrite fails");
        if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0)
                yyerror("Rewrite of header fails");
@@ -589,8 +685,10 @@ delexit()
 
 delete()
 {
 
 delete()
 {
-       if (useVM == 0 || tmpn1[0])
-               unlink(tmpn1);
+       if (useVM == 0 || tokfilename[0])
+               unlink(tokfilename);
+       if (strfilename[0])
+               unlink(strfilename);
 }
 
 sawabort()
 }
 
 sawabort()